Re: [PATCH v15 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-07-10 Thread Baolin Wang
Hi Felipe,

On 1 July 2016 at 14:05, Baolin Wang <baolin.w...@linaro.org> wrote:
> Currently the Linux kernel does not provide any standard integration of this
> feature that integrates the USB subsystem with the system power regulation
> provided by PMICs meaning that either vendors must add this in their kernels
> or USB gadget devices based on Linux (such as mobile phones) may not behave
> as they should. Thus provide a standard framework for doing this in kernel.
>
> Now introduce one user with wm831x_power to support and test the usb charger,
> which is pending testing. Moreover there may be other potential users will use
> it in future.
>
> Changes since v14:
>  - Add kernel documentation for struct usb_cahrger.
>  - Remove some redundant WARN() functions.
>
> Changes since v13:
>  - Remove the charger checking in usb_gadget_vbus_draw() function.
>  - Rename some functions in charger.c file.
>  - Rebase on git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git 
> tags/usb-for-v4.8
>
> Changes since v12:
>  - Remove the class and device things.
>  - Link usb charger to udc-core.ko.
>  - Create one "charger" subdirectory which holds all charger-related 
> attributes.
>
> Changes since v11:
>  - Reviewed and tested by Li Jun.
>
> Changes since v10:
>  - Introduce usb_charger_get_state() function to check charger state.
>  - Remove the mutex lock in usb_charger_set_cur_limit_by_type() function
>  in case will be issued in atomic context.
>
> Baolin Wang (4):
>   usb: gadget: Introduce the usb charger framework
>   usb: gadget: Support for the usb charger framework
>   usb: gadget: Integrate with the usb gadget supporting for usb charger
>   power: wm831x_power: Support USB charger current limit management
>
>  drivers/power/wm831x_power.c |   69 
>  drivers/usb/gadget/Kconfig   |8 +
>  drivers/usb/gadget/udc/Makefile  |1 +
>  drivers/usb/gadget/udc/charger.c |  738 
> ++
>  drivers/usb/gadget/udc/core.c|   17 +
>  include/linux/mfd/wm831x/pdata.h |3 +
>  include/linux/usb/charger.h  |  183 ++
>  include/linux/usb/gadget.h   |3 +
>  include/uapi/linux/usb/charger.h |   31 ++
>  9 files changed, 1053 insertions(+)
>  create mode 100644 drivers/usb/gadget/udc/charger.c
>  create mode 100644 include/linux/usb/charger.h
>  create mode 100644 include/uapi/linux/usb/charger.h
>
> --
> 1.7.9.5
>

Do you have any other comments about this v15 patchset? If not, could
you please add this version patchset into your 'next' branch? Thanks a
lot.

-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: gadget: f_midi: Add checking if it need align buffer's size to an ep's maxpacketsize

2016-07-07 Thread Baolin Wang
On 7 July 2016 at 20:51, Michal Nazarewicz <min...@mina86.com> wrote:
> On Thu, Jul 07 2016, Baolin Wang wrote:
>> Some gadget device (such as dwc3 gadget) requires quirk_ep_out_aligned_size
>> attribute, which means it need to align the request buffer's size to an ep's
>> maxpacketsize.
>>
>> Thus we add usb_ep_align_maybe() function to check if it is need to align
>> the request buffer's size to an ep's maxpacketsize.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>
> Acked-by: Michal Nazarewicz <min...@mina86.com>
>
>> ---
>>  drivers/usb/gadget/function/f_midi.c |   18 +++---
>>  1 file changed, 11 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/usb/gadget/function/f_midi.c 
>> b/drivers/usb/gadget/function/f_midi.c
>> index 58fc199..2e3f11e 100644
>> --- a/drivers/usb/gadget/function/f_midi.c
>> +++ b/drivers/usb/gadget/function/f_midi.c
>> @@ -328,7 +328,7 @@ static int f_midi_start_ep(struct f_midi *midi,
>>  static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned 
>> alt)
>>  {
>>   struct f_midi *midi = func_to_midi(f);
>> - unsigned i;
>> + unsigned i, length;
>>   int err;
>>
>>   /* we only set alt for MIDIStreaming interface */
>> @@ -345,9 +345,11 @@ static int f_midi_set_alt(struct usb_function *f, 
>> unsigned intf, unsigned alt)
>>
>>   /* pre-allocate write usb requests to use on f_midi_transmit. */
>>   while (kfifo_avail(>in_req_fifo)) {
>> - struct usb_request *req =
>> - midi_alloc_ep_req(midi->in_ep, midi->buflen);
>> + struct usb_request *req;
>>
>> + length = usb_ep_align_maybe(midi->gadget, midi->in_ep,
>> + midi->buflen);
>> + req = midi_alloc_ep_req(midi->in_ep, length);
>>   if (req == NULL)
>>   return -ENOMEM;
>>
>> @@ -359,10 +361,12 @@ static int f_midi_set_alt(struct usb_function *f, 
>> unsigned intf, unsigned alt)
>>
>>   /* allocate a bunch of read buffers and queue them all at once. */
>>   for (i = 0; i < midi->qlen && err == 0; i++) {
>> - struct usb_request *req =
>> - midi_alloc_ep_req(midi->out_ep,
>> - max_t(unsigned, midi->buflen,
>> - bulk_out_desc.wMaxPacketSize));
>> + struct usb_request *req;
>> +
>> + length = usb_ep_align_maybe(midi->gadget, midi->out_ep,
>> + midi->buflen);
>> + req = midi_alloc_ep_req(midi->out_ep,
>> + max_t(unsigned, length, bulk_out_desc.wMaxPacketSize));
>
> Perhaps:
>
> +   length = midi->buflen < bulk_out_desc.wMaxPacketSize
> +   ? bulk_out_desc.wMaxPacketSize
> +   : usb_ep_align_maybe(midi->gadget, midi->out_ep,
> +midi->buflen);
> +   req = midi_alloc_ep_req(midi->out_ep, length);
>
> I find it somewhat cleaner.  Up to you.

But if the gadget does not requires 'quirk_ep_out_aligned_size', then
we also can keep midi->buflen length although midi->buflen <
bulk_out_desc.wMaxPacketSize, right? Thanks for your comment.

>
>>   if (req == NULL)
>>   return -ENOMEM;
>>
>
> --
> Best regards
> ミハウ “퓶퓲퓷퓪86” ナザレヴイツ
> «If at first you don’t succeed, give up skydiving»



-- 
Baolin.wang
Best Regards


[PATCH] usb: core: Add runtime resume checking

2016-08-09 Thread Baolin Wang
When the usb device has entered suspend state by runtime suspend method, and
the sustem also try to enter suspend state by issuing usb_dev_suspend(), it
will issue pm_runtime_resume() function to deal with wrong wakeup setting in
choose_wakeup() function.

But if usb device resumes failed due to xhci has been into suspend state and
hardware is not accessible, which will set runtime errors. Thus when there is
slave attached, usb device will resume failed by runtime resume method due to
previous runtime errors.

Then we should check if it resumes successfully in choose_wakeup() function,
if it failed we should clear the runtime errors by pm_runtime_set_suspended()
function to avoid runtime resume failure.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/core/driver.c |9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index dadd1e8d..a1a0f5f 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1412,6 +1412,7 @@ static int usb_resume_both(struct usb_device *udev, 
pm_message_t msg)
 static void choose_wakeup(struct usb_device *udev, pm_message_t msg)
 {
int w;
+   int ret;
 
/* Remote wakeup is needed only when we actually go to sleep.
 * For things like FREEZE and QUIESCE, if the device is already
@@ -1431,8 +1432,12 @@ static void choose_wakeup(struct usb_device *udev, 
pm_message_t msg)
/* If the device is autosuspended with the wrong wakeup setting,
 * autoresume now so the setting can be changed.
 */
-   if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup)
-   pm_runtime_resume(>dev);
+   if (udev->state == USB_STATE_SUSPENDED && w != udev->do_remote_wakeup) {
+   ret = pm_runtime_resume(>dev);
+   if (ret == -ESHUTDOWN)
+   pm_runtime_set_suspended(>dev);
+   }
+
udev->do_remote_wakeup = w;
 }
 
-- 
1.7.9.5



Re: [PATCH v14 1/4] usb: gadget: Introduce the usb charger framework

2016-06-30 Thread Baolin Wang
Hi Felipe,

On 30 June 2016 at 18:30, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> +static ssize_t charger_state_show(struct device *dev,
>> +   struct device_attribute *attr,
>> +   char *buf)
>> +{
>> + struct usb_charger *uchger = dev_to_uchger(dev);
>> + int cnt;
>> +
>> + switch (uchger->state) {
>> + case USB_CHARGER_PRESENT:
>> + cnt = sprintf(buf, "%s\n", "PRESENT");
>> + break;
>> + case USB_CHARGER_REMOVE:
>> + cnt = sprintf(buf, "%s\n", "REMOVE");
>> + break;
>> + default:
>> + cnt = sprintf(buf, "%s\n", "UNKNOWN");
>> + break;
>
> are these the only states we need? Don't we need at least "CHARGING" and
> "ERROR" or something like that? Maybe those are exposed elsewhere,
> dunno.

Present state means we are charging. For charging error, I think it
can be exposed in power driver, which is more proper. Until now I only
see PRESENT and REMOVE state are useful.

>
>> +static int __usb_charger_set_cur_limit_by_type(struct usb_charger *uchger,
>> +enum usb_charger_type type,
>> +unsigned int cur_limit)
>> +{
>> + if (WARN(!uchger, "charger can not be NULL"))
>> + return -EINVAL;
>
> IIRC, I mentioned that this should assume charger to be a valid
> pointer. Look at this, for a second:
>
> You check that you have a valid pointer here...

Okay. I will remove this.

>
>> +int usb_charger_set_cur_limit_by_type(struct usb_charger *uchger,
>> +   enum usb_charger_type type,
>> +   unsigned int cur_limit)
>> +{
>> + int ret;
>> +
>> + if (WARN(!uchger, "charger can not be NULL"))
>> + return -EINVAL;
>
> ... and here, before calling the other function. This is the only place
> which should check for valid uchger.

Okay.

>
>> + mutex_lock(>lock);
>> + ret = __usb_charger_set_cur_limit_by_type(uchger, type, cur_limit);
>> + mutex_unlock(>lock);
>> +
>> + return ret;
>> +}
>> +EXPORT_SYMBOL_GPL(usb_charger_set_cur_limit_by_type);
>> +
>> +/*
>> + * usb_charger_set_cur_limit() - Set the current limitation.
>> + * @uchger - the usb charger instance.
>> + * @cur_limit_set - the current limitation.
>> + */
>> +int usb_charger_set_cur_limit(struct usb_charger *uchger,
>> +   struct usb_charger_cur_limit *cur_limit_set)
>> +{
>> + if (WARN(!uchger || !cur_limit_set, "charger or setting can't be 
>> NULL"))
>> + return -EINVAL;
>
> I can see a pattern here. Not *all* errors need a splat. Sometimes a
> simple pr_err() or dev_err() (when you have a valid dev pointer) are
> enough.

Make sense.

>
>> diff --git a/include/linux/usb/charger.h b/include/linux/usb/charger.h
>> new file mode 100644
>> index 000..d2e745e
>> --- /dev/null
>> +++ b/include/linux/usb/charger.h
>> @@ -0,0 +1,164 @@
>> +#ifndef __LINUX_USB_CHARGER_H__
>> +#define __LINUX_USB_CHARGER_H__
>> +
>> +#include 
>> +#include 
>> +
>> +#define CHARGER_NAME_MAX 30
>> +
>> +/* Current limitation by charger type */
>> +struct usb_charger_cur_limit {
>> + unsigned int sdp_cur_limit;
>> + unsigned int dcp_cur_limit;
>> + unsigned int cdp_cur_limit;
>> + unsigned int aca_cur_limit;
>> +};
>> +
>> +struct usb_charger_nb {
>> + struct notifier_block   nb;
>> + struct usb_charger  *uchger;
>> +};
>> +
>
> please add KernelDoc here. And mention the fields which aren't supposed
> to be accessed directly but should rely on the accessor functions. At
> least type and state prefer to be accessed by their respective
> getter/setter methods.

Will add kernel doc for struct usb_charger. Thanks for your comments.

>
>> +struct usb_charger {
>> + charname[CHARGER_NAME_MAX];
>> + struct list_headlist;
>> + struct raw_notifier_headuchger_nh;
>> + /* protect the notifier head and charger */
>> + struct mutexlock;
>> + int id;
>> + enum usb_charger_type   type;
>> + enum usb_cha

[PATCH] usb: gadget: Add the gserial port checking in gs_start_tx()

2016-06-30 Thread Baolin Wang
When usb gadget is set gadget serial function, it will be crash in below
situation.

It will clean the 'port->port_usb' pointer in gserial_disconnect() function
when usb link is inactive, but it will release lock for disabling the endpoints
in this function. Druing the lock release period, it maybe complete one request
to issue gs_write_complete()--->gs_start_tx() function, but the 'port->port_usb'
pointer had been set NULL, thus it will be crash in gs_start_tx() function.

This patch adds the 'port->port_usb' pointer checking in gs_start_tx() function
to avoid this situation.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/gadget/function/u_serial.c |7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/function/u_serial.c 
b/drivers/usb/gadget/function/u_serial.c
index 3580f19..66a0910 100644
--- a/drivers/usb/gadget/function/u_serial.c
+++ b/drivers/usb/gadget/function/u_serial.c
@@ -375,10 +375,15 @@ __acquires(>port_lock)
 */
 {
struct list_head*pool = >write_pool;
-   struct usb_ep   *in = port->port_usb->in;
+   struct usb_ep   *in;
int status = 0;
booldo_tty_wake = false;
 
+   if (!port->port_usb)
+   return status;
+
+   in = port->port_usb->in;
+
while (!port->write_busy && !list_empty(pool)) {
struct usb_request  *req;
int len;
-- 
1.7.9.5



[PATCH v15 1/4] usb: gadget: Introduce the usb charger framework

2016-07-01 Thread Baolin Wang
This patch introduces the usb charger driver based on usb gadget that
makes an enhancement to a power driver. It works well in practice but
that requires a system with suitable hardware.

The basic conception of the usb charger is that, when one usb charger
is added or removed by reporting from the usb gadget state change or
the extcon device state change, the usb charger will report to power
user to set the current limitation.

The usb charger will register notifiees on the usb gadget or the extcon
device to get notified the usb charger state. It also supplies the
notification mechanism to userspace When the usb charger state is changed.

Power user will register a notifiee on the usb charger to get notified
by status changes from the usb charger. It will report to power user
to set the current limitation when detecting the usb charger is added
or removed from extcon device state or usb gadget state.

This patch doesn't yet integrate with the gadget code, so some functions
which rely on the 'gadget' are not completed, that will be implemented
in the following patches.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  677 ++
 include/linux/usb/charger.h  |  183 +++
 include/uapi/linux/usb/charger.h |   31 ++
 5 files changed, 900 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3c3f31c..acea3f7 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -134,6 +134,14 @@ config U_SERIAL_CONSOLE
help
   It supports the serial gadget can be used as a console.
 
+config USB_CHARGER
+   bool "USB charger support"
+   select EXTCON
+   help
+ The usb charger driver based on the usb gadget that makes an
+ enhancement to a power driver which can set the current limitation
+ when the usb charger is added or removed.
+
 source "drivers/usb/gadget/udc/Kconfig"
 
 #
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 98e74ed..ede2351 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -2,6 +2,7 @@
 CFLAGS_trace.o := -I$(src)
 
 udc-core-y := core.o trace.o
+udc-core-$(CONFIG_USB_CHARGER) += charger.o
 
 #
 # USB peripheral controller drivers
diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
new file mode 100644
index 000..54c1712f
--- /dev/null
+++ b/drivers/usb/gadget/udc/charger.c
@@ -0,0 +1,677 @@
+/*
+ * charger.c -- USB charger driver
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Default current limit by charger type. */
+#define DEFAULT_SDP_CUR_LIMIT  500
+#define DEFAULT_SDP_CUR_LIMIT_SS   900
+#define DEFAULT_DCP_CUR_LIMIT  1500
+#define DEFAULT_CDP_CUR_LIMIT  1500
+#define DEFAULT_ACA_CUR_LIMIT  1500
+
+static DEFINE_IDA(usb_charger_ida);
+static LIST_HEAD(charger_list);
+static DEFINE_MUTEX(charger_lock);
+
+static unsigned int __usb_charger_get_cur_limit(struct usb_charger *uchger);
+
+static struct usb_charger *dev_to_uchger(struct device *dev)
+{
+   return NULL;
+}
+
+/*
+ * charger_current_show() - Show the charger current limit.
+ */
+static ssize_t charger_current_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+
+   return sprintf(buf, "%u\n", __usb_charger_get_cur_limit(uchger));
+}
+static DEVICE_ATTR_RO(charger_current);
+
+/*
+ * charger_type_show() - Show the charger type.
+ *
+ * It can be SDP/DCP/CDP/ACA type, else for unknown type.
+ */
+static ssize_t charger_type_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   int cnt;
+
+   switch (uchger->type) {
+   case SDP_TYPE:
+   cnt = sprintf(buf, "%s\n", "SDP");
+   break;
+   case DCP_TYPE:
+   cnt = sprintf(buf, "%s\n", "DCP");
+   break;
+   case CDP_TYPE:
+   cnt = spr

[PATCH v15 4/4] power: wm831x_power: Support USB charger current limit management

2016-07-01 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Acked-by: Lee Jones <lee.jo...@linaro.org>
Acked-by: Charles Keepax <ckee...@opensource.wolfsonmicro.com>
Acked-by: Peter Chen <peter.c...@freescale.com>
Acked-by: Sebastian Reichel <s...@kernel.org>
---
 drivers/power/wm831x_power.c |   69 ++
 include/linux/mfd/wm831x/pdata.h |3 ++
 2 files changed, 72 insertions(+)

diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 7082301..cef1812 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   unsigned int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,8 +647,31 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   if (wm831x_pdata && wm831x_pdata->usb_gadget) {
+   power->usb_charger =
+   usb_charger_find_by_name(wm831x_pdata->usb_gadget);
+   if (IS_ERR(power->usb_charger)) {
+   ret = PTR_ERR(power->usb_charger);
+   dev_err(>dev,
+   "Failed to find USB gadget: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power->usb_charger,
+ >usb_notify);
+   if (ret != 0) {
+   dev_err(>dev,
+   "Failed to register notifier: %d\n", ret);
+   goto err_usb_charger;
+   }
+   }
+
return ret;
 
+err_usb_charger:
+   /* put_device on charger */
 err_bat_irq:
--i;
for (; i >= 0; i--) {
@@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_charger) {
+   usb_charger_unregister_notify(wm831x_power->usb_charger,
+ _power->usb_notify);
+   /* Free charger */
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index dcc9631..5af8399 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -126,6 +126,9 @@ struct wm831x_pdata {
/** The driver should initiate a power off sequence during shutdown */
bool soft_shutdown;
 
+   /** dev_name of USB charger gadget to integrate with */
+   const char *usb_gadget;
+
int irq_base;
int gpio_base;
int gpio_defaults[WM831X_GPIO_NUM];
-- 
1.7.9.5



[PATCH v15 2/4] usb: gadget: Support for the usb charger framework

2016-07-01 Thread Baolin Wang
For supporting the usb charger, it adds the usb_charger_init() and
usb_charger_exit() functions for usb charger initialization and exit.

It will report to the usb charger when the gadget state is changed,
then the usb charger can do the power things.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/core.c |   17 +
 include/linux/usb/gadget.h|3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index ff8685e..bdf1874 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -578,12 +579,17 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_connect);
  * reporting how much power the device may consume.  For example, this
  * could affect how quickly batteries are recharged.
  *
+ * It will also notify the USB charger how much power the device may
+ * consume if there is a USB charger linking with the gadget.
+ *
  * Returns zero on success, else negative errno.
  */
 int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
int ret = 0;
 
+   usb_charger_set_cur_limit_by_gadget(gadget, mA);
+
if (!gadget->ops->vbus_draw) {
ret = -EOPNOTSUPP;
goto out;
@@ -965,6 +971,9 @@ static void usb_gadget_state_work(struct work_struct *work)
struct usb_gadget *gadget = work_to_gadget(work);
struct usb_udc *udc = gadget->udc;
 
+   /* when the gadget state is changed, then report to USB charger */
+   usb_charger_plug_by_gadget(gadget, gadget->state);
+
if (udc)
sysfs_notify(>dev.kobj, NULL, "state");
 }
@@ -1134,6 +1143,10 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret)
goto err4;
 
+   ret = usb_charger_init(gadget);
+   if (ret)
+   goto err5;
+
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
 
@@ -1154,6 +1167,9 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
return 0;
 
+err5:
+   device_del(>dev);
+
 err4:
list_del(>list);
mutex_unlock(_lock);
@@ -1262,6 +1278,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
kobject_uevent(>dev.kobj, KOBJ_REMOVE);
flush_work(>work);
device_unregister(>dev);
+   usb_charger_exit(gadget);
device_unregister(>dev);
 }
 EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 612dbdf..c864b51 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define UDC_TRACE_STR_MAX  512
 
@@ -328,6 +329,7 @@ struct usb_gadget_ops {
  * @in_epnum: last used in ep number
  * @mA: last set mA value
  * @otg_caps: OTG capabilities of this gadget.
+ * @charger: Negotiate the power with the usb charger.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  * gadget driver must provide a USB OTG descriptor.
@@ -385,6 +387,7 @@ struct usb_gadget {
unsignedin_epnum;
unsignedmA;
struct usb_otg_caps *otg_caps;
+   struct usb_charger  *charger;
 
unsignedsg_supported:1;
unsignedis_otg:1;
-- 
1.7.9.5



[PATCH v15 3/4] usb: gadget: Integrate with the usb gadget supporting for usb charger

2016-07-01 Thread Baolin Wang
When the usb gadget supporting for usb charger is ready, the usb charger
can implement the usb_charger_plug_by_gadget() function, usb_charger_exit()
function and dev_to_uchger() function by getting 'struct usb_charger' from
'struct gadget'.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/charger.c |   67 --
 1 file changed, 64 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
index 54c1712f..57f9fd2 100644
--- a/drivers/usb/gadget/udc/charger.c
+++ b/drivers/usb/gadget/udc/charger.c
@@ -36,7 +36,9 @@ static unsigned int __usb_charger_get_cur_limit(struct 
usb_charger *uchger);
 
 static struct usb_charger *dev_to_uchger(struct device *dev)
 {
-   return NULL;
+   struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
+
+   return gadget->charger;
 }
 
 /*
@@ -305,7 +307,13 @@ static int __usb_charger_set_cur_limit_by_type(struct 
usb_charger *uchger,
 int usb_charger_set_cur_limit_by_gadget(struct usb_gadget *gadget,
unsigned int cur_limit)
 {
-   return 0;
+   struct usb_charger *uchger = gadget->charger;
+
+   if (!uchger)
+   return -EINVAL;
+
+   return __usb_charger_set_cur_limit_by_type(uchger, uchger->type,
+  cur_limit);
 }
 EXPORT_SYMBOL_GPL(usb_charger_set_cur_limit_by_gadget);
 
@@ -563,11 +571,52 @@ usb_charger_plug_by_extcon(struct notifier_block *nb,
 int usb_charger_plug_by_gadget(struct usb_gadget *gadget,
   unsigned long state)
 {
+   struct usb_charger *uchger = gadget->charger;
+   enum usb_charger_state uchger_state;
+
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   /*
+* Report event to power to setting the current limitation
+* for this usb charger when one usb charger state is changed
+* with detecting by usb gadget state.
+*/
+   if (uchger->old_gadget_state != state) {
+   uchger->old_gadget_state = state;
+
+   if (state >= USB_STATE_ATTACHED)
+   uchger_state = USB_CHARGER_PRESENT;
+   else if (state == USB_STATE_NOTATTACHED)
+   uchger_state = USB_CHARGER_REMOVE;
+   else
+   uchger_state = USB_CHARGER_DEFAULT;
+
+   usb_charger_notify_others(uchger, uchger_state);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_plug_by_gadget);
 
 /*
+ * usb_charger_unregister() - Unregister a usb charger.
+ * @uchger - the usb charger to be unregistered.
+ */
+static int usb_charger_unregister(struct usb_charger *uchger)
+{
+   ida_simple_remove(_charger_ida, uchger->id);
+   sysfs_remove_groups(>gadget->dev.kobj, usb_charger_groups);
+
+   mutex_lock(_lock);
+   list_del(>list);
+   mutex_unlock(_lock);
+
+   kfree(uchger);
+   return 0;
+}
+
+/*
  * usb_charger_register() - Register a new usb charger.
  * @uchger - the new usb charger instance.
  */
@@ -647,6 +696,7 @@ int usb_charger_init(struct usb_gadget *ugadget)
 
/* register a notifier on a usb gadget device */
uchger->gadget = ugadget;
+   ugadget->charger = uchger;
uchger->old_gadget_state = USB_STATE_NOTATTACHED;
 
/* register a new usb charger */
@@ -669,7 +719,18 @@ fail:
 
 int usb_charger_exit(struct usb_gadget *ugadget)
 {
-   return 0;
+   struct usb_charger *uchger = ugadget->charger;
+
+   if (!uchger)
+   return -EINVAL;
+
+   ugadget->charger = NULL;
+   if (uchger->extcon_dev)
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_USB,
+  >extcon_nb.nb);
+
+   return usb_charger_unregister(uchger);
 }
 
 MODULE_AUTHOR("Baolin Wang <baolin.w...@linaro.org>");
-- 
1.7.9.5



[PATCH v15 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-07-01 Thread Baolin Wang
Currently the Linux kernel does not provide any standard integration of this
feature that integrates the USB subsystem with the system power regulation
provided by PMICs meaning that either vendors must add this in their kernels
or USB gadget devices based on Linux (such as mobile phones) may not behave
as they should. Thus provide a standard framework for doing this in kernel.

Now introduce one user with wm831x_power to support and test the usb charger,
which is pending testing. Moreover there may be other potential users will use
it in future.

Changes since v14:
 - Add kernel documentation for struct usb_cahrger.
 - Remove some redundant WARN() functions.

Changes since v13:
 - Remove the charger checking in usb_gadget_vbus_draw() function.
 - Rename some functions in charger.c file.
 - Rebase on git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git 
tags/usb-for-v4.8

Changes since v12:
 - Remove the class and device things.
 - Link usb charger to udc-core.ko.
 - Create one "charger" subdirectory which holds all charger-related attributes.

Changes since v11:
 - Reviewed and tested by Li Jun.

Changes since v10:
 - Introduce usb_charger_get_state() function to check charger state.
 - Remove the mutex lock in usb_charger_set_cur_limit_by_type() function
 in case will be issued in atomic context.

Baolin Wang (4):
  usb: gadget: Introduce the usb charger framework
  usb: gadget: Support for the usb charger framework
  usb: gadget: Integrate with the usb gadget supporting for usb charger
  power: wm831x_power: Support USB charger current limit management

 drivers/power/wm831x_power.c |   69 
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  738 ++
 drivers/usb/gadget/udc/core.c|   17 +
 include/linux/mfd/wm831x/pdata.h |3 +
 include/linux/usb/charger.h  |  183 ++
 include/linux/usb/gadget.h   |3 +
 include/uapi/linux/usb/charger.h |   31 ++
 9 files changed, 1053 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

-- 
1.7.9.5



[PATCH v14 1/4] usb: gadget: Introduce the usb charger framework

2016-06-29 Thread Baolin Wang
This patch introduces the usb charger driver based on usb gadget that
makes an enhancement to a power driver. It works well in practice but
that requires a system with suitable hardware.

The basic conception of the usb charger is that, when one usb charger
is added or removed by reporting from the usb gadget state change or
the extcon device state change, the usb charger will report to power
user to set the current limitation.

The usb charger will register notifiees on the usb gadget or the extcon
device to get notified the usb charger state. It also supplies the
notification mechanism to userspace When the usb charger state is changed.

Power user will register a notifiee on the usb charger to get notified
by status changes from the usb charger. It will report to power user
to set the current limitation when detecting the usb charger is added
or removed from extcon device state or usb gadget state.

This patch doesn't yet integrate with the gadget code, so some functions
which rely on the 'gadget' are not completed, that will be implemented
in the following patches.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  679 ++
 include/linux/usb/charger.h  |  164 +
 include/uapi/linux/usb/charger.h |   31 ++
 5 files changed, 883 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 3c3f31c..acea3f7 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -134,6 +134,14 @@ config U_SERIAL_CONSOLE
help
   It supports the serial gadget can be used as a console.
 
+config USB_CHARGER
+   bool "USB charger support"
+   select EXTCON
+   help
+ The usb charger driver based on the usb gadget that makes an
+ enhancement to a power driver which can set the current limitation
+ when the usb charger is added or removed.
+
 source "drivers/usb/gadget/udc/Kconfig"
 
 #
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 98e74ed..ede2351 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -2,6 +2,7 @@
 CFLAGS_trace.o := -I$(src)
 
 udc-core-y := core.o trace.o
+udc-core-$(CONFIG_USB_CHARGER) += charger.o
 
 #
 # USB peripheral controller drivers
diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
new file mode 100644
index 000..7abecf3
--- /dev/null
+++ b/drivers/usb/gadget/udc/charger.c
@@ -0,0 +1,679 @@
+/*
+ * charger.c -- USB charger driver
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DEFAULT_SDP_CUR_LIMIT  500
+#define DEFAULT_SDP_CUR_LIMIT_SS   900
+#define DEFAULT_DCP_CUR_LIMIT  1500
+#define DEFAULT_CDP_CUR_LIMIT  1500
+#define DEFAULT_ACA_CUR_LIMIT  1500
+
+static DEFINE_IDA(usb_charger_ida);
+static LIST_HEAD(charger_list);
+static DEFINE_MUTEX(charger_lock);
+
+static unsigned int __usb_charger_get_cur_limit(struct usb_charger *uchger);
+
+static struct usb_charger *dev_to_uchger(struct device *dev)
+{
+   return NULL;
+}
+
+/*
+ * charger_current_show() - Show the charger current limit.
+ */
+static ssize_t charger_current_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+
+   return sprintf(buf, "%u\n", __usb_charger_get_cur_limit(uchger));
+}
+static DEVICE_ATTR_RO(charger_current);
+
+/*
+ * charger_type_show() - Show the charger type.
+ *
+ * It can be SDP/DCP/CDP/ACA type, else for unknown type.
+ */
+static ssize_t charger_type_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   int cnt;
+
+   switch (uchger->type) {
+   case SDP_TYPE:
+   cnt = sprintf(buf, "%s\n", "SDP");
+   break;
+   case DCP_TYPE:
+   cnt = sprintf(buf, "%s\n", "DCP");
+   break;
+   case CDP_TYPE:
+   cnt = sprintf(buf, "%s\n", "CDP");
+  

[PATCH v14 4/4] power: wm831x_power: Support USB charger current limit management

2016-06-29 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Acked-by: Lee Jones <lee.jo...@linaro.org>
Acked-by: Charles Keepax <ckee...@opensource.wolfsonmicro.com>
Acked-by: Peter Chen <peter.c...@freescale.com>
Acked-by: Sebastian Reichel <s...@kernel.org>
---
 drivers/power/wm831x_power.c |   69 ++
 include/linux/mfd/wm831x/pdata.h |3 ++
 2 files changed, 72 insertions(+)

diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c
index 7082301..cef1812 100644
--- a/drivers/power/wm831x_power.c
+++ b/drivers/power/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,43 @@ static enum power_supply_property wm831x_usb_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+   unsigned int i, best;
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,8 +647,31 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   if (wm831x_pdata && wm831x_pdata->usb_gadget) {
+   power->usb_charger =
+   usb_charger_find_by_name(wm831x_pdata->usb_gadget);
+   if (IS_ERR(power->usb_charger)) {
+   ret = PTR_ERR(power->usb_charger);
+   dev_err(>dev,
+   "Failed to find USB gadget: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power->usb_charger,
+ >usb_notify);
+   if (ret != 0) {
+   dev_err(>dev,
+   "Failed to register notifier: %d\n", ret);
+   goto err_usb_charger;
+   }
+   }
+
return ret;
 
+err_usb_charger:
+   /* put_device on charger */
 err_bat_irq:
--i;
for (; i >= 0; i--) {
@@ -637,6 +700,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_charger) {
+   usb_charger_unregister_notify(wm831x_power->usb_charger,
+ _power->usb_notify);
+   /* Free charger */
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index dcc9631..5af8399 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -126,6 +126,9 @@ struct wm831x_pdata {
/** The driver should initiate a power off sequence during shutdown */
bool soft_shutdown;
 
+   /** dev_name of USB charger gadget to integrate with */
+   const char *usb_gadget;
+
int irq_base;
int gpio_base;
int gpio_defaults[WM831X_GPIO_NUM];
-- 
1.7.9.5



[PATCH v14 2/4] usb: gadget: Support for the usb charger framework

2016-06-29 Thread Baolin Wang
For supporting the usb charger, it adds the usb_charger_init() and
usb_charger_exit() functions for usb charger initialization and exit.

It will report to the usb charger when the gadget state is changed,
then the usb charger can do the power things.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/core.c |   17 +
 include/linux/usb/gadget.h|3 +++
 2 files changed, 20 insertions(+)

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index ff8685e..bdf1874 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -578,12 +579,17 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_connect);
  * reporting how much power the device may consume.  For example, this
  * could affect how quickly batteries are recharged.
  *
+ * It will also notify the USB charger how much power the device may
+ * consume if there is a USB charger linking with the gadget.
+ *
  * Returns zero on success, else negative errno.
  */
 int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
int ret = 0;
 
+   usb_charger_set_cur_limit_by_gadget(gadget, mA);
+
if (!gadget->ops->vbus_draw) {
ret = -EOPNOTSUPP;
goto out;
@@ -965,6 +971,9 @@ static void usb_gadget_state_work(struct work_struct *work)
struct usb_gadget *gadget = work_to_gadget(work);
struct usb_udc *udc = gadget->udc;
 
+   /* when the gadget state is changed, then report to USB charger */
+   usb_charger_plug_by_gadget(gadget, gadget->state);
+
if (udc)
sysfs_notify(>dev.kobj, NULL, "state");
 }
@@ -1134,6 +1143,10 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret)
goto err4;
 
+   ret = usb_charger_init(gadget);
+   if (ret)
+   goto err5;
+
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
 
@@ -1154,6 +1167,9 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
return 0;
 
+err5:
+   device_del(>dev);
+
 err4:
list_del(>list);
mutex_unlock(_lock);
@@ -1262,6 +1278,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
kobject_uevent(>dev.kobj, KOBJ_REMOVE);
flush_work(>work);
device_unregister(>dev);
+   usb_charger_exit(gadget);
device_unregister(>dev);
 }
 EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 612dbdf..c864b51 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define UDC_TRACE_STR_MAX  512
 
@@ -328,6 +329,7 @@ struct usb_gadget_ops {
  * @in_epnum: last used in ep number
  * @mA: last set mA value
  * @otg_caps: OTG capabilities of this gadget.
+ * @charger: Negotiate the power with the usb charger.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  * gadget driver must provide a USB OTG descriptor.
@@ -385,6 +387,7 @@ struct usb_gadget {
unsignedin_epnum;
unsignedmA;
struct usb_otg_caps *otg_caps;
+   struct usb_charger  *charger;
 
unsignedsg_supported:1;
unsignedis_otg:1;
-- 
1.7.9.5



[PATCH v14 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-06-29 Thread Baolin Wang
Currently the Linux kernel does not provide any standard integration of this
feature that integrates the USB subsystem with the system power regulation
provided by PMICs meaning that either vendors must add this in their kernels
or USB gadget devices based on Linux (such as mobile phones) may not behave
as they should. Thus provide a standard framework for doing this in kernel.

Now introduce one user with wm831x_power to support and test the usb charger,
which is pending testing. Moreover there may be other potential users will use
it in future.

Changes since v13:
 - Remove the charger checking in usb_gadget_vbus_draw() function.
 - Rename some functions in charger.c file.
 - Rebase on git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git 
tags/usb-for-v4.8

Changes since v12:
 - Remove the class and device things.
 - Link usb charger to udc-core.ko.
 - Create one "charger" subdirectory which holds all charger-related attributes.

Changes since v11:
 - Reviewed and tested by Li Jun.

Changes since v10:
 - Introduce usb_charger_get_state() function to check charger state.
 - Remove the mutex lock in usb_charger_set_cur_limit_by_type() function
 in case will be issued in atomic context.

Baolin Wang (4):
  usb: gadget: Introduce the usb charger framework
  usb: gadget: Support for the usb charger framework
  usb: gadget: Integrate with the usb gadget supporting for usb charger
  power: wm831x_power: Support USB charger current limit management

 drivers/power/wm831x_power.c |   69 
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  743 ++
 drivers/usb/gadget/udc/core.c|   17 +
 include/linux/mfd/wm831x/pdata.h |3 +
 include/linux/usb/charger.h  |  164 +
 include/linux/usb/gadget.h   |3 +
 include/uapi/linux/usb/charger.h |   31 ++
 9 files changed, 1039 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

-- 
1.7.9.5



[PATCH v14 3/4] usb: gadget: Integrate with the usb gadget supporting for usb charger

2016-06-29 Thread Baolin Wang
When the usb gadget supporting for usb charger is ready, the usb charger
can implement the usb_charger_plug_by_gadget() function, usb_charger_exit()
function and dev_to_uchger() function by getting 'struct usb_charger' from
'struct gadget'.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/charger.c |   70 --
 1 file changed, 67 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
index 7abecf3..45c0bf1b 100644
--- a/drivers/usb/gadget/udc/charger.c
+++ b/drivers/usb/gadget/udc/charger.c
@@ -35,7 +35,9 @@ static unsigned int __usb_charger_get_cur_limit(struct 
usb_charger *uchger);
 
 static struct usb_charger *dev_to_uchger(struct device *dev)
 {
-   return NULL;
+   struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
+
+   return gadget->charger;
 }
 
 /*
@@ -308,7 +310,13 @@ static int __usb_charger_set_cur_limit_by_type(struct 
usb_charger *uchger,
 int usb_charger_set_cur_limit_by_gadget(struct usb_gadget *gadget,
unsigned int cur_limit)
 {
-   return 0;
+   struct usb_charger *uchger = gadget->charger;
+
+   if (!uchger)
+   return 0;
+
+   return __usb_charger_set_cur_limit_by_type(uchger, uchger->type,
+  cur_limit);
 }
 EXPORT_SYMBOL_GPL(usb_charger_set_cur_limit_by_gadget);
 
@@ -562,11 +570,55 @@ usb_charger_plug_by_extcon(struct notifier_block *nb,
 int usb_charger_plug_by_gadget(struct usb_gadget *gadget,
   unsigned long state)
 {
+   struct usb_charger *uchger = gadget->charger;
+   enum usb_charger_state uchger_state;
+
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   /*
+* Report event to power to setting the current limitation
+* for this usb charger when one usb charger state is changed
+* with detecting by usb gadget state.
+*/
+   if (uchger->old_gadget_state != state) {
+   uchger->old_gadget_state = state;
+
+   if (state >= USB_STATE_ATTACHED)
+   uchger_state = USB_CHARGER_PRESENT;
+   else if (state == USB_STATE_NOTATTACHED)
+   uchger_state = USB_CHARGER_REMOVE;
+   else
+   uchger_state = USB_CHARGER_DEFAULT;
+
+   usb_charger_notify_others(uchger, uchger_state);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_plug_by_gadget);
 
 /*
+ * usb_charger_unregister() - Unregister a usb charger.
+ * @uchger - the usb charger to be unregistered.
+ */
+static int usb_charger_unregister(struct usb_charger *uchger)
+{
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   ida_simple_remove(_charger_ida, uchger->id);
+   sysfs_remove_groups(>gadget->dev.kobj, usb_charger_groups);
+
+   mutex_lock(_lock);
+   list_del(>list);
+   mutex_unlock(_lock);
+
+   kfree(uchger);
+   return 0;
+}
+
+/*
  * usb_charger_register() - Register a new usb charger.
  * @uchger - the new usb charger instance.
  */
@@ -649,6 +701,7 @@ int usb_charger_init(struct usb_gadget *ugadget)
 
/* register a notifier on a usb gadget device */
uchger->gadget = ugadget;
+   ugadget->charger = uchger;
uchger->old_gadget_state = USB_STATE_NOTATTACHED;
 
/* register a new usb charger */
@@ -671,7 +724,18 @@ fail:
 
 int usb_charger_exit(struct usb_gadget *ugadget)
 {
-   return 0;
+   struct usb_charger *uchger = ugadget->charger;
+
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   ugadget->charger = NULL;
+   if (uchger->extcon_dev)
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_USB,
+      >extcon_nb.nb);
+
+   return usb_charger_unregister(uchger);
 }
 
 MODULE_AUTHOR("Baolin Wang <baolin.w...@linaro.org>");
-- 
1.7.9.5



Re: [PATCH v12 2/4] gadget: Support for the usb charger framework

2016-06-29 Thread Baolin Wang
Hi Felipe,

On 29 June 2016 at 20:06, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>>> For supporting the usb charger, it adds the usb_charger_init() and
>>>>>>>> usb_charger_exit() functions for usb charger initialization and exit.
>>>>>>>>
>>>>>>>> It will report to the usb charger when the gadget state is changed,
>>>>>>>> then the usb charger can do the power things.
>>>>>>>>
>>>>>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>>>>>> Reviewed-by: Li Jun <jun...@nxp.com>
>>>>>>>> Tested-by: Li Jun <jun...@nxp.com>
>>>>>>>
>>>>>>> Before anything, I must say that I really liked this patch. It's
>>>>>>> minimaly invasive to udc core and does all the necessary changes. If it
>>>>>>> wasn't for the extra charger class, this would've been perfect.
>>>>>>>
>>>>>>> Can't you just tie a charger to a UDC and avoid the charger class
>>>>>>> completely?
>>>>>>>
>>>>>>>>  static inline int usb_gadget_vbus_draw(struct usb_gadget *gadget, 
>>>>>>>> unsigned mA)
>>>>>>>>  {
>>>>>>>> + if (gadget->charger)
>>>>>>>
>>>>>>> I guess you could do this check inside
>>>>>>> usb_gadget_set_cur_limit_by_type() itself.
>>>>>>
>>>>>> We will access the 'gadget->charger->type' member when issuing
>>>>>> usb_gadget_set_cur_limit_by_type(), so I think I should leave the
>>>>>> check here in next new version.
>>>>>
>>>>> Here's what I mean:
>>>>>
>>>>> int usb_charger_set_cur_limit(struct usb_gadget *gadget, unsigned int mA)
>>>>> {
>>>>> struct usb_charger *charger;
>>>>> enum usb_charger_type type;
>>>>>
>>>>> if (!gadget->charger)
>>>>> return 0;
>>>>>
>>>>> charger = gadget->charger;
>>>>> type = charger->type;
>>>>>
>>>>> return __usb_charger_set_cur_limit(charger, type, mA);
>>>>> }
>>>>
>>>> But that means we need to export  both 'usb_charger_set_cur_limit()'
>>>> function and '__usb_charger_set_cur_limit()' function in charger.c
>>>> file. Cause some user may want to set the current limitation by one
>>>> charger type parameter (may be not from charger->type), like by
>>>> issuing '__usb_charger_set_cur_limit(charger, SDP_TYPE, mA)'. How do
>>>> you think about this situation? Thanks.
>>>
>>> if we have that requirement, that's totally fine. Just rename
>>> __usb_charger_set_cur_limit() back to
>>> _usb_charger_set_cur_limit_by_type() and expose both. But
>>> set_cur_limit_by_type can assume its arguments are valid at all times.
>>
>> Make sense. I'll fix this issue in v14 version. Thanks.
>
> there's one thing bothering me though:
>
> gadget->charger is supposed to be "current detected charger" right? If
> we have a single port tied to a single charger, in which case would we
> *ever* need to change current limit of any charger type other than
> "current charger" ?

What I mean is user can set the current limit by charger type as what
they want at initial stage. As we know the default current of SDP (not
super speed) is 500 mA, but user can set the current limit of SDP as
450 mA if there are some special on their own platform by issuing
'__usb_charger_set_cur_limit(charger, SDP_TYPE, 450)'.

>
> IOW, why do we need _set_cur_limit_by_type() exported at all?
>
> --
> balbi



-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: gadget: Add the suspend state checking when stopping gadget

2016-06-20 Thread Baolin Wang
On 20 June 2016 at 16:15, Felipe Balbi <ba...@kernel.org> wrote:
> Baolin Wang <baolin.w...@linaro.org> writes:
>
>> It will be crash to stop gadget when the dwc3 device had been into suspend
>> state, thus we need to check if the dwc3 device had been into suspend state
>> when UDC try to stop gadget.
>>
>> By the way I have rebased on your 'testing/next' branch.
>
> do you really want this note to be in commit log? Seems like this should
> be after tearline below.

Sorry. I'll remove this in next version. Thanks for your comment.

>
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>>  drivers/usb/dwc3/gadget.c |3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 6dde376..351769e 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1791,6 +1791,9 @@ err0:
>>
>>  static void __dwc3_gadget_stop(struct dwc3 *dwc)
>>  {
>> + if (pm_runtime_suspended(dwc->dev))
>> + return;
>> +
>>   dwc3_gadget_disable_irq(dwc);
>>   __dwc3_gadget_ep_disable(dwc->eps[0]);
>>   __dwc3_gadget_ep_disable(dwc->eps[1]);
>> --
>> 1.7.9.5
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
> --
> balbi



-- 
Baolin.wang
Best Regards


[PATCH v2] usb: dwc3: gadget: Add the suspend state checking when stopping gadget

2016-06-20 Thread Baolin Wang
It will be crash to stop gadget when the dwc3 device had been into suspend
state, thus we need to check if the dwc3 device had been into suspend state
when UDC try to stop gadget.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/dwc3/gadget.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 6dde376..351769e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1791,6 +1791,9 @@ err0:
 
 static void __dwc3_gadget_stop(struct dwc3 *dwc)
 {
+   if (pm_runtime_suspended(dwc->dev))
+   return;
+
dwc3_gadget_disable_irq(dwc);
__dwc3_gadget_ep_disable(dwc->eps[0]);
__dwc3_gadget_ep_disable(dwc->eps[1]);
-- 
1.7.9.5



Re: [PATCH v5 1/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-05 Thread Baolin Wang
Hi Mathias,

On 31 January 2017 at 21:14, Mathias Nyman
<mathias.ny...@linux.intel.com> wrote:
> On 16.01.2017 12:56, Baolin Wang wrote:
>>
>> Hi Mathias,
>
>
> Hi
>
> Sorry about the long review delay
> CC Alan in case my pm assumptions need to be corrected
>
>
>>
>> On 13 December 2016 at 15:49, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>
>>> Enable the xhci plat runtime PM for parent device to suspend/resume xhci.
>>> Also call pm_runtime_get_noresume() in probe() function in case the
>>> parent
>>> device doesn't call suspend/resume callback by runtime PM now.
>>>
>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>> ---
>>> Changes since v4:
>>>   - No updates.
>>>
>>> Changes since v3:
>>>   - Fix kbuild error.
>>>
>>> Changes since v2:
>>>   - Add pm_runtime_get_noresume() in probe() function.
>>>   - Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in remove()
>>> function.
>>>
>>> Changes since v1:
>>>   - No updates.
>>> ---
>>
>>
>> Do you have any comments about this patch? Thanks.
>>
>>>   drivers/usb/host/xhci-plat.c |   41
>>> -
>>>   1 file changed, 36 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>> index ed56bf9..5805c6a 100644
>>> --- a/drivers/usb/host/xhci-plat.c
>>> +++ b/drivers/usb/host/xhci-plat.c
>>> @@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device
>>> *pdev)
>>>  if (ret)
>>>  goto dealloc_usb2_hcd;
>>>
>>> +   pm_runtime_get_noresume(>dev);
>>> +   pm_runtime_set_active(>dev);
>>> +   pm_runtime_enable(>dev);
>>> +
>>>  return 0;
>>>
>>>
>
> To me this looks like we are not really enabling runtime pm for xhci, we
> increment the
> usage count in probe, and keep it until remove is called.
>
> This would normally prevent parent dwc3 from runtime suspending, but I see
> that in patch 2/2 adds
> pm_suspend_ignore_children(dev, true) to dwc3, and, that dwc3 actually
> controls xhci runtime
> pm by calling pm_runtime_get/put for xhci in its own dwc3
> runtime_suspend/resume callbacks.
>
> Looks a bit upside down to me, what's the reason for this?
>
> what prevents calling pm_runtime_put_* before leaving probe in xhci and let
> pm code handle
> the runtime suspend and parent/child relationships?

When dwc3 controller is working on host mode, which will create and
add the USB hcd for host side. Then if we want to suspend dwc3
controller as host mode, the USB device (bus) of host side will
runtime suspend automatically if there are no slave attached (by
usb_runtime_suspend()--->usb_suspend_both()--->usb_suspend_interface()--->usb_suspend_device()--->generic_suspend()--->hcd_bus_suspend()--->xhci_bus_suspend()),
but we should not suspend xHCI device (issuing xhci_suspend()) now,
since some other  controllers did not implement the runtime PM to
control xHCI device's runtime state, which will cause other
controllers can not resume xHCI device (issuing xhci_resume()) if the
xHCI device suspend automatically by its child device. Thus we should
get the runtime count for xHCI device in xhci_plat_probe() in case
xHCI device will also suspend automatically by its child device.
According to that, for xHCI device's parent: dwc3 device, we should
put the xHCI device's runtime count to suspend xHCI device manually.

-- 
Baolin.wang
Best Regards


Re: [PATCH v5 1/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-05 Thread Baolin Wang
Hi Robert,

On 26 January 2017 at 01:30, Robert Foss  wrote:
> Looks good to me.
>
> Feel free to add my r-b.

OK, thanks for your reviewing.

-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-02-21 Thread Baolin Wang
On 17 February 2017 at 16:04, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> (One possible approach would be to have the setup routine return
>>>> different values for explicit and implicit status stages -- for
>>>> example, return 1 if it wants to submit an explicit status request.
>>>> That wouldn't be very different from the current
>>>> USB_GADGET_DELAYED_STATUS approach.)
>>>
>>> not really, no. The idea was for composite.c and/or functions to support
>>> both methods (temporarily) and use "gadget->wants_explicit_stages" to
>>> explicitly queue DATA and STATUS. That would mean that f_mass_storage
>>> wouldn't have to return DELAYED_STATUS if
>>> (gadget->wants_explicit_stages).
>>>
>>> After all UDCs are converted over and set wants_explicit_stages (which
>>> should all be done in a single series), then we get rid of the flag and
>>> the older method of DELAYED_STATUS.
>>
>> (Sorry for late reply due to my holiday)
>> I also met the problem pointed by Alan, from my test, I still want to
>> need one return value to indicate if it wants to submit an explicit
>> status request. Think about the Control-IN with a data stage, we can
>> not get the STATUS phase request from usb_ep_queue() call, and we need
>
> why not? wLength tells you that this is a 3-stage transfer. Gadget
> driver should be able to figure out that it needs to usb_ep_queue()
> another request for status stage.

I tried again, but still can not work. Suppose the no-data control:
(1) SET_ADDRESS request: function driver will not queue one request
for status phase by usb_ep_queue() call.
(2) SET_CONFIGURATION request: function driver will queue one 0-length
request for status phase by usb_ep_queue() call, especially for
mass_storage driver, it will queue one request  for status phase
later.

So I am not sure how the Gadget driver can figure out that it needs to
usb_ep_queue() another request for status stage when handling the
no-data control?

>> to handle this STATUS phase request in dwc3_ep0_xfernotready(). But
>> Control-OUT will get one 0-length IN request for the status stage from
>> usb_ep_queue(), so we need one return value from setup routine to
>
> no we don't :-)
>
>> distinguish these in dwc3_ep0_xfernotready(), or we can not handle
>> status request correctly. Maybe I missed something else.
>>>
>>>> On the other hand, I am very doubtful about requiring explicit setup
>>>> requests.
>>>
>>> right, me too ;-)
>>
>> So do you suggest me continue to try to do this? Thanks.
>
> explicit setup? no
> explicit status? yes
>
> If you don't wanna do it, it's fine :-) I'll just add to my TODO
> list. It just depends on how much other tasks you have on your end ;-)
>
> --
> balbi



-- 
Baolin.wang
Best Regards


Re: [PATCH v19 2/4] usb: gadget: Support for the usb charger framework

2017-02-20 Thread Baolin Wang
On 20 February 2017 at 18:08, kbuild test robot <l...@intel.com> wrote:
> Hi Baolin,
>
> [auto build test ERROR on v4.9-rc8]
> [cannot apply to balbi-usb/next usb/usb-testing battery/master next-20170220]
> [if your patch is applied to the wrong git tree, please drop us a note to 
> help improve the system]
>
> url:
> https://github.com/0day-ci/linux/commits/Baolin-Wang/Introduce-usb-charger-framework-to-deal-with-the-usb-gadget-power-negotation/20170220-173051
> config: i386-randconfig-x015-201708 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=i386
>
> All errors (new ones prefixed by >>):
>
>In file included from drivers/usb/gadget/udc/core.c:28:0:
>include/linux/usb/charger.h: In function 'usb_charger_get_state':
>>> include/linux/usb/charger.h:151:9: error: 'USB_CHARGER_REMOVE' undeclared 
>>> (first use in this function)
>  return USB_CHARGER_REMOVE;

Ah, missed fixing the state name without enable USB charger. Will fix
in next version.

> ^~
>include/linux/usb/charger.h:151:9: note: each undeclared identifier is 
> reported only once for each function it appears in
>
> vim +/USB_CHARGER_REMOVE +151 include/linux/usb/charger.h
>
> 28929615 Baolin Wang 2017-02-20  145return UNKNOWN_TYPE;
> 28929615 Baolin Wang 2017-02-20  146  }
> 28929615 Baolin Wang 2017-02-20  147
> 28929615 Baolin Wang 2017-02-20  148  static inline enum usb_charger_state
> 28929615 Baolin Wang 2017-02-20  149  usb_charger_get_state(struct 
> usb_charger *uchger)
> 28929615 Baolin Wang 2017-02-20  150  {
> 28929615 Baolin Wang 2017-02-20 @151    return USB_CHARGER_REMOVE;
> 28929615 Baolin Wang 2017-02-20  152  }
> 28929615 Baolin Wang 2017-02-20  153
> 28929615 Baolin Wang 2017-02-20  154  static inline int 
> usb_charger_detect_type(struct usb_charger *uchger)
>
> :: The code at line 151 was first introduced by commit
> :: 289296154f05985dedc08273f04d5b738450b3c7 usb: gadget: Introduce the 
> usb charger framework
>
> :: TO: Baolin Wang <baolin.w...@linaro.org>
> :: CC: 0day robot <fengguang...@intel.com>
>
> ---
> 0-DAY kernel test infrastructureOpen Source Technology Center
> https://lists.01.org/pipermail/kbuild-all   Intel Corporation



-- 
Baolin.wang
Best Regards


Re: [PATCH v5 1/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-20 Thread Baolin Wang
On 20 February 2017 at 23:10, Mathias Nyman
<mathias.ny...@linux.intel.com> wrote:
> On 20.02.2017 04:47, Baolin Wang wrote:
>>
>> Hi Mathias,
>>
>> On 6 February 2017 at 13:26, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>
>>> Hi Mathias,
>>>
>>> On 31 January 2017 at 21:14, Mathias Nyman
>>> <mathias.ny...@linux.intel.com> wrote:
>>>>
>>>> On 16.01.2017 12:56, Baolin Wang wrote:
>>>>>
>>>>>
>>>>> Hi Mathias,
>>>>
>>>>
>>>>
>>>> Hi
>>>>
>>>> Sorry about the long review delay
>>>> CC Alan in case my pm assumptions need to be corrected
>>>>
>>>>
>>>>>
>>>>> On 13 December 2016 at 15:49, Baolin Wang <baolin.w...@linaro.org>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> Enable the xhci plat runtime PM for parent device to suspend/resume
>>>>>> xhci.
>>>>>> Also call pm_runtime_get_noresume() in probe() function in case the
>>>>>> parent
>>>>>> device doesn't call suspend/resume callback by runtime PM now.
>>>>>>
>>>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>>>> ---
>>>>>> Changes since v4:
>>>>>>- No updates.
>>>>>>
>>>>>> Changes since v3:
>>>>>>- Fix kbuild error.
>>>>>>
>>>>>> Changes since v2:
>>>>>>- Add pm_runtime_get_noresume() in probe() function.
>>>>>>- Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in
>>>>>> remove()
>>>>>> function.
>>>>>>
>>>>>> Changes since v1:
>>>>>>- No updates.
>>>>>> ---
>>>>>
>>>>>
>>>>>
>>>>> Do you have any comments about this patch? Thanks.
>>>>>
>>>>>>drivers/usb/host/xhci-plat.c |   41
>>>>>> -
>>>>>>1 file changed, 36 insertions(+), 5 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/usb/host/xhci-plat.c
>>>>>> b/drivers/usb/host/xhci-plat.c
>>>>>> index ed56bf9..5805c6a 100644
>>>>>> --- a/drivers/usb/host/xhci-plat.c
>>>>>> +++ b/drivers/usb/host/xhci-plat.c
>>>>>> @@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device
>>>>>> *pdev)
>>>>>>   if (ret)
>>>>>>   goto dealloc_usb2_hcd;
>>>>>>
>>>>>> +   pm_runtime_get_noresume(>dev);
>>>>>> +   pm_runtime_set_active(>dev);
>>>>>> +   pm_runtime_enable(>dev);
>>>>>> +
>>>>>>   return 0;
>>>>>>
>>>>>>
>>>>
>>>> To me this looks like we are not really enabling runtime pm for xhci, we
>>>> increment the
>>>> usage count in probe, and keep it until remove is called.
>>>>
>>>> This would normally prevent parent dwc3 from runtime suspending, but I
>>>> see
>>>> that in patch 2/2 adds
>>>> pm_suspend_ignore_children(dev, true) to dwc3, and, that dwc3 actually
>>>> controls xhci runtime
>>>> pm by calling pm_runtime_get/put for xhci in its own dwc3
>>>> runtime_suspend/resume callbacks.
>>>>
>>>> Looks a bit upside down to me, what's the reason for this?
>>>>
>>>> what prevents calling pm_runtime_put_* before leaving probe in xhci and
>>>> let
>>>> pm code handle
>>>> the runtime suspend and parent/child relationships?
>>>
>>>
>>> When dwc3 controller is working on host mode, which will create and
>>> add the USB hcd for host side. Then if we want to suspend dwc3
>>> controller as host mode, the USB device (bus) of host side will
>>> runtime suspend automatically if there are no slave attached (by
>>>
>>> usb_runtime_suspend()--->usb_suspend_both()--->usb_suspend_interface()--->usb_suspend_device()--->generic_suspend()--->hcd_bus_suspend()--->xhci_bus_suspend()),
>>> but we should not suspend xHCI device (issuing xhci_suspend()) now,
>>> since som

Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-02-16 Thread Baolin Wang
On 23 January 2017 at 19:57, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Alan Stern <st...@rowland.harvard.edu> writes:
>> On Mon, 16 Jan 2017, Felipe Balbi wrote:
>>
>>> > The gadget driver never calls usb_ep_queue in order to receive the next
>>> > SETUP packet; the UDC driver takes care of SETUP handling
>>> > automatically.
>>>
>>> yeah, that's another thing I'd like to change. Currently, we have no
>>> means to either try to implement device-initiated LPM without adding a
>>> ton of hacks to UDC drivers. If we require upper layers (composite.c,
>>> most of the time) to usb_ep_queue() separate requests for all 3 phases
>>> of a ctrl transfer, we can actually rely on the fact that a new SETUP
>>> phase hasn't been queued yet to trigger U3 entry.
>>
>> I haven't given any thought to LPM.
>
> okay
>
>> However, requiring gadget drivers to request SETUP packets seems rather
>> questionable.  It flies against the USB spec, which requires
>
> right, maybe SETUP is a bit of an overkill. DATA and STATUS, however,
> should be doable.
>
>> peripherals to accept SETUP packets at any time -- a device is not
>> allowed to NAK or STALL a SETUP packet (see 8.4.6.4 in the USB-2 spec).
>> In fact, the hardware in UDCs probably isn't capable of doing it.
>>
>> This means that to do what you want, the UDC driver would have to
>> accept SETUP packets at any time, and store the most recent packet
>> contents.  Then, when the gadget driver submits a request, the UDC
>> driver would give it this stored data.  It would also have to detect
>
> that's right, I missed that part.
>
>> and prevent a nasty race where the gadget driver tries to queue a
>> request on ep0 that is a response to an old SETUP, one that has already
>> been overwritten.  I'm not even sure preventing this race would be
>> possible in your scheme.
>>
>> The advantage to invoking the gadget driver's setup callback directly
>> from the UDC driver's interrupt handler is that the gadget driver will
>> know immediately when an old SETUP has become stale.  (That's what
>> ep0_req_tag is for in f_mass_storage.)  It also provides a concurrency
>> guarantee, because the driver does not re-enable UDC SETUP interrupts
>> until the handler is finished.
>>
>>> Another detail that this helps is that PM (overall) becomes simpler as,
>>> most likely, we won't need to mess with transfer cancellation, for
>>> example.
>>
>> System PM on a gadget is always troublesome.  Even if the USB
>> connection is a wakeup source, it may not be possible to guarantee that
>> the gadget can wake up quickly enough to handle an incoming packet.
>
> that's true.
>
>>> > You are suggesting that status stage requests should not be queued
>>> > automatically by UDC drivers but instead queued explicitly by gadget
>>> > drivers.  This would mean changing every UDC driver and every gadget
>>> > driver.
>>>
>>> yes, a bit of work but has been done before. One example that comes to
>>> mind is when I added ->udc_start() and ->udc_stop(). It's totally
>>> doable. We can, for instance, add a temporary
>>> "wants_explicit_ctrl_phases"  flag to struct usb_gadget which, if set,
>>> will tell composite.c (or whatever) that the UDC wants explicitly queued
>>> ctrl phases.
>>
>> The term used in the USB spec is "stage", not "phase".  "Phase" refers
>> to the packets making up a single transaction: token, data, and
>> handshake.
>>
>> Also, data stages are already explicit.  So your temporary flag might
>> better be called "wants_explicit_status_stages".
>
> I stand corrected ;-)
>
>>> Then add support for that to each UDC and set the flag. Once all are
>>> converted, add one extra patch to remove the flag and the legacy
>>> code. This has, of course, the draw back of increasing complexity until
>>> everything is converted over; but if it's all done in a single series, I
>>> can't see any problems with that.
>>>
>>> > Also, it won't fix the race that Baolin Wang found.  The setup routine
>>>
>>> well, it will help... see below.
>>>
>>> > is always called in interrupt context, so it can't sleep.  Doing
>>> > anything non-trivial will require a separate task, and it's possible
>>> > that this task will try to enqueue the data-stage or status-stage
>>> > request before the UDC drive

Re: [PATCH v5 1/2] usb: host: plat: Enable xhci plat runtime PM

2017-02-19 Thread Baolin Wang
Hi Mathias,

On 6 February 2017 at 13:26, Baolin Wang <baolin.w...@linaro.org> wrote:
> Hi Mathias,
>
> On 31 January 2017 at 21:14, Mathias Nyman
> <mathias.ny...@linux.intel.com> wrote:
>> On 16.01.2017 12:56, Baolin Wang wrote:
>>>
>>> Hi Mathias,
>>
>>
>> Hi
>>
>> Sorry about the long review delay
>> CC Alan in case my pm assumptions need to be corrected
>>
>>
>>>
>>> On 13 December 2016 at 15:49, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>>
>>>> Enable the xhci plat runtime PM for parent device to suspend/resume xhci.
>>>> Also call pm_runtime_get_noresume() in probe() function in case the
>>>> parent
>>>> device doesn't call suspend/resume callback by runtime PM now.
>>>>
>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>> ---
>>>> Changes since v4:
>>>>   - No updates.
>>>>
>>>> Changes since v3:
>>>>   - Fix kbuild error.
>>>>
>>>> Changes since v2:
>>>>   - Add pm_runtime_get_noresume() in probe() function.
>>>>   - Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in remove()
>>>> function.
>>>>
>>>> Changes since v1:
>>>>   - No updates.
>>>> ---
>>>
>>>
>>> Do you have any comments about this patch? Thanks.
>>>
>>>>   drivers/usb/host/xhci-plat.c |   41
>>>> -
>>>>   1 file changed, 36 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>>> index ed56bf9..5805c6a 100644
>>>> --- a/drivers/usb/host/xhci-plat.c
>>>> +++ b/drivers/usb/host/xhci-plat.c
>>>> @@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device
>>>> *pdev)
>>>>  if (ret)
>>>>  goto dealloc_usb2_hcd;
>>>>
>>>> +   pm_runtime_get_noresume(>dev);
>>>> +   pm_runtime_set_active(>dev);
>>>> +   pm_runtime_enable(>dev);
>>>> +
>>>>  return 0;
>>>>
>>>>
>>
>> To me this looks like we are not really enabling runtime pm for xhci, we
>> increment the
>> usage count in probe, and keep it until remove is called.
>>
>> This would normally prevent parent dwc3 from runtime suspending, but I see
>> that in patch 2/2 adds
>> pm_suspend_ignore_children(dev, true) to dwc3, and, that dwc3 actually
>> controls xhci runtime
>> pm by calling pm_runtime_get/put for xhci in its own dwc3
>> runtime_suspend/resume callbacks.
>>
>> Looks a bit upside down to me, what's the reason for this?
>>
>> what prevents calling pm_runtime_put_* before leaving probe in xhci and let
>> pm code handle
>> the runtime suspend and parent/child relationships?
>
> When dwc3 controller is working on host mode, which will create and
> add the USB hcd for host side. Then if we want to suspend dwc3
> controller as host mode, the USB device (bus) of host side will
> runtime suspend automatically if there are no slave attached (by
> usb_runtime_suspend()--->usb_suspend_both()--->usb_suspend_interface()--->usb_suspend_device()--->generic_suspend()--->hcd_bus_suspend()--->xhci_bus_suspend()),
> but we should not suspend xHCI device (issuing xhci_suspend()) now,
> since some other  controllers did not implement the runtime PM to
> control xHCI device's runtime state, which will cause other
> controllers can not resume xHCI device (issuing xhci_resume()) if the
> xHCI device suspend automatically by its child device. Thus we should
> get the runtime count for xHCI device in xhci_plat_probe() in case
> xHCI device will also suspend automatically by its child device.
> According to that, for xHCI device's parent: dwc3 device, we should
> put the xHCI device's runtime count to suspend xHCI device manually.
>

Any more comments?

-- 
Baolin.wang
Best Regards


Re: [PATCH RESEND v7 1/1] usb: xhci: plat: Enable async suspend/resume

2017-02-19 Thread Baolin Wang
On 10 February 2017 at 22:56, Robert Foss <robert.f...@collabora.com> wrote:
> From: Andrew Bresticker <abres...@chromium.org>
>
> USB host controllers can take a significant amount of time to suspend
> and resume, adding several hundred miliseconds to the kernel resume
> time. Since the XHCI controller has no outside dependencies (other than
> clocks, which are suspended late/resumed early), allow it to suspend and
> resume asynchronously.
>
> Signed-off-by: Andrew Bresticker <abres...@chromium.org>
> Tested-by: Andrew Bresticker <abres...@chromium.org>
> Tested-by: Robert Foss <robert.f...@collabora.com>
> Signed-off-by: Robert Foss <robert.f...@collabora.com>
> ---
>  drivers/usb/host/xhci-plat.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index 3cf8e120c620..4d6741a0d8f8 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -257,6 +257,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
>
> pm_runtime_set_active(>dev);
> pm_runtime_enable(>dev);
> +   device_enable_async_suspend(>dev);
>
> return 0;
>
> --
> 2.11.0.453.g787f75f05
>

Reviewed-by: Baolin Wang <baolin.w...@linaro.org>

-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-02-19 Thread Baolin Wang
On 17 February 2017 at 16:04, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> (One possible approach would be to have the setup routine return
>>>> different values for explicit and implicit status stages -- for
>>>> example, return 1 if it wants to submit an explicit status request.
>>>> That wouldn't be very different from the current
>>>> USB_GADGET_DELAYED_STATUS approach.)
>>>
>>> not really, no. The idea was for composite.c and/or functions to support
>>> both methods (temporarily) and use "gadget->wants_explicit_stages" to
>>> explicitly queue DATA and STATUS. That would mean that f_mass_storage
>>> wouldn't have to return DELAYED_STATUS if
>>> (gadget->wants_explicit_stages).
>>>
>>> After all UDCs are converted over and set wants_explicit_stages (which
>>> should all be done in a single series), then we get rid of the flag and
>>> the older method of DELAYED_STATUS.
>>
>> (Sorry for late reply due to my holiday)
>> I also met the problem pointed by Alan, from my test, I still want to
>> need one return value to indicate if it wants to submit an explicit
>> status request. Think about the Control-IN with a data stage, we can
>> not get the STATUS phase request from usb_ep_queue() call, and we need
>
> why not? wLength tells you that this is a 3-stage transfer. Gadget
> driver should be able to figure out that it needs to usb_ep_queue()
> another request for status stage.
>
>> to handle this STATUS phase request in dwc3_ep0_xfernotready(). But
>> Control-OUT will get one 0-length IN request for the status stage from
>> usb_ep_queue(), so we need one return value from setup routine to
>
> no we don't :-)
>
>> distinguish these in dwc3_ep0_xfernotready(), or we can not handle
>> status request correctly. Maybe I missed something else.
>>>
>>>> On the other hand, I am very doubtful about requiring explicit setup
>>>> requests.
>>>
>>> right, me too ;-)
>>
>> So do you suggest me continue to try to do this? Thanks.
>
> explicit setup? no
> explicit status? yes
>
> If you don't wanna do it, it's fine :-) I'll just add to my TODO
> list. It just depends on how much other tasks you have on your end ;-)

OK, I will take some time to check and test again. It will be better
if I send out one RFC patch to review.

-- 
Baolin.wang
Best Regards


[PATCH v19 1/4] usb: gadget: Introduce the usb charger framework

2017-02-20 Thread Baolin Wang
This patch introduces the usb charger driver based on usb gadget that
makes an enhancement to a power driver. It works well in practice but
that requires a system with suitable hardware.

The basic conception of the usb charger is that, when one usb charger
is added or removed by reporting from the usb gadget state change or
the extcon device state change, the usb charger will report to power
user to set the current limitation.

The usb charger will register notifiees on the usb gadget or the extcon
device to get notified the usb charger state. It also supplies the
notification mechanism to userspace When the usb charger state is changed.

Power user will register a notifiee on the usb charger to get notified
by status changes from the usb charger. It will report to power user
to set the current limitation when detecting the usb charger is added
or removed from extcon device state or usb gadget state.

This patch doesn't yet integrate with the gadget code, so some functions
which rely on the 'gadget' are not completed, that will be implemented
in the following patches.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/Kconfig   |8 +
 drivers/usb/gadget/udc/Makefile  |1 +
 drivers/usb/gadget/udc/charger.c |  770 ++
 include/linux/usb/charger.h  |  176 +
 include/uapi/linux/usb/charger.h |   31 ++
 5 files changed, 986 insertions(+)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 8ad2032..60d2f29 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -134,6 +134,14 @@ config U_SERIAL_CONSOLE
help
   It supports the serial gadget can be used as a console.
 
+config USB_CHARGER
+   bool "USB charger support"
+   select EXTCON
+   help
+ The usb charger driver based on the usb gadget that makes an
+ enhancement to a power driver which can set the current limitation
+ when the usb charger is added or removed.
+
 source "drivers/usb/gadget/udc/Kconfig"
 
 #
diff --git a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile
index 98e74ed..ede2351 100644
--- a/drivers/usb/gadget/udc/Makefile
+++ b/drivers/usb/gadget/udc/Makefile
@@ -2,6 +2,7 @@
 CFLAGS_trace.o := -I$(src)
 
 udc-core-y := core.o trace.o
+udc-core-$(CONFIG_USB_CHARGER) += charger.o
 
 #
 # USB peripheral controller drivers
diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
new file mode 100644
index 000..6d62f54
--- /dev/null
+++ b/drivers/usb/gadget/udc/charger.c
@@ -0,0 +1,770 @@
+/*
+ * charger.c -- USB charger driver
+ *
+ * Copyright (C) 2016 Linaro Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Default current range by charger type. */
+#define DEFAULT_SDP_CUR_MIN2
+#define DEFAULT_SDP_CUR_MAX500
+#define DEFAULT_SDP_CUR_MIN_SS 150
+#define DEFAULT_SDP_CUR_MAX_SS 900
+#define DEFAULT_DCP_CUR_MIN500
+#define DEFAULT_DCP_CUR_MAX5000
+#define DEFAULT_CDP_CUR_MIN1500
+#define DEFAULT_CDP_CUR_MAX5000
+#define DEFAULT_ACA_CUR_MIN1500
+#define DEFAULT_ACA_CUR_MAX5000
+
+static DEFINE_IDA(usb_charger_ida);
+static LIST_HEAD(charger_list);
+static DEFINE_MUTEX(charger_lock);
+
+static struct usb_charger *dev_to_uchger(struct device *dev)
+{
+   return NULL;
+}
+
+/*
+ * charger_current_show() - Show the charger current.
+ */
+static ssize_t charger_current_show(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   unsigned int min, max;
+
+   usb_charger_get_current(uchger, , );
+   return sprintf(buf, "%u-%u\n", min, max);
+}
+static DEVICE_ATTR_RO(charger_current);
+
+/*
+ * charger_type_show() - Show the charger type.
+ *
+ * It can be SDP/DCP/CDP/ACA type, else for unknown type.
+ */
+static ssize_t charger_type_show(struct device *dev,
+struct device_attribute *attr,
+char *buf)
+{
+   struct usb_charger *uchger = dev_to_uchger(dev);
+   enum usb_charger_type type = usb_charger_get_type(uchger);
+   int cnt;
+
+   switch (type) {
+   case SDP_TYPE:
+   cnt = sprintf(buf, "%s\n", "SDP");
+   break;
+ 

[PATCH v19 3/4] usb: gadget: Integrate with the usb gadget supporting for usb charger

2017-02-20 Thread Baolin Wang
When the usb gadget supporting for usb charger is ready, the usb charger
can implement the usb_charger_plug_by_gadget() function, usb_charger_exit()
function and dev_to_uchger() function by getting 'struct usb_charger' from
'struct gadget'.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/charger.c |   97 +-
 1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/charger.c b/drivers/usb/gadget/udc/charger.c
index 6d62f54..19eb044 100644
--- a/drivers/usb/gadget/udc/charger.c
+++ b/drivers/usb/gadget/udc/charger.c
@@ -38,7 +38,9 @@
 
 static struct usb_charger *dev_to_uchger(struct device *dev)
 {
-   return NULL;
+   struct usb_gadget *gadget = container_of(dev, struct usb_gadget, dev);
+
+   return gadget->charger;
 }
 
 /*
@@ -398,6 +400,18 @@ static int __usb_charger_set_cur_limit_by_type(struct 
usb_charger *uchger,
 int usb_charger_set_cur_limit_by_gadget(struct usb_gadget *gadget,
unsigned int cur_limit)
 {
+   struct usb_charger *uchger = gadget->charger;
+   int ret;
+
+   if (!uchger)
+   return -EINVAL;
+
+   ret = __usb_charger_set_cur_limit_by_type(uchger, uchger->type,
+ cur_limit);
+   if (ret)
+   return ret;
+
+   schedule_work(>work);
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_set_cur_limit_by_gadget);
@@ -622,11 +636,66 @@ static int usb_charger_plug_by_extcon(struct 
notifier_block *nb,
 int usb_charger_plug_by_gadget(struct usb_gadget *gadget,
   unsigned long state)
 {
+   struct usb_charger *uchger = gadget->charger;
+   enum usb_charger_state uchger_state;
+
+   if (WARN(!uchger, "charger can not be NULL"))
+   return -EINVAL;
+
+   /*
+* Report event to power to setting the current limitation
+* for this usb charger when one usb charger state is changed
+* with detecting by usb gadget state.
+*/
+   if (uchger->old_gadget_state != state) {
+   uchger->old_gadget_state = state;
+
+   if (state >= USB_STATE_ATTACHED) {
+   uchger_state = USB_CHARGER_PRESENT;
+   } else if (state == USB_STATE_NOTATTACHED) {
+   mutex_lock(>lock);
+
+   /*
+* Need check the charger type to make sure the usb
+* cable is removed, in case it just changes the usb
+* function with configfs.
+*/
+   if (uchger->type != UNKNOWN_TYPE) {
+   mutex_unlock(>lock);
+   return 0;
+   }
+
+   mutex_unlock(>lock);
+   uchger_state = USB_CHARGER_ABSENT;
+   } else {
+   uchger_state = USB_CHARGER_DEFAULT;
+   }
+
+   usb_charger_notify_state(uchger, uchger_state);
+   }
+
return 0;
 }
 EXPORT_SYMBOL_GPL(usb_charger_plug_by_gadget);
 
 /*
+ * usb_charger_unregister() - Unregister a usb charger.
+ * @uchger - the usb charger to be unregistered.
+ */
+static int usb_charger_unregister(struct usb_charger *uchger)
+{
+   ida_simple_remove(_charger_ida, uchger->id);
+   sysfs_remove_groups(>gadget->dev.kobj, usb_charger_groups);
+   uchger->id = -1;
+
+   mutex_lock(_lock);
+   list_del(>list);
+   mutex_unlock(_lock);
+
+   return 0;
+}
+
+/*
  * usb_charger_register() - Register a new usb charger.
  * @uchger - the new usb charger instance.
  */
@@ -725,6 +794,7 @@ int usb_charger_init(struct usb_gadget *ugadget)
}
 
uchger->gadget = ugadget;
+   ugadget->charger = uchger;
uchger->old_gadget_state = USB_STATE_NOTATTACHED;
 
/* Register a new usb charger */
@@ -762,6 +832,31 @@ int usb_charger_init(struct usb_gadget *ugadget)
 
 int usb_charger_exit(struct usb_gadget *ugadget)
 {
+   struct usb_charger *uchger = ugadget->charger;
+
+   if (!uchger)
+   return -EINVAL;
+
+   usb_charger_unregister(uchger);
+   ugadget->charger = NULL;
+
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_USB,
+  >extcon_nb.nb);
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_CHG_USB_SDP,
+  >extcon_type_nb.nb);
+   extcon_unregister_notifier(uchger->extcon_dev,
+  EXTCON_CHG_USB_CDP,
+  >extcon_type_nb.n

[PATCH v19 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2017-02-20 Thread Baolin Wang
ce v14:
 - Add kernel documentation for struct usb_cahrger.
 - Remove some redundant WARN() functions.

Changes since v13:
 - Remove the charger checking in usb_gadget_vbus_draw() function.
 - Rename some functions in charger.c file.
 - Rebase on git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git 
tags/usb-for-v4.8

Changes since v12:
 - Remove the class and device things.
 - Link usb charger to udc-core.ko.
 - Create one "charger" subdirectory which holds all charger-related attributes.

Changes since v11:
 - Reviewed and tested by Li Jun.

Changes since v10:
 - Introduce usb_charger_get_state() function to check charger state.
 - Remove the mutex lock in usb_charger_set_cur_limit_by_type() function
 in case will be issued in atomic context.

Baolin Wang (4):
  usb: gadget: Introduce the usb charger framework
  usb: gadget: Support for the usb charger framework
  usb: gadget: Integrate with the usb gadget supporting for usb charger
  power: wm831x_power: Support USB charger current limit management

 drivers/power/supply/wm831x_power.c |   63 +++
 drivers/usb/gadget/Kconfig  |8 +
 drivers/usb/gadget/udc/Makefile |1 +
 drivers/usb/gadget/udc/charger.c|  865 +++
 drivers/usb/gadget/udc/core.c   |   19 +-
 include/linux/usb/charger.h |  176 +++
 include/linux/usb/gadget.h  |3 +
 include/uapi/linux/usb/charger.h|   31 ++
 8 files changed, 1165 insertions(+), 1 deletion(-)
 create mode 100644 drivers/usb/gadget/udc/charger.c
 create mode 100644 include/linux/usb/charger.h
 create mode 100644 include/uapi/linux/usb/charger.h

-- 
1.7.9.5



[PATCH v19 4/4] power: wm831x_power: Support USB charger current limit management

2017-02-20 Thread Baolin Wang
Integrate with the newly added USB charger interface to limit the current
we draw from the USB input based on the input device configuration
identified by the USB stack, allowing us to charge more quickly from high
current inputs without drawing more current than specified from others.

Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Acked-by: Lee Jones <lee.jo...@linaro.org>
Acked-by: Charles Keepax <ckee...@opensource.wolfsonmicro.com>
Acked-by: Peter Chen <peter.c...@freescale.com>
Acked-by: Sebastian Reichel <s...@kernel.org>
---
 drivers/power/supply/wm831x_power.c |   63 +++
 1 file changed, 63 insertions(+)

diff --git a/drivers/power/supply/wm831x_power.c 
b/drivers/power/supply/wm831x_power.c
index 7082301..b5f1652 100644
--- a/drivers/power/supply/wm831x_power.c
+++ b/drivers/power/supply/wm831x_power.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -31,6 +32,8 @@ struct wm831x_power {
char usb_name[20];
char battery_name[20];
bool have_battery;
+   struct usb_charger *usb_charger;
+   struct notifier_block usb_notify;
 };
 
 static int wm831x_power_check_online(struct wm831x *wm831x, int supply,
@@ -125,6 +128,42 @@ static int wm831x_usb_get_prop(struct power_supply *psy,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
 };
 
+/* In milliamps */
+static const unsigned int wm831x_usb_limits[] = {
+   0,
+   2,
+   100,
+   500,
+   900,
+   1500,
+   1800,
+   550,
+};
+
+static int wm831x_usb_limit_change(struct notifier_block *nb,
+  unsigned long limit, void *data)
+{
+   struct wm831x_power *wm831x_power = container_of(nb,
+struct wm831x_power,
+usb_notify);
+
+   /* Find the highest supported limit */
+   best = 0;
+   for (i = 0; i < ARRAY_SIZE(wm831x_usb_limits); i++) {
+   if (limit >= wm831x_usb_limits[i] &&
+   wm831x_usb_limits[best] < wm831x_usb_limits[i])
+   best = i;
+   }
+
+   dev_dbg(wm831x_power->wm831x->dev,
+   "Limiting USB current to %umA", wm831x_usb_limits[best]);
+
+   wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE,
+   WM831X_USB_ILIM_MASK, best);
+
+   return 0;
+}
+
 /*
  * Battery properties
  */
@@ -607,8 +646,26 @@ static int wm831x_power_probe(struct platform_device *pdev)
}
}
 
+   power->usb_charger = usb_charger_get_instance();
+   if (IS_ERR(power->usb_charger)) {
+   ret = PTR_ERR(power->usb_charger);
+   dev_err(>dev, "Failed to find USB gadget: %d\n", ret);
+   goto err_bat_irq;
+   }
+
+   power->usb_notify.notifier_call = wm831x_usb_limit_change;
+
+   ret = usb_charger_register_notify(power->usb_charger,
+ >usb_notify);
+   if (ret != 0) {
+   dev_err(>dev, "Failed to register notifier: %d\n", ret);
+   goto err_usb_charger;
+   }
+
return ret;
 
+err_usb_charger:
+   /* put_device on charger */
 err_bat_irq:
--i;
for (; i >= 0; i--) {
@@ -637,6 +694,12 @@ static int wm831x_power_remove(struct platform_device 
*pdev)
struct wm831x *wm831x = wm831x_power->wm831x;
int irq, i;
 
+   if (wm831x_power->usb_charger) {
+   usb_charger_unregister_notify(wm831x_power->usb_charger,
+ _power->usb_notify);
+   /* Free charger */
+   }
+
for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
irq = wm831x_irq(wm831x, 
 platform_get_irq_byname(pdev,
-- 
1.7.9.5



[PATCH v19 2/4] usb: gadget: Support for the usb charger framework

2017-02-20 Thread Baolin Wang
For supporting the usb charger, it adds the usb_charger_init() and
usb_charger_exit() functions for usb charger initialization and exit.

It will report to the usb charger when the gadget state is changed,
then the usb charger can do the power things.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Reviewed-by: Li Jun <jun...@nxp.com>
Tested-by: Li Jun <jun...@nxp.com>
---
 drivers/usb/gadget/udc/core.c |   19 ++-
 include/linux/usb/gadget.h|3 +++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c
index 9483489..90df022 100644
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -576,12 +577,17 @@ int usb_gadget_vbus_connect(struct usb_gadget *gadget)
  * reporting how much power the device may consume.  For example, this
  * could affect how quickly batteries are recharged.
  *
+ * It will also notify the USB charger how much power the device may
+ * consume if there is a USB charger linking with the gadget.
+ *
  * Returns zero on success, else negative errno.
  */
 int usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA)
 {
int ret = 0;
 
+   usb_charger_set_cur_limit_by_gadget(gadget, mA);
+
if (!gadget->ops->vbus_draw) {
ret = -EOPNOTSUPP;
goto out;
@@ -963,6 +969,9 @@ static void usb_gadget_state_work(struct work_struct *work)
struct usb_gadget *gadget = work_to_gadget(work);
struct usb_udc *udc = gadget->udc;
 
+   /* when the gadget state is changed, then report to USB charger */
+   usb_charger_plug_by_gadget(gadget, gadget->state);
+
if (udc)
sysfs_notify(>dev.kobj, NULL, "state");
 }
@@ -1132,6 +1141,10 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret)
goto err4;
 
+   ret = usb_charger_init(gadget);
+   if (ret)
+   goto err5;
+
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
 
@@ -1143,7 +1156,7 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
if (ret != -EPROBE_DEFER)
list_del(>pending);
if (ret)
-   goto err5;
+   goto err6;
break;
}
}
@@ -1152,6 +1165,9 @@ int usb_add_gadget_udc_release(struct device *parent, 
struct usb_gadget *gadget,
 
return 0;
 
+err6:
+   usb_charger_exit(gadget);
+
 err5:
device_del(>dev);
 
@@ -1263,6 +1279,7 @@ void usb_del_gadget_udc(struct usb_gadget *gadget)
kobject_uevent(>dev.kobj, KOBJ_REMOVE);
flush_work(>work);
device_unregister(>dev);
+   usb_charger_exit(gadget);
device_unregister(>dev);
 }
 EXPORT_SYMBOL_GPL(usb_del_gadget_udc);
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index e4516e9..b4d7be2 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define UDC_TRACE_STR_MAX  512
 
@@ -328,6 +329,7 @@ struct usb_gadget_ops {
  * @in_epnum: last used in ep number
  * @mA: last set mA value
  * @otg_caps: OTG capabilities of this gadget.
+ * @charger: Negotiate the power with the usb charger.
  * @sg_supported: true if we can handle scatter-gather
  * @is_otg: True if the USB device port uses a Mini-AB jack, so that the
  * gadget driver must provide a USB OTG descriptor.
@@ -387,6 +389,7 @@ struct usb_gadget {
unsignedin_epnum;
unsignedmA;
struct usb_otg_caps *otg_caps;
+   struct usb_charger  *charger;
 
unsignedsg_supported:1;
unsignedis_otg:1;
-- 
1.7.9.5



[RFC PATCH 3/3] usb: phy: fsl: Remove the set_power callback

2017-01-18 Thread Baolin Wang
Since the set_power callback did not do anything for power setting,
then remove it.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/phy/phy-fsl-usb.c |   12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index 94eb292..392ab42 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -642,17 +642,6 @@ static int fsl_otg_set_peripheral(struct usb_otg *otg,
return 0;
 }
 
-/* Set OTG port power, only for B-device */
-static int fsl_otg_set_power(struct usb_phy *phy, unsigned mA)
-{
-   if (!fsl_otg_dev)
-   return -ENODEV;
-   if (phy->otg->state == OTG_STATE_B_PERIPHERAL)
-   pr_info("FSL OTG: Draw %d mA\n", mA);
-
-   return 0;
-}
-
 /*
  * Delayed pin detect interrupt processing.
  *
@@ -821,7 +810,6 @@ static int fsl_otg_conf(struct platform_device *pdev)
/* initialize the otg structure */
fsl_otg_tc->phy.label = DRIVER_DESC;
fsl_otg_tc->phy.dev = >dev;
-   fsl_otg_tc->phy.set_power = fsl_otg_set_power;
 
fsl_otg_tc->phy.otg->usb_phy = _otg_tc->phy;
fsl_otg_tc->phy.otg->set_host = fsl_otg_set_host;
-- 
1.7.9.5



[RFC PATCH 1/3] usb: phy: ab8500: Remove the set_power callback

2017-01-18 Thread Baolin Wang
There are no users will use the vbus_draw variable set by set_power()
callback to set the vbus current. Thus we can remove it.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/phy/phy-ab8500-usb.c |   20 
 1 file changed, 20 deletions(-)

diff --git a/drivers/usb/phy/phy-ab8500-usb.c b/drivers/usb/phy/phy-ab8500-usb.c
index a03caf4..3dfbb97 100644
--- a/drivers/usb/phy/phy-ab8500-usb.c
+++ b/drivers/usb/phy/phy-ab8500-usb.c
@@ -1036,25 +1036,6 @@ static unsigned ab8500_eyediagram_workaroud(struct 
ab8500_usb *ab, unsigned mA)
return mA;
 }
 
-static int ab8500_usb_set_power(struct usb_phy *phy, unsigned mA)
-{
-   struct ab8500_usb *ab;
-
-   if (!phy)
-   return -ENODEV;
-
-   ab = phy_to_ab(phy);
-
-   mA = ab8500_eyediagram_workaroud(ab, mA);
-
-   ab->vbus_draw = mA;
-
-   atomic_notifier_call_chain(>phy.notifier,
-   UX500_MUSB_VBUS, >vbus_draw);
-
-   return 0;
-}
-
 static int ab8500_usb_set_suspend(struct usb_phy *x, int suspend)
 {
/* TODO */
@@ -1392,7 +1373,6 @@ static int ab8500_usb_probe(struct platform_device *pdev)
ab->phy.otg = otg;
ab->phy.label   = "ab8500";
ab->phy.set_suspend = ab8500_usb_set_suspend;
-   ab->phy.set_power   = ab8500_usb_set_power;
ab->phy.otg->state  = OTG_STATE_UNDEFINED;
 
otg->usb_phy= >phy;
-- 
1.7.9.5



[RFC PATCH 2/3] usb: phy: msm: Remove the set_power callback

2017-01-18 Thread Baolin Wang
Since it will not set the PMIC current drawn from USB configuration by
set_power callback, then remove it.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/phy/phy-msm-usb.c |   18 --
 1 file changed, 18 deletions(-)

diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c
index 8a34759..9e52890 100644
--- a/drivers/usb/phy/phy-msm-usb.c
+++ b/drivers/usb/phy/phy-msm-usb.c
@@ -842,23 +842,6 @@ static void msm_otg_notify_charger(struct msm_otg *motg, 
unsigned mA)
motg->cur_power = mA;
 }
 
-static int msm_otg_set_power(struct usb_phy *phy, unsigned mA)
-{
-   struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
-
-   /*
-* Gadget driver uses set_power method to notify about the
-* available current based on suspend/configured states.
-*
-* IDEV_CHG can be drawn irrespective of suspend/un-configured
-* states when CDP/ACA is connected.
-*/
-   if (motg->chg_type == USB_SDP_CHARGER)
-   msm_otg_notify_charger(motg, mA);
-
-   return 0;
-}
-
 static void msm_otg_start_host(struct usb_phy *phy, int on)
 {
struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
@@ -1950,7 +1933,6 @@ static int msm_otg_probe(struct platform_device *pdev)
}
 
phy->init = msm_phy_init;
-   phy->set_power = msm_otg_set_power;
phy->notify_disconnect = msm_phy_notify_disconnect;
phy->type = USB_PHY_TYPE_USB2;
 
-- 
1.7.9.5



[RFC PATCH 0/3] Remove some dummy set_power callbacks

2017-01-18 Thread Baolin Wang
In future we plan to introduce USB charger to set PMIC current drawn from
USB configuration, instead of using set_power callback in phy driver. Moreover
in these 3 phy drivers, the set_power callback did not implement anything
to set PMIC current, thus we should remove them.

Baolin Wang (3):
  usb: phy: ab8500: Remove the set_power callback
  usb: phy: msm: Remove the set_power callback
  usb: phy: fsl: Remove the set_power callback

 drivers/usb/phy/phy-ab8500-usb.c |   20 
 drivers/usb/phy/phy-fsl-usb.c|   12 
 drivers/usb/phy/phy-msm-usb.c|   18 --
 3 files changed, 50 deletions(-)

-- 
1.7.9.5



Re: [PATCH] usb: dwc3: core: Disable USB2.0 phy suspend when dwc3 acts as host role

2017-01-18 Thread Baolin Wang
Hi John,

On 19 January 2017 at 11:31, John Youn <john.y...@synopsys.com> wrote:
> On 1/18/2017 7:12 PM, Baolin Wang wrote:
>> Hi John,
>>
>> On 19 January 2017 at 09:33, John Youn <john.y...@synopsys.com> wrote:
>>> On 1/16/2017 2:38 AM, Felipe Balbi wrote:
>>>>
>>>> Hi,
>>>>
>>>> John Youn <john.y...@synopsys.com> writes:
>>>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>>>> When dwc3 controller acts as host role with attaching slow speed 
>>>>>>>>> device
>>>>>>>>> (like mouse or keypad). Then if we plugged out the slow speed device,
>>>>>>>>> it will timeout to run the deconfiguration endpoint command to drop 
>>>>>>>>> the
>>>>>>>>> endpoint's resources. Some xHCI command timeout log as below when
>>>>>>>>> disconnecting one slow device:
>>>>>>>>>
>>>>>>>>> [   99.807739] c0 xhci-hcd.0.auto: Port Status Change Event for port 1
>>>>>>>>> [   99.814699] c0 xhci-hcd.0.auto: resume root hub
>>>>>>>>> [   99.819992] c0 xhci-hcd.0.auto: handle_port_status: starting port
>>>>>>>>>  polling.
>>>>>>>>> [   99.827808] c0 xhci-hcd.0.auto: get port status, actual port 0 
>>>>>>>>> status
>>>>>>>>>  = 0x202a0
>>>>>>>>> [   99.835903] c0 xhci-hcd.0.auto: Get port status returned 0x10100
>>>>>>>>> [   99.850052] c0 xhci-hcd.0.auto: clear port connect change, actual
>>>>>>>>>  port 0 status  = 0x2a0
>>>>>>>>> [   99.859313] c0 xhci-hcd.0.auto: Cancel URB ffc01ed6cd00, dev 1,
>>>>>>>>>  ep 0x81, starting at offset 
>>>>>>>>> 0xc406d210
>>>>>>>>> [   99.869645] c0 xhci-hcd.0.auto: // Ding dong!
>>>>>>>>> [   99.874776] c0 xhci-hcd.0.auto: Stopped on Transfer TRB
>>>>>>>>> [   99.880713] c0 xhci-hcd.0.auto: Removing canceled TD starting at
>>>>>>>>>  0xc406d210 (dma).
>>>>>>>>> [   99.889012] c0 xhci-hcd.0.auto: Finding endpoint context
>>>>>>>>> [   99.895069] c0 xhci-hcd.0.auto: Cycle state = 0x1
>>>>>>>>> [   99.900519] c0 xhci-hcd.0.auto: New dequeue segment =
>>>>>>>>>  ffc1112f0880 (virtual)
>>>>>>>>> [   99.908655] c0 xhci-hcd.0.auto: New dequeue pointer = 0xc406d220 
>>>>>>>>> (DMA)
>>>>>>>>> [   99.915927] c0 xhci-hcd.0.auto: Set TR Deq Ptr cmd, new deq seg =
>>>>>>>>>  ffc1112f0880 (0xc406d000 dma),
>>>>>>>>>  new deq ptr = ff8002175220
>>>>>>>>>  (0xc406d220 dma), new cycle = 1
>>>>>>>>> [   99.931242] c0 xhci-hcd.0.auto: // Ding dong!
>>>>>>>>> [   99.936360] c0 xhci-hcd.0.auto: Successful Set TR Deq Ptr cmd,
>>>>>>>>>  deq = @c406d220
>>>>>>>>> [   99.944458] c0 xhci-hcd.0.auto: xhci_hub_status_data: stopping port
>>>>>>>>>  polling.
>>>>>>>>> [  100.047619] c0 xhci-hcd.0.auto: xhci_drop_endpoint called for udev
>>>>>>>>>  ffc01ae08800
>>>>>>>>> [  100.057002] c0 xhci-hcd.0.auto: drop ep 0x81, slot id 1, new drop
>>>>>>>>>  flags = 0x8, new add flags = 0x0
>>>>>>>>> [  100.067878] c0 xhci-hcd.0.auto: xhci_check_bandwidth called for 
>>>>>>>>> udev
>>>>>>>>>  ffc01ae08800
>>>>>>>>> [  100.076868] c0 xhci-hcd.0.auto: New Input Control Context:
>>>>>>>>>
>>>>>>>>> ..
>>>>>>

Re: [PATCH] usb: dwc3: core: Disable USB2.0 phy suspend when dwc3 acts as host role

2017-01-18 Thread Baolin Wang
Hi John,

On 19 January 2017 at 09:33, John Youn <john.y...@synopsys.com> wrote:
> On 1/16/2017 2:38 AM, Felipe Balbi wrote:
>>
>> Hi,
>>
>> John Youn <john.y...@synopsys.com> writes:
>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>> When dwc3 controller acts as host role with attaching slow speed device
>>>>>>> (like mouse or keypad). Then if we plugged out the slow speed device,
>>>>>>> it will timeout to run the deconfiguration endpoint command to drop the
>>>>>>> endpoint's resources. Some xHCI command timeout log as below when
>>>>>>> disconnecting one slow device:
>>>>>>>
>>>>>>> [   99.807739] c0 xhci-hcd.0.auto: Port Status Change Event for port 1
>>>>>>> [   99.814699] c0 xhci-hcd.0.auto: resume root hub
>>>>>>> [   99.819992] c0 xhci-hcd.0.auto: handle_port_status: starting port
>>>>>>>  polling.
>>>>>>> [   99.827808] c0 xhci-hcd.0.auto: get port status, actual port 0 status
>>>>>>>  = 0x202a0
>>>>>>> [   99.835903] c0 xhci-hcd.0.auto: Get port status returned 0x10100
>>>>>>> [   99.850052] c0 xhci-hcd.0.auto: clear port connect change, actual
>>>>>>>  port 0 status  = 0x2a0
>>>>>>> [   99.859313] c0 xhci-hcd.0.auto: Cancel URB ffc01ed6cd00, dev 1,
>>>>>>>  ep 0x81, starting at offset 0xc406d210
>>>>>>> [   99.869645] c0 xhci-hcd.0.auto: // Ding dong!
>>>>>>> [   99.874776] c0 xhci-hcd.0.auto: Stopped on Transfer TRB
>>>>>>> [   99.880713] c0 xhci-hcd.0.auto: Removing canceled TD starting at
>>>>>>>  0xc406d210 (dma).
>>>>>>> [   99.889012] c0 xhci-hcd.0.auto: Finding endpoint context
>>>>>>> [   99.895069] c0 xhci-hcd.0.auto: Cycle state = 0x1
>>>>>>> [   99.900519] c0 xhci-hcd.0.auto: New dequeue segment =
>>>>>>>  ffc1112f0880 (virtual)
>>>>>>> [   99.908655] c0 xhci-hcd.0.auto: New dequeue pointer = 0xc406d220 
>>>>>>> (DMA)
>>>>>>> [   99.915927] c0 xhci-hcd.0.auto: Set TR Deq Ptr cmd, new deq seg =
>>>>>>>  ffc1112f0880 (0xc406d000 dma),
>>>>>>>  new deq ptr = ff8002175220
>>>>>>>  (0xc406d220 dma), new cycle = 1
>>>>>>> [   99.931242] c0 xhci-hcd.0.auto: // Ding dong!
>>>>>>> [   99.936360] c0 xhci-hcd.0.auto: Successful Set TR Deq Ptr cmd,
>>>>>>>  deq = @c406d220
>>>>>>> [   99.944458] c0 xhci-hcd.0.auto: xhci_hub_status_data: stopping port
>>>>>>>  polling.
>>>>>>> [  100.047619] c0 xhci-hcd.0.auto: xhci_drop_endpoint called for udev
>>>>>>>  ffc01ae08800
>>>>>>> [  100.057002] c0 xhci-hcd.0.auto: drop ep 0x81, slot id 1, new drop
>>>>>>>  flags = 0x8, new add flags = 0x0
>>>>>>> [  100.067878] c0 xhci-hcd.0.auto: xhci_check_bandwidth called for udev
>>>>>>>  ffc01ae08800
>>>>>>> [  100.076868] c0 xhci-hcd.0.auto: New Input Control Context:
>>>>>>>
>>>>>>> ..
>>>>>>>
>>>>>>> [  100.427252] c0 xhci-hcd.0.auto: // Ding dong!
>>>>>>> [  105.430728] c0 xhci-hcd.0.auto: Command timeout
>>>>>>> [  105.436029] c0 xhci-hcd.0.auto: Abort command ring
>>>>>>> [  113.558223] c0 xhci-hcd.0.auto: Command completion event does not 
>>>>>>> match
>>>>>>>  command
>>>>>>> [  113.569778] c0 xhci-hcd.0.auto: Timeout while waiting for configure
>>>>>>>  endpoint command
>>>>>>>
>>>>>>> The reason is it will suspend USB phy to disable phy clock when
>>>

Re: [PATCH v5 1/2] usb: host: plat: Enable xhci plat runtime PM

2017-01-16 Thread Baolin Wang
Hi Mathias,

On 13 December 2016 at 15:49, Baolin Wang <baolin.w...@linaro.org> wrote:
> Enable the xhci plat runtime PM for parent device to suspend/resume xhci.
> Also call pm_runtime_get_noresume() in probe() function in case the parent
> device doesn't call suspend/resume callback by runtime PM now.
>
> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
> ---
> Changes since v4:
>  - No updates.
>
> Changes since v3:
>  - Fix kbuild error.
>
> Changes since v2:
>  - Add pm_runtime_get_noresume() in probe() function.
>  - Add pm_runtime_set_suspended()/pm_runtime_put_noidle() in remove() 
> function.
>
> Changes since v1:
>  - No updates.
> ---

Do you have any comments about this patch? Thanks.

>  drivers/usb/host/xhci-plat.c |   41 -
>  1 file changed, 36 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
> index ed56bf9..5805c6a 100644
> --- a/drivers/usb/host/xhci-plat.c
> +++ b/drivers/usb/host/xhci-plat.c
> @@ -246,6 +246,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
> if (ret)
> goto dealloc_usb2_hcd;
>
> +   pm_runtime_get_noresume(>dev);
> +   pm_runtime_set_active(>dev);
> +   pm_runtime_enable(>dev);
> +
> return 0;
>
>
> @@ -274,6 +278,10 @@ static int xhci_plat_remove(struct platform_device *dev)
> struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> struct clk *clk = xhci->clk;
>
> +   pm_runtime_set_suspended(>dev);
> +   pm_runtime_put_noidle(>dev);
> +   pm_runtime_disable(>dev);
> +
> usb_remove_hcd(xhci->shared_hcd);
> usb_phy_shutdown(hcd->usb_phy);
>
> @@ -311,14 +319,37 @@ static int xhci_plat_resume(struct device *dev)
>
> return xhci_resume(xhci, 0);
>  }
> +#endif /* CONFIG_PM_SLEEP */
> +
> +#ifdef CONFIG_PM
> +static int xhci_plat_runtime_suspend(struct device *dev)
> +{
> +   struct usb_hcd  *hcd = dev_get_drvdata(dev);
> +   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> +
> +   return xhci_suspend(xhci, device_may_wakeup(dev));
> +}
> +
> +static int xhci_plat_runtime_resume(struct device *dev)
> +{
> +   struct usb_hcd  *hcd = dev_get_drvdata(dev);
> +   struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> +
> +   return xhci_resume(xhci, 0);
> +}
> +
> +static int xhci_plat_runtime_idle(struct device *dev)
> +{
> +   return 0;
> +}
> +#endif /* CONFIG_PM */
>
>  static const struct dev_pm_ops xhci_plat_pm_ops = {
> SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume)
> +
> +   SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, 
> xhci_plat_runtime_resume,
> +  xhci_plat_runtime_idle)
>  };
> -#define DEV_PM_OPS (_plat_pm_ops)
> -#else
> -#define DEV_PM_OPS NULL
> -#endif /* CONFIG_PM */
>
>  static const struct acpi_device_id usb_xhci_acpi_match[] = {
> /* XHCI-compliant USB Controller */
> @@ -332,7 +363,7 @@ static int xhci_plat_resume(struct device *dev)
> .remove = xhci_plat_remove,
> .driver = {
> .name = "xhci-hcd",
> -   .pm = DEV_PM_OPS,
> +   .pm = _plat_pm_ops,
> .of_match_table = of_match_ptr(usb_xhci_of_match),
> .acpi_match_table = ACPI_PTR(usb_xhci_acpi_match),
> },
> --
> 1.7.9.5
>



-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-01-16 Thread Baolin Wang
Hi,

On 16 January 2017 at 19:29, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> Hi,
>>
>> On 16 January 2017 at 18:56, Felipe Balbi <ba...@kernel.org> wrote:
>>>
>>> Hi,
>>>
>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> When handing the SETUP packet by composite_setup(), we will release the
>>>> dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup
>>>> function, which means we need to delay handling the STATUS phase.
>>>
>>> this sentence needs a little work. Seems like it's missing some
>>> information.
>>>
>>> anyway, I get that we release the lock but...
>>>
>>>> But during the lock release period, maybe the request for handling delay
>>>
>>> execution of ->setup() itself should be locked. I can see that it's only
>>> locked for set_config() which is rather peculiar.
>>>
>>> What exact request you had when you triggered this? (Hint: dwc3
>>> tracepoints print out ctrl request bytes). IIRC, only set_config() or
>>> f->set_alt() can actually return USB_GADGET_DELAYED_STATUS.
>>
>> Yes, when host set configuration for mass storage driver, it can
>> produce this issue.
>>
>>>
>>> Which gadget driver were you using when you triggered this?
>>
>> mass storage driver. When host issues the setting config request, we
>> will get USB_GADGET_DELAYED_STATUS result from
>> set_config()--->fsg_set_alt(). Then the mass storage driver will issue
>> one thread to complete the status stage by ep0_queue() (this thread
>> may be running on another core), then if the thread issues ep0_queue()
>> too fast before we get the dwc->lock in dwc3_ep0_delegate_req() or
>> before we get into the STATUS stage, then we can not handle this
>> request for the delay STATUS stage in dwc3_gadget_ep0_queue().
>>
>>>
>>> Another point here is that the really robust way of fixing this is to
>>> get rid of USB_GADGET_DELAYED_STATUS altogether and just make sure
>>> gadget drivers know how to queue requests for all three phases of a
>>> Control Transfer.
>>>
>>> A lot of code will be removed from all gadget drivers and UDC drivers
>>> while combining all of it in a single place in composite.c.
>>>
>>> The reason I'm saying this is that other UDC drivers might have similar
>>> races already but they just haven't triggered.
>>
>> Yes, maybe.
>>
>>>
>>>> STATUS phase has been queued into list before we set 'dwc->delayed_status'
>>>> flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance
>>>> to handle the STATUS phase. Thus we should check if the request for delay
>>>> STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase in
>>>> dwc3_ep0_xfernotready(), if so, we should handle it.
>>>>
>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>> ---
>>>>  drivers/usb/dwc3/ep0.c |   14 ++
>>>>  1 file changed, 14 insertions(+)
>>>>
>>>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>>> index 9bb1f85..e689ced 100644
>>>> --- a/drivers/usb/dwc3/ep0.c
>>>> +++ b/drivers/usb/dwc3/ep0.c
>>>> @@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
>>>>   dwc->ep0state = EP0_STATUS_PHASE;
>>>>
>>>>   if (dwc->delayed_status) {
>>>> + struct dwc3_ep *dep = dwc->eps[0];
>>>> +
>>>>   WARN_ON_ONCE(event->endpoint_number != 1);
>>>> + /*
>>>> +  * We should handle the delay STATUS phase here if 
>>>> the
>>>> +  * request for handling delay STATUS has been queued
>>>> +  * into the list.
>>>> +  */
>>>> + if (!list_empty(>pending_list)) {
>>>> + dwc->delayed_status = false;
>>>> + usb_gadget_set_state(>gadget,
>>>> +  USB_STATE_CONFIGURED);
>>>
>>> Isn't this patch also changing the normal case when usb_ep_queue() comes
>>> later? I guess list_empty() protects against that...
>>
>> I think it will not change other cases, we only handle the delayed
>> status and I've tested it for a while and I did not find any problem.
>
> Alright, it's important enough to fix this bug. Can you also have a look
> into dropping USB_GADGET_DELAYED_STATUS altogether? If you're too busy,
> no issues. It'll stay in my queue.

Okay, I will have a look at f_mass_storage driver to see if we can
drop USB_GADGET_DELAYED_STATUS. Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH v5 2/2] usb: dwc3: core: Support the dwc3 host suspend/resume

2017-01-16 Thread Baolin Wang
Hi,

On 16 January 2017 at 18:28, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> For some mobile devices with strict power management, we also want to suspend
>> the host when the slave is detached for power saving. Thus we add the host
>> suspend/resume functions to support this requirement.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>> Changes since v4:
>>  - Remove Kconfig and just enable host suspend/resume.
>>  - Simplify the dwc3_host_suspend/resume() function.
>>
>> Changes since v3:
>>  - No updates.
>>
>> Changes since v2:
>>  - Remove pm_children_suspended() and other unused macros.
>>
>> Changes since v1:
>>  - Add pm_runtime.h head file to avoid kbuild error.
>> ---
>>  drivers/usb/dwc3/core.c |   26 +-
>>  drivers/usb/dwc3/core.h |7 +++
>>  drivers/usb/dwc3/host.c |   21 +
>>  3 files changed, 53 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 9a4a5e4..7ad4bc3 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -1091,6 +1091,7 @@ static int dwc3_probe(struct platform_device *pdev)
>>   pm_runtime_use_autosuspend(dev);
>>   pm_runtime_set_autosuspend_delay(dev, DWC3_DEFAULT_AUTOSUSPEND_DELAY);
>>   pm_runtime_enable(dev);
>> + pm_suspend_ignore_children(dev, true);
>>   ret = pm_runtime_get_sync(dev);
>>   if (ret < 0)
>>   goto err1;
>> @@ -1215,15 +1216,27 @@ static int dwc3_remove(struct platform_device *pdev)
>>  static int dwc3_suspend_common(struct dwc3 *dwc)
>>  {
>>   unsigned long   flags;
>> + int ret;
>>
>>   switch (dwc->dr_mode) {
>>   case USB_DR_MODE_PERIPHERAL:
>> + spin_lock_irqsave(>lock, flags);
>> + dwc3_gadget_suspend(dwc);
>> + spin_unlock_irqrestore(>lock, flags);
>> + break;
>>   case USB_DR_MODE_OTG:
>> + ret = dwc3_host_suspend(dwc);
>> + if (ret)
>> + return ret;
>> +
>>   spin_lock_irqsave(>lock, flags);
>>   dwc3_gadget_suspend(dwc);
>>   spin_unlock_irqrestore(>lock, flags);
>>   break;
>>   case USB_DR_MODE_HOST:
>> + ret = dwc3_host_suspend(dwc);
>> + if (ret)
>> + return ret;
>>   default:
>>   /* do nothing */
>>   break;
>> @@ -1245,12 +1258,23 @@ static int dwc3_resume_common(struct dwc3 *dwc)
>>
>>   switch (dwc->dr_mode) {
>>   case USB_DR_MODE_PERIPHERAL:
>> + spin_lock_irqsave(>lock, flags);
>> + dwc3_gadget_resume(dwc);
>> + spin_unlock_irqrestore(>lock, flags);
>> + break;
>>   case USB_DR_MODE_OTG:
>> + ret = dwc3_host_resume(dwc);
>> + if (ret)
>> + return ret;
>> +
>>   spin_lock_irqsave(>lock, flags);
>>   dwc3_gadget_resume(dwc);
>>   spin_unlock_irqrestore(>lock, flags);
>> - /* FALLTHROUGH */
>> + break;
>>   case USB_DR_MODE_HOST:
>> + ret = dwc3_host_resume(dwc);
>> + if (ret)
>> + return ret;
>>   default:
>>   /* do nothing */
>>   break;
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index b585a30..1099168 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>> @@ -1158,11 +1158,18 @@ static inline bool dwc3_is_usb31(struct dwc3 *dwc)
>>  #if IS_ENABLED(CONFIG_USB_DWC3_HOST) || 
>> IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE)
>>  int dwc3_host_init(struct dwc3 *dwc);
>>  void dwc3_host_exit(struct dwc3 *dwc);
>> +int dwc3_host_suspend(struct dwc3 *dwc);
>> +int dwc3_host_resume(struct dwc3 *dwc);
>>  #else
>>  static inline int dwc3_host_init(struct dwc3 *dwc)
>>  { return 0; }
>>  static inline void dwc3_host_exit(struct dwc3 *dwc)
>>  { }
>> +
>> +static inline int dwc3_host_suspend(struct dwc3 *dwc)
>> +{ return 0; }
>> +static inline int dwc3_host_resume(struct dwc3 *dwc)
>> +{ return 0; }
>>  #endif
>>
>>  #if IS_ENABLED(CONFIG_USB_DWC3_GADGET) |

Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-01-16 Thread Baolin Wang
Hi,

On 16 January 2017 at 18:56, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> When handing the SETUP packet by composite_setup(), we will release the
>> dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup
>> function, which means we need to delay handling the STATUS phase.
>
> this sentence needs a little work. Seems like it's missing some
> information.
>
> anyway, I get that we release the lock but...
>
>> But during the lock release period, maybe the request for handling delay
>
> execution of ->setup() itself should be locked. I can see that it's only
> locked for set_config() which is rather peculiar.
>
> What exact request you had when you triggered this? (Hint: dwc3
> tracepoints print out ctrl request bytes). IIRC, only set_config() or
> f->set_alt() can actually return USB_GADGET_DELAYED_STATUS.

Yes, when host set configuration for mass storage driver, it can
produce this issue.

>
> Which gadget driver were you using when you triggered this?

mass storage driver. When host issues the setting config request, we
will get USB_GADGET_DELAYED_STATUS result from
set_config()--->fsg_set_alt(). Then the mass storage driver will issue
one thread to complete the status stage by ep0_queue() (this thread
may be running on another core), then if the thread issues ep0_queue()
too fast before we get the dwc->lock in dwc3_ep0_delegate_req() or
before we get into the STATUS stage, then we can not handle this
request for the delay STATUS stage in dwc3_gadget_ep0_queue().

>
> Another point here is that the really robust way of fixing this is to
> get rid of USB_GADGET_DELAYED_STATUS altogether and just make sure
> gadget drivers know how to queue requests for all three phases of a
> Control Transfer.
>
> A lot of code will be removed from all gadget drivers and UDC drivers
> while combining all of it in a single place in composite.c.
>
> The reason I'm saying this is that other UDC drivers might have similar
> races already but they just haven't triggered.

Yes, maybe.

>
>> STATUS phase has been queued into list before we set 'dwc->delayed_status'
>> flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance
>> to handle the STATUS phase. Thus we should check if the request for delay
>> STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase in
>> dwc3_ep0_xfernotready(), if so, we should handle it.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>>  drivers/usb/dwc3/ep0.c |   14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>> index 9bb1f85..e689ced 100644
>> --- a/drivers/usb/dwc3/ep0.c
>> +++ b/drivers/usb/dwc3/ep0.c
>> @@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
>>   dwc->ep0state = EP0_STATUS_PHASE;
>>
>>   if (dwc->delayed_status) {
>> + struct dwc3_ep *dep = dwc->eps[0];
>> +
>>   WARN_ON_ONCE(event->endpoint_number != 1);
>> + /*
>> +  * We should handle the delay STATUS phase here if the
>> +  * request for handling delay STATUS has been queued
>> +  * into the list.
>> +  */
>> + if (!list_empty(>pending_list)) {
>> + dwc->delayed_status = false;
>> + usb_gadget_set_state(>gadget,
>> +  USB_STATE_CONFIGURED);
>
> Isn't this patch also changing the normal case when usb_ep_queue() comes
> later? I guess list_empty() protects against that...

I think it will not change other cases, we only handle the delayed
status and I've tested it for a while and I did not find any problem.

-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-01-16 Thread Baolin Wang
Hi,

On 16 January 2017 at 20:06, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> Hi,
>>
>> On 16 January 2017 at 19:29, Felipe Balbi <ba...@kernel.org> wrote:
>>>
>>> Hi,
>>>
>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> Hi,
>>>>
>>>> On 16 January 2017 at 18:56, Felipe Balbi <ba...@kernel.org> wrote:
>>>>>
>>>>> Hi,
>>>>>
>>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>> When handing the SETUP packet by composite_setup(), we will release the
>>>>>> dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup
>>>>>> function, which means we need to delay handling the STATUS phase.
>>>>>
>>>>> this sentence needs a little work. Seems like it's missing some
>>>>> information.
>>>>>
>>>>> anyway, I get that we release the lock but...
>>>>>
>>>>>> But during the lock release period, maybe the request for handling delay
>>>>>
>>>>> execution of ->setup() itself should be locked. I can see that it's only
>>>>> locked for set_config() which is rather peculiar.
>>>>>
>>>>> What exact request you had when you triggered this? (Hint: dwc3
>>>>> tracepoints print out ctrl request bytes). IIRC, only set_config() or
>>>>> f->set_alt() can actually return USB_GADGET_DELAYED_STATUS.
>>>>
>>>> Yes, when host set configuration for mass storage driver, it can
>>>> produce this issue.
>>>>
>>>>>
>>>>> Which gadget driver were you using when you triggered this?
>>>>
>>>> mass storage driver. When host issues the setting config request, we
>>>> will get USB_GADGET_DELAYED_STATUS result from
>>>> set_config()--->fsg_set_alt(). Then the mass storage driver will issue
>>>> one thread to complete the status stage by ep0_queue() (this thread
>>>> may be running on another core), then if the thread issues ep0_queue()
>>>> too fast before we get the dwc->lock in dwc3_ep0_delegate_req() or
>>>> before we get into the STATUS stage, then we can not handle this
>>>> request for the delay STATUS stage in dwc3_gadget_ep0_queue().
>>>>
>>>>>
>>>>> Another point here is that the really robust way of fixing this is to
>>>>> get rid of USB_GADGET_DELAYED_STATUS altogether and just make sure
>>>>> gadget drivers know how to queue requests for all three phases of a
>>>>> Control Transfer.
>>>>>
>>>>> A lot of code will be removed from all gadget drivers and UDC drivers
>>>>> while combining all of it in a single place in composite.c.
>>>>>
>>>>> The reason I'm saying this is that other UDC drivers might have similar
>>>>> races already but they just haven't triggered.
>>>>
>>>> Yes, maybe.
>>>>
>>>>>
>>>>>> STATUS phase has been queued into list before we set 
>>>>>> 'dwc->delayed_status'
>>>>>> flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance
>>>>>> to handle the STATUS phase. Thus we should check if the request for delay
>>>>>> STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase in
>>>>>> dwc3_ep0_xfernotready(), if so, we should handle it.
>>>>>>
>>>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>>>> ---
>>>>>>  drivers/usb/dwc3/ep0.c |   14 ++
>>>>>>  1 file changed, 14 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>>>>> index 9bb1f85..e689ced 100644
>>>>>> --- a/drivers/usb/dwc3/ep0.c
>>>>>> +++ b/drivers/usb/dwc3/ep0.c
>>>>>> @@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 
>>>>>> *dwc,
>>>>>>   dwc->ep0state = EP0_STATUS_PHASE;
>>>>>>
>>>>>>   if (dwc->delayed_status) {
>>>>>> + struct dwc3_ep *dep = dwc->eps[0];
>>>>>> +
>>>>>>   WARN_ON_ONCE(event-&

Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-01-17 Thread Baolin Wang
Hi,

On 17 January 2017 at 18:39, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>>>> When handing the SETUP packet by composite_setup(), we will release the
>>>>>>>> dwc->lock. If we get the 'USB_GADGET_DELAYED_STATUS' result from setup
>>>>>>>> function, which means we need to delay handling the STATUS phase.
>>>>>>>
>>>>>>> this sentence needs a little work. Seems like it's missing some
>>>>>>> information.
>>>>>>>
>>>>>>> anyway, I get that we release the lock but...
>>>>>>>
>>>>>>>> But during the lock release period, maybe the request for handling 
>>>>>>>> delay
>>>>>>>
>>>>>>> execution of ->setup() itself should be locked. I can see that it's only
>>>>>>> locked for set_config() which is rather peculiar.
>>>>>>>
>>>>>>> What exact request you had when you triggered this? (Hint: dwc3
>>>>>>> tracepoints print out ctrl request bytes). IIRC, only set_config() or
>>>>>>> f->set_alt() can actually return USB_GADGET_DELAYED_STATUS.
>>>>>>
>>>>>> Yes, when host set configuration for mass storage driver, it can
>>>>>> produce this issue.
>>>>>>
>>>>>>>
>>>>>>> Which gadget driver were you using when you triggered this?
>>>>>>
>>>>>> mass storage driver. When host issues the setting config request, we
>>>>>> will get USB_GADGET_DELAYED_STATUS result from
>>>>>> set_config()--->fsg_set_alt(). Then the mass storage driver will issue
>>>>>> one thread to complete the status stage by ep0_queue() (this thread
>>>>>> may be running on another core), then if the thread issues ep0_queue()
>>>>>> too fast before we get the dwc->lock in dwc3_ep0_delegate_req() or
>>>>>> before we get into the STATUS stage, then we can not handle this
>>>>>> request for the delay STATUS stage in dwc3_gadget_ep0_queue().
>>>>>>
>>>>>>>
>>>>>>> Another point here is that the really robust way of fixing this is to
>>>>>>> get rid of USB_GADGET_DELAYED_STATUS altogether and just make sure
>>>>>>> gadget drivers know how to queue requests for all three phases of a
>>>>>>> Control Transfer.
>>>>>>>
>>>>>>> A lot of code will be removed from all gadget drivers and UDC drivers
>>>>>>> while combining all of it in a single place in composite.c.
>>>>>>>
>>>>>>> The reason I'm saying this is that other UDC drivers might have similar
>>>>>>> races already but they just haven't triggered.
>>>>>>
>>>>>> Yes, maybe.
>>>>>>
>>>>>>>
>>>>>>>> STATUS phase has been queued into list before we set 
>>>>>>>> 'dwc->delayed_status'
>>>>>>>> flag or entering 'EP0_STATUS_PHASE' phase, then we will miss the chance
>>>>>>>> to handle the STATUS phase. Thus we should check if the request for 
>>>>>>>> delay
>>>>>>>> STATUS phase has been enqueued when entering 'EP0_STATUS_PHASE' phase 
>>>>>>>> in
>>>>>>>> dwc3_ep0_xfernotready(), if so, we should handle it.
>>>>>>>>
>>>>>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>>>>>> ---
>>>>>>>>  drivers/usb/dwc3/ep0.c |   14 ++
>>>>>>>>  1 file changed, 14 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>>>>>>> index 9bb1f85..e689ced 100644
>>>>>>>> --- a/drivers/usb/dwc3/ep0.c
>>>>>>>> +++ b/drivers/usb/dwc3/ep0.c
>>>>>>>> @@ -1123,7 +1123,21 @@ static void dwc3_ep0_xfernotready(struct dwc3 
>>>>>>>> *dwc,
>>>>>>>>   dwc->ep0state = EP0_STATUS_PHASE;
>>>>>>>

[PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-21 Thread Baolin Wang
For system debugging, we usually want to know who sets one alarm timer, the
time of the timer, when the timer started and fired and so on. Thus adding
tracepoints can help us trace the alarmtimer information.

For example, when we debug the system supend/resume, if the system is always
resumed by RTC alarm, we can find out which process set the alarm timer to
resume system by below trace log:

..
Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
process:Binder:2976_6
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 0:11:0

Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 0:34:0

system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35

system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35

system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: alarmtimer 
type:ALARM_BOOTTIME
expires time: 2012-1-1 0:34:0
..

>From the trace log, we can find out the 'Binder:2976_7' process set one alarm
timer which resumes the system.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v2:
 - Add TRACE_DEFINE_ENUM() macros.
 - Change the time variables type to save space in the ring buffer.
 - Add trace_alarmtimer_suspend_enabled() in case of tracing is not enabled.

Changes since v1:
 - Fix the kbuild error.
 - Modify the changelog with adding trace log.
---
 include/trace/events/alarmtimer.h |  137 +
 kernel/time/alarmtimer.c  |   23 ++-
 2 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/alarmtimer.h

diff --git a/include/trace/events/alarmtimer.h 
b/include/trace/events/alarmtimer.h
new file mode 100644
index 000..6a34bc9
--- /dev/null
+++ b/include/trace/events/alarmtimer.h
@@ -0,0 +1,137 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM alarmtimer
+
+#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ALARMTIMER_H
+
+#include 
+#include 
+#include 
+
+TRACE_DEFINE_ENUM(ALARM_REALTIME);
+TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
+
+#define show_alarm_type(type)  __print_flags(type, " | ",  \
+   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
+   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
+
+DECLARE_EVENT_CLASS(alarm_setting,
+
+   TP_PROTO(struct rtc_time *rtc_time, int flag),
+
+   TP_ARGS(rtc_time, flag),
+
+   TP_STRUCT__entry(
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   ),
+
+   TP_fast_assign(
+   __entry->second = rtc_time->tm_sec;
+   __entry->minute = rtc_time->tm_min;
+   __entry->hour = rtc_time->tm_hour;
+   __entry->day = rtc_time->tm_mday;
+   __entry->mon = rtc_time->tm_mon;
+   __entry->year = rtc_time->tm_year;
+   __entry->alarm_type = flag;
+   ),
+
+   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
+ show_alarm_type((1 << __entry->alarm_type)),
+ __entry->year + 1900,
+ __entry->mon + 1,
+ __entry->day,
+ __entry->hour,
+ __entry->minute,
+ __entry->second
+   )
+);
+
+DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
+
+   TP_PROTO(struct rtc_time *time, int flag),
+
+   TP_ARGS(time, flag)
+);
+
+DECLARE_EVENT_CLASS(alarm_processing,
+
+   TP_PROTO(struct alarm *alarm, char *process_name),
+
+   TP_ARGS(alarm, process_name),
+
+   TP_STRUCT__entry(
+   __field(unsigned long long, expires)
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   __string(name, process_name)
+   ),
+
+   TP_fast_assign(
+   __entry->expires = alarm->node.expires.tv64;
+   __entry->second = rtc_ktime_to_tm(alarm->node.expires).t

Re: [PATCH v2] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-19 Thread Baolin Wang
Hi Steven,

On 18 August 2016 at 22:33, Steven Rostedt <rost...@goodmis.org> wrote:
> On Thu, 18 Aug 2016 16:47:39 +0800
> Baolin Wang <baolin.w...@linaro.org> wrote:
>  since v1:
>>  - Fix the kbuild error.
>>  - Modify the changelog with adding trace log.
>> ---
>>  include/trace/events/alarmtimer.h |  134 
>> +
>>  kernel/time/alarmtimer.c  |   21 +-
>>  2 files changed, 152 insertions(+), 3 deletions(-)
>>  create mode 100644 include/trace/events/alarmtimer.h
>>
>> diff --git a/include/trace/events/alarmtimer.h 
>> b/include/trace/events/alarmtimer.h
>> new file mode 100644
>> index 000..eea4e12
>> --- /dev/null
>> +++ b/include/trace/events/alarmtimer.h
>> @@ -0,0 +1,134 @@
>> +#undef TRACE_SYSTEM
>> +#define TRACE_SYSTEM alarmtimer
>> +
>> +#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
>> +#define _TRACE_ALARMTIMER_H
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> +#define show_alarm_type(type)__print_flags(type, " | ",  \
>> + { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
>> + { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
>
> As ALARM_REALTIME and ALARM_BOOTTIME are both enums, they will not be
> converted for userspace. Can you add the following:
>
> TRACE_DEFINE_ENUM(ALARM_REALTIME);
> TRACE_DEFINE_ENUM(ALARM_BOOTTIME);

OK.

>
>> +
>> +DECLARE_EVENT_CLASS(alarm_setting,
>> +
>> + TP_PROTO(struct rtc_time *rtc_time, int flag),
>> +
>> + TP_ARGS(rtc_time, flag),
>> +
>> + TP_STRUCT__entry(
>> + __field(unsigned int, second)
>> + __field(unsigned int, minute)
>> + __field(unsigned int, hour)
>> + __field(unsigned int, day)
>> + __field(unsigned int, mon)
>> + __field(unsigned int, year)
>> + __field(unsigned int, alarm_type)
>
> To save space in the ring buffer, perhaps we can make the above not
> take up so much space:
>
> unsigned char, second
> unsigned char, minute
> unsigned char, hour
> unsigned char, day
> unsigned char, mon
> unsigned char, alarm_type
> unsigned short, year
>
> Why use 32 bits when most of the values fit nicely in one byte, and no
> more than a 16 bytes. Also, order doesn't really matter for output, but
> works well for compacting, as the above is only 8 bytes total.

Make sense. Will fix in next version.

>
>
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->second = rtc_time->tm_sec;
>> + __entry->minute = rtc_time->tm_min;
>> + __entry->hour = rtc_time->tm_hour;
>> + __entry->day = rtc_time->tm_mday;
>> + __entry->mon = rtc_time->tm_mon;
>> + __entry->year = rtc_time->tm_year;
>> + __entry->alarm_type = flag;
>> + ),
>> +
>> + TP_printk("alarmtimer type:%s expires time: %u-%u-%u %u:%u:%u",
>> +   show_alarm_type((1 << __entry->alarm_type)),
>> +   __entry->year + 1900,
>> +   __entry->mon + 1,
>> +   __entry->day,
>> +   __entry->hour,
>> +   __entry->minute,
>> +   __entry->second
>> + )
>> +);
>> +
>> +DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
>> +
>> + TP_PROTO(struct rtc_time *time, int flag),
>> +
>> + TP_ARGS(time, flag)
>> +);
>> +
>> +DECLARE_EVENT_CLASS(alarm_processing,
>> +
>> + TP_PROTO(struct alarm *alarm, char *process_name),
>> +
>> + TP_ARGS(alarm, process_name),
>> +
>> + TP_STRUCT__entry(
>> + __field(unsigned long long, expires)
>> + __field(unsigned int, second)
>> + __field(unsigned int, minute)
>> + __field(unsigned int, hour)
>> + __field(unsigned int, day)
>> + __field(unsigned int, mon)
>> + __field(unsigned int, year)
>> + __field(unsigned int, alarm_type)
>
> Same here.
>
>> + __string(name, process_name)
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->expires = alarm->node.expires.tv64;
>> + __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec

Re: [PATCH 2/4] usb: host: xhci: Introduce one new 'usb3_slow_suspend' member for xhci private data

2016-08-19 Thread Baolin Wang
Hi Felipe,

On 18 August 2016 at 21:42, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi Baolin,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>>>>>> index e2e2487..162f17c 100644
>>>>>> --- a/drivers/usb/host/xhci-plat.c
>>>>>> +++ b/drivers/usb/host/xhci-plat.c
>>>>>> @@ -250,6 +250,9 @@ static int xhci_plat_probe(struct platform_device 
>>>>>> *pdev)
>>>>>>   (pdata && pdata->usb3_lpm_capable))
>>>>>>   xhci->quirks |= XHCI_LPM_SUPPORT;
>>>>>>
>>>>>> + if (pdata && pdata->usb3_slow_suspend)
>>>>>> + xhci->quirks |= XHCI_SLOW_SUSPEND;
>>>>>
>>>>> I remember having a discussion about this with Paul Z and it turned out
>>>>> that we really didn't need SLOW_SUSPEND. Can you describe further in
>>>>> what situation you need this quirk?
>>>>
>>>> On my dwc3 platform, xhci suspend will be failed if we have not
>>>> enabled XHCI_SLOW_SUSPEND quirk.
>>>
>>> fail how? What error do you see? Do you have some traces of what's
>>> happening? Did you try figuring out if this is, perhaps, caused by some
>>> call ordering which is wrong? Perhaps disabling PHYs too early or
>>> something like that?
>>
>> It shows the warning "WARN: xHC CMD_RUN timeout" when running
>> xhci_suspend(). If I enbale XHCI_SLOW_SUSPEND quirk, then it can work
>> well. I did not try to figure out other things, due to I think the
>> dwc3 need XHCI_SLOW_SUSPEND quirk. But I can re-try to figure out if
>> there are other issues if you still believe that dwc3 does not need
>> XHCI_SLOW_SUSPEND quirk. Thanks.
>
> When I discussed this with Paul Z, he told me there was no known
> DWC3 SoC that really needed SLOW_SUSPEND, so it's likely to be a bug in
> either xhci or dwc3.
>
> Please try to track this down. I would start looking at ordering with
> PHY poweroff or something like that.

OK. Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH] usb: dwc3: ep0: Fix the possible missed request for handling delay STATUS phase

2017-03-02 Thread Baolin Wang
Hi,

On 28 February 2017 at 06:11, Alan Stern <st...@rowland.harvard.edu> wrote:
> On Tue, 21 Feb 2017, Baolin Wang wrote:
>
>> On 17 February 2017 at 16:04, Felipe Balbi <ba...@kernel.org> wrote:
>> >
>> > Hi,
>> >
>> > Baolin Wang <baolin.w...@linaro.org> writes:
>> >>>> (One possible approach would be to have the setup routine return
>> >>>> different values for explicit and implicit status stages -- for
>> >>>> example, return 1 if it wants to submit an explicit status request.
>> >>>> That wouldn't be very different from the current
>> >>>> USB_GADGET_DELAYED_STATUS approach.)
>> >>>
>> >>> not really, no. The idea was for composite.c and/or functions to support
>> >>> both methods (temporarily) and use "gadget->wants_explicit_stages" to
>> >>> explicitly queue DATA and STATUS. That would mean that f_mass_storage
>> >>> wouldn't have to return DELAYED_STATUS if
>> >>> (gadget->wants_explicit_stages).
>> >>>
>> >>> After all UDCs are converted over and set wants_explicit_stages (which
>> >>> should all be done in a single series), then we get rid of the flag and
>> >>> the older method of DELAYED_STATUS.
>> >>
>> >> (Sorry for late reply due to my holiday)
>> >> I also met the problem pointed by Alan, from my test, I still want to
>> >> need one return value to indicate if it wants to submit an explicit
>> >> status request. Think about the Control-IN with a data stage, we can
>> >> not get the STATUS phase request from usb_ep_queue() call, and we need
>> >
>> > why not? wLength tells you that this is a 3-stage transfer. Gadget
>> > driver should be able to figure out that it needs to usb_ep_queue()
>> > another request for status stage.
>>
>> I tried again, but still can not work. Suppose the no-data control:
>> (1) SET_ADDRESS request: function driver will not queue one request
>> for status phase by usb_ep_queue() call.
>
> Function drivers do not handle Set-Address requests at all.  The UDC
> driver handles these requests without telling the gadget driver about
> them.

Correct. What I mean is it will not queue one request for status phase
by usb_ep_queue() call, UDC driver will do that.

>
>> (2) SET_CONFIGURATION request: function driver will queue one 0-length
>> request for status phase by usb_ep_queue() call, especially for
>> mass_storage driver, it will queue one request  for status phase
>> later.
>>
>> So I am not sure how the Gadget driver can figure out that it needs to
>> usb_ep_queue() another request for status stage when handling the
>> no-data control?
>
> Gadget drivers already queue status-stage requests for no-data
> control-OUT requests.  The difficulty comes when you want to handle an
> IN request or an OUT request with a data stage.
>

I try to explain that explicitly, In dwc3 driver, we can handle the
STATUS phase request in 2 places: (1) in usb_ep_queue(), (2) in
dwc3_ep0_xfernotready()
For no-data control-OUT requests:
(1) SET_ADDRESS request: no request queued for status phase by
usb_ep_queue(), dwc3 driver need handle the STATUS phase request when
one not-ready-event comes in dwc3_ep0_xfernotready() function.
(2) SET_CONFIGURATION request: function driver will queue one 0-length
request for status phase by usb_ep_queue(), but we can handle this
request in usb_ep_queue() or dwc3_ep0_xfernotready(). When the
function driver queued one 0-length request for status phase before
the not-ready-event comes, we need handle this request in
dwc3_ep0_xfernotready() when the not-ready-event comes. When  the
function driver queued one 0-length request for status phase after the
not-ready-event comes, we can handle this request in usb_ep_queue().
So in dwc3_ep0_xfernotready(), we need to check if the request for
status phase has been queued into pending request list, but if the
pending request list is NULL, which means the function driver have not
queued one 0-length request until now (then we can handle it in
usb_ep_queue()), or situation (1) (no request queued for status
phase), then I can not identify this 2 situations to determine where I
can handle the status request. Hope I make it clear.

Your concern about an IN request or an OUT request with a data stage,
I agree with Felipe and we can identify. Thanks.
-- 
Baolin.wang
Best Regards


[PATCH v4 2/3] mmc: core: Factor out the alignment of erase size

2016-09-05 Thread Baolin Wang
In order to clean up the mmc_erase() function and do some optimization
for erase size alignment, factor out the guts of erase size alignment
into mmc_align_erase_size() function.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Tested-by: Shawn Lin <shawn@rock-chips.com>
---
 drivers/mmc/core/core.c |   60 +--
 1 file changed, 37 insertions(+), 23 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 7d7209d..5f93eef 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2202,6 +2202,37 @@ out:
return err;
 }
 
+static unsigned int mmc_align_erase_size(struct mmc_card *card,
+unsigned int *from,
+unsigned int *to,
+unsigned int nr)
+{
+   unsigned int from_new = *from, nr_new = nr, rem;
+
+   rem = from_new % card->erase_size;
+   if (rem) {
+   rem = card->erase_size - rem;
+   from_new += rem;
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+   }
+
+   rem = nr_new % card->erase_size;
+   if (rem)
+   nr_new -= rem;
+
+   if (nr_new == 0)
+   return 0;
+
+   /* 'from' and 'to' are inclusive */
+   *to = from_new + nr_new - 1;
+   *from = from_new;
+
+   return nr_new;
+}
+
 /**
  * mmc_erase - erase sectors.
  * @card: card to erase
@@ -2234,31 +2265,14 @@ int mmc_erase(struct mmc_card *card, unsigned int from, 
unsigned int nr,
}
 
if (arg == MMC_ERASE_ARG) {
-   rem = from % card->erase_size;
-   if (rem) {
-   rem = card->erase_size - rem;
-   from += rem;
-   if (nr > rem)
-   nr -= rem;
-   else
-   return 0;
-   }
-   rem = nr % card->erase_size;
-   if (rem)
-   nr -= rem;
+   nr = mmc_align_erase_size(card, , , nr);
+   if (nr == 0)
+   return 0;
+   } else {
+   /* 'from' and 'to' are inclusive */
+   to -= 1;
}
 
-   if (nr == 0)
-   return 0;
-
-   to = from + nr;
-
-   if (to <= from)
-   return -EINVAL;
-
-   /* 'from' and 'to' are inclusive */
-   to -= 1;
-
/*
 * Special case where only one erase-group fits in the timeout budget:
 * If the region crosses an erase-group boundary on this particular
-- 
1.7.9.5



[PATCH v4 3/3] mmc: core: Optimize the mmc erase size alignment

2016-09-05 Thread Baolin Wang
In most cases the 'card->erase_size' is power of 2, then the round_up/down()
function is more efficient than '%' operation when the 'card->erase_size' is
power of 2.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Tested-by: Shawn Lin <shawn@rock-chips.com>
---
 drivers/mmc/core/core.c |   34 ++
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 5f93eef..e014949 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2209,19 +2209,37 @@ static unsigned int mmc_align_erase_size(struct 
mmc_card *card,
 {
unsigned int from_new = *from, nr_new = nr, rem;
 
-   rem = from_new % card->erase_size;
-   if (rem) {
-   rem = card->erase_size - rem;
-   from_new += rem;
+   /*
+* When the 'card->erase_size' is power of 2, we can use round_up/down()
+* to align the erase size efficiently.
+*/
+   if (is_power_of_2(card->erase_size)) {
+   unsigned int temp = from_new;
+
+   from_new = round_up(temp, card->erase_size);
+   rem = from_new - temp;
+
if (nr_new > rem)
nr_new -= rem;
else
return 0;
-   }
 
-   rem = nr_new % card->erase_size;
-   if (rem)
-   nr_new -= rem;
+   nr_new = round_down(nr_new, card->erase_size);
+   } else {
+   rem = from_new % card->erase_size;
+   if (rem) {
+   rem = card->erase_size - rem;
+   from_new += rem;
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+   }
+
+   rem = nr_new % card->erase_size;
+   if (rem)
+   nr_new -= rem;
+   }
 
if (nr_new == 0)
return 0;
-- 
1.7.9.5



[PATCH v4 1/3] mmc: core: Remove some redundant validations in mmc_erase() function

2016-09-05 Thread Baolin Wang
Before issuing mmc_erase() function, users always have checked if it can
erase with mmc_can_erase/trim/discard() function, thus remove the redundant
erase checking in mmc_erase() function.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Tested-by: Shawn Lin <shawn@rock-chips.com>
---
Changes since v3:
 - Split into 3 separate patches.
 - Add test tag by Shawn.

Changes since v2:
 - Add nr checking and other optimization in mmc_erase() function.

Changes since v1:
 - Add the alignment if card->erase_size is not power of 2.
---
 drivers/mmc/core/core.c |7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e55cde6..7d7209d 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2217,13 +2217,6 @@ int mmc_erase(struct mmc_card *card, unsigned int from, 
unsigned int nr,
unsigned int rem, to = from + nr;
int err;
 
-   if (!(card->host->caps & MMC_CAP_ERASE) ||
-   !(card->csd.cmdclass & CCC_ERASE))
-   return -EOPNOTSUPP;
-
-   if (!card->erase_size)
-   return -EOPNOTSUPP;
-
if (mmc_card_sd(card) && arg != MMC_ERASE_ARG)
return -EOPNOTSUPP;
 
-- 
1.7.9.5



Re: [PATCH v3] mmc: core: Optimize the mmc erase size alignment

2016-09-05 Thread Baolin Wang
Hi Shawn,

On 2 September 2016 at 16:34, Shawn Lin <shawn@rock-chips.com> wrote:
> Hi Baolin,
>
> On 2016/8/31 17:32, Baolin Wang wrote:
>>
>> Before issuing mmc_erase() function, users always have checked if it can
>> erase with mmc_can_erase/trim/discard() function, thus remove the
>> redundant
>> erase checking in mmc_erase() function.
>>
>> This patch also optimizes the erase start/end sector alignment with
>
>
> It implies you could split this patch into two for dealing with diff
> things. :) Otherwise, you could add my test tag,

Yes, I will split it into two separate patches and thanks for your testing.

>
> Tested-by: Shawn Lin <shawn@rock-chips.com>
>
>
>> round_up()/round_down() function, when erase command is MMC_ERASE_ARG.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>> Changes since v2:
>>  - Add nr checking and other optimization in mmc_erase() function.
>>
>> Changes since v1:
>>  - Add the alignment if card->erase_size is not power of 2.
>> ---
>>  drivers/mmc/core/core.c |   82
>> ++-
>>  1 file changed, 53 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index e55cde6..52156d4 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -2202,6 +2202,51 @@ out:
>> return err;
>>  }
>>
>> +static unsigned int mmc_align_erase_size(struct mmc_card *card,
>> +unsigned int *from,
>> +unsigned int *to,
>> +unsigned int nr)
>> +{
>> +   unsigned int from_new = *from, nr_new = nr, rem;
>> +
>> +   if (is_power_of_2(card->erase_size)) {
>> +   unsigned int temp = from_new;
>> +
>> +   from_new = round_up(temp, card->erase_size);
>> +   rem = from_new - temp;
>> +
>> +   if (nr_new > rem)
>> +   nr_new -= rem;
>> +   else
>> +   return 0;
>> +
>> +   nr_new = round_down(nr_new, card->erase_size);
>> +   } else {
>> +   rem = from_new % card->erase_size;
>> +   if (rem) {
>> +   rem = card->erase_size - rem;
>> +   from_new += rem;
>> +   if (nr_new > rem)
>> +   nr_new -= rem;
>> +   else
>> +   return 0;
>> +   }
>> +
>> +   rem = nr_new % card->erase_size;
>> +   if (rem)
>> +   nr_new -= rem;
>> +   }
>> +
>> +   if (nr_new == 0)
>> +   return 0;
>> +
>> +   /* 'from' and 'to' are inclusive */
>> +   *to = from_new + nr_new - 1;
>> +   *from = from_new;
>> +
>> +   return nr_new;
>> +}
>> +
>>  /**
>>   * mmc_erase - erase sectors.
>>   * @card: card to erase
>> @@ -2217,13 +2262,6 @@ int mmc_erase(struct mmc_card *card, unsigned int
>> from, unsigned int nr,
>> unsigned int rem, to = from + nr;
>> int err;
>>
>> -   if (!(card->host->caps & MMC_CAP_ERASE) ||
>> -   !(card->csd.cmdclass & CCC_ERASE))
>> -   return -EOPNOTSUPP;
>> -
>> -   if (!card->erase_size)
>> -   return -EOPNOTSUPP;
>> -
>> if (mmc_card_sd(card) && arg != MMC_ERASE_ARG)
>> return -EOPNOTSUPP;
>>
>> @@ -2240,31 +2278,17 @@ int mmc_erase(struct mmc_card *card, unsigned int
>> from, unsigned int nr,
>> return -EINVAL;
>> }
>>
>> -   if (arg == MMC_ERASE_ARG) {
>> -   rem = from % card->erase_size;
>> -   if (rem) {
>> -   rem = card->erase_size - rem;
>> -   from += rem;
>> -   if (nr > rem)
>> -   nr -= rem;
>> -   else
>> -   return 0;
>> -   }
>> -   rem = nr % card->erase_size;
>> -   if (rem)
>> -   nr -= rem;
>> -   }
>> -
>> if (nr == 0)
>> return 0;
>>
>> -   to = from + nr;
>> -
>> -   if (to <= from)
>> -   return -EINVAL;
>> -
>> -   /* 'from' and 'to' are inclusive */
>> -   to -= 1;
>> +   if (arg == MMC_ERASE_ARG) {
>> +   nr = mmc_align_erase_size(card, , , nr);
>> +   if (nr == 0)
>> +   return 0;
>> +   } else {
>> +   /* 'from' and 'to' are inclusive */
>> +   to -= 1;
>> +   }
>>
>> /*
>>  * Special case where only one erase-group fits in the timeout
>> budget:
>>
>
>
> --
> Best Regards
> Shawn Lin
>



-- 
Baolin.wang
Best Regards


Re: [PATCH v3] mmc: core: Optimize the mmc erase size alignment

2016-09-05 Thread Baolin Wang
Hi Ulf,


On 2 September 2016 at 17:43, Ulf Hansson <ulf.hans...@linaro.org> wrote:
> On 31 August 2016 at 11:32, Baolin Wang <baolin.w...@linaro.org> wrote:
>> Before issuing mmc_erase() function, users always have checked if it can
>> erase with mmc_can_erase/trim/discard() function, thus remove the redundant
>> erase checking in mmc_erase() function.
>>
>> This patch also optimizes the erase start/end sector alignment with
>> round_up()/round_down() function, when erase command is MMC_ERASE_ARG.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>> Changes since v2:
>>  - Add nr checking and other optimization in mmc_erase() function.
>>
>> Changes since v1:
>>  - Add the alignment if card->erase_size is not power of 2.
>> ---
>>  drivers/mmc/core/core.c |   82 
>> ++-
>>  1 file changed, 53 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index e55cde6..52156d4 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -2202,6 +2202,51 @@ out:
>> return err;
>>  }
>>
>> +static unsigned int mmc_align_erase_size(struct mmc_card *card,
>> +unsigned int *from,
>> +unsigned int *to,
>> +unsigned int nr)
>> +{
>
> How about make one patch that starts by moving the existing code into
> a separate function, then on top as a new change, start playing with
> the optimizations!?
> That would be more easy to review.

Make sense. I'll do what you suggested in next version.

>
>> +   unsigned int from_new = *from, nr_new = nr, rem;
>> +
>> +   if (is_power_of_2(card->erase_size)) {
>
> I would like some comment in the code, to understand what/why we do this.

I think the erase_size is power of 2 in most cases, then the
round_up/down() is more efficient than '%' operation. I'll add some
comments to explain that.

>
>> +   unsigned int temp = from_new;
>> +
>> +   from_new = round_up(temp, card->erase_size);
>> +   rem = from_new - temp;
>> +
>> +   if (nr_new > rem)
>> +   nr_new -= rem;
>> +   else
>> +   return 0;
>> +
>> +   nr_new = round_down(nr_new, card->erase_size);
>> +   } else {
>
> Ditto.
>
>> +   rem = from_new % card->erase_size;
>> +   if (rem) {
>> +   rem = card->erase_size - rem;
>> +   from_new += rem;
>> +   if (nr_new > rem)
>> +   nr_new -= rem;
>> +   else
>> +   return 0;
>> +   }
>> +
>> +   rem = nr_new % card->erase_size;
>> +   if (rem)
>> +   nr_new -= rem;
>> +   }
>> +
>> +   if (nr_new == 0)
>> +   return 0;
>> +
>> +   /* 'from' and 'to' are inclusive */
>> +   *to = from_new + nr_new - 1;
>> +   *from = from_new;
>> +
>> +   return nr_new;
>> +}
>> +
>>  /**
>>   * mmc_erase - erase sectors.
>>   * @card: card to erase
>> @@ -2217,13 +2262,6 @@ int mmc_erase(struct mmc_card *card, unsigned int 
>> from, unsigned int nr,
>> unsigned int rem, to = from + nr;
>> int err;
>>
>> -   if (!(card->host->caps & MMC_CAP_ERASE) ||
>> -   !(card->csd.cmdclass & CCC_ERASE))
>> -   return -EOPNOTSUPP;
>> -
>> -   if (!card->erase_size)
>> -   return -EOPNOTSUPP;
>> -
>
> I agree with Shawn here, please try to have one patch taking care of
> one thing. If we find out that things goes wrong later, then it's
> easier to drop/revert a change which causes the regression.

OK.

>
> Moreover, for the above particular change, I don't think you should
> remove these validations, as this is an API being exported. You may
> convert to use mmc_can_erase() though.

These validations are redundant, since we always have checked if it
can erase with mmc_can_erase/trim/discard() function before issuing
mmc_erase(). Another hand these validations should be moved into
mmc_can_erase() not in mmc_erase() function.

>
> Regarding all the mmc erase related exported APIs, there are cer

Re: [PATCH v4 2/3] mmc: core: Factor out the alignment of erase size

2016-09-06 Thread Baolin Wang
Hi Andreas,

On 6 September 2016 at 12:34, Andreas Mohr <a...@lisas.de> wrote:
> On Tue, Sep 06, 2016 at 10:55:11AM +0800, Baolin Wang wrote:
>> In order to clean up the mmc_erase() function and do some optimization
>> for erase size alignment, factor out the guts of erase size alignment
>> into mmc_align_erase_size() function.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> Tested-by: Shawn Lin <shawn@rock-chips.com>
>> ---
>>  drivers/mmc/core/core.c |   60 
>> +--
>>  1 file changed, 37 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index 7d7209d..5f93eef 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -2202,6 +2202,37 @@ out:
>>   return err;
>>  }
>>
>> +static unsigned int mmc_align_erase_size(struct mmc_card *card,
>> +  unsigned int *from,
>> +  unsigned int *to,
>> +  unsigned int nr)
>> +{
>> + unsigned int from_new = *from, nr_new = nr, rem;
>> +
>> + rem = from_new % card->erase_size;
>> + if (rem) {
>> + rem = card->erase_size - rem;
>> + from_new += rem;
>> + if (nr_new > rem)
>> + nr_new -= rem;
>> + else
>> + return 0;
>> + }
>> +
>> + rem = nr_new % card->erase_size;
>> + if (rem)
>> + nr_new -= rem;
>> +
>> + if (nr_new == 0)
>> + return 0;
>> +
>> + /* 'from' and 'to' are inclusive */
>> + *to = from_new + nr_new - 1;
>> + *from = from_new;
>> +
>> + return nr_new;
>> +}
>> +
>>  /**
>>   * mmc_erase - erase sectors.
>>   * @card: card to erase
>> @@ -2234,31 +2265,14 @@ int mmc_erase(struct mmc_card *card, unsigned int 
>> from, unsigned int nr,
>>   }
>>
>>   if (arg == MMC_ERASE_ARG) {
>> - rem = from % card->erase_size;
>> - if (rem) {
>> - rem = card->erase_size - rem;
>> - from += rem;
>> - if (nr > rem)
>> - nr -= rem;
>> - else
>> - return 0;
>> - }
>> - rem = nr % card->erase_size;
>> - if (rem)
>> - nr -= rem;
>> + nr = mmc_align_erase_size(card, , , nr);
>> + if (nr == 0)
>> + return 0;
>> + } else {
>> + /* 'from' and 'to' are inclusive */
>> + to -= 1;
>>   }
>>
>> - if (nr == 0)
>> - return 0;
>> -
>> - to = from + nr;
>> -
>> - if (to <= from)
>> - return -EINVAL;
>
> Hmm, this is swallowing -EINVAL behaviour
> i.e., now possibly violating protocol?

I didn't see what situation will make variable 'to' is less than
'from' since I think variable 'nr' is always larger than 0, right? If
so, we should remove this useless checking. Thanks.

>
> (this may easily be ok - haven't done an extensive review -
> but since the commit has that characteristic change,
> the commit message should contain that detail)
>
> Thanks for the cleanup work & HTH,
>
> Andreas Mohr



-- 
Baolin.wang
Best Regards


Re: [PATCH v4 2/3] mmc: core: Factor out the alignment of erase size

2016-09-06 Thread Baolin Wang
On 6 September 2016 at 15:19, Andreas Mohr <a...@lisas.de> wrote:
> On Tue, Sep 06, 2016 at 02:26:06PM +0800, Baolin Wang wrote:
>> On 6 September 2016 at 12:34, Andreas Mohr <a...@lisas.de> wrote:
>> >> - to = from + nr;
>> >> -
>> >> - if (to <= from)
>> >> - return -EINVAL;
>> >
>> > Hmm, this is swallowing -EINVAL behaviour
>> > i.e., now possibly violating protocol?
>>
>> I didn't see what situation will make variable 'to' is less than
>> 'from' since I think variable 'nr' is always larger than 0, right? If
>> so, we should remove this useless checking. Thanks.
>
> Hmm, indeed, since all participating variables are unsigned,
> the existing calculation should never hit this.
> However, one could argue that this is an additional safeguard
> against implementation source getting modified in a way
> that will suddenly result in this pathologic case becoming true
> (where a -EINVAL bailout surely will then pinpoint things
> much more visibly for some users,
> as opposed to potential data corruption or some such).

OK. I'll add this checking.

>
>
>
> I have seen another change
>
>> - if (nr == 0)
>> - return 0;
>
> where it gets moved out of common path
> and into MMC_ERASE_ARG-specific branch
> (likely because the subsequent common-path conditional of
> nr > rem
> is deemed sufficient).
>
> This seems to be again a change
> where a simple yet crucial
> device geometry calculation post-condition
> (either to > from, or nr > 0)
> is then not verified specifically/separately.
>
> Ultimately, I am not sure whether or not
> these (post-)conditions should be verified
> in their most basic, simple form,
> as an extra/separate verification step.

After some investigation, I think we add this checking is more safer.
Thanks for your comments.

-- 
Baolin.wang
Best Regards


Re: [PATCH v4 2/3] mmc: core: Factor out the alignment of erase size

2016-09-06 Thread Baolin Wang
On 6 September 2016 at 15:52, Adrian Hunter <adrian.hun...@intel.com> wrote:
> On 6/09/2016 9:26 a.m., Baolin Wang wrote:
>>
>> Hi Andreas,
>>
>> On 6 September 2016 at 12:34, Andreas Mohr <a...@lisas.de> wrote:
>>>
>>> On Tue, Sep 06, 2016 at 10:55:11AM +0800, Baolin Wang wrote:
>>>>
>>>> In order to clean up the mmc_erase() function and do some optimization
>>>> for erase size alignment, factor out the guts of erase size alignment
>>>> into mmc_align_erase_size() function.
>>>>
>>>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>>>> Tested-by: Shawn Lin <shawn@rock-chips.com>
>>>> ---
>>>>   drivers/mmc/core/core.c |   60
>>>> +--
>>>>   1 file changed, 37 insertions(+), 23 deletions(-)
>>>>
>>>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>>>> index 7d7209d..5f93eef 100644
>>>> --- a/drivers/mmc/core/core.c
>>>> +++ b/drivers/mmc/core/core.c
>>>> @@ -2202,6 +2202,37 @@ out:
>>>>return err;
>>>>   }
>>>>
>>>> +static unsigned int mmc_align_erase_size(struct mmc_card *card,
>>>> +  unsigned int *from,
>>>> +  unsigned int *to,
>>>> +  unsigned int nr)
>>>> +{
>>>> + unsigned int from_new = *from, nr_new = nr, rem;
>>>> +
>>>> + rem = from_new % card->erase_size;
>>>> + if (rem) {
>>>> + rem = card->erase_size - rem;
>>>> + from_new += rem;
>>>> + if (nr_new > rem)
>>>> + nr_new -= rem;
>>>> + else
>>>> + return 0;
>>>> + }
>>>> +
>>>> + rem = nr_new % card->erase_size;
>>>> + if (rem)
>>>> + nr_new -= rem;
>>>> +
>>>> + if (nr_new == 0)
>>>> + return 0;
>>>> +
>>>> + /* 'from' and 'to' are inclusive */
>>>> + *to = from_new + nr_new - 1;
>>>> + *from = from_new;
>>>> +
>>>> + return nr_new;
>>>> +}
>>>> +
>>>>   /**
>>>>* mmc_erase - erase sectors.
>>>>* @card: card to erase
>>>> @@ -2234,31 +2265,14 @@ int mmc_erase(struct mmc_card *card, unsigned
>>>> int from, unsigned int nr,
>>>>}
>>>>
>>>>if (arg == MMC_ERASE_ARG) {
>>>> - rem = from % card->erase_size;
>>>> - if (rem) {
>>>> - rem = card->erase_size - rem;
>>>> - from += rem;
>>>> - if (nr > rem)
>>>> - nr -= rem;
>>>> - else
>>>> - return 0;
>>>> - }
>>>> - rem = nr % card->erase_size;
>>>> - if (rem)
>>>> - nr -= rem;
>>>> + nr = mmc_align_erase_size(card, , , nr);
>>>> + if (nr == 0)
>>>> + return 0;
>>>> + } else {
>>>> + /* 'from' and 'to' are inclusive */
>>>> + to -= 1;
>>>>}
>>>>
>>>> - if (nr == 0)
>>>> - return 0;
>>>> -
>>>> - to = from + nr;
>>>> -
>>>> - if (to <= from)
>>>> - return -EINVAL;
>>>
>>>
>>> Hmm, this is swallowing -EINVAL behaviour
>>> i.e., now possibly violating protocol?
>>
>>
>> I didn't see what situation will make variable 'to' is less than
>> 'from' since I think variable 'nr' is always larger than 0, right? If
>> so, we should remove this useless checking. Thanks.
>
>
> It is checking overflows.

Yes, you are right, my mistake. I will add this checking in next version.

>
>>
>>>
>>> (this may easily be ok - haven't done an extensive review -
>>> but since the commit has that characteristic change,
>>> the commit message should contain that detail)
>>>
>>> Thanks for the cleanup work & HTH,
>>>
>>> Andreas Mohr
>>
>>
>>
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Baolin.wang
Best Regards


[PATCH v5 2/2] mmc: core: Optimize the mmc erase size alignment

2016-09-06 Thread Baolin Wang
In most cases the 'card->erase_size' is power of 2, then the round_up/down()
function is more efficient than '%' operation when the 'card->erase_size' is
power of 2.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Tested-by: Shawn Lin <shawn@rock-chips.com>
---
 drivers/mmc/core/core.c |   34 ++
 1 file changed, 26 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 11b4897..4264ac6 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2209,19 +2209,37 @@ static unsigned int mmc_align_erase_size(struct 
mmc_card *card,
 {
unsigned int from_new = *from, nr_new = nr, rem;
 
-   rem = from_new % card->erase_size;
-   if (rem) {
-   rem = card->erase_size - rem;
-   from_new += rem;
+   /*
+* When the 'card->erase_size' is power of 2, we can use round_up/down()
+* to align the erase size efficiently.
+*/
+   if (is_power_of_2(card->erase_size)) {
+   unsigned int temp = from_new;
+
+   from_new = round_up(temp, card->erase_size);
+   rem = from_new - temp;
+
if (nr_new > rem)
nr_new -= rem;
else
return 0;
-   }
 
-   rem = nr_new % card->erase_size;
-   if (rem)
-   nr_new -= rem;
+   nr_new = round_down(nr_new, card->erase_size);
+   } else {
+   rem = from_new % card->erase_size;
+   if (rem) {
+   rem = card->erase_size - rem;
+   from_new += rem;
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+   }
+
+   rem = nr_new % card->erase_size;
+   if (rem)
+   nr_new -= rem;
+   }
 
if (nr_new == 0)
return 0;
-- 
1.7.9.5



[PATCH v5 1/2] mmc: core: Factor out the alignment of erase size

2016-09-06 Thread Baolin Wang
In order to clean up the mmc_erase() function and do some optimization
for erase size alignment, factor out the guts of erase size alignment
into mmc_align_erase_size() function.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Tested-by: Shawn Lin <shawn@rock-chips.com>
---
Changes since v4:
 - Abandon the patch removing the checking if mmc can erase.
 - Add missing validations in mmc_erase().

Changes since v3:
 - Split into 3 separate patches.
 - Add test tag by Shawn.

Changes since v2:
 - Add nr checking and other optimization in mmc_erase() function.

Changes since v1:
 - Add the alignment if card->erase_size is not power of 2.
---
 drivers/mmc/core/core.c |   48 +++
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e55cde6..11b4897 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2202,6 +2202,36 @@ out:
return err;
 }
 
+static unsigned int mmc_align_erase_size(struct mmc_card *card,
+unsigned int *from,
+unsigned int *to,
+unsigned int nr)
+{
+   unsigned int from_new = *from, nr_new = nr, rem;
+
+   rem = from_new % card->erase_size;
+   if (rem) {
+   rem = card->erase_size - rem;
+   from_new += rem;
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+   }
+
+   rem = nr_new % card->erase_size;
+   if (rem)
+   nr_new -= rem;
+
+   if (nr_new == 0)
+   return 0;
+
+   *to = from_new + nr_new;
+   *from = from_new;
+
+   return nr_new;
+}
+
 /**
  * mmc_erase - erase sectors.
  * @card: card to erase
@@ -2240,26 +2270,12 @@ int mmc_erase(struct mmc_card *card, unsigned int from, 
unsigned int nr,
return -EINVAL;
}
 
-   if (arg == MMC_ERASE_ARG) {
-   rem = from % card->erase_size;
-   if (rem) {
-   rem = card->erase_size - rem;
-   from += rem;
-   if (nr > rem)
-   nr -= rem;
-   else
-   return 0;
-   }
-   rem = nr % card->erase_size;
-   if (rem)
-   nr -= rem;
-   }
+   if (arg == MMC_ERASE_ARG)
+   nr = mmc_align_erase_size(card, , , nr);
 
if (nr == 0)
return 0;
 
-   to = from + nr;
-
if (to <= from)
return -EINVAL;
 
-- 
1.7.9.5



Re: [PATCH v4 1/3] mmc: core: Remove some redundant validations in mmc_erase() function

2016-09-06 Thread Baolin Wang
On 6 September 2016 at 20:17, Ulf Hansson <ulf.hans...@linaro.org> wrote:
> On 6 September 2016 at 04:55, Baolin Wang <baolin.w...@linaro.org> wrote:
>> Before issuing mmc_erase() function, users always have checked if it can
>> erase with mmc_can_erase/trim/discard() function, thus remove the redundant
>> erase checking in mmc_erase() function.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> Tested-by: Shawn Lin <shawn@rock-chips.com>
>> ---
>> Changes since v3:
>>  - Split into 3 separate patches.
>>  - Add test tag by Shawn.
>>
>> Changes since v2:
>>  - Add nr checking and other optimization in mmc_erase() function.
>>
>> Changes since v1:
>>  - Add the alignment if card->erase_size is not power of 2.
>> ---
>>  drivers/mmc/core/core.c |7 ---
>>  1 file changed, 7 deletions(-)
>>
>> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
>> index e55cde6..7d7209d 100644
>> --- a/drivers/mmc/core/core.c
>> +++ b/drivers/mmc/core/core.c
>> @@ -2217,13 +2217,6 @@ int mmc_erase(struct mmc_card *card, unsigned int 
>> from, unsigned int nr,
>> unsigned int rem, to = from + nr;
>> int err;
>>
>> -   if (!(card->host->caps & MMC_CAP_ERASE) ||
>> -   !(card->csd.cmdclass & CCC_ERASE))
>> -   return -EOPNOTSUPP;
>> -
>> -   if (!card->erase_size)
>> -   return -EOPNOTSUPP;
>> -
>
> Could we postpone this until after a clean-up-series of the mmc erase 
> functions?
>
> Until the function remains an exported API, I think it should keep
> doing this validations.

OK. That's reasonable.

>
>> if (mmc_card_sd(card) && arg != MMC_ERASE_ARG)
>> return -EOPNOTSUPP;
>>
>> --
>> 1.7.9.5
>>
>
> Kind regards
> Uffe



-- 
Baolin.wang
Best Regards


Re: [tip:timers/core] time: alarmtimer: Add tracepoints for alarmtimers

2016-09-06 Thread Baolin Wang
Hi John and Ingo,

On 7 September 2016 at 08:10, John Stultz <john.stu...@linaro.org> wrote:
> On Tue, Sep 6, 2016 at 2:49 AM, Ingo Molnar <mi...@kernel.org> wrote:
>>
>> * tip-bot for Baolin Wang <tip...@zytor.com> wrote:
>>
>>> Commit-ID:  a0a6e06d545a753740c9d8d5ce2c4fdd3ab1c021
>>> Gitweb: 
>>> http://git.kernel.org/tip/a0a6e06d545a753740c9d8d5ce2c4fdd3ab1c021
>>> Author: Baolin Wang <baolin.w...@linaro.org>
>>> AuthorDate: Mon, 22 Aug 2016 12:23:14 +0800
>>> Committer:  John Stultz <john.stu...@linaro.org>
>>> CommitDate: Wed, 31 Aug 2016 14:44:18 -0700
>>>
>>> time: alarmtimer: Add tracepoints for alarmtimers
>>
>> FYI, this commit causes a build failure on the S390 defconfig:
>>
>>   kernel/built-in.o:/home/mingo/tip/include/trace/events/alarmtimer.h:62: 
>> more undefined references to `rtc_ktime_to_tm' follow
>>
>> Removing that commit solved the build failure. Other architectures (that I
>> checked) build fine.

I am sorry for the build failure on S390. I will send out the new
version to fix it ASAP. Thanks for John's help.

>
> Baolin: It looks like the issue is rtc_ktime_to_tm is defined in the
> CONFIG_RTC_LIB optional drivers/rtc/rtc-lib.c, which s390 does not
> include.
>
> Something like (forgive the whitespace damage, as this was copied and pasted):
> diff --git a/include/trace/events/alarmtimer.h
> b/include/trace/events/alarmtimer.h
> index 6a34bc9..a4f78cc 100644
> --- a/include/trace/events/alarmtimer.h
> +++ b/include/trace/events/alarmtimer.h
> @@ -77,6 +77,7 @@ DECLARE_EVENT_CLASS(alarm_processing,
> __string(name, process_name)
> ),
>
> +#ifdef CONFIG_RTC_LIB
> TP_fast_assign(
> __entry->expires = alarm->node.expires.tv64;
> __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec;
> @@ -89,6 +90,20 @@ DECLARE_EVENT_CLASS(alarm_processing,
> __assign_str(name, process_name);
> ),
>
> +#else
> +   TP_fast_assign(
> +   __entry->expires = alarm->node.expires.tv64;
> +   __entry->second = 0;
> +   __entry->minute = 0;
> +   __entry->hour = 0;
> +   __entry->day = 0;
> +   __entry->mon = 0;
> +   __entry->year =0;
> +   __entry->alarm_type = alarm->type;
> +   __assign_str(name, process_name);
> +   ),
> +#endif
> +
> TP_printk("process:%s alarmtimer type:%s expires:%llu "
>   "time: %hu-%u-%u %u:%u:%u",
>   __get_str(name),
>
> Seems to resolve it, but I think a better solution is needed.
>
> thanks
> -john



-- 
Baolin.wang
Best Regards


Re: [PATCH] rtc: Add some dummy static inline functions

2016-09-07 Thread Baolin Wang
Hi,

On 7 September 2016 at 20:12, Alexandre Belloni
<alexandre.bell...@free-electrons.com> wrote:
> On 07/09/2016 at 15:17:26 +0800, Baolin Wang wrote :
>> Add some dummy static inline functions in case CONFIG_RTC_LIB is not defined.
>>
>
> The question your commit log should answer is why?

I will add the commit log to explain why like below, thanks.

The patch (commit id: a0a6e06d545a753740c9d8d5ce2c4fdd3ab1c021) adding
tracepoints for alarmtimers will build failed on S390 platform, due to
S390 defconfig did not define CONFIG_RTC_LIB macro to define the
rtc_ktime_to_tm() function which is used in this patch. Thus we should
add dummy static inline functions in case CONFIG_RTC_LIB is not
defined.

>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> Fixes: a0a6e06d545a ("time: alarmtimer: Add tracepoints for alarmtimers")
>> ---
>>  include/linux/rtc.h |   49 -
>>  1 file changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/rtc.h b/include/linux/rtc.h
>> index b693ada..521f752 100644
>> --- a/include/linux/rtc.h
>> +++ b/include/linux/rtc.h
>> @@ -16,13 +16,60 @@
>>  #include 
>>  #include 
>>
>> +#ifdef CONFIG_RTC_LIB
>>  extern int rtc_month_days(unsigned int month, unsigned int year);
>> -extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int 
>> year);
>> +extern int rtc_year_days(unsigned int day, unsigned int month,
>> +  unsigned int year);
>>  extern int rtc_valid_tm(struct rtc_time *tm);
>>  extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
>>  extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
>>  ktime_t rtc_tm_to_ktime(struct rtc_time tm);
>>  struct rtc_time rtc_ktime_to_tm(ktime_t kt);
>> +#else
>> +static inline int rtc_month_days(unsigned int month, unsigned int year)
>> +{
>> + return 0;
>> +}
>> +
>> +static inline int rtc_year_days(unsigned int day, unsigned int month,
>> + unsigned int year)
>> +{
>> + return 0;
>> +}
>> +
>> +static inline int rtc_valid_tm(struct rtc_time *tm)
>> +{
>> + return 0;
>> +}
>> +
>> +static inline time64_t rtc_tm_to_time64(struct rtc_time *tm)
>> +{
>> + time64_t ret;
>> +
>> + memset(, 0, sizeof(time64_t));
>> + return ret;
>> +}
>> +
>> +static inline void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
>> +{
>> +}
>> +
>> +static inline ktime_t rtc_tm_to_ktime(struct rtc_time tm)
>> +{
>> + ktime_t ret;
>> +
>> + memset(, 0, sizeof(ktime_t));
>> + return ret;
>> +}
>> +
>> +static inline struct rtc_time rtc_ktime_to_tm(ktime_t kt)
>> +{
>> + struct rtc_time ret;
>> +
>> + memset(, 0, sizeof(struct rtc_time));
>> + return ret;
>> +}
>> +#endif
>>
>>  /*
>>   * rtc_tm_sub - Return the difference in seconds.
>> --
>> 1.7.9.5
>>
>
> --
> Alexandre Belloni, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com



-- 
Baolin.wang
Best Regards


Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-09-08 Thread Baolin Wang
On 8 September 2016 at 15:31, NeilBrown <ne...@suse.com> wrote:
> On Thu, Sep 08 2016, Baolin Wang wrote:
>
>> Hi Neil,
>>
>> On 6 September 2016 at 13:40, NeilBrown <nfbr...@novell.com> wrote:
>>> On Mon, Aug 29 2016, Baolin Wang wrote:
>>>
>>>> Hi Felipe,
>>>>
>>>> On 11 August 2016 at 11:14, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>>> Hi Felipe,
>>>>>
>>>>> On 1 August 2016 at 15:09, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>>>> Currently the Linux kernel does not provide any standard integration of 
>>>>>> this
>>>>>> feature that integrates the USB subsystem with the system power 
>>>>>> regulation
>>>>>> provided by PMICs meaning that either vendors must add this in their 
>>>>>> kernels
>>>>>> or USB gadget devices based on Linux (such as mobile phones) may not 
>>>>>> behave
>>>>>> as they should. Thus provide a standard framework for doing this in 
>>>>>> kernel.
>>>>>>
>>>>>> Now introduce one user with wm831x_power to support and test the usb 
>>>>>> charger,
>>>>>> which is pending testing. Moreover there may be other potential users 
>>>>>> will use
>>>>>> it in future.
>>>>>
>>>>> Could you please apply this patchset into your 'next' branch if you
>>>>> have no comments about it? Thank you.
>>>>
>>>> Since there are no other comments about this patchset for a long time,
>>>> could you please apply this patchset? Thanks.
>>>
>>
>> Sorry for the late reply.
>>
>>> Sorry, I should have replied earlier.  Tim Bird mentioned on the
>>> ksummit-discuss list that there was a frustration with this not making
>>> progress so I decided to contribute what I could now.
>>>
>>> I think this patch set is attempting to address an important problem
>>> that needs solving.  However I think it gets some key aspects wrong.
>>> Maybe they can get fixed up after the patchset is upstream, maybe they
>>> should be fixed first - I have no strong opinion on that.
>>>
>>> My main complaints involve the detection and handling of the different
>>> charger types - DCP, CDP, ACA etc.
>>> The big-picture requirement here that the PHY will detect the physical
>>> properties of the cable (e.g. resistance to ground on ID) and determine
>>> the type of charger expected.  This information must be communicated to
>>> the PMIC "power_supply" device so it can regulate the power being drawn
>>> through the cable.
>>>
>>> The first problem is that there are two different ways that the
>>> distinction between DCP, CDP, ACA etc can be represented in Linux.  They
>>> are cable types in the 'extcon' subsystem, and they are power_supply
>>> types in the 'power_supply' subsystem.  This duplication is confusing.
>>> It is not caused by your patch set, but I believe your patchset needs to
>>> work with the duplication and I think it does so poorly.
>>
>> Now the usb charger will not get charger type from 'extcon' subsystem,
>> we get the charger type from 'power_supply' and calllback
>> 'get_charger_type' for users.
>
> I understand this.  I think it is wrong because, in general, the
> power_supply doesn't know what the charger_type is (it might know it is
> USB, but most don't know which sort of USB).  The PHY knows that, not
> the power_supply.

I don't think so. Now many platforms will detect the charger type by
PMIC hardware, and we can get the charger type by PMIC hardware
register. Then power supply driver can access the PMIC register to get
the charger type. Here USB charger just considers if the accessing the
PMIC register to get charger type is implemented in power supply, it
is optional depending on what your platform designed.

>>
>>>
>>> In my mind, the power_supply should *not* know about this distinction at
>>> all (except possibly as an advisor attribute simiarly to the current
>>> battery technology attribute).  The other types it knows of are "AC",
>>> "USB", and "BATTERY".  The contrast between these is quite different
>>> From the contrast between DCP, CDP, ACA, which, from the perspective of
>>> the power supply, are almost irrelevant.  Your patchset effectively
>>> examines the power_supply_type of one power_supply, a

[PATCH] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-09-08 Thread Baolin Wang
When we change the USB function with configfs dynamically, we possibly met this
situation: one core is doing the control transfer, another core is trying to
unregister the USB gadget from userspace, we must wait for completing this
control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.

Also adding some disconnect checking to avoid queuing any requests when the
gadget is stopped.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/dwc3/ep0.c|8 
 drivers/usb/dwc3/gadget.c |   32 +++-
 2 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..11519d7 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
usb_request *request,
int ret;
 
spin_lock_irqsave(>lock, flags);
+   if (dwc->pullups_connected == false) {
+   dwc3_trace(trace_dwc3_ep0,
+   "queuing request %p to %s when gadget is disconnected",
+   request, dep->name);
+   ret = -ESHUTDOWN;
+   goto out;
+   }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_ep0,
"trying to queue request %p to disabled %s",
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..bbac8f5 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
struct dwc3 *dwc = dep->dwc;
int ret;
 
+   if (dwc->pullups_connected == false) {
+   dwc3_trace(trace_dwc3_gadget,
+   "queuing request %p to %s when gadget is disconnected",
+   >request, dep->endpoint.name);
+   return -ESHUTDOWN;
+   }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_gadget,
"trying to queue request %p to disabled %s",
@@ -1434,6 +1441,13 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
is_on, int suspend)
if (pm_runtime_suspended(dwc->dev))
return 0;
 
+   /*
+* Per databook, when we want to stop the gadget, if a control transfer
+* is still in process, complete it and get the core into setup phase.
+*/
+   if (!is_on && dwc->ep0state != EP0_SETUP_PHASE)
+   return -EBUSY;
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (is_on) {
if (dwc->revision <= DWC3_REVISION_187A) {
@@ -1481,12 +1495,20 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int 
is_on)
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long   flags;
int ret;
+   int timeout = 500;
 
is_on = !!is_on;
 
-   spin_lock_irqsave(>lock, flags);
-   ret = dwc3_gadget_run_stop(dwc, is_on, false);
-   spin_unlock_irqrestore(>lock, flags);
+   do {
+   spin_lock_irqsave(>lock, flags);
+   ret = dwc3_gadget_run_stop(dwc, is_on, false);
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (ret != -EBUSY)
+   break;
+
+   udelay(10);
+   } while (--timeout);
 
return ret;
 }
@@ -1990,7 +2012,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
 * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 * early on so DWC3_EP_BUSY flag gets cleared
 */
-   if (!dep->endpoint.desc)
+   if (!dep->endpoint.desc || dwc->pullups_connected == false)
return 1;
 
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
@@ -2064,7 +2086,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 
*dwc,
 * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 * early on so DWC3_EP_BUSY flag gets cleared
 */
-   if (!dep->endpoint.desc)
+   if (!dep->endpoint.desc || dwc->pullups_connected == false)
return;
 
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-- 
1.7.9.5



Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-09-08 Thread Baolin Wang
Hi Neil,

On 6 September 2016 at 13:40, NeilBrown <nfbr...@novell.com> wrote:
> On Mon, Aug 29 2016, Baolin Wang wrote:
>
>> Hi Felipe,
>>
>> On 11 August 2016 at 11:14, Baolin Wang <baolin.w...@linaro.org> wrote:
>>> Hi Felipe,
>>>
>>> On 1 August 2016 at 15:09, Baolin Wang <baolin.w...@linaro.org> wrote:
>>>> Currently the Linux kernel does not provide any standard integration of 
>>>> this
>>>> feature that integrates the USB subsystem with the system power regulation
>>>> provided by PMICs meaning that either vendors must add this in their 
>>>> kernels
>>>> or USB gadget devices based on Linux (such as mobile phones) may not behave
>>>> as they should. Thus provide a standard framework for doing this in kernel.
>>>>
>>>> Now introduce one user with wm831x_power to support and test the usb 
>>>> charger,
>>>> which is pending testing. Moreover there may be other potential users will 
>>>> use
>>>> it in future.
>>>
>>> Could you please apply this patchset into your 'next' branch if you
>>> have no comments about it? Thank you.
>>
>> Since there are no other comments about this patchset for a long time,
>> could you please apply this patchset? Thanks.
>

Sorry for the late reply.

> Sorry, I should have replied earlier.  Tim Bird mentioned on the
> ksummit-discuss list that there was a frustration with this not making
> progress so I decided to contribute what I could now.
>
> I think this patch set is attempting to address an important problem
> that needs solving.  However I think it gets some key aspects wrong.
> Maybe they can get fixed up after the patchset is upstream, maybe they
> should be fixed first - I have no strong opinion on that.
>
> My main complaints involve the detection and handling of the different
> charger types - DCP, CDP, ACA etc.
> The big-picture requirement here that the PHY will detect the physical
> properties of the cable (e.g. resistance to ground on ID) and determine
> the type of charger expected.  This information must be communicated to
> the PMIC "power_supply" device so it can regulate the power being drawn
> through the cable.
>
> The first problem is that there are two different ways that the
> distinction between DCP, CDP, ACA etc can be represented in Linux.  They
> are cable types in the 'extcon' subsystem, and they are power_supply
> types in the 'power_supply' subsystem.  This duplication is confusing.
> It is not caused by your patch set, but I believe your patchset needs to
> work with the duplication and I think it does so poorly.

Now the usb charger will not get charger type from 'extcon' subsystem,
we get the charger type from 'power_supply' and calllback
'get_charger_type' for users.

>
> In my mind, the power_supply should *not* know about this distinction at
> all (except possibly as an advisor attribute simiarly to the current
> battery technology attribute).  The other types it knows of are "AC",
> "USB", and "BATTERY".  The contrast between these is quite different
> From the contrast between DCP, CDP, ACA, which, from the perspective of
> the power supply, are almost irrelevant.  Your patchset effectively
> examines the power_supply_type of one power_supply, and communicates it
> to another.  It isn't clear to me how the first power_supply gets the
> information, or what the relationship between the two power_supplies is
> meant to be.

We just get the charger type from the power supply which can get the
charger type from register or something else, and the usb charger did
nothing for this power supply. In some platform, the charger type is
get in power supply driver, thus we should link this power supply to
get the charger type when USB cable is plugin. If you don't get
charger type from power supply driver, then it does not need to link
this power supply phandle.

>
> It makes much more sense, to me, to utilized the knowledge of this
> distinction that extcon provides.  A usb PHY can register an extcon,
> declare the sorts of cables that it can detect, and tell the extcon as
> cables appear or disappear.  The PMIC power_supply can then register with
> that extcon for events and can find out when a cable is attached, and
> what sort of cable.
> Your usb-charging framework would be well placed to help the
> power_supply to find the correct extcon, and possibly even to handle the
> registration for events.
>
> Your framework does currently register with extcon, but only listens for
> EXTCON_USB cables.  I don't think that cable type is (reliably) reported
> when a DCP (for example) is plugged in

[PATCH v2] rtc: Add some dummy static inline functions

2016-09-07 Thread Baolin Wang
The patch (commit id: a0a6e06d545a753740c9d8d5ce2c4fdd3ab1c021) adding
tracepoints for alarmtimers will build failed on S390 platform, due to
S390 defconfig did not define CONFIG_RTC_LIB macro to define the
rtc_ktime_to_tm() function which is used in this patch. Thus we should
add dummy static inline functions in case CONFIG_RTC_LIB is not defined.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Fixes: a0a6e06d545a ("time: alarmtimer: Add tracepoints for alarmtimers")
---
Changes since v1:
 - Modify the commit log.
---
 include/linux/rtc.h |   49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b693ada..521f752 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -16,13 +16,60 @@
 #include 
 #include 
 
+#ifdef CONFIG_RTC_LIB
 extern int rtc_month_days(unsigned int month, unsigned int year);
-extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int 
year);
+extern int rtc_year_days(unsigned int day, unsigned int month,
+unsigned int year);
 extern int rtc_valid_tm(struct rtc_time *tm);
 extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
 extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
 ktime_t rtc_tm_to_ktime(struct rtc_time tm);
 struct rtc_time rtc_ktime_to_tm(ktime_t kt);
+#else
+static inline int rtc_month_days(unsigned int month, unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_year_days(unsigned int day, unsigned int month,
+   unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_valid_tm(struct rtc_time *tm)
+{
+   return 0;
+}
+
+static inline time64_t rtc_tm_to_time64(struct rtc_time *tm)
+{
+   time64_t ret;
+
+   memset(, 0, sizeof(time64_t));
+   return ret;
+}
+
+static inline void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
+{
+}
+
+static inline ktime_t rtc_tm_to_ktime(struct rtc_time tm)
+{
+   ktime_t ret;
+
+   memset(, 0, sizeof(ktime_t));
+   return ret;
+}
+
+static inline struct rtc_time rtc_ktime_to_tm(ktime_t kt)
+{
+   struct rtc_time ret;
+
+   memset(, 0, sizeof(struct rtc_time));
+   return ret;
+}
+#endif
 
 /*
  * rtc_tm_sub - Return the difference in seconds.
-- 
1.7.9.5



Re: [PATCH v4] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-07 Thread Baolin Wang
Hi Thomas,

On 8 September 2016 at 00:03, Thomas Gleixner  wrote:
> On Tue, 6 Sep 2016, John Stultz wrote:
>> > Changes since v3:
>> >  - Fix the build error on S390.
>>
>> Since the original change is already applied to tip/timers/core, can
>> you provide an incremental patch (a patch against tip/timers/core)
>> that fixes the issue, rather then resending the entire patch?
>
> I zapped it from timers/core as it was the top commit. So we can redo it
> completely, but we can do it incremental as well. Whatever you prefer.

I've send out one incremental patch to fix this issue[1]. Thanks.

[1] https://lkml.org/lkml/2016/9/7/828

-- 
Baolin.wang
Best Regards


Re: [PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-30 Thread Baolin Wang
Hi Steven,

On 30 August 2016 at 23:42, Steven Rostedt <rost...@goodmis.org> wrote:
> On Tue, 30 Aug 2016 19:50:20 +0800
> Baolin Wang <baolin.w...@linaro.org> wrote:
>
>> Hi,
>>
>> On 22 August 2016 at 12:23, Baolin Wang <baolin.w...@linaro.org> wrote:
>> > For system debugging, we usually want to know who sets one alarm timer, the
>> > time of the timer, when the timer started and fired and so on. Thus adding
>> > tracepoints can help us trace the alarmtimer information.
>> >
>> > For example, when we debug the system supend/resume, if the system is 
>> > always
>> > resumed by RTC alarm, we can find out which process set the alarm timer to
>> > resume system by below trace log:
>> >
>> > ..
>> > Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
>> > process:Binder:2976_6
>> > alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>> >
>> > Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
>> > process:Binder:2976_7
>> > alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 
>> > 0:11:0
>> >
>> > Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
>> > process:Binder:2976_7
>> > alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 
>> > 0:34:0
>> >
>> > system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
>> > process:system_server
>> > alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>> >
>> > system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
>> > process:system_server
>> > alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35
>> >
>> > system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: 
>> > alarmtimer type:ALARM_BOOTTIME
>> > expires time: 2012-1-1 0:34:0
>> > ..
>> >
>> > From the trace log, we can find out the 'Binder:2976_7' process set one 
>> > alarm
>> > timer which resumes the system.
>>
>> Do you have any comments about this patch? Thanks.
>
> Looks fine to me.
>
> Acked-by: Steven Rostedt <rost...@goodmis.org>
>
> Now you need to get the time maintainers to accept it.

Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-30 Thread Baolin Wang
On 31 August 2016 at 02:58, John Stultz <john.stu...@linaro.org> wrote:
> On Tue, Aug 30, 2016 at 4:50 AM, Baolin Wang <baolin.w...@linaro.org> wrote:
>> Hi,
>>
>> On 22 August 2016 at 12:23, Baolin Wang <baolin.w...@linaro.org> wrote:
>>> For system debugging, we usually want to know who sets one alarm timer, the
>>> time of the timer, when the timer started and fired and so on. Thus adding
>>> tracepoints can help us trace the alarmtimer information.
>>>
>>> For example, when we debug the system supend/resume, if the system is always
>>> resumed by RTC alarm, we can find out which process set the alarm timer to
>>> resume system by below trace log:
>>>
>>> ..
>>> Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
>>> process:Binder:2976_6
>>> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>>>
>>> Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
>>> process:Binder:2976_7
>>> alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 
>>> 0:11:0
>>>
>>> Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
>>> process:Binder:2976_7
>>> alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 
>>> 0:34:0
>>>
>>> system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
>>> process:system_server
>>> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>>>
>>> system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
>>> process:system_server
>>> alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35
>>>
>>> system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: alarmtimer 
>>> type:ALARM_BOOTTIME
>>> expires time: 2012-1-1 0:34:0
>>> ..
>>>
>>> From the trace log, we can find out the 'Binder:2976_7' process set one 
>>> alarm
>>> timer which resumes the system.
>>
>> Do you have any comments about this patch? Thanks.
>
> No objection from me. I'll queue it for testing.

Thanks, John.

>
> thanks
> -john



-- 
Baolin.wang
Best Regards


Re: [PATCH v3] time: alarmtimer: Add the trcepoints for alarmtimer

2016-08-30 Thread Baolin Wang
Hi,

On 22 August 2016 at 12:23, Baolin Wang <baolin.w...@linaro.org> wrote:
> For system debugging, we usually want to know who sets one alarm timer, the
> time of the timer, when the timer started and fired and so on. Thus adding
> tracepoints can help us trace the alarmtimer information.
>
> For example, when we debug the system supend/resume, if the system is always
> resumed by RTC alarm, we can find out which process set the alarm timer to
> resume system by below trace log:
>
> ..
> Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start: 
> process:Binder:2976_6
> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>
> Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel: 
> process:Binder:2976_7
> alarmtimer type:ALARM_BOOTTIME expires:13254630600 time: 2012-1-2 
> 0:11:0
>
> Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start: 
> process:Binder:2976_7
> alarmtimer type:ALARM_BOOTTIME expires:13253780400 time: 2012-1-1 
> 0:34:0
>
> system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel: 
> process:system_server
> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1 0:20:35
>
> system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
> process:system_server
> alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1 0:20:35
>
> system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend: alarmtimer 
> type:ALARM_BOOTTIME
> expires time: 2012-1-1 0:34:0
> ..
>
> From the trace log, we can find out the 'Binder:2976_7' process set one alarm
> timer which resumes the system.

Do you have any comments about this patch? Thanks.

>
> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
> ---
> Changes since v2:
>  - Add TRACE_DEFINE_ENUM() macros.
>  - Change the time variables type to save space in the ring buffer.
>  - Add trace_alarmtimer_suspend_enabled() in case of tracing is not enabled.
>
> Changes since v1:
>  - Fix the kbuild error.
>  - Modify the changelog with adding trace log.
> ---
>  include/trace/events/alarmtimer.h |  137 
> +
>  kernel/time/alarmtimer.c  |   23 ++-
>  2 files changed, 157 insertions(+), 3 deletions(-)
>  create mode 100644 include/trace/events/alarmtimer.h
>
> diff --git a/include/trace/events/alarmtimer.h 
> b/include/trace/events/alarmtimer.h
> new file mode 100644
> index 000..6a34bc9
> --- /dev/null
> +++ b/include/trace/events/alarmtimer.h
> @@ -0,0 +1,137 @@
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM alarmtimer
> +
> +#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_ALARMTIMER_H
> +
> +#include 
> +#include 
> +#include 
> +
> +TRACE_DEFINE_ENUM(ALARM_REALTIME);
> +TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
> +
> +#define show_alarm_type(type)  __print_flags(type, " | ",  \
> +   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
> +   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
> +
> +DECLARE_EVENT_CLASS(alarm_setting,
> +
> +   TP_PROTO(struct rtc_time *rtc_time, int flag),
> +
> +   TP_ARGS(rtc_time, flag),
> +
> +   TP_STRUCT__entry(
> +   __field(unsigned char, second)
> +   __field(unsigned char, minute)
> +   __field(unsigned char, hour)
> +   __field(unsigned char, day)
> +   __field(unsigned char, mon)
> +   __field(unsigned short, year)
> +   __field(unsigned char, alarm_type)
> +   ),
> +
> +   TP_fast_assign(
> +   __entry->second = rtc_time->tm_sec;
> +   __entry->minute = rtc_time->tm_min;
> +   __entry->hour = rtc_time->tm_hour;
> +   __entry->day = rtc_time->tm_mday;
> +   __entry->mon = rtc_time->tm_mon;
> +   __entry->year = rtc_time->tm_year;
> +   __entry->alarm_type = flag;
> +   ),
> +
> +   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
> + show_alarm_type((1 << __entry->alarm_type)),
> + __entry->year + 1900,
> + __entry->mon + 1,
> + __entry->day,
> + __entry->hour,
> + __entry->minute,
> + __entry->second
> +   )
> +);
> +
> +DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
> +
> +   TP_PROTO(struct rtc_time *time, int flag),
> +
> +   TP_ARGS(time, flag)
> +);
> +
> +DECLARE_EVEN

Re: [PATCH 1/4] usb: host: xhci: Move the xhci quirks checking to the right place

2016-08-30 Thread Baolin Wang
Hi Mathias,

On 18 August 2016 at 15:17, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> It will reset the xhci quirks in xhci_gen_setup() function when xhci try to
>> add one hcd, thus we need to move the XHCI_LPM_SUPPORT quirk checking after
>> adding hcd.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>>  drivers/usb/host/xhci-plat.c |8 
>>  1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
>> index 1f3f981..e2e2487 100644
>> --- a/drivers/usb/host/xhci-plat.c
>> +++ b/drivers/usb/host/xhci-plat.c
>> @@ -223,10 +223,6 @@ static int xhci_plat_probe(struct platform_device *pdev)
>>   goto disable_clk;
>>   }
>>
>> - if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
>> - (pdata && pdata->usb3_lpm_capable))
>> - xhci->quirks |= XHCI_LPM_SUPPORT;
>> -
>>   if (HCC_MAX_PSA(xhci->hcc_params) >= 4)
>>   xhci->shared_hcd->can_do_streams = 1;
>>
>> @@ -250,6 +246,10 @@ static int xhci_plat_probe(struct platform_device *pdev)
>>   if (ret)
>>   goto dealloc_usb2_hcd;
>>
>> + if ((node && of_property_read_bool(node, "usb3-lpm-capable")) ||
>> + (pdata && pdata->usb3_lpm_capable))
>> + xhci->quirks |= XHCI_LPM_SUPPORT;
>> +
>
> Mathias, any comments here?

Do you have any comments about this? Thanks.

-- 
Baolin.wang
Best Regards


[PATCH v3] mmc: core: Optimize the mmc erase size alignment

2016-08-31 Thread Baolin Wang
Before issuing mmc_erase() function, users always have checked if it can
erase with mmc_can_erase/trim/discard() function, thus remove the redundant
erase checking in mmc_erase() function.

This patch also optimizes the erase start/end sector alignment with
round_up()/round_down() function, when erase command is MMC_ERASE_ARG.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v2:
 - Add nr checking and other optimization in mmc_erase() function.

Changes since v1:
 - Add the alignment if card->erase_size is not power of 2.
---
 drivers/mmc/core/core.c |   82 ++-
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index e55cde6..52156d4 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2202,6 +2202,51 @@ out:
return err;
 }
 
+static unsigned int mmc_align_erase_size(struct mmc_card *card,
+unsigned int *from,
+unsigned int *to,
+unsigned int nr)
+{
+   unsigned int from_new = *from, nr_new = nr, rem;
+
+   if (is_power_of_2(card->erase_size)) {
+   unsigned int temp = from_new;
+
+   from_new = round_up(temp, card->erase_size);
+   rem = from_new - temp;
+
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+
+   nr_new = round_down(nr_new, card->erase_size);
+   } else {
+   rem = from_new % card->erase_size;
+   if (rem) {
+   rem = card->erase_size - rem;
+   from_new += rem;
+   if (nr_new > rem)
+   nr_new -= rem;
+   else
+   return 0;
+   }
+
+   rem = nr_new % card->erase_size;
+   if (rem)
+   nr_new -= rem;
+   }
+
+   if (nr_new == 0)
+   return 0;
+
+   /* 'from' and 'to' are inclusive */
+   *to = from_new + nr_new - 1;
+   *from = from_new;
+
+   return nr_new;
+}
+
 /**
  * mmc_erase - erase sectors.
  * @card: card to erase
@@ -2217,13 +2262,6 @@ int mmc_erase(struct mmc_card *card, unsigned int from, 
unsigned int nr,
unsigned int rem, to = from + nr;
int err;
 
-   if (!(card->host->caps & MMC_CAP_ERASE) ||
-   !(card->csd.cmdclass & CCC_ERASE))
-   return -EOPNOTSUPP;
-
-   if (!card->erase_size)
-   return -EOPNOTSUPP;
-
if (mmc_card_sd(card) && arg != MMC_ERASE_ARG)
return -EOPNOTSUPP;
 
@@ -2240,31 +2278,17 @@ int mmc_erase(struct mmc_card *card, unsigned int from, 
unsigned int nr,
return -EINVAL;
}
 
-   if (arg == MMC_ERASE_ARG) {
-   rem = from % card->erase_size;
-   if (rem) {
-   rem = card->erase_size - rem;
-   from += rem;
-   if (nr > rem)
-   nr -= rem;
-   else
-   return 0;
-   }
-   rem = nr % card->erase_size;
-   if (rem)
-   nr -= rem;
-   }
-
if (nr == 0)
return 0;
 
-   to = from + nr;
-
-   if (to <= from)
-   return -EINVAL;
-
-   /* 'from' and 'to' are inclusive */
-   to -= 1;
+   if (arg == MMC_ERASE_ARG) {
+   nr = mmc_align_erase_size(card, , , nr);
+   if (nr == 0)
+   return 0;
+   } else {
+   /* 'from' and 'to' are inclusive */
+   to -= 1;
+   }
 
/*
 * Special case where only one erase-group fits in the timeout budget:
-- 
1.7.9.5



Re: [PATCH] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-09-08 Thread Baolin Wang
Hi Felipe,

On 8 September 2016 at 20:00, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> When we change the USB function with configfs dynamically, we possibly met 
>> this
>> situation: one core is doing the control transfer, another core is trying to
>> unregister the USB gadget from userspace, we must wait for completing this
>> control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.
>>
>> Also adding some disconnect checking to avoid queuing any requests when the
>> gadget is stopped.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>>  drivers/usb/dwc3/ep0.c|8 
>>  drivers/usb/dwc3/gadget.c |   32 +++-
>>  2 files changed, 35 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>> index fe79d77..11519d7 100644
>> --- a/drivers/usb/dwc3/ep0.c
>> +++ b/drivers/usb/dwc3/ep0.c
>> @@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
>> usb_request *request,
>>   int ret;
>>
>>   spin_lock_irqsave(>lock, flags);
>> + if (dwc->pullups_connected == false) {
>> + dwc3_trace(trace_dwc3_ep0,
>> + "queuing request %p to %s when gadget is disconnected",
>> + request, dep->name);
>> + ret = -ESHUTDOWN;
>> + goto out;
>> + }
>
> this could go on its own patch, however we can use if
> (!dwc->pullups_connected) instead.

Indeed. I will split it into one separate patch.

>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 1783406..bbac8f5 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep 
>> *dep, struct dwc3_request *req)
>>   struct dwc3 *dwc = dep->dwc;
>>   int ret;
>>
>> + if (dwc->pullups_connected == false) {
>> + dwc3_trace(trace_dwc3_gadget,
>> + "queuing request %p to %s when gadget is disconnected",
>> + >request, dep->endpoint.name);
>> + return -ESHUTDOWN;
>> + }
>
> ditto

OK.

>
>> @@ -1434,6 +1441,13 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
>> is_on, int suspend)
>>   if (pm_runtime_suspended(dwc->dev))
>>   return 0;
>>
>> + /*
>> +  * Per databook, when we want to stop the gadget, if a control transfer
>> +  * is still in process, complete it and get the core into setup phase.
>> +  */
>
> Do you have the section reference for this? Which databook version are
> you reading?

The databook version is 2.80a and you can find this description in
section 8.1.8 "Device-Initiated Disconnect".

>
>> + if (!is_on && dwc->ep0state != EP0_SETUP_PHASE)
>> + return -EBUSY;
>> +
>>   reg = dwc3_readl(dwc->regs, DWC3_DCTL);
>>   if (is_on) {
>>   if (dwc->revision <= DWC3_REVISION_187A) {
>> @@ -1481,12 +1495,20 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, 
>> int is_on)
>>   struct dwc3 *dwc = gadget_to_dwc(g);
>>   unsigned long   flags;
>>   int ret;
>> + int timeout = 500;
>>
>>   is_on = !!is_on;
>>
>> - spin_lock_irqsave(>lock, flags);
>> - ret = dwc3_gadget_run_stop(dwc, is_on, false);
>> - spin_unlock_irqrestore(>lock, flags);
>> + do {
>> + spin_lock_irqsave(>lock, flags);
>> + ret = dwc3_gadget_run_stop(dwc, is_on, false);
>> + spin_unlock_irqrestore(>lock, flags);
>> +
>> + if (ret != -EBUSY)
>> + break;
>> +
>> + udelay(10);
>> + } while (--timeout);
>
> no, this is not a good idea at all. I'd rather see:
>
> wait_event_timeout(dwc->wq, dwc->ep0state == EP0_SETUP_PHASE,
> jiffies + msecs_to_jiffies(500));
>
> or, perhaps, a wait_for_completion_timeout(). Then, ep0.c needs to call
> complete() everytime Status Phase completes. That's probably a better
> idea ;-)

Yes, you are right. I will fix that with your suggestion. Thanks.

>
>> @@ -1990,7 +2012,7 @@ static int dwc3_cleanup_done_r

Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-09-09 Thread Baolin Wang
On 9 September 2016 at 07:13, NeilBrown <ne...@suse.com> wrote:
> On Thu, Sep 08 2016, Baolin Wang wrote:
>
>> On 8 September 2016 at 15:31, NeilBrown <ne...@suse.com> wrote:
>>> On Thu, Sep 08 2016, Baolin Wang wrote:
>>>>
>>>> Now the usb charger will not get charger type from 'extcon' subsystem,
>>>> we get the charger type from 'power_supply' and calllback
>>>> 'get_charger_type' for users.
>>>
>>> I understand this.  I think it is wrong because, in general, the
>>> power_supply doesn't know what the charger_type is (it might know it is
>>> USB, but most don't know which sort of USB).  The PHY knows that, not
>>> the power_supply.
>>
>> I don't think so. Now many platforms will detect the charger type by
>> PMIC hardware, and we can get the charger type by PMIC hardware
>> register. Then power supply driver can access the PMIC register to get
>> the charger type. Here USB charger just considers if the accessing the
>> PMIC register to get charger type is implemented in power supply, it
>> is optional depending on what your platform designed.
>>
>
> In practice, the USB PHY and the Power manager will often be in the same
> IC (the PMIC) so the driver for one could look at the registers for the
> other.
> But there is no guarantee that the hardware works like that.  It is
> best to create a generally design.

Yes, we hope to create one generally design, so we need to consider
this situation: the power supply getting the charger type by accessing
PMIC registers. The registers which save the charger type are not
always belong to the USB PHY, may be just some registers on PMIC.

Now in mainline kernel, there are 3 methods can get the charger type
which need to integrate with USB charger framework:
1. power supply
2. extcon (need to add as you suggested)
3. others (by 'get_charger_type' callback of USB charger)

> Conceptually, the PHY is separate from the power manager and a solution
> which recognises that will be more universal.
>
> If the power manager can always just look at that phy registers to know
> what sort of charger is connected, why does you framework need to work
> with charger types at all?
>
>>>>
>>>> Yes, but you must think about some special cases on some platforms.
>>>> Users may need to change the current in some situations, thus we
>>>> should export one API for users to change the current. (I think you
>>>> misunderstand the current limit here, that is the current for power
>>>> driver  to draw).
>>>
>>> Can you be specific about these "special cases" please?
>>> I cannot think of any.
>>
>> Suppose the USB configuration requests 100mA, then we should set the
>> USB charger current is 100mA by __usb_charger_set_cur_limit_by_type()
>> funtion, then notify this to power driver.
>
> ahh I had missed something there.  It's a while since I looked
> closely at these patches.
>
> Only this usage of usb_charger_set_cur_limit_by_type() is really
> nonsensical.
>
> If the cable is detected as being DCP or CDP or ACA (or ACA/DOCK) then
> the number negotiated with the USB configuration is not relevant and
> should be ignored.  There is a guaranteed minimum which is at least the
> maximum that *can* be negotiated.

Yes. If it is not relevant, we will no't set the current from USB
configuration. Just when your charger type is SDP and the USB
enumeration is done, we can get the USB configuration from host to set
current.

>
> It is only when the cable appears to be a SDP (standard downstream
> port) that the usb-config negotiation is relevant.  That is because the
> minimum guaranteed for SDP is only 100mA.
>
> NeilBrown



-- 
Baolin.wang
Best Regards


[PATCH v2 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-09-09 Thread Baolin Wang
When we change the USB function with configfs dynamically, we possibly met this
situation: one core is doing the control transfer, another core is trying to
unregister the USB gadget from userspace, we must wait for completing this
control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/dwc3/core.c   |1 +
 drivers/usb/dwc3/core.h   |2 ++
 drivers/usb/dwc3/ep0.c|2 ++
 drivers/usb/dwc3/gadget.c |   21 +
 4 files changed, 26 insertions(+)

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 057739d..22787b6 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -999,6 +999,7 @@ static int dwc3_probe(struct platform_device *pdev)
goto err0;
 
spin_lock_init(>lock);
+   init_completion(>ep0_completed);
 
if (!dev->dma_mask) {
dev->dma_mask = dev->parent->dma_mask;
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b2317e7..858e661 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -745,6 +745,7 @@ struct dwc3_scratchpad_array {
  * @ep0_usb_req: dummy req used while handling STD USB requests
  * @ep0_bounce_addr: dma address of ep0_bounce
  * @scratch_addr: dma address of scratchbuf
+ * @ep0_completed: One control tranfer is completed
  * @lock: for synchronizing
  * @dev: pointer to our struct device
  * @xhci: pointer to our xHCI child
@@ -843,6 +844,7 @@ struct dwc3 {
dma_addr_t  ep0_bounce_addr;
dma_addr_t  scratch_addr;
struct dwc3_request ep0_usb_req;
+   struct completion   ep0_completed;
 
/* device lock */
spinlock_t  lock;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 632e5a4..baf932d 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -286,6 +286,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 
dwc->ep0state = EP0_SETUP_PHASE;
dwc3_ep0_out_start(dwc);
+   complete(>ep0_completed);
 }
 
 int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
@@ -935,6 +936,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
dwc->ep0state = EP0_SETUP_PHASE;
dwc3_ep0_out_start(dwc);
+   complete(>ep0_completed);
 }
 
 static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1a33308..c9026ce 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1441,6 +1441,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
is_on, int suspend)
if (pm_runtime_suspended(dwc->dev))
return 0;
 
+   /*
+* Per databook, when we want to stop the gadget, if a control transfer
+* is still in process, complete it and get the core into setup phase.
+*/
+   if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
+   reinit_completion(>ep0_completed);
+   return -EBUSY;
+   }
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (is_on) {
if (dwc->revision <= DWC3_REVISION_187A) {
@@ -1491,10 +1500,22 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int 
is_on)
 
is_on = !!is_on;
 
+try_again:
spin_lock_irqsave(>lock, flags);
ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(>lock, flags);
 
+   if (ret == -EBUSY) {
+   ret = wait_for_completion_timeout(>ep0_completed,
+ msecs_to_jiffies(100));
+   if (ret == 0) {
+   dev_err(dwc->dev, "timeout to stop gadget.\n");
+   return -ETIMEDOUT;
+   } else {
+   goto try_again;
+   }
+   }
+
return ret;
 }
 
-- 
1.7.9.5



[PATCH v2 1/2] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-09-09 Thread Baolin Wang
When system has stpped the gadget, we should avoid queuing any requests
which will cause tranfer failed. Thus adding some disconnect checking to
avoid this situation.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v1:
 - Split into 2 separate ptaches.
 - Choose complete mechanism instead of polling.
---
 drivers/usb/dwc3/ep0.c|8 
 drivers/usb/dwc3/gadget.c |   12 +---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..632e5a4 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
usb_request *request,
int ret;
 
spin_lock_irqsave(>lock, flags);
+   if (!dwc->pullups_connected) {
+   dwc3_trace(trace_dwc3_ep0,
+   "queuing request %p to %s when gadget is disconnected",
+   request, dep->name);
+   ret = -ESHUTDOWN;
+   goto out;
+   }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_ep0,
"trying to queue request %p to disabled %s",
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..1a33308 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
struct dwc3 *dwc = dep->dwc;
int ret;
 
+   if (!dwc->pullups_connected) {
+   dwc3_trace(trace_dwc3_gadget,
+   "queuing request %p to %s when gadget is disconnected",
+   >request, dep->endpoint.name);
+   return -ESHUTDOWN;
+   }
+
if (!dep->endpoint.desc) {
dwc3_trace(trace_dwc3_gadget,
"trying to queue request %p to disabled %s",
@@ -1984,13 +1991,12 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
if (ret)
break;
}
-
/*
 * Our endpoint might get disabled by another thread during
 * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 * early on so DWC3_EP_BUSY flag gets cleared
 */
-   if (!dep->endpoint.desc)
+   if (!dep->endpoint.desc || !dwc->pullups_connected)
return 1;
 
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
@@ -2064,7 +2070,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 
*dwc,
 * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
 * early on so DWC3_EP_BUSY flag gets cleared
 */
-   if (!dep->endpoint.desc)
+   if (!dep->endpoint.desc || !dwc->pullups_connected)
return;
 
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
-- 
1.7.9.5



Re: [PATCH v3 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-09-29 Thread Baolin Wang
Hi Felipe,

On 19 September 2016 at 19:52, Baolin Wang <baolin.w...@linaro.org> wrote:
> When we change the USB function with configfs dynamically, we possibly met 
> this
> situation: one core is doing the control transfer, another core is trying to
> unregister the USB gadget from userspace, we must wait for completing this
> control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.
>

Any comments about this new version patchset? Thanks.

> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
> ---
>  drivers/usb/dwc3/core.h   |2 ++
>  drivers/usb/dwc3/ep0.c|2 ++
>  drivers/usb/dwc3/gadget.c |   23 +++
>  3 files changed, 27 insertions(+)
>
> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
> index b2317e7..01a6fbd 100644
> --- a/drivers/usb/dwc3/core.h
> +++ b/drivers/usb/dwc3/core.h
> @@ -745,6 +745,7 @@ struct dwc3_scratchpad_array {
>   * @ep0_usb_req: dummy req used while handling STD USB requests
>   * @ep0_bounce_addr: dma address of ep0_bounce
>   * @scratch_addr: dma address of scratchbuf
> + * @ep0_in_setup: One control tranfer is completed and enter setup phase
>   * @lock: for synchronizing
>   * @dev: pointer to our struct device
>   * @xhci: pointer to our xHCI child
> @@ -843,6 +844,7 @@ struct dwc3 {
> dma_addr_t  ep0_bounce_addr;
> dma_addr_t  scratch_addr;
> struct dwc3_request ep0_usb_req;
> +   struct completion   ep0_in_setup;
>
> /* device lock */
> spinlock_t  lock;
> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> index fe79d77..06c167a 100644
> --- a/drivers/usb/dwc3/ep0.c
> +++ b/drivers/usb/dwc3/ep0.c
> @@ -311,6 +311,8 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
> ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
> DWC3_TRBCTL_CONTROL_SETUP, false);
> WARN_ON(ret < 0);
> +
> +   complete(>ep0_in_setup);
>  }
>
>  static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index ca2ae5b..3a30d51 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1437,6 +1437,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
> is_on, int suspend)
> if (pm_runtime_suspended(dwc->dev))
> return 0;
>
> +   /*
> +* Per databook, when we want to stop the gadget, if a control 
> transfer
> +* is still in process, complete it and get the core into setup phase.
> +*/
> +   if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
> +   reinit_completion(>ep0_in_setup);
> +   return -EBUSY;
> +   }
> +
> reg = dwc3_readl(dwc->regs, DWC3_DCTL);
> if (is_on) {
> if (dwc->revision <= DWC3_REVISION_187A) {
> @@ -1487,10 +1496,22 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, 
> int is_on)
>
> is_on = !!is_on;
>
> +try_again:
> spin_lock_irqsave(>lock, flags);
> ret = dwc3_gadget_run_stop(dwc, is_on, false);
> spin_unlock_irqrestore(>lock, flags);
>
> +   if (ret == -EBUSY) {
> +   ret = wait_for_completion_timeout(>ep0_in_setup,
> + msecs_to_jiffies(500));
> +   if (ret == 0) {
> +   dev_err(dwc->dev, "timeout to stop gadget.\n");
> +   return -ETIMEDOUT;
> +   } else {
> +   goto try_again;
> +   }
> +   }
> +
> return ret;
>  }
>
> @@ -2914,6 +2935,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
> goto err4;
> }
>
> +   init_completion(>ep0_in_setup);
> +
> dwc->gadget.ops = _gadget_ops;
> dwc->gadget.speed   = USB_SPEED_UNKNOWN;
> dwc->gadget.sg_supported= true;
> --
> 1.7.9.5
>



-- 
Baolin.wang
Best Regards


Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-10-05 Thread Baolin Wang
Hi Felipe,

>> But you do!
>> The mA number from the USB configuration is passed to usb_gadget_vbus_draw.
>> Your patch passes that to usb_charger_set_cur_limit_by_type()
>> which calls __usb_charger_set_cur_limit_by_type() which will set the
>> cur_limit for whichever type uchger->type currently is.
>>
>> So when it is not relevant, your code *does* set some current limit.
>
> Suppose the charger type is DCP(it is not relevant to the mA number
> from the USB configuration ), it will not do the USB enumeration, then
> no USB configuration from host to set current.

>From the talking, there are some issues (thanks for Neil's comments)
need to be fixed as below:
1. Need to add the method getting charger type from extcon subsystem.
2. Need to remove the method getting charger type from power supply.
3. There are still some different views about reporting the maximum
current or minimum current to power driver.

Now the current v16 patchset can work well on my Spreadtrum platform
and Jun's NXP platform, if you like to apply this patchset then I can
send out new patches to fix above issues. If you don't like that, I
can send out new version patchset to fix above issues. Could you  give
me some suggestions what should I do next step? Thanks.

>
> --
> Baolin.wang
> Best Regards



-- 
Baolin.wang
Best Regards


Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-10-05 Thread Baolin Wang
Hi Felipe,

On 5 October 2016 at 15:47, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi Baolin,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> But you do!
>>>> The mA number from the USB configuration is passed to usb_gadget_vbus_draw.
>>>> Your patch passes that to usb_charger_set_cur_limit_by_type()
>>>> which calls __usb_charger_set_cur_limit_by_type() which will set the
>>>> cur_limit for whichever type uchger->type currently is.
>>>>
>>>> So when it is not relevant, your code *does* set some current limit.
>>>
>>> Suppose the charger type is DCP(it is not relevant to the mA number
>>> from the USB configuration ), it will not do the USB enumeration, then
>>> no USB configuration from host to set current.
>>
>> From the talking, there are some issues (thanks for Neil's comments)
>> need to be fixed as below:
>> 1. Need to add the method getting charger type from extcon subsystem.
>> 2. Need to remove the method getting charger type from power supply.
>> 3. There are still some different views about reporting the maximum
>> current or minimum current to power driver.
>>
>> Now the current v16 patchset can work well on my Spreadtrum platform
>> and Jun's NXP platform, if you like to apply this patchset then I can
>> send out new patches to fix above issues. If you don't like that, I
>> can send out new version patchset to fix above issues. Could you  give
>> me some suggestions what should I do next step? Thanks.
>
> Merge window just opened, nothing will happen for about 2 weeks. How
> about you send a new version after merge window closes and we go from
> there? Fixing 1 and 2 is needed. 3 we need to consider more

Sure. I will send out the new version with fixing these issues. Thanks.

> carefully. Perhaps report both minimum and maximum somehow?
>
> Neil, comments?
>
> --
> balbi



-- 
Baolin.wang
Best Regards


[RESEND PATCH v3 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-10-04 Thread Baolin Wang
When we change the USB function with configfs dynamically, we possibly met this
situation: one core is doing the control transfer, another core is trying to
unregister the USB gadget from userspace, we must wait for completing this
control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/dwc3/core.h   |2 ++
 drivers/usb/dwc3/ep0.c|2 ++
 drivers/usb/dwc3/gadget.c |   23 +++
 3 files changed, 27 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b2317e7..9128725 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -745,6 +745,7 @@ struct dwc3_scratchpad_array {
  * @ep0_usb_req: dummy req used while handling STD USB requests
  * @ep0_bounce_addr: dma address of ep0_bounce
  * @scratch_addr: dma address of scratchbuf
+ * @ep0_in_setup: One control transfer is completed and enter setup phase
  * @lock: for synchronizing
  * @dev: pointer to our struct device
  * @xhci: pointer to our xHCI child
@@ -843,6 +844,7 @@ struct dwc3 {
dma_addr_t  ep0_bounce_addr;
dma_addr_t  scratch_addr;
struct dwc3_request ep0_usb_req;
+   struct completion   ep0_in_setup;
 
/* device lock */
spinlock_t  lock;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..06c167a 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -311,6 +311,8 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
DWC3_TRBCTL_CONTROL_SETUP, false);
WARN_ON(ret < 0);
+
+   complete(>ep0_in_setup);
 }
 
 static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ca2ae5b..fef023a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1437,6 +1437,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
is_on, int suspend)
if (pm_runtime_suspended(dwc->dev))
return 0;
 
+   /*
+* Per databook, when we want to stop the gadget, if a control transfer
+* is still in process, complete it and get the core into setup phase.
+*/
+   if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
+   reinit_completion(>ep0_in_setup);
+   return -EBUSY;
+   }
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (is_on) {
if (dwc->revision <= DWC3_REVISION_187A) {
@@ -1487,10 +1496,22 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int 
is_on)
 
is_on = !!is_on;
 
+try_again:
spin_lock_irqsave(>lock, flags);
ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(>lock, flags);
 
+   if (ret == -EBUSY) {
+   ret = wait_for_completion_timeout(>ep0_in_setup,
+ msecs_to_jiffies(500));
+   if (ret == 0) {
+   dev_err(dwc->dev, "timeout to stop gadget.\n");
+   ret = -ETIMEDOUT;
+   } else {
+   goto try_again;
+   }
+   }
+
return ret;
 }
 
@@ -2914,6 +2935,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
goto err4;
}
 
+   init_completion(>ep0_in_setup);
+
dwc->gadget.ops = _gadget_ops;
dwc->gadget.speed   = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported= true;
-- 
1.7.9.5



[RESEND PATCH v3 1/2] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-10-04 Thread Baolin Wang
When system has stpped the gadget, we should avoid queuing any requests
which will cause tranfer failed. Thus adding some disconnect checking to
avoid this situation.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v2:
 - Move disconnect checking into dwc3_send_gadget_ep_cmd().
 - Rename completion name and issue complete() at one place.
 - Move completion initialization into dwc3_gadget_init().

Changes since v1:
 - Split into 2 separate ptaches.
 - Choose complete mechanism instead of polling.
---
 drivers/usb/dwc3/gadget.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..ca2ae5b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -241,6 +241,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned 
cmd,
int susphy = false;
int ret = -EINVAL;
 
+   if (!dwc->pullups_connected)
+   return -ESHUTDOWN;
+
/*
 * Synopsys Databook 2.60a states, on section 6.3.2.5.[1-8], that if
 * we're issuing an endpoint command, we must check if
-- 
1.7.9.5



Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-10-07 Thread Baolin Wang
Hi Neil,

On 5 October 2016 at 18:44, NeilBrown <ne...@suse.com> wrote:
> On Wed, Oct 05 2016, Felipe Balbi wrote:
>
>> Hi Baolin,
>>
>> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>> But you do!
>>>>> The mA number from the USB configuration is passed to 
>>>>> usb_gadget_vbus_draw.
>>>>> Your patch passes that to usb_charger_set_cur_limit_by_type()
>>>>> which calls __usb_charger_set_cur_limit_by_type() which will set the
>>>>> cur_limit for whichever type uchger->type currently is.
>>>>>
>>>>> So when it is not relevant, your code *does* set some current limit.
>>>>
>>>> Suppose the charger type is DCP(it is not relevant to the mA number
>>>> from the USB configuration ), it will not do the USB enumeration, then
>>>> no USB configuration from host to set current.
>>>
>>> From the talking, there are some issues (thanks for Neil's comments)
>>> need to be fixed as below:
>>> 1. Need to add the method getting charger type from extcon subsystem.
>>> 2. Need to remove the method getting charger type from power supply.
>>> 3. There are still some different views about reporting the maximum
>>> current or minimum current to power driver.
>>>
>>> Now the current v16 patchset can work well on my Spreadtrum platform
>>> and Jun's NXP platform, if you like to apply this patchset then I can
>
> I'm really curious how much testing this has had.  Have you actually
> plugged in different cable types (SDP DCP DCP ACA) and has each one been
> detected correctly?  Because I cannot see how that could happen with the
> code you have posted.

I transplanted the USB charger framework to our Spreadtrum platform
with implementing the 'get_charger_type' callback to get the charger
type in power driver. Cause we get the charger type from accessing the
PMIC registers not from USB PHY.

>
>>> send out new patches to fix above issues. If you don't like that, I
>>> can send out new version patchset to fix above issues. Could you  give
>>> me some suggestions what should I do next step? Thanks.
>>
>> Merge window just opened, nothing will happen for about 2 weeks. How
>> about you send a new version after merge window closes and we go from
>> there? Fixing 1 and 2 is needed. 3 we need to consider more
>> carefully. Perhaps report both minimum and maximum somehow?
>>
>> Neil, comments?
>
> This probably seems a bit harsh, but I really think the current patchset
> should be discarded and the the project started again with a clear
> vision of what is required.  What we currently have is too confused.

Probably not. Now the USB charger framework tried to integrate all
different charger plugged/unplugged events, and all different charger
type getting methods, then noticed the plugged/unplugged events and
charger current to power driver, which I think that is what USB
charger should really do. Moreover, this patchset is reviewed and
helped by many people (thanks Felipe, Greg, Mark, Peter and Jun), I
really hope I can make it better to upstream.

>
> To respond to the points:
>>> 1. Need to add the method getting charger type from extcon subsystem.
>
> Yes.  This should be the only way to get the charger type.

Not really. Like I said, some platform's charger detection is done by
hardware not USB PHY, thus we can get the charger type from PMIC
hardware registers.

>
>>> 2. Need to remove the method getting charger type from power supply.
>
> Also need to remove the ->get_charger_type() method as there is no
> credible use-case for this.

No. User can implement the get_charger_type() method to access the
PMIC registers to get the charger type, which is one very common
method.

>
>>> 3. There are still some different views about reporting the maximum
>>> current or minimum current to power driver.
>
> I think those were resolved.  There was some confusion over whether a
> particular power manager wanted to be told the maximum or the minimum,
> but I think both have a clear use case in different hardware.

So, seems I should report both minimum and maximum.

>
> Also: We don't want another notifier_chain.  The usb_notifier combined
> with the extcon notifier are sufficient.  Possibly it would be sensible
> to replace the usb notifier with a new new notifier chain, but don't add
> something without first cleaning up what is there.

USB charger is one virtual device not one actual hardware device, we
should not mess it together with usb_notifier or extcon notifier.

>
> Also: resolve the question of whether it could ever make sense to have
>  more tha

Re: [PATCH 2/2] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-21 Thread Baolin Wang
On 21 September 2016 at 15:26, Thomas Gleixner <t...@linutronix.de> wrote:
> On Wed, 21 Sep 2016, Baolin Wang wrote:
>> On 21 September 2016 at 06:27, Thomas Gleixner <t...@linutronix.de> wrote:
>> >> + TP_fast_assign(
>> >> + __entry->second = rtc_time->tm_sec;
>> >> + __entry->minute = rtc_time->tm_min;
>> >> + __entry->hour = rtc_time->tm_hour;
>> >> + __entry->day = rtc_time->tm_mday;
>> >> + __entry->mon = rtc_time->tm_mon;
>> >> + __entry->year = rtc_time->tm_year;
>> >> + __entry->alarm_type = flag;
>> >
>> > What's the value of storing the alarm time in RTC format?
>>
>> As suggested by Steven, change the type of RTC value to save trace buffer.
>
> A single u64 does not take more storage space than this and it's a single
> store.

OK.

>
>> > 2) You store the expiry time again in RTC format. Store the information in
>> >a plain u64 and be done with it.
>>
>> But I still think the RTC format is more readable for debugging alarm timer.
>
> That's what post processing is for.
>
>> > What's the point of this conditional? Avoiding rtc_ktime_to_tm() ? Oh 
>> > well...
>> >
>> >> + tm_set = rtc_ktime_to_tm(now);
>> >> + trace_alarmtimer_suspend(_set, type);
>> >
>> > "now" is CLOCK_REALTIME based. You store the type of the alarm timer which
>> > is the first to expire and therefor is the one setting the RTC value, but
>> > we don't know which timer it is. Useful - NOT!
>>
>> We can know the timer by comparing the expire time.
>
> Please make it similar to the timer/hrtimer tracing so people can reuse
> their postprocessing scripts with minimial tweaks.

OK. Thanks.

-- 
Baolin.wang
Best Regards


Re: [PATCH v2 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-09-19 Thread Baolin Wang
Hi Felipe,

On 19 September 2016 at 17:58, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>> index 1a33308..c9026ce 100644
>>>> --- a/drivers/usb/dwc3/gadget.c
>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>> @@ -1441,6 +1441,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, 
>>>> int is_on, int suspend)
>>>>   if (pm_runtime_suspended(dwc->dev))
>>>>   return 0;
>>>>
>>>> + /*
>>>> +  * Per databook, when we want to stop the gadget, if a control 
>>>> transfer
>>>> +  * is still in process, complete it and get the core into setup 
>>>> phase.
>>>> +  */
>>>> + if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
>>>> + reinit_completion(>ep0_completed);
>>>
>>> this seems unnecessary to me. Also, why return here so the caller has to
>>
>> We should re-init the completion due to it will complete control
>> transfer many times before we try to stop gadget.
>
> not sure I get this comment, care to furter explain what you mean?

Sorry for confusing comment. What I mean is it will issue
'complete(>ep0_completed)' when one control transfer is
completed, and it will increase the completion->done when every
'complete()' function is issued.

If there are seveal control transfers are completed (completion->done
is not 0 bow) and dwc->ep0state is not in EP0_SETUP_PHASE satus when
we want to stop gadget, then we should wait for completion. If we
don't call 'reinit_completion(>ep0_completed)' (it will reset
completion->done as 0 ), it will not wait for 500ms in
wait_for_completion_timeout() funtion. Hope I make it clear.

>
>>> wait? You could just have called wait_for_completion() here straight
>>> away:
>>>
>>> if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
>>> /* should this be interruptible? */
>>> ret = wait_for_completion_timeout(>ep0_in_setup,
>>> msecs_to_jiffies(500));
>>> if (ret == 0) {
>>> dwc3_trace(trace_dwc3_gadget, "RUN/STOP timeout");
>>> return -ETIMEDOUT;
>>> }
>>> }
>>>
>>> There's also no need for that "try_again" trickery. We either can halt
>>> the controller within 500ms or we cannot.
>>
>> But this is in atomic context and we can not issue
>> wait_for_completion_timeout() in atomic context, then we should just
>> return here.
>
> heh, good point. Missed that :-)

OK:)

-- 
Baolin.wang
Best Regards


Re: [PATCH v16 0/4] Introduce usb charger framework to deal with the usb gadget power negotation

2016-09-18 Thread Baolin Wang
Hi Neil,

Sorry for late reply due yo my holiday.

On 10 September 2016 at 05:19, NeilBrown <ne...@suse.com> wrote:
> On Fri, Sep 09 2016, Baolin Wang wrote:
>
>>>
>>> In practice, the USB PHY and the Power manager will often be in the same
>>> IC (the PMIC) so the driver for one could look at the registers for the
>>> other.
>>> But there is no guarantee that the hardware works like that.  It is
>>> best to create a generally design.
>>
>> Yes, we hope to create one generally design, so we need to consider
>> this situation: the power supply getting the charger type by accessing
>> PMIC registers. The registers which save the charger type are not
>> always belong to the USB PHY, may be just some registers on PMIC.
>
> If the power_supply can directly detect the type of charger, then it
> doesn't need any usb-charger-infrastructure to tell it.  It can handle
> current selection entirely internally.
> Surely the only interesting case for a framework to address is the one
> where the power_supply cannot directly detect the charger type.

But power supply also need one plugged or unplugged event to set
current from USB charger framework. Another hand, considering one
generic framework, since power supply support API (e.g.:
power_supply_get_property()) to get charger type for others, we should
integrate power supply into USB charger framework.

>
>>
>> Now in mainline kernel, there are 3 methods can get the charger type
>> which need to integrate with USB charger framework:
>> 1. power supply
>> 2. extcon (need to add as you suggested)
>> 3. others (by 'get_charger_type' callback of USB charger)
>
> There is no "get_charger_type" now in the mainline kernel.

We want to create one generic framework, thus we should consider some
users want to implement the function to get charger type by accessing
PMIC registers or else.

>
>>>>
>>>> Suppose the USB configuration requests 100mA, then we should set the
>>>> USB charger current is 100mA by __usb_charger_set_cur_limit_by_type()
>>>> funtion, then notify this to power driver.
>>>
>>> ahh I had missed something there.  It's a while since I looked
>>> closely at these patches.
>>>
>>> Only this usage of usb_charger_set_cur_limit_by_type() is really
>>> nonsensical.
>>>
>>> If the cable is detected as being DCP or CDP or ACA (or ACA/DOCK) then
>>> the number negotiated with the USB configuration is not relevant and
>>> should be ignored.  There is a guaranteed minimum which is at least the
>>> maximum that *can* be negotiated.
>>
>> Yes. If it is not relevant, we will no't set the current from USB
>> configuration. Just when your charger type is SDP and the USB
>> enumeration is done, we can get the USB configuration from host to set
>> current.
>
> But you do!
> The mA number from the USB configuration is passed to usb_gadget_vbus_draw.
> Your patch passes that to usb_charger_set_cur_limit_by_type()
> which calls __usb_charger_set_cur_limit_by_type() which will set the
> cur_limit for whichever type uchger->type currently is.
>
> So when it is not relevant, your code *does* set some current limit.

Suppose the charger type is DCP(it is not relevant to the mA number
from the USB configuration ), it will not do the USB enumeration, then
no USB configuration from host to set current.

-- 
Baolin.wang
Best Regards


[PATCH 1/2] rtc: Add some dummy static inline functions

2016-09-18 Thread Baolin Wang
The patch 2 in this patchset adding tracepoints for alarmtimers will build
failed on S390 platform, due to S390 defconfig did not define CONFIG_RTC_LIB
macro to define the rtc_ktime_to_tm() function which is used in this patch.
Thus we should add some ummy static inline functions in case CONFIG_RTC_LIB
is not defined.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 include/linux/rtc.h |   49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b693ada..521f752 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -16,13 +16,60 @@
 #include 
 #include 
 
+#ifdef CONFIG_RTC_LIB
 extern int rtc_month_days(unsigned int month, unsigned int year);
-extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int 
year);
+extern int rtc_year_days(unsigned int day, unsigned int month,
+unsigned int year);
 extern int rtc_valid_tm(struct rtc_time *tm);
 extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
 extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
 ktime_t rtc_tm_to_ktime(struct rtc_time tm);
 struct rtc_time rtc_ktime_to_tm(ktime_t kt);
+#else
+static inline int rtc_month_days(unsigned int month, unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_year_days(unsigned int day, unsigned int month,
+   unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_valid_tm(struct rtc_time *tm)
+{
+   return 0;
+}
+
+static inline time64_t rtc_tm_to_time64(struct rtc_time *tm)
+{
+   time64_t ret;
+
+   memset(, 0, sizeof(time64_t));
+   return ret;
+}
+
+static inline void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
+{
+}
+
+static inline ktime_t rtc_tm_to_ktime(struct rtc_time tm)
+{
+   ktime_t ret;
+
+   memset(, 0, sizeof(ktime_t));
+   return ret;
+}
+
+static inline struct rtc_time rtc_ktime_to_tm(ktime_t kt)
+{
+   struct rtc_time ret;
+
+   memset(, 0, sizeof(struct rtc_time));
+   return ret;
+}
+#endif
 
 /*
  * rtc_tm_sub - Return the difference in seconds.
-- 
1.7.9.5



[PATCH 2/2] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-18 Thread Baolin Wang
For system debugging, we sometimes want to know who sets one
alarm timer, the time of the timer, when the timer started and
fired and so on. Thus adding tracepoints can help us trace the
alarmtimer information.

For example, when we debug the system supend/resume, if the
system is always resumed by RTC alarm, we can find out which
process set the alarm timer to resume system by below trace log:

..
Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start:
process:Binder:2976_6
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
0:20:35

Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel:
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13254630600 time:
2012-1-2 0:11:0

Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start:
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13253780400 time:
2012-1-1 0:34:0

system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel:
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
0:20:35

system_server-2976  [003] d..2  1076.605608: alarmtimer_start:
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1
0:20:35

system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend:
alarmtimer type:ALARM_BOOTTIME
expires time: 2012-1-1 0:34:0
..

>From the trace log, we can find out the 'Binder:2976_7' process
set one alarm timer which resumes the system.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Acked-by: Steven Rostedt <rost...@goodmis.org>
---
 include/trace/events/alarmtimer.h |  137 +
 kernel/time/alarmtimer.c  |   23 ++-
 2 files changed, 157 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/alarmtimer.h

diff --git a/include/trace/events/alarmtimer.h 
b/include/trace/events/alarmtimer.h
new file mode 100644
index 000..a7eba5a
--- /dev/null
+++ b/include/trace/events/alarmtimer.h
@@ -0,0 +1,137 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM alarmtimer
+
+#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ALARMTIMER_H
+
+#include 
+#include 
+#include 
+
+TRACE_DEFINE_ENUM(ALARM_REALTIME);
+TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
+
+#define show_alarm_type(type)  __print_flags(type, " | ",  \
+   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
+   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
+
+DECLARE_EVENT_CLASS(alarm_setting,
+
+   TP_PROTO(struct rtc_time *rtc_time, int flag),
+
+   TP_ARGS(rtc_time, flag),
+
+   TP_STRUCT__entry(
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   ),
+
+   TP_fast_assign(
+   __entry->second = rtc_time->tm_sec;
+   __entry->minute = rtc_time->tm_min;
+   __entry->hour = rtc_time->tm_hour;
+   __entry->day = rtc_time->tm_mday;
+   __entry->mon = rtc_time->tm_mon;
+   __entry->year = rtc_time->tm_year;
+   __entry->alarm_type = flag;
+   ),
+
+   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
+ show_alarm_type((1 << __entry->alarm_type)),
+ __entry->year + 1900,
+ __entry->mon + 1,
+ __entry->day,
+ __entry->hour,
+ __entry->minute,
+ __entry->second
+   )
+);
+
+DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
+
+   TP_PROTO(struct rtc_time *time, int flag),
+
+   TP_ARGS(time, flag)
+);
+
+DECLARE_EVENT_CLASS(alarm_processing,
+
+   TP_PROTO(struct alarm *alarm, char *process_name),
+
+   TP_ARGS(alarm, process_name),
+
+   TP_STRUCT__entry(
+   __field(unsigned long long, expires)
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   __string(name, process_name)
+   ),
+
+   TP_fast_assign(
+   __entry->expires = alarm->node.expires.tv64;
+   __entry->alarm_type = alarm->type;
+   __assign_str(name, process_name);
+   __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec;
+   __entry->minute = rtc_ktime_to_tm(alarm->node.expires).tm_min;
+   __entry->hour = rtc_ktime

Re: [PATCH v2 1/2] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-09-17 Thread Baolin Wang
Hi Felipe,

Sorry for late reply due to my holiday.

On 9 September 2016 at 18:47, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> When system has stpped the gadget, we should avoid queuing any requests
>> which will cause tranfer failed. Thus adding some disconnect checking to
>> avoid this situation.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>
> do you mind if we discuss this for a little longer?

Sure.

>
>> ---
>> Changes since v1:
>>  - Split into 2 separate ptaches.
>>  - Choose complete mechanism instead of polling.
>> ---
>>  drivers/usb/dwc3/ep0.c|8 
>>  drivers/usb/dwc3/gadget.c |   12 +---
>>  2 files changed, 17 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>> index fe79d77..632e5a4 100644
>> --- a/drivers/usb/dwc3/ep0.c
>> +++ b/drivers/usb/dwc3/ep0.c
>> @@ -228,6 +228,14 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct 
>> usb_request *request,
>>   int ret;
>>
>>   spin_lock_irqsave(>lock, flags);
>> + if (!dwc->pullups_connected) {
>> + dwc3_trace(trace_dwc3_ep0,
>> + "queuing request %p to %s when gadget is disconnected",
>> + request, dep->name);
>> + ret = -ESHUTDOWN;
>> + goto out;
>> + }
>
> I have been thinking about this branch here. It's not a problem to queue
> a request with pullups disconnected. It's only a problem to issue
> START_TRANSFER without RUN_STOP bit set.
>
> So maybe this check should be done in dwc3_send_gadget_ep_cmd(). By
> doing that we also make sure to do the check in one place and one place
> only because all endpoints rely dwc3_send_gadget_ep_cmd().

OK, that makes sense to me.

>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 1783406..1a33308 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1040,6 +1040,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep 
>> *dep, struct dwc3_request *req)
>>   struct dwc3 *dwc = dep->dwc;
>>   int ret;
>>
>> + if (!dwc->pullups_connected) {
>> + dwc3_trace(trace_dwc3_gadget,
>> + "queuing request %p to %s when gadget is disconnected",
>> + >request, dep->endpoint.name);
>> + return -ESHUTDOWN;
>> + }
>> +
>>   if (!dep->endpoint.desc) {
>>   dwc3_trace(trace_dwc3_gadget,
>>   "trying to queue request %p to disabled %s",
>> @@ -1984,13 +1991,12 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
>> struct dwc3_ep *dep,
>>   if (ret)
>>   break;
>>   }
>> -
>
> trailing change.

Ah, sorry. Will remove it.

>
>>   /*
>>* Our endpoint might get disabled by another thread during
>>* dwc3_gadget_giveback(). If that happens, we're just gonna return 1
>>* early on so DWC3_EP_BUSY flag gets cleared
>>*/
>> - if (!dep->endpoint.desc)
>> + if (!dep->endpoint.desc || !dwc->pullups_connected)
>
> I'm still considering this as well. Sure, we kill pullups before the
> descriptor is set to NULL, but that shouldn't be a problem. What will
> happen is:
>
> usb_gadget_disconnect();
> udc->driver->disconnect();
>  for_each_ep() {
>   for_each_request() {
>usb_ep_dequeue();
>   }
>   usb_ep_disable();
>dep->endpoint.desc = NULL;
>  }
> udc->driver->unbind();
> usb_gadget_udc_stop();
>
> I don't see a problem here. Did you manage to trigger any failure when
> you didn't have this check? Care to show some logs? We might have a bug
> elsewhere which we don't want to mask by adding this check here.

If we did not add this 'pullups_connected' checking here, it maybe
will kick one transfer to cause a problem of TART_TRANSFER, but it
also can be removed if we check in dwc3_send_gadget_ep_cmd() as you
suggested. Thanks for your comments and I will send out the new patch.


-- 
Baolin.wang
Best Regards


Re: [PATCH v2 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-09-17 Thread Baolin Wang
Hi Felipe,

On 9 September 2016 at 19:03, Felipe Balbi <ba...@kernel.org> wrote:
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
>> index 057739d..22787b6 100644
>> --- a/drivers/usb/dwc3/core.c
>> +++ b/drivers/usb/dwc3/core.c
>> @@ -999,6 +999,7 @@ static int dwc3_probe(struct platform_device *pdev)
>>   goto err0;
>>
>>   spin_lock_init(>lock);
>> + init_completion(>ep0_completed);
>
> this should be done only when gadget is required; meaning that this
> should be moved to dwc3_gadget_init()

OK.

>
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index b2317e7..858e661 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>
> [...]
>
>> @@ -843,6 +844,7 @@ struct dwc3 {
>>   dma_addr_t  ep0_bounce_addr;
>>   dma_addr_t  scratch_addr;
>>   struct dwc3_request ep0_usb_req;
>> + struct completion   ep0_completed;
>
> when you call this "ep0_completed" it seems like you're defining a flag,
> but you're not :) How about "ep0_in_setup" instead? That conveys the
> idea that we're waiting for ep0 to reach setup phase.

Make sense and will change it.

>
>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>> index 632e5a4..baf932d 100644
>> --- a/drivers/usb/dwc3/ep0.c
>> +++ b/drivers/usb/dwc3/ep0.c
>> @@ -286,6 +286,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
>>
>>   dwc->ep0state = EP0_SETUP_PHASE;
>>   dwc3_ep0_out_start(dwc);
>> + complete(>ep0_completed);
>
> no, this is wrong. I see what you're trying to do here, but we don't
> want to duplicate this call to complete() right? One thing we can
> realize is that *always* after STATUS phase or after a STALL, we will go
> through dwc3_ep0_out_start(), this mean we can call complete() before
> starting the following SETUP phase.
>
> Single place to call complete() ;-)

Make sense to me and I will fix that in next version.

>
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 1a33308..c9026ce 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -1441,6 +1441,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
>> is_on, int suspend)
>>   if (pm_runtime_suspended(dwc->dev))
>>   return 0;
>>
>> + /*
>> +  * Per databook, when we want to stop the gadget, if a control transfer
>> +  * is still in process, complete it and get the core into setup phase.
>> +  */
>> + if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
>> + reinit_completion(>ep0_completed);
>
> this seems unnecessary to me. Also, why return here so the caller has to

We should re-init the completion due to it will complete control
transfer many times before we try to stop gadget.

> wait? You could just have called wait_for_completion() here straight
> away:
>
> if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
> /* should this be interruptible? */
> ret = wait_for_completion_timeout(>ep0_in_setup,
> msecs_to_jiffies(500));
> if (ret == 0) {
> dwc3_trace(trace_dwc3_gadget, "RUN/STOP timeout");
> return -ETIMEDOUT;
> }
> }
>
> There's also no need for that "try_again" trickery. We either can halt
> the controller within 500ms or we cannot.

But this is in atomic context and we can not issue
wait_for_completion_timeout() in atomic context, then we should just
return here.

-- 
Baolin.wang
Best Regards


[PATCH v3 1/2] usb: dwc3: gadget: Add disconnect checking when changing function dynamically

2016-09-19 Thread Baolin Wang
When system has stpped the gadget, we should avoid queuing any requests
which will cause tranfer failed. Thus adding some disconnect checking to
avoid this situation.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v2:
 - Move disconnect checking into dwc3_send_gadget_ep_cmd().
 - Rename completion name and issue complete() at one place.
 - Move completion initialization into dwc3_gadget_init().

Changes since v1:
 - Split into 2 separate ptaches.
 - Choose complete mechanism instead of polling.
---
 drivers/usb/dwc3/gadget.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 1783406..ca2ae5b 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -241,6 +241,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned 
cmd,
int susphy = false;
int ret = -EINVAL;
 
+   if (!dwc->pullups_connected)
+   return -ESHUTDOWN;
+
/*
 * Synopsys Databook 2.60a states, on section 6.3.2.5.[1-8], that if
 * we're issuing an endpoint command, we must check if
-- 
1.7.9.5



[PATCH v3 2/2] usb: dwc3: Wait for control tranfer completed when stopping gadget

2016-09-19 Thread Baolin Wang
When we change the USB function with configfs dynamically, we possibly met this
situation: one core is doing the control transfer, another core is trying to
unregister the USB gadget from userspace, we must wait for completing this
control tranfer, or it will hang the controller to set the DEVCTRLHLT flag.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/dwc3/core.h   |2 ++
 drivers/usb/dwc3/ep0.c|2 ++
 drivers/usb/dwc3/gadget.c |   23 +++
 3 files changed, 27 insertions(+)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index b2317e7..01a6fbd 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -745,6 +745,7 @@ struct dwc3_scratchpad_array {
  * @ep0_usb_req: dummy req used while handling STD USB requests
  * @ep0_bounce_addr: dma address of ep0_bounce
  * @scratch_addr: dma address of scratchbuf
+ * @ep0_in_setup: One control tranfer is completed and enter setup phase
  * @lock: for synchronizing
  * @dev: pointer to our struct device
  * @xhci: pointer to our xHCI child
@@ -843,6 +844,7 @@ struct dwc3 {
dma_addr_t  ep0_bounce_addr;
dma_addr_t  scratch_addr;
struct dwc3_request ep0_usb_req;
+   struct completion   ep0_in_setup;
 
/* device lock */
spinlock_t  lock;
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d77..06c167a 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -311,6 +311,8 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
DWC3_TRBCTL_CONTROL_SETUP, false);
WARN_ON(ret < 0);
+
+   complete(>ep0_in_setup);
 }
 
 static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ca2ae5b..3a30d51 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1437,6 +1437,15 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int 
is_on, int suspend)
if (pm_runtime_suspended(dwc->dev))
return 0;
 
+   /*
+* Per databook, when we want to stop the gadget, if a control transfer
+* is still in process, complete it and get the core into setup phase.
+*/
+   if (!is_on && dwc->ep0state != EP0_SETUP_PHASE) {
+   reinit_completion(>ep0_in_setup);
+   return -EBUSY;
+   }
+
reg = dwc3_readl(dwc->regs, DWC3_DCTL);
if (is_on) {
if (dwc->revision <= DWC3_REVISION_187A) {
@@ -1487,10 +1496,22 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int 
is_on)
 
is_on = !!is_on;
 
+try_again:
spin_lock_irqsave(>lock, flags);
ret = dwc3_gadget_run_stop(dwc, is_on, false);
spin_unlock_irqrestore(>lock, flags);
 
+   if (ret == -EBUSY) {
+   ret = wait_for_completion_timeout(>ep0_in_setup,
+ msecs_to_jiffies(500));
+   if (ret == 0) {
+   dev_err(dwc->dev, "timeout to stop gadget.\n");
+   return -ETIMEDOUT;
+   } else {
+   goto try_again;
+   }
+   }
+
return ret;
 }
 
@@ -2914,6 +2935,8 @@ int dwc3_gadget_init(struct dwc3 *dwc)
goto err4;
}
 
+   init_completion(>ep0_in_setup);
+
dwc->gadget.ops = _gadget_ops;
dwc->gadget.speed   = USB_SPEED_UNKNOWN;
dwc->gadget.sg_supported= true;
-- 
1.7.9.5



Re: [PATCH v2] usb: gadget: Add uevent to notify userspace

2016-09-22 Thread Baolin Wang
Hi,

On 22 September 2016 at 20:53, Felipe Balbi <ba...@kernel.org> wrote:
>
>
> Hi,
>
> Baolin Wang <baolin.w...@linaro.org> writes:
>>>>  static const struct usb_gadget_driver configfs_driver_template = {
>>>>   .bind   = configfs_composite_bind,
>>>>   .unbind = configfs_composite_unbind,
>>>>
>>>> +#ifdef CONFIG_USB_CONFIGFS_UEVENT
>>>> + .setup  = configfs_setup,
>>>> + .reset  = configfs_disconnect,
>>>> + .disconnect = configfs_disconnect,
>>>> +#else
>>>>   .setup  = composite_setup,
>>>>   .reset  = composite_disconnect,
>>>>   .disconnect = composite_disconnect,
>>>> +#endif
>
> nope, this is quite wrong.
>
>>>> @@ -1453,6 +1556,10 @@ static struct config_group *gadgets_make(
>>>>   gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL);
>>>>   gi->composite.name = gi->composite.gadget_driver.function;
>>>>
>>>> +#ifdef CONFIG_USB_CONFIGFS_UEVENT
>>>> + INIT_WORK(>work, configfs_work);
>>>> +#endif
>>>
>>> This is just way too ugly, please make it so there are no #ifdefs in the
>>> .c files.
>>>
>>> Or, as others said, why is this a build option at all, why would you not
>>> always want this enabled if you are relying on it all of the time?
>>
>> Sometimes userspace does not need the notification, it is not all the
>> time. Anyway I will remove the macro if you still insist on that.
>
> what's wrong with the sysfs we already have for this?

If Android system userspace can support udc-core's uevents like Badhri
said, I am fine with that.

-- 
Baolin.wang
Best Regards


[PATCH] usb: gadget: Add uevent to notify userspace

2016-09-22 Thread Baolin Wang
From: Badhri Jagan Sridharan <bad...@google.com>

Some USB managament on userspace (like Android system) rely on the uevents
generated by the composition driver to generate user notifications. Thus this
patch adds uevents to be generated whenever USB changes its state: connected,
disconnected, configured.

The original code was created by Badhri Jagan Sridharan, and I did some
optimization.

CC: Badhri Jagan Sridharan <bad...@google.com>
Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
 drivers/usb/gadget/Kconfig|8 +++
 drivers/usb/gadget/configfs.c |  107 +
 2 files changed, 115 insertions(+)

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 2ea3fc3..9f5d0c6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -223,6 +223,14 @@ config USB_CONFIGFS
  appropriate symbolic links.
  For more information see Documentation/usb/gadget_configfs.txt.
 
+config USB_CONFIGFS_UEVENT
+   boolean "Uevent notification of Gadget state"
+   depends on USB_CONFIGFS
+   help
+ Enable uevent notifications to userspace when the gadget
+ state changes. The gadget can be in any of the following
+ three states: "CONNECTED/DISCONNECTED/CONFIGURED"
+
 config USB_CONFIGFS_SERIAL
bool "Generic serial bulk in/out"
depends on USB_CONFIGFS
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 3984787..4c2bc27 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -60,6 +60,11 @@ struct gadget_info {
bool use_os_desc;
char b_vendor_code;
char qw_sign[OS_STRING_QW_SIGN_LEN];
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+   bool connected;
+   bool sw_connected;
+   struct work_struct work;
+#endif
 };
 
 static inline struct gadget_info *to_gadget_info(struct config_item *item)
@@ -1197,6 +1202,57 @@ int composite_dev_prepare(struct usb_composite_driver 
*composite,
 int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
  struct usb_ep *ep0);
 
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+static void configfs_work(struct work_struct *data)
+{
+   struct gadget_info *gi = container_of(data, struct gadget_info, work);
+   struct usb_composite_dev *cdev = >cdev;
+   char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
+   char *connected[2] = { "USB_STATE=CONNECTED", NULL };
+   char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
+   /* 0-connected 1-configured 2-disconnected */
+   bool status[3] = { false, false, false };
+   unsigned long flags;
+   bool uevent_sent = false;
+
+   spin_lock_irqsave(>lock, flags);
+   if (cdev->config && gi->connected)
+   status[1] = true;
+
+   if (gi->connected != gi->sw_connected) {
+   if (gi->connected)
+   status[0] = true;
+   else
+   status[2] = true;
+   gi->sw_connected = gi->connected;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (status[0]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, connected);
+   pr_info("%s: sent uevent %s\n", __func__, connected[0]);
+   uevent_sent = true;
+   }
+
+   if (status[1]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, configured);
+   pr_info("%s: sent uevent %s\n", __func__, configured[0]);
+   uevent_sent = true;
+   }
+
+   if (status[2]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, disconnected);
+   pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
+   uevent_sent = true;
+   }
+
+   if (!uevent_sent) {
+   pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
+   gi->connected, gi->sw_connected, cdev->config);
+   }
+}
+#endif
+
 static void purge_configs_funcs(struct gadget_info *gi)
 {
struct usb_configuration*c;
@@ -1386,13 +1442,60 @@ static void configfs_composite_unbind(struct usb_gadget 
*gadget)
set_gadget_data(gadget, NULL);
 }
 
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+static int configfs_setup(struct usb_gadget *gadget,
+ const struct usb_ctrlrequest *c)
+{
+   struct usb_composite_dev *cdev = get_gadget_data(gadget);
+   struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
+   int value = -EOPNOTSUPP;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   if (!gi->connected) {
+   gi->connected = 1;
+   schedule_work(>work);
+   }
+   spin_unlock_irqrestore(>lock, flag

Re: [PATCH v2] usb: gadget: Add uevent to notify userspace

2016-09-22 Thread Baolin Wang
On 22 September 2016 at 20:23, Greg KH <gre...@linuxfoundation.org> wrote:
> On Thu, Sep 22, 2016 at 07:43:59PM +0800, Baolin Wang wrote:
>> From: Badhri Jagan Sridharan <bad...@google.com>
>>
>> Some USB managament on userspace (like Android system) rely on the uevents
>> generated by the composition driver to generate user notifications. Thus this
>> patch adds uevents to be generated whenever USB changes its state: connected,
>> disconnected, configured.
>>
>> The original code was created by Badhri Jagan Sridharan, and I did some
>> optimization.
>>
>> Signed-off-by: Badhri Jagan Sridharan <bad...@google.com>
>
> You can't just add someone's signed-off-by to a patch, go read what the
> legal agreement you just made for someone else at a different company
> (hint, you might get a nasty-gram from a google lawyer...)

OK. I will talk with Badhri if I can upstream these.

>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> ---
>> Changes since v1:
>>  - Add Badhri's Signed-off-by.
>> ---
>>  drivers/usb/gadget/Kconfig|8 +++
>>  drivers/usb/gadget/configfs.c |  107 
>> +
>>  2 files changed, 115 insertions(+)
>>
>> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
>> index 2ea3fc3..9f5d0c6 100644
>> --- a/drivers/usb/gadget/Kconfig
>> +++ b/drivers/usb/gadget/Kconfig
>> @@ -223,6 +223,14 @@ config USB_CONFIGFS
>> appropriate symbolic links.
>> For more information see Documentation/usb/gadget_configfs.txt.
>>
>> +config USB_CONFIGFS_UEVENT
>> + boolean "Uevent notification of Gadget state"
>> + depends on USB_CONFIGFS
>
>
>
>> + help
>> +   Enable uevent notifications to userspace when the gadget
>> +   state changes. The gadget can be in any of the following
>> +   three states: "CONNECTED/DISCONNECTED/CONFIGURED"
>> +
>>  config USB_CONFIGFS_SERIAL
>>   bool "Generic serial bulk in/out"
>>   depends on USB_CONFIGFS
>> diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
>> index 3984787..4c2bc27 100644
>> --- a/drivers/usb/gadget/configfs.c
>> +++ b/drivers/usb/gadget/configfs.c
>> @@ -60,6 +60,11 @@ struct gadget_info {
>>   bool use_os_desc;
>>   char b_vendor_code;
>>   char qw_sign[OS_STRING_QW_SIGN_LEN];
>> +#ifdef CONFIG_USB_CONFIGFS_UEVENT
>> + bool connected;
>> + bool sw_connected;
>> + struct work_struct work;
>> +#endif
>>  };
>>
>>  static inline struct gadget_info *to_gadget_info(struct config_item *item)
>> @@ -1197,6 +1202,57 @@ int composite_dev_prepare(struct usb_composite_driver 
>> *composite,
>>  int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
>> struct usb_ep *ep0);
>>
>> +#ifdef CONFIG_USB_CONFIGFS_UEVENT
>> +static void configfs_work(struct work_struct *data)
>> +{
>> + struct gadget_info *gi = container_of(data, struct gadget_info, work);
>> + struct usb_composite_dev *cdev = >cdev;
>> + char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
>> + char *connected[2] = { "USB_STATE=CONNECTED", NULL };
>> + char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
>> + /* 0-connected 1-configured 2-disconnected */
>> + bool status[3] = { false, false, false };
>> + unsigned long flags;
>> + bool uevent_sent = false;
>> +
>> + spin_lock_irqsave(>lock, flags);
>> + if (cdev->config && gi->connected)
>> + status[1] = true;
>> +
>> + if (gi->connected != gi->sw_connected) {
>> + if (gi->connected)
>> + status[0] = true;
>> + else
>> + status[2] = true;
>> + gi->sw_connected = gi->connected;
>> + }
>> + spin_unlock_irqrestore(>lock, flags);
>> +
>> + if (status[0]) {
>> + kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, connected);
>> + pr_info("%s: sent uevent %s\n", __func__, connected[0]);
>
> You are kidding, right?
>
>> + uevent_sent = true;
>> + }
>> +
>> + if (status[1]) {
>> + kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, configured);
>> + pr_info("%s: sent uevent %s\n", __func__, configured[0])

Re: [PATCH] usb: gadget: Add uevent to notify userspace

2016-09-22 Thread Baolin Wang
On 22 September 2016 at 18:58, Mark Brown <broo...@kernel.org> wrote:
> On Thu, Sep 22, 2016 at 06:53:12PM +0800, Baolin Wang wrote:
>> From: Badhri Jagan Sridharan <bad...@google.com>
>>
>> Some USB managament on userspace (like Android system) rely on the uevents
>> generated by the composition driver to generate user notifications. Thus this
>> patch adds uevents to be generated whenever USB changes its state: connected,
>> disconnected, configured.
>>
>> The original code was created by Badhri Jagan Sridharan, and I did some
>> optimization.
>>
>> CC: Badhri Jagan Sridharan <bad...@google.com>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>
> If you're sending a patch someone else wrote you need their
> Signed-off-by - if they didn't provide one you need to talk to them
> about that and get it.

Ah, I missed that. I will add it if there are no objection from Badhr.i

>
>> +config USB_CONFIGFS_UEVENT
>> + boolean "Uevent notification of Gadget state"
>> + depends on USB_CONFIGFS
>> + help
>> +   Enable uevent notifications to userspace when the gadget
>> +   state changes. The gadget can be in any of the following
>> +   three states: "CONNECTED/DISCONNECTED/CONFIGURED"
>
> Why not just generate the events unconditionally?

If userspace doesn't need notification, then we can save some time to
do the enumeration without the uevent things.

-- 
Baolin.wang
Best Regards


[PATCH v2] usb: gadget: Add uevent to notify userspace

2016-09-22 Thread Baolin Wang
From: Badhri Jagan Sridharan <bad...@google.com>

Some USB managament on userspace (like Android system) rely on the uevents
generated by the composition driver to generate user notifications. Thus this
patch adds uevents to be generated whenever USB changes its state: connected,
disconnected, configured.

The original code was created by Badhri Jagan Sridharan, and I did some
optimization.

Signed-off-by: Badhri Jagan Sridharan <bad...@google.com>
Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
---
Changes since v1:
 - Add Badhri's Signed-off-by.
---
 drivers/usb/gadget/Kconfig|8 +++
 drivers/usb/gadget/configfs.c |  107 +
 2 files changed, 115 insertions(+)

diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 2ea3fc3..9f5d0c6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -223,6 +223,14 @@ config USB_CONFIGFS
  appropriate symbolic links.
  For more information see Documentation/usb/gadget_configfs.txt.
 
+config USB_CONFIGFS_UEVENT
+   boolean "Uevent notification of Gadget state"
+   depends on USB_CONFIGFS
+   help
+ Enable uevent notifications to userspace when the gadget
+ state changes. The gadget can be in any of the following
+ three states: "CONNECTED/DISCONNECTED/CONFIGURED"
+
 config USB_CONFIGFS_SERIAL
bool "Generic serial bulk in/out"
depends on USB_CONFIGFS
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 3984787..4c2bc27 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -60,6 +60,11 @@ struct gadget_info {
bool use_os_desc;
char b_vendor_code;
char qw_sign[OS_STRING_QW_SIGN_LEN];
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+   bool connected;
+   bool sw_connected;
+   struct work_struct work;
+#endif
 };
 
 static inline struct gadget_info *to_gadget_info(struct config_item *item)
@@ -1197,6 +1202,57 @@ int composite_dev_prepare(struct usb_composite_driver 
*composite,
 int composite_os_desc_req_prepare(struct usb_composite_dev *cdev,
  struct usb_ep *ep0);
 
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+static void configfs_work(struct work_struct *data)
+{
+   struct gadget_info *gi = container_of(data, struct gadget_info, work);
+   struct usb_composite_dev *cdev = >cdev;
+   char *disconnected[2] = { "USB_STATE=DISCONNECTED", NULL };
+   char *connected[2] = { "USB_STATE=CONNECTED", NULL };
+   char *configured[2] = { "USB_STATE=CONFIGURED", NULL };
+   /* 0-connected 1-configured 2-disconnected */
+   bool status[3] = { false, false, false };
+   unsigned long flags;
+   bool uevent_sent = false;
+
+   spin_lock_irqsave(>lock, flags);
+   if (cdev->config && gi->connected)
+   status[1] = true;
+
+   if (gi->connected != gi->sw_connected) {
+   if (gi->connected)
+   status[0] = true;
+   else
+   status[2] = true;
+   gi->sw_connected = gi->connected;
+   }
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (status[0]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, connected);
+   pr_info("%s: sent uevent %s\n", __func__, connected[0]);
+   uevent_sent = true;
+   }
+
+   if (status[1]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, configured);
+   pr_info("%s: sent uevent %s\n", __func__, configured[0]);
+   uevent_sent = true;
+   }
+
+   if (status[2]) {
+   kobject_uevent_env(>dev->kobj, KOBJ_CHANGE, disconnected);
+   pr_info("%s: sent uevent %s\n", __func__, disconnected[0]);
+   uevent_sent = true;
+   }
+
+   if (!uevent_sent) {
+   pr_info("%s: did not send uevent (%d %d %p)\n", __func__,
+   gi->connected, gi->sw_connected, cdev->config);
+   }
+}
+#endif
+
 static void purge_configs_funcs(struct gadget_info *gi)
 {
struct usb_configuration*c;
@@ -1386,13 +1442,60 @@ static void configfs_composite_unbind(struct usb_gadget 
*gadget)
set_gadget_data(gadget, NULL);
 }
 
+#ifdef CONFIG_USB_CONFIGFS_UEVENT
+static int configfs_setup(struct usb_gadget *gadget,
+ const struct usb_ctrlrequest *c)
+{
+   struct usb_composite_dev *cdev = get_gadget_data(gadget);
+   struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev);
+   int value = -EOPNOTSUPP;
+   unsigned long flags;
+
+   spin_lock_irqsave(>lock, flags);
+   if (!gi->connected) {
+   gi->connected = 1;
+ 

Re: [PATCH 1/2] rtc: Add some dummy static inline functions

2016-09-20 Thread Baolin Wang
Hi,

On 21 September 2016 at 05:36, Thomas Gleixner <t...@linutronix.de> wrote:
> On Sun, 18 Sep 2016, Baolin Wang wrote:
>
>> The patch 2 in this patchset adding tracepoints for alarmtimers will build
>> failed on S390 platform, due to S390 defconfig did not define CONFIG_RTC_LIB
>> macro to define the rtc_ktime_to_tm() function which is used in this patch.
>> Thus we should add some ummy static inline functions in case CONFIG_RTC_LIB
>> is not defined.
>
> I told you before that adding these inlines has the danger that we
> introduce code which uses these functions in places which does not depend
> on RTC_LIB. The resulting wreckage is going to be subtle and hard to debug.

Make sense. (By the way I am sorry I did not receive your previous
comments in my mailbox and I checked again I found it was treated as
spam.)

>
> This still stands and this patch is going nowhere.
>
> Thanks,
>
> tglx



-- 
Baolin.wang
Best Regards


Re: [PATCH 2/2] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-20 Thread Baolin Wang
On 21 September 2016 at 06:27, Thomas Gleixner <t...@linutronix.de> wrote:
> On Sun, 18 Sep 2016, Baolin Wang wrote:
>> +DECLARE_EVENT_CLASS(alarm_setting,
>
> What is alarm_setting? Without looking at the DEFINE_EVENT which uses this
> I cannot decode the meaning.

Will rename it.

>
>> + TP_STRUCT__entry(
>> + __field(unsigned char, second)
>> + __field(unsigned char, minute)
>> + __field(unsigned char, hour)
>> + __field(unsigned char, day)
>> + __field(unsigned char, mon)
>> + __field(unsigned short, year)
>> + __field(unsigned char, alarm_type)
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->second = rtc_time->tm_sec;
>> + __entry->minute = rtc_time->tm_min;
>> + __entry->hour = rtc_time->tm_hour;
>> + __entry->day = rtc_time->tm_mday;
>> + __entry->mon = rtc_time->tm_mon;
>> + __entry->year = rtc_time->tm_year;
>> + __entry->alarm_type = flag;
>
> What's the value of storing the alarm time in RTC format?

As suggested by Steven, change the type of RTC value to save trace buffer.

>
> What's wrong with simply storing the flat u64 based wall clock time?
> Nothing, because you can do the RTC format conversion in user space.
>
>> +DECLARE_EVENT_CLASS(alarm_processing,
>
> Again alarm_processing is not telling me anything.

Is alarm_class OK?

>
>> +
>> + TP_PROTO(struct alarm *alarm, char *process_name),
>
> Why do you want to store process_name? The tracer already tracks the name
> of the process in which context the tracepoint is taken. So what's the
> point of this? Look at the output:
>
> system_server-2976  [003] d..2  1076.605608: alarmtimer_start: 
> process:system_server
>
> Completely pointless duplicated information.

OK. Will remove it.

>
>> +
>> + TP_ARGS(alarm, process_name),
>> +
>> + TP_STRUCT__entry(
>> + __field(unsigned long long, expires)
>> + __field(unsigned char, second)
>> + __field(unsigned char, minute)
>> + __field(unsigned char, hour)
>> + __field(unsigned char, day)
>> + __field(unsigned char, mon)
>> + __field(unsigned short, year)
>> + __field(unsigned char, alarm_type)
>> + __string(name, process_name)
>> + ),
>> +
>> + TP_fast_assign(
>> + __entry->expires = alarm->node.expires.tv64;
>> + __entry->alarm_type = alarm->type;
>> + __assign_str(name, process_name);
>> + __entry->second = rtc_ktime_to_tm(alarm->node.expires).tm_sec;
>> + __entry->minute = rtc_ktime_to_tm(alarm->node.expires).tm_min;
>> + __entry->hour = rtc_ktime_to_tm(alarm->node.expires).tm_hour;
>> + __entry->day = rtc_ktime_to_tm(alarm->node.expires).tm_mday;
>> + __entry->mon = rtc_ktime_to_tm(alarm->node.expires).tm_mon;
>> + __entry->year = rtc_ktime_to_tm(alarm->node.expires).tm_year;
>
> This is utter crap for various reasons:
>
> 1) You store the expiry time over and over and in most cases it's simply
>pointless.

I will remove the 'expires' variable.

>
>- If the timer is started then we want to store the expiry time.
>
>- If the timer fires then the programmed expiry time is available from
>  the start trace point and you miss to store the information which is
>  really interesting: The actual time at which the timer expires
>  (REAL/BOOT)
>
>- If the timer is canceled then the expiry time in the timer is not
>  interesting at all. All you care is about the fact that the timer has
>  been canceled. The expiry time can still be retrieved from the start
>  trace point.
>
>- The restart tracepoint is redundant as well because either you see:
>
>  start -> expire -> start or start -> start which is clearly a restart.
>
>  If you put the start trace point into alarmtimer_enqueue() then you
>  spare the extra code size for two tracepoints because that is used in
>  start and restart

Make sense.

>
>See the hrtimer and timer tracepoints for reference.
>
>
> 2) You store the expiry time again in RTC format. Store the information in
>a plain u64 and be done with it.

But I still think the RTC format is more readable for debugging alarm timer.

>
>
>> +DEFINE_EVENT(alarm_processi

Re: [PATCH v4] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-07 Thread Baolin Wang
Hi John,

On 7 September 2016 at 14:17, John Stultz <john.stu...@linaro.org> wrote:
> On Tue, Sep 6, 2016 at 11:06 PM, Baolin Wang <baolin.w...@linaro.org> wrote:
>> For system debugging, we sometimes want to know who sets one
>> alarm timer, the time of the timer, when the timer started and
>> fired and so on. Thus adding tracepoints can help us trace the
>> alarmtimer information.
>>
>> For example, when we debug the system supend/resume, if the
>> system is always resumed by RTC alarm, we can find out which
>> process set the alarm timer to resume system by below trace log:
>>
>> ..
>> Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start:
>> process:Binder:2976_6
>> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
>> 0:20:35
>>
>> Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel:
>> process:Binder:2976_7
>> alarmtimer type:ALARM_BOOTTIME expires:13254630600 time:
>> 2012-1-2 0:11:0
>>
>> Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start:
>> process:Binder:2976_7
>> alarmtimer type:ALARM_BOOTTIME expires:13253780400 time:
>> 2012-1-1 0:34:0
>>
>> system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel:
>> process:system_server
>> alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
>> 0:20:35
>>
>> system_server-2976  [003] d..2  1076.605608: alarmtimer_start:
>> process:system_server
>> alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1
>> 0:20:35
>>
>> system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend:
>> alarmtimer type:ALARM_BOOTTIME
>> expires time: 2012-1-1 0:34:0
>> ..
>>
>> From the trace log, we can find out the 'Binder:2976_7' process
>> set one alarm timer which resumes the system.
>>
>> Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
>> Acked-by: Steven Rostedt <rost...@goodmis.org>
>> ---
>> Changes since v3:
>>  - Fix the build error on S390.
>
> Since the original change is already applied to tip/timers/core, can
> you provide an incremental patch (a patch against tip/timers/core)
> that fixes the issue, rather then resending the entire patch?

OK.

>
> Also, the "#ifdef CONFIG_RTC_LIB" solution I proposed was sort of a
> hack, so I'd hope to see something better.
>
> One better solution would be to add a dummy static inline
> implementation of rtc_ktime_to_tm() in include/linux/rtc.h.
>
> ie something like:
> #ifdef CONFIG_RTC_LIB
> struct rtc_time rtc_ktime_to_tm(ktime_t kt);
> #else
> static inline rtc_time rtc_ktime_to_tm(ktime_t kt)
> {
> struct rt_time ret;
> memset(, 0,  sizeof(struct rt_time));
> return ret;
> }
> #endif

Make sense. Thanks.

>
> thanks
> -john
>
> thanks
> -john



-- 
Baolin.wang
Best Regards


[PATCH v4] time: alarmtimer: Add the trcepoints for alarmtimer

2016-09-07 Thread Baolin Wang
For system debugging, we sometimes want to know who sets one
alarm timer, the time of the timer, when the timer started and
fired and so on. Thus adding tracepoints can help us trace the
alarmtimer information.

For example, when we debug the system supend/resume, if the
system is always resumed by RTC alarm, we can find out which
process set the alarm timer to resume system by below trace log:

..
Binder:2976_6-3473  [005] d..2  1076.587732: alarmtimer_start:
process:Binder:2976_6
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
0:20:35

Binder:2976_7-3480  [002] d..2  1076.592707: alarmtimer_cancel:
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13254630600 time:
2012-1-2 0:11:0

Binder:2976_7-3480  [002] d..2  1076.592731: alarmtimer_start:
process:Binder:2976_7
alarmtimer type:ALARM_BOOTTIME expires:13253780400 time:
2012-1-1 0:34:0

system_server-2976  [003] d..2  1076.605587: alarmtimer_cancel:
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415400 time: 1970-1-1
0:20:35

system_server-2976  [003] d..2  1076.605608: alarmtimer_start:
process:system_server
alarmtimer type:ALARM_BOOTTIME expires:123415500 time: 1970-1-1
0:20:35

system_server-3000  [002] ...1  1087.737565: alarmtimer_suspend:
alarmtimer type:ALARM_BOOTTIME
expires time: 2012-1-1 0:34:0
..

>From the trace log, we can find out the 'Binder:2976_7' process
set one alarm timer which resumes the system.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Acked-by: Steven Rostedt <rost...@goodmis.org>
---
Changes since v3:
 - Fix the build error on S390.

Changes since v2:
 - Add TRACE_DEFINE_ENUM() macros.
 - Change the time variables type to save space in the ring buffer.
 - Add trace_alarmtimer_suspend_enabled() in case of tracing is not enabled.

Changes since v1:
 - Fix the kbuild error.
 - Modify the changelog with adding trace log.
---
 include/trace/events/alarmtimer.h |  146 +
 kernel/time/alarmtimer.c  |   23 +-
 2 files changed, 166 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/alarmtimer.h

diff --git a/include/trace/events/alarmtimer.h 
b/include/trace/events/alarmtimer.h
new file mode 100644
index 000..7ab9a36
--- /dev/null
+++ b/include/trace/events/alarmtimer.h
@@ -0,0 +1,146 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM alarmtimer
+
+#if !defined(_TRACE_ALARMTIMER_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_ALARMTIMER_H
+
+#include 
+#include 
+#include 
+
+TRACE_DEFINE_ENUM(ALARM_REALTIME);
+TRACE_DEFINE_ENUM(ALARM_BOOTTIME);
+
+#define show_alarm_type(type)  __print_flags(type, " | ",  \
+   { 1 << ALARM_REALTIME, "ALARM_REALTIME" },  \
+   { 1 << ALARM_BOOTTIME, "ALARM_BOOTTIME" })
+
+DECLARE_EVENT_CLASS(alarm_setting,
+
+   TP_PROTO(struct rtc_time *rtc_time, int flag),
+
+   TP_ARGS(rtc_time, flag),
+
+   TP_STRUCT__entry(
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   ),
+
+   TP_fast_assign(
+   __entry->second = rtc_time->tm_sec;
+   __entry->minute = rtc_time->tm_min;
+   __entry->hour = rtc_time->tm_hour;
+   __entry->day = rtc_time->tm_mday;
+   __entry->mon = rtc_time->tm_mon;
+   __entry->year = rtc_time->tm_year;
+   __entry->alarm_type = flag;
+   ),
+
+   TP_printk("alarmtimer type:%s expires time: %hu-%u-%u %u:%u:%u",
+ show_alarm_type((1 << __entry->alarm_type)),
+ __entry->year + 1900,
+ __entry->mon + 1,
+ __entry->day,
+ __entry->hour,
+ __entry->minute,
+ __entry->second
+   )
+);
+
+DEFINE_EVENT(alarm_setting, alarmtimer_suspend,
+
+   TP_PROTO(struct rtc_time *time, int flag),
+
+   TP_ARGS(time, flag)
+);
+
+DECLARE_EVENT_CLASS(alarm_processing,
+
+   TP_PROTO(struct alarm *alarm, char *process_name),
+
+   TP_ARGS(alarm, process_name),
+
+   TP_STRUCT__entry(
+   __field(unsigned long long, expires)
+   __field(unsigned char, second)
+   __field(unsigned char, minute)
+   __field(unsigned char, hour)
+   __field(unsigned char, day)
+   __field(unsigned char, mon)
+   __field(unsigned short, year)
+   __field(unsigned char, alarm_type)
+   __string(name, process_name)
+   ),
+
+   TP_fast_assign(
+   __entry->expires 

[PATCH] rtc: Add some dummy static inline functions

2016-09-07 Thread Baolin Wang
Add some dummy static inline functions in case CONFIG_RTC_LIB is not defined.

Signed-off-by: Baolin Wang <baolin.w...@linaro.org>
Fixes: a0a6e06d545a ("time: alarmtimer: Add tracepoints for alarmtimers")
---
 include/linux/rtc.h |   49 -
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index b693ada..521f752 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -16,13 +16,60 @@
 #include 
 #include 
 
+#ifdef CONFIG_RTC_LIB
 extern int rtc_month_days(unsigned int month, unsigned int year);
-extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int 
year);
+extern int rtc_year_days(unsigned int day, unsigned int month,
+unsigned int year);
 extern int rtc_valid_tm(struct rtc_time *tm);
 extern time64_t rtc_tm_to_time64(struct rtc_time *tm);
 extern void rtc_time64_to_tm(time64_t time, struct rtc_time *tm);
 ktime_t rtc_tm_to_ktime(struct rtc_time tm);
 struct rtc_time rtc_ktime_to_tm(ktime_t kt);
+#else
+static inline int rtc_month_days(unsigned int month, unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_year_days(unsigned int day, unsigned int month,
+   unsigned int year)
+{
+   return 0;
+}
+
+static inline int rtc_valid_tm(struct rtc_time *tm)
+{
+   return 0;
+}
+
+static inline time64_t rtc_tm_to_time64(struct rtc_time *tm)
+{
+   time64_t ret;
+
+   memset(, 0, sizeof(time64_t));
+   return ret;
+}
+
+static inline void rtc_time64_to_tm(time64_t time, struct rtc_time *tm)
+{
+}
+
+static inline ktime_t rtc_tm_to_ktime(struct rtc_time tm)
+{
+   ktime_t ret;
+
+   memset(, 0, sizeof(ktime_t));
+   return ret;
+}
+
+static inline struct rtc_time rtc_ktime_to_tm(ktime_t kt)
+{
+   struct rtc_time ret;
+
+   memset(, 0, sizeof(struct rtc_time));
+   return ret;
+}
+#endif
 
 /*
  * rtc_tm_sub - Return the difference in seconds.
-- 
1.7.9.5



<    1   2   3   4   5   6   7   8   9   10   >