Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751169AbbHGIdv (ORCPT ); Fri, 7 Aug 2015 04:33:51 -0400 Received: from mail-yk0-f176.google.com ([209.85.160.176]:35790 "EHLO mail-yk0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750884AbbHGIdr (ORCPT ); Fri, 7 Aug 2015 04:33:47 -0400 MIME-Version: 1.0 In-Reply-To: <20150807054157.GD13200@shlinux2> References: <2ba023cbaa1dd96fd5e31e2f01cc0a599a3a5e55.1438844454.git.baolin.wang@linaro.org> <20150807054157.GD13200@shlinux2> Date: Fri, 7 Aug 2015 16:33:46 +0800 Message-ID: Subject: Re: [PATCH 1/2] gadget: Introduce the usb charger framework From: Baolin Wang To: Peter Chen Cc: Felipe Balbi , Mark Brown , LKML , Greg KH , sojka@merica.cz, Alan Stern , andreas@gaisler.com, linux-usb@vger.kernel.org, device-mainlining@lists.linuxfoundation.org Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 24649 Lines: 729 On 7 August 2015 at 13:41, Peter Chen wrote: > On Thu, Aug 06, 2015 at 03:03:48PM +0800, Baolin Wang wrote: >> 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. >> >> 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. >> >> Signed-off-by: Baolin Wang >> --- >> drivers/usb/gadget/charger.c | 547 +++++++++++++++++++++++++++++++++++++++ >> include/linux/usb/usb_charger.h | 101 ++++++++ >> 2 files changed, 648 insertions(+) >> create mode 100644 drivers/usb/gadget/charger.c >> create mode 100644 include/linux/usb/usb_charger.h >> >> diff --git a/drivers/usb/gadget/charger.c b/drivers/usb/gadget/charger.c >> new file mode 100644 >> index 0000000..3ca0180 >> --- /dev/null >> +++ b/drivers/usb/gadget/charger.c >> @@ -0,0 +1,547 @@ >> +/* >> + * usb charger.c -- USB charger driver >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License as published by >> + * the Free Software Foundation; either version 2 of the License, or >> + * (at your option) any later version. >> + */ >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#define DEFAULT_CUR_PROTECT (50) >> +#define DEFAULT_SDP_CUR_LIMIT (500 - DEFAULT_CUR_PROTECT) >> +#define DEFAULT_DCP_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) >> +#define DEFAULT_CDP_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) >> +#define DEFAULT_ACA_CUR_LIMIT (1500 - DEFAULT_CUR_PROTECT) >> + >> +static LIST_HEAD(usb_charger_list); >> +static DEFINE_MUTEX(usb_charger_list_lock); >> + >> +/* >> + * usb_charger_find_by_name - Get the usb charger device by name. >> + * @name - usb charger device name. >> + * >> + * notes: when this function walks the list and returns a charger >> + * it's dropped the lock which means that something else could come >> + * along and delete the charger before we dereference the pointer. >> + * It's very unlikely but it's a possibility so you should take care >> + * of it. >> + * Thus when you get the usb charger by name, you should call >> + * put_usb_charger() to derease the reference count of the usb charger. >> + * >> + * return the instance of usb charger device. >> + */ >> +struct usb_charger *usb_charger_find_by_name(char *name) >> +{ >> + struct usb_charger *uchger; >> + >> + if (!name) >> + return ERR_PTR(-EINVAL); >> + >> + mutex_lock(&usb_charger_list_lock); >> + list_for_each_entry(uchger, &usb_charger_list, entry) { >> + if (!strcmp(uchger->name, name)) { >> + get_usb_charger(uchger); >> + mutex_unlock(&usb_charger_list_lock); >> + return uchger; >> + } >> + } >> + mutex_unlock(&usb_charger_list_lock); >> + >> + return NULL; >> +} >> + >> +/* >> + * usb_charger_register_notify() - Register a notifiee to get notified by >> + * any attach status changes from the usb charger type detection. >> + * @uchger - the usb charger device which is monitored. >> + * @nb - a notifier block to be registered. >> + */ >> +void usb_charger_register_notify(struct usb_charger *uchger, >> + struct notifier_block *nb) >> +{ >> + unsigned long flags; >> + >> + spin_lock_irqsave(&uchger->lock, flags); >> + raw_notifier_chain_register(&uchger->uchger_nh, nb); >> + spin_unlock_irqrestore(&uchger->lock, flags); >> +} >> + >> +/* >> + * usb_charger_unregister_notify() - Unregister a notifiee from the usb charger. >> + * @uchger - the usb charger device which is monitored. >> + * @nb - a notifier block to be unregistered. >> + */ >> +void usb_charger_unregister_notify(struct usb_charger *uchger, >> + struct notifier_block *nb) >> +{ >> + unsigned long flags; >> + >> + spin_lock_irqsave(&uchger->lock, flags); >> + raw_notifier_chain_unregister(&uchger->uchger_nh, nb); >> + spin_unlock_irqrestore(&uchger->lock, flags); >> +} >> + >> +/* >> + * usb_charger_register_extcon_notifier() - Register a notifiee of the usb >> + * charger to get notified by any attach status changes from >> + * the extcon device. >> + * @uchger - the usb charger device. >> + * @edev - the extcon device. >> + * @extcon_id - extcon id. >> + */ >> +int usb_charger_register_extcon_notifier(struct usb_charger *uchger, >> + struct extcon_dev *edev, >> + unsigned int extcon_id) >> +{ >> + if (!uchger || !edev) >> + return -EINVAL; >> + >> + return extcon_register_notifier(edev, extcon_id, &uchger->extcon_nb.nb); >> +} >> + >> +/* >> + * usb_charger_unregister_extcon_notifier() - Unregister a notifiee of the >> + * usb charger from the extcon device. >> + * @uchger - the usb charger device. >> + * @edev - the extcon device. >> + * @extcon_id - extcon id. >> + */ >> +int usb_charger_unregister_extcon_notifier(struct usb_charger *uchger, >> + struct extcon_dev *edev, >> + unsigned int extcon_id) >> +{ >> + if (!uchger || !edev) >> + return -EINVAL; >> + >> + return extcon_unregister_notifier(edev, extcon_id, &uchger->extcon_nb.nb); >> +} >> + >> +/* >> + * usb_charger_register_gadget_notifier() - Register a notifiee of the usb >> + * charger to get notified by any attach status changes from >> + * the usb gadget device. >> + * @uchger - the usb charger device. >> + */ >> +int usb_charger_register_gadget_notifier(struct usb_charger *uchger) >> +{ >> + struct usb_gadget *ugadget = uchger->gadget; >> + >> + return usb_gadget_register_notify(ugadget, &uchger->gadget_nb); >> +} > > usb_gadget_register_notify is defined at your 2nd patch, it will > cause 'git bisect' problem. > Oh, I miss that and will fix that. >> + >> +/* >> + * usb_charger_unregister_gadget_notifier() - Unregister a notifiee of the usb >> + * charger from the usb gadget device. >> + * @uchger - the usb charger device. >> + */ >> +int usb_charger_unregister_gadget_notifier(struct usb_charger *uchger) >> +{ >> + struct usb_gadget *ugadget = uchger->gadget; >> + >> + return usb_gadget_unregister_notify(ugadget, &uchger->gadget_nb); >> +} >> + >> +/* >> + * usb_charger_set_cur_limit() - Set the current limitation. >> + * @uchger - the usb charger device. >> + * @xxx_cur - the current limit by different charger type. >> + * >> + */ >> +int usb_charger_set_cur_limit(struct usb_charger *uchger, >> + struct usb_charger_cur_limit *cur_limit_set) >> +{ >> + if (!uchger || !cur_limit_set) >> + return -EINVAL; >> + >> + uchger->cur_limit.sdp_cur_limit = cur_limit_set->sdp_cur_limit; >> + uchger->cur_limit.dcp_cur_limit = cur_limit_set->dcp_cur_limit; >> + uchger->cur_limit.cdp_cur_limit = cur_limit_set->cdp_cur_limit; >> + uchger->cur_limit.aca_cur_limit = cur_limit_set->aca_cur_limit; >> + return 0; >> +} >> + >> +/* >> + * usb_charger_get_cur_limit() - Get the current limitation by different usb >> + * charger type. >> + * @uchger - the usb charger device. >> + * @type - the usb charger type. >> + * >> + * return the current limitation to set. >> + */ >> +static unsigned int >> +usb_charger_get_cur_limit(struct usb_charger *uchger) >> +{ >> + enum usb_charger_type uchger_type = uchger->type; >> + unsigned int cur_limit; >> + >> + switch (uchger_type) { >> + case SDP_TYPE: >> + cur_limit = uchger->cur_limit.sdp_cur_limit; >> + break; >> + case DCP_TYPE: >> + cur_limit = uchger->cur_limit.dcp_cur_limit; >> + break; >> + case CDP_TYPE: >> + cur_limit = uchger->cur_limit.cdp_cur_limit; >> + break; >> + case ACA_TYPE: >> + cur_limit = uchger->cur_limit.aca_cur_limit; >> + break; >> + default: >> + return 0; >> + } >> + >> + return cur_limit; >> +} >> + >> +/* >> + * usb_charger_detect_type() - Get the usb charger type by the callback which is >> + * implemented by user. >> + * @uchger - the usb charger device. >> + * >> + * return the usb charger type. >> + */ >> +enum usb_charger_type >> +usb_charger_detect_type(struct usb_charger *uchger) >> +{ >> + if (uchger->gadget && uchger->gadget->ops >> + && uchger->gadget->ops->get_charger_type) >> + uchger->type = >> + uchger->gadget->ops->get_charger_type(uchger->gadget); >> + else >> + uchger->type = UNKNOWN_TYPE; >> + >> + return uchger->type; >> +} >> + >> +/* >> + * usb_charger_notifier_others() - It will notify other device registered on >> + * usb charger. >> + * @uchger - the usb charger device. >> + * >> + */ >> +static void >> +usb_charger_notify_others(struct usb_charger *uchger, >> + enum usb_charger_state state) >> +{ >> + unsigned long flags; >> + >> + spin_lock_irqsave(&uchger->lock, flags); > > it is better to use mutex_lock instead of disabling interrupt since > checking charger type may cause sleeping. > Yes, I'll think about the lock again. >> + uchger->state = state; >> + >> + switch (state) { >> + case USB_CHARGER_PRESENT: >> + usb_charger_detect_type(uchger); >> + raw_notifier_call_chain(&uchger->uchger_nh, >> + usb_charger_get_cur_limit(uchger), >> + uchger); >> + break; >> + case USB_CHARGER_REMOVE: >> + uchger->type = UNKNOWN_TYPE; >> + raw_notifier_call_chain(&uchger->uchger_nh, 0, uchger); >> + break; >> + default: >> + dev_warn(&uchger->dev, "Unknown USB charger state: %d\n", >> + state); >> + break; >> + } >> + spin_unlock_irqrestore(&uchger->lock, flags); >> +} >> + >> +/* >> + * usb_charger_plug_by_extcon() - The notifier call function which is registered >> + * on the extcon device. >> + * @nb - thr notifier block that notified by extcon device. >> + * @state - the extcon device state changed. >> + * @data - here specify a extcon device. >> + * >> + * return the notify flag. >> + */ >> +static int >> +usb_charger_plug_by_extcon(struct notifier_block *nb, >> + unsigned long state, void *data) >> +{ >> + struct usb_charger_nb *extcon_nb = >> + container_of(nb, struct usb_charger_nb, nb); >> + struct usb_charger *uchger = extcon_nb->uchger; >> + enum usb_charger_state uchger_state; >> + >> + if (!uchger) >> + return NOTIFY_BAD; >> + >> + /* Report event to power to setting the current limitation >> + * for this usb charger when one usb charger is added or removed >> + * with detecting by extcon device. >> + */ >> + if (state) >> + uchger_state = USB_CHARGER_PRESENT; >> + else >> + uchger_state = USB_CHARGER_REMOVE; >> + >> + usb_charger_notify_others(uchger, uchger_state); >> + >> + return NOTIFY_OK; >> +} >> + >> +/* >> + * usb_charger_plug_by_gadget() - Set the usb charger current limitation >> + * according to the usb gadget device state. >> + * @data - here specify a usb charger device. >> + * >> + */ >> +static int >> +usb_charger_plug_by_gadget(struct notifier_block *nb, >> + unsigned long state, void *data) >> +{ >> + struct usb_gadget *gadget = (struct usb_gadget *)data; >> + struct usb_charger *uchger = gadget->uchger; >> + enum usb_charger_state uchger_state; >> + >> + if (!uchger) >> + return NOTIFY_BAD; >> + >> + /* 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 NOTIFY_OK; >> +} >> + >> +static int devm_uchger_dev_match(struct device *dev, void *res, void *data) >> +{ >> + struct usb_charger **r = res; >> + >> + if (WARN_ON(!r || !*r)) >> + return 0; >> + >> + return *r == data; >> +} >> + >> +static void usb_charger_release(struct device *dev) >> +{ >> + struct usb_charger *uchger = dev_get_drvdata(dev); >> + >> + if (!atomic_dec_and_test(&uchger->count)) { >> + dev_err(dev, "The usb charger is still in use\n"); >> + return; >> + } >> + >> + kfree(uchger->name); >> + kfree(uchger); >> +} >> + >> +/* >> + * usb_charger_unregister() - Unregister a usb charger device. >> + * @uchger - the usb charger device. >> + * >> + */ >> +int usb_charger_unregister(struct usb_charger *uchger) >> +{ >> + if (!uchger) >> + return -EINVAL; >> + >> + mutex_lock(&usb_charger_list_lock); >> + list_del(&uchger->entry); >> + mutex_unlock(&usb_charger_list_lock); >> + >> + device_unregister(&uchger->dev); >> + return 0; >> +} >> + >> +static void devm_uchger_dev_unreg(struct device *dev, void *res) >> +{ >> + usb_charger_unregister(*(struct usb_charger **)res); >> +} >> + >> +void devm_usb_charger_unregister(struct device *dev, >> + struct usb_charger *uchger) >> +{ >> + devres_release(dev, devm_uchger_dev_unreg, >> + devm_uchger_dev_match, uchger); >> +} >> + >> +/* >> + * usb_charger_register() - Register a new usb charger device. >> + * @uchger - the new usb charger device. >> + * >> + */ >> +int usb_charger_register(struct device *dev, struct usb_charger *uchger) >> +{ >> + static atomic_t uchger_no = ATOMIC_INIT(-1); >> + struct usb_charger *tmp; >> + int ret; >> + >> + if (!uchger) { >> + dev_err(dev, "no device provided for charger\n"); >> + return -EINVAL; >> + } >> + >> + uchger->dev.parent = dev; >> + uchger->dev.release = usb_charger_release; >> + dev_set_name(&uchger->dev, "usb-chger%lu", >> + (unsigned long)atomic_inc_return(&uchger_no)); > > For the name of usb-charger, which not using "usb-charger.x" directly? OK. >> + >> + ret = device_register(&uchger->dev); >> + if (ret) { >> + put_device(&uchger->dev); >> + return ret; >> + } >> + >> + dev_set_drvdata(&uchger->dev, uchger); >> + >> + mutex_lock(&usb_charger_list_lock); >> + list_for_each_entry(tmp, &usb_charger_list, entry) { >> + if (!(strcmp(tmp->name, uchger->name))) { >> + mutex_unlock(&usb_charger_list_lock); >> + ret = -EEXIST; >> + goto out; >> + } >> + } >> + list_add_tail(&uchger->entry, &usb_charger_list); >> + mutex_unlock(&usb_charger_list_lock); >> + >> + return 0; >> + >> +out: >> + dev_err(dev, "Failed to register usb charger (%s)\n", >> + uchger->name); >> + device_unregister(&uchger->dev); >> + put_device(&uchger->dev); >> + return ret; >> +} >> + >> +int devm_usb_charger_register(struct device *dev, >> + struct usb_charger *uchger) >> +{ >> + struct usb_charger **ptr; >> + int ret; >> + >> + ptr = devres_alloc(devm_uchger_dev_unreg, sizeof(*ptr), GFP_KERNEL); >> + if (!ptr) >> + return -ENOMEM; >> + >> + ret = usb_charger_register(dev, uchger); >> + if (ret) { >> + devres_free(ptr); >> + return ret; >> + } >> + >> + *ptr = uchger; >> + devres_add(dev, ptr); >> + >> + return 0; >> +} >> + >> +int usb_charger_init(struct usb_gadget *ugadget) >> +{ >> + struct usb_charger *uchger; >> + struct extcon_dev *edev; >> + char buf[100]; >> + char *str; >> + int ret; >> + >> + if (!ugadget) >> + return -EINVAL; >> + >> + uchger = devm_kzalloc(&ugadget->dev, sizeof(struct usb_charger), >> + GFP_KERNEL); >> + if (!uchger) >> + return -ENOMEM; >> + >> + sprintf(buf, "usb-charger.%s", ugadget->name); >> + str = devm_kzalloc(&ugadget->dev, sizeof(char) * (strlen(buf) + 1), >> + GFP_KERNEL); >> + if (!str) >> + return -ENOMEM; >> + >> + strcpy(str, buf); >> + uchger->name = str; >> + uchger->type = UNKNOWN_TYPE; >> + uchger->state = USB_CHARGER_DEFAULT; >> + uchger->cur_limit.sdp_cur_limit = DEFAULT_SDP_CUR_LIMIT; >> + uchger->cur_limit.dcp_cur_limit = DEFAULT_DCP_CUR_LIMIT; >> + uchger->cur_limit.cdp_cur_limit = DEFAULT_CDP_CUR_LIMIT; >> + uchger->cur_limit.aca_cur_limit = DEFAULT_ACA_CUR_LIMIT; >> + >> + atomic_set(&uchger->count, 1); >> + spin_lock_init(&uchger->lock); >> + INIT_LIST_HEAD(&uchger->entry); >> + RAW_INIT_NOTIFIER_HEAD(&uchger->uchger_nh); >> + >> + /* register a notifier on a extcon device if it is exsited */ >> + edev = extcon_get_edev_by_phandle(ugadget->dev.parent, 0); >> + if (!IS_ERR_OR_NULL(edev)) { >> + uchger->extcon_dev = edev; >> + uchger->extcon_nb.nb.notifier_call = usb_charger_plug_by_extcon; >> + uchger->extcon_nb.uchger = uchger; >> + usb_charger_register_extcon_notifier(uchger, edev, EXTCON_USB); >> + } >> + >> + /* register a notifier on a usb gadget device */ >> + uchger->gadget = ugadget; >> + ugadget->uchger = uchger; >> + uchger->old_gadget_state = ugadget->state; >> + uchger->gadget_nb.notifier_call = usb_charger_plug_by_gadget; >> + usb_charger_register_gadget_notifier(uchger); >> + >> + ret = usb_charger_register(&ugadget->dev, uchger); >> + if (ret) >> + goto reg_fail; >> + >> + return 0; >> + >> +reg_fail: >> + if (uchger->extcon_dev) >> + usb_charger_unregister_extcon_notifier(uchger, >> + uchger->extcon_dev, EXTCON_USB); >> + >> + usb_charger_unregister_gadget_notifier(uchger); >> + return ret; >> +} >> + >> +int usb_charger_exit(struct usb_gadget *ugadget) >> +{ >> + struct usb_charger *uchger = ugadget->uchger; >> + >> + if (!uchger) >> + return -EINVAL; >> + >> + if (uchger->extcon_dev) >> + usb_charger_unregister_extcon_notifier(uchger, >> + uchger->extcon_dev, EXTCON_USB); >> + >> + usb_charger_unregister_gadget_notifier(uchger); >> + return usb_charger_unregister(uchger); >> +} >> + >> +MODULE_AUTHOR("Baolin Wang "); >> +MODULE_DESCRIPTION("USB charger driver"); >> diff --git a/include/linux/usb/usb_charger.h b/include/linux/usb/usb_charger.h >> new file mode 100644 >> index 0000000..da4d3c9 >> --- /dev/null >> +++ b/include/linux/usb/usb_charger.h >> @@ -0,0 +1,101 @@ >> +#ifndef __LINUX_USB_CHARGER_H__ >> +#define __LINUX_USB_CHARGER_H__ >> + >> +#include >> +#include >> +#include >> +#include >> + >> +/* USB charger type: >> + * SDP (Standard Downstream Port) >> + * DCP (Dedicated Charging Port) >> + * CDP (Charging Downstream Port) >> + * ACA (Accessory Charger Adapters) >> + */ >> +enum usb_charger_type { >> + UNKNOWN_TYPE, >> + SDP_TYPE, >> + DCP_TYPE, >> + CDP_TYPE, >> + ACA_TYPE, >> +}; >> + >> +/* USB charger state */ >> +enum usb_charger_state { >> + USB_CHARGER_DEFAULT, >> + USB_CHARGER_PRESENT, >> + USB_CHARGER_REMOVE, >> +}; >> + >> +/* 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; >> +}; >> + >> +struct usb_charger { >> + /* Internal data. Please do not set. */ >> + const char *name; >> + struct device dev; >> + struct raw_notifier_head uchger_nh; >> + struct list_head entry; >> + spinlock_t lock; >> + enum usb_charger_type type; >> + enum usb_charger_state state; >> + atomic_t count; >> + >> + /* For supporting extcon usb gpio */ >> + struct extcon_dev *extcon_dev; >> + struct usb_charger_nb extcon_nb; >> + >> + /* For supporting usb gadget */ >> + struct usb_gadget *gadget; >> + enum usb_device_state old_gadget_state; >> + struct notifier_block gadget_nb; >> + >> + /* Current limitation */ >> + struct usb_charger_cur_limit cur_limit; >> +}; >> + >> +extern struct usb_charger *usb_charger_find_by_name(char *name); >> + >> +extern void usb_charger_register_notify(struct usb_charger *uchger, >> + struct notifier_block *nb); >> +extern void usb_charger_unregister_notify(struct usb_charger *uchger, >> + struct notifier_block *nb); >> + >> +extern int usb_charger_register_extcon_notifier(struct usb_charger *uchger, >> + struct extcon_dev *edev, >> + unsigned int extcon_id); >> +extern int usb_charger_unregister_extcon_notifier(struct usb_charger *uchger, >> + struct extcon_dev *edev, >> + unsigned int extcon_id); >> + >> +extern int usb_charger_register_gadget_notifier(struct usb_charger *uchger); >> +extern int usb_charger_unregister_gadget_notifier(struct usb_charger *uchger); >> + >> +extern int usb_charger_set_cur_limit(struct usb_charger *uchger, >> + struct usb_charger_cur_limit *cur_limit_set); >> +extern enum usb_charger_type usb_charger_detect_type(struct usb_charger *uchger); >> + >> +extern int usb_charger_init(struct usb_gadget *ugadget); >> +extern int usb_charger_exit(struct usb_gadget *ugadget); >> + >> +static inline void get_usb_charger(struct usb_charger *uchger) >> +{ >> + atomic_inc(&uchger->count); >> +} >> + >> +static inline void put_usb_charger(struct usb_charger *uchger) >> +{ >> + atomic_dec(&uchger->count); >> +} >> + >> +#endif /* __LINUX_USB_CHARGER_H__ */ >> -- >> 1.7.9.5 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-usb" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > > Best Regards, > Peter Chen -- Baolin.wang Best Regards -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/