]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'extcon-fixes-for-4.16-rc3' of git://git.kernel.org/pub/scm/linux/kernel...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Feb 2018 07:57:23 +0000 (08:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 20 Feb 2018 07:57:23 +0000 (08:57 +0100)
Chanwoo writes:

Update extcon for v4.16-rc3

This patch fixes issue of X-power extcon-axp288 and Intel extcon-int3496 driver.
- For extcon-int3496 driver,
Process id-pin first so that we start with the right status in order to fix
a race where the initial work might still be running while other drivers
were already calling extcon_get_state().
- For extcon-axp288 driver,
Revert the patch[1] which were applied to v4.16-rc1 because there are better
ways with usb-role-switch and constify the axp288_pwr_up_down_info array.
[1] 60ed99961469a3 ("extcon: axp288: Redo charger type detection a couple of seconds after probe()")

drivers/android/binder.c
drivers/misc/mei/bus.c
drivers/misc/mei/client.c

index 15e3d3c2260ddc915f49732f1076f3a7ee0f540e..764b63a5aadefe5c73ef849ee5b377b134e3841e 100644 (file)
@@ -1991,8 +1991,14 @@ static void binder_send_failed_reply(struct binder_transaction *t,
                                        &target_thread->reply_error.work);
                                wake_up_interruptible(&target_thread->wait);
                        } else {
-                               WARN(1, "Unexpected reply error: %u\n",
-                                               target_thread->reply_error.cmd);
+                               /*
+                                * Cannot get here for normal operation, but
+                                * we can if multiple synchronous transactions
+                                * are sent without blocking for responses.
+                                * Just ignore the 2nd error in this case.
+                                */
+                               pr_warn("Unexpected reply error: %u\n",
+                                       target_thread->reply_error.cmd);
                        }
                        binder_inner_proc_unlock(target_thread->proc);
                        binder_thread_dec_tmpref(target_thread);
@@ -2193,7 +2199,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
        int debug_id = buffer->debug_id;
 
        binder_debug(BINDER_DEBUG_TRANSACTION,
-                    "%d buffer release %d, size %zd-%zd, failed at %p\n",
+                    "%d buffer release %d, size %zd-%zd, failed at %pK\n",
                     proc->pid, buffer->debug_id,
                     buffer->data_size, buffer->offsets_size, failed_at);
 
@@ -3705,7 +3711,7 @@ static int binder_thread_write(struct binder_proc *proc,
                                }
                        }
                        binder_debug(BINDER_DEBUG_DEAD_BINDER,
-                                    "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n",
+                                    "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n",
                                     proc->pid, thread->pid, (u64)cookie,
                                     death);
                        if (death == NULL) {
@@ -4376,6 +4382,15 @@ static int binder_thread_release(struct binder_proc *proc,
 
        binder_inner_proc_unlock(thread->proc);
 
+       /*
+        * This is needed to avoid races between wake_up_poll() above and
+        * and ep_remove_waitqueue() called for other reasons (eg the epoll file
+        * descriptor being closed); ep_remove_waitqueue() holds an RCU read
+        * lock, so we can be sure it's done after calling synchronize_rcu().
+        */
+       if (thread->looper & BINDER_LOOPER_STATE_POLL)
+               synchronize_rcu();
+
        if (send_reply)
                binder_send_failed_reply(send_reply, BR_DEAD_REPLY);
        binder_release_work(proc, &thread->todo);
@@ -4391,6 +4406,8 @@ static __poll_t binder_poll(struct file *filp,
        bool wait_for_proc_work;
 
        thread = binder_get_thread(proc);
+       if (!thread)
+               return POLLERR;
 
        binder_inner_proc_lock(thread->proc);
        thread->looper |= BINDER_LOOPER_STATE_POLL;
@@ -5034,7 +5051,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
        spin_lock(&t->lock);
        to_proc = t->to_proc;
        seq_printf(m,
-                  "%s %d: %p from %d:%d to %d:%d code %x flags %x pri %ld r%d",
+                  "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %ld r%d",
                   prefix, t->debug_id, t,
                   t->from ? t->from->proc->pid : 0,
                   t->from ? t->from->pid : 0,
@@ -5058,7 +5075,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
        }
        if (buffer->target_node)
                seq_printf(m, " node %d", buffer->target_node->debug_id);
-       seq_printf(m, " size %zd:%zd data %p\n",
+       seq_printf(m, " size %zd:%zd data %pK\n",
                   buffer->data_size, buffer->offsets_size,
                   buffer->data);
 }
index 3e5eabdae8d968d92ac9cedd5c83225267513126..772d02922529e2722184d23df7e65891f1b2b596 100644 (file)
@@ -548,12 +548,6 @@ int mei_cldev_disable(struct mei_cl_device *cldev)
                goto out;
        }
 
-       if (bus->dev_state == MEI_DEV_POWER_DOWN) {
-               dev_dbg(bus->dev, "Device is powering down, don't bother with disconnection\n");
-               err = 0;
-               goto out;
-       }
-
        err = mei_cl_disconnect(cl);
        if (err < 0)
                dev_err(bus->dev, "Could not disconnect from the ME client\n");
index be64969d986abcd6e6da6fcec6bb2f019b404a22..7e60c1817c311e0b54a0711c116adb8eea89cf00 100644 (file)
@@ -945,6 +945,12 @@ int mei_cl_disconnect(struct mei_cl *cl)
                return 0;
        }
 
+       if (dev->dev_state == MEI_DEV_POWER_DOWN) {
+               cl_dbg(dev, cl, "Device is powering down, don't bother with disconnection\n");
+               mei_cl_set_disconnected(cl);
+               return 0;
+       }
+
        rets = pm_runtime_get(dev->dev);
        if (rets < 0 && rets != -EINPROGRESS) {
                pm_runtime_put_noidle(dev->dev);