W1: split master mutex to avoid deadlocks.
[firefly-linux-kernel-4.4.55.git] / drivers / w1 / w1.c
index 2f2e894ea0c84e23392db10c0fb4e46b25b00ab3..1a574370d2cd22ec4686604520c9f139052afba9 100644 (file)
@@ -557,7 +557,7 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
        struct w1_master *md = NULL;
        struct w1_slave *sl = NULL;
        char *event_owner, *name;
-       int err;
+       int err = 0;
 
        if (dev->driver == &w1_master_driver) {
                md = container_of(dev, struct w1_master, dev);
@@ -576,19 +576,17 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
                        event_owner, name, dev_name(dev));
 
        if (dev->driver != &w1_slave_driver || !sl)
-               return 0;
+               goto end;
 
        err = add_uevent_var(env, "W1_FID=%02X", sl->reg_num.family);
        if (err)
-               return err;
+               goto end;
 
        err = add_uevent_var(env, "W1_SLAVE_ID=%024LX",
                             (unsigned long long)sl->reg_num.id);
-       if (err)
-               return err;
-
-       return 0;
-};
+end:
+       return err;
+}
 #else
 static int w1_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
@@ -887,16 +885,21 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
                 *
                 * Return 0 - device(s) present, 1 - no devices present.
                 */
+               mutex_lock(&dev->bus_mutex);
                if (w1_reset_bus(dev)) {
+                       mutex_unlock(&dev->bus_mutex);
                        dev_dbg(&dev->dev, "No devices present on the wire.\n");
                        break;
                }
 
                /* Do fast search on single slave bus */
                if (dev->max_slave_count == 1) {
+                       int rv;
                        w1_write_8(dev, W1_READ_ROM);
+                       rv = w1_read_block(dev, (u8 *)&rn, 8);
+                       mutex_unlock(&dev->bus_mutex);
 
-                       if (w1_read_block(dev, (u8 *)&rn, 8) == 8 && rn)
+                       if (rv == 8 && rn)
                                cb(dev, rn);
 
                        break;
@@ -929,10 +932,12 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
                        rn |= (tmp64 << i);
 
                        if (kthread_should_stop()) {
+                               mutex_unlock(&dev->bus_mutex);
                                dev_dbg(&dev->dev, "Abort w1_search\n");
                                return;
                        }
                }
+               mutex_unlock(&dev->bus_mutex);
 
                if ( (triplet_ret & 0x03) != 0x03 ) {
                        if ( (desc_bit == last_zero) || (last_zero < 0))