]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
mtd: change struct flchip_shared spinlock locking into mutex
authorStefani Seibold <stefani@seibold.net>
Thu, 5 Aug 2010 07:19:26 +0000 (09:19 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Aug 2010 23:45:54 +0000 (16:45 -0700)
commit 8ae664184c45def51ff0b61d4bd6c6671db6cb4f upstream.

This patch prevent to schedule while atomic by changing the
flchip_shared spinlock into a mutex. This should be save since no atomic
path will use this lock.

It was suggested by Arnd Bergmann and Vasiliy Kulikov.

Signed-off-by: Stefani Seibold <stefani@seibold.net>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/lpddr/lpddr_cmds.c
include/linux/mtd/flashchip.h

index 62f3ea9de848cabfb481014ca0b6176893da5a0f..33640614c51acbbfce39d89c11fa8de194270ba6 100644 (file)
@@ -717,7 +717,7 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
                chip = &newcfi->chips[0];
                for (i = 0; i < cfi->numchips; i++) {
                        shared[i].writing = shared[i].erasing = NULL;
-                       spin_lock_init(&shared[i].lock);
+                       mutex_init(&shared[i].lock);
                        for (j = 0; j < numparts; j++) {
                                *chip = cfi->chips[i];
                                chip->start += j << partshift;
@@ -886,7 +886,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                 */
                struct flchip_shared *shared = chip->priv;
                struct flchip *contender;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                contender = shared->writing;
                if (contender && contender != chip) {
                        /*
@@ -899,7 +899,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                         * get_chip returns success we're clear to go ahead.
                         */
                        ret = mutex_trylock(&contender->mutex);
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        if (!ret)
                                goto retry;
                        mutex_unlock(&chip->mutex);
@@ -914,7 +914,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                                mutex_unlock(&contender->mutex);
                                return ret;
                        }
-                       spin_lock(&shared->lock);
+                       mutex_lock(&shared->lock);
 
                        /* We should not own chip if it is already
                         * in FL_SYNCING state. Put contender and retry. */
@@ -930,7 +930,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                 * on this chip. Sleep. */
                if (mode == FL_ERASING && shared->erasing
                    && shared->erasing->oldstate == FL_ERASING) {
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
                        mutex_unlock(&chip->mutex);
@@ -944,7 +944,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
                shared->writing = chip;
                if (mode == FL_ERASING)
                        shared->erasing = chip;
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
        ret = chip_ready(map, chip, adr, mode);
        if (ret == -EAGAIN)
@@ -959,7 +959,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
 
        if (chip->priv) {
                struct flchip_shared *shared = chip->priv;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                if (shared->writing == chip && chip->oldstate == FL_READY) {
                        /* We own the ability to write, but we're done */
                        shared->writing = shared->erasing;
@@ -967,7 +967,7 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                                /* give back ownership to who we loaned it from */
                                struct flchip *loaner = shared->writing;
                                mutex_lock(&loaner->mutex);
-                               spin_unlock(&shared->lock);
+                               mutex_unlock(&shared->lock);
                                mutex_unlock(&chip->mutex);
                                put_chip(map, loaner, loaner->start);
                                mutex_lock(&chip->mutex);
@@ -985,11 +985,11 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
                         * Don't let the switch below mess things up since
                         * we don't have ownership to resume anything.
                         */
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        wake_up(&chip->wq);
                        return;
                }
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        switch(chip->oldstate) {
index fece5be587156b76f39d884ec62ca19bfc3e4db9..04fdfcca93f72b2db3c2b24ba41ddc913813fe98 100644 (file)
@@ -98,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
        numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
        for (i = 0; i < numchips; i++) {
                shared[i].writing = shared[i].erasing = NULL;
-               spin_lock_init(&shared[i].lock);
+               mutex_init(&shared[i].lock);
                for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
                        *chip = lpddr->chips[i];
                        chip->start += j << lpddr->chipshift;
@@ -217,7 +217,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                 */
                struct flchip_shared *shared = chip->priv;
                struct flchip *contender;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                contender = shared->writing;
                if (contender && contender != chip) {
                        /*
@@ -230,7 +230,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                         * get_chip returns success we're clear to go ahead.
                         */
                        ret = mutex_trylock(&contender->mutex);
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        if (!ret)
                                goto retry;
                        mutex_unlock(&chip->mutex);
@@ -245,7 +245,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                                mutex_unlock(&contender->mutex);
                                return ret;
                        }
-                       spin_lock(&shared->lock);
+                       mutex_lock(&shared->lock);
 
                        /* We should not own chip if it is already in FL_SYNCING
                         * state. Put contender and retry. */
@@ -261,7 +261,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                   Must sleep in such a case. */
                if (mode == FL_ERASING && shared->erasing
                    && shared->erasing->oldstate == FL_ERASING) {
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
                        mutex_unlock(&chip->mutex);
@@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode)
                shared->writing = chip;
                if (mode == FL_ERASING)
                        shared->erasing = chip;
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        ret = chip_ready(map, chip, mode);
@@ -348,7 +348,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
 {
        if (chip->priv) {
                struct flchip_shared *shared = chip->priv;
-               spin_lock(&shared->lock);
+               mutex_lock(&shared->lock);
                if (shared->writing == chip && chip->oldstate == FL_READY) {
                        /* We own the ability to write, but we're done */
                        shared->writing = shared->erasing;
@@ -356,7 +356,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
                                /* give back the ownership */
                                struct flchip *loaner = shared->writing;
                                mutex_lock(&loaner->mutex);
-                               spin_unlock(&shared->lock);
+                               mutex_unlock(&shared->lock);
                                mutex_unlock(&chip->mutex);
                                put_chip(map, loaner);
                                mutex_lock(&chip->mutex);
@@ -374,11 +374,11 @@ static void put_chip(struct map_info *map, struct flchip *chip)
                         * Don't let the switch below mess things up since
                         * we don't have ownership to resume anything.
                         */
-                       spin_unlock(&shared->lock);
+                       mutex_unlock(&shared->lock);
                        wake_up(&chip->wq);
                        return;
                }
-               spin_unlock(&shared->lock);
+               mutex_unlock(&shared->lock);
        }
 
        switch (chip->oldstate) {
index f43e9b49b751bd479e033e154cc0440689f9ff52..23cc10f8e3435f1cccbecd293ba068e6e8317afb 100644 (file)
@@ -92,7 +92,7 @@ struct flchip {
 /* This is used to handle contention on write/erase operations
    between partitions of the same physical chip. */
 struct flchip_shared {
-       spinlock_t lock;
+       struct mutex lock;
        struct flchip *writing;
        struct flchip *erasing;
 };