From e7d9dd5ab15fa6d895929176592d6946bf329cf8 Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Sat, 3 Dec 2016 16:56:49 +0800 Subject: extcon: Return error code on failure Function get_zeroed_page() returns a NULL pointer if there is no enough memory. In function extcon_sync(), it returns 0 if the call to get_zeroed_page() fails. The return value 0 indicates success in the context, which is incosistent with the execution status. This patch fixes the bug by returning -ENOMEM. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=188611 Signed-off-by: Pan Bian Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/extcon/extcon.c') diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 78298460d168..7c1e3a7b14e0 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -453,7 +453,7 @@ int extcon_sync(struct extcon_dev *edev, unsigned int id) dev_err(&edev->dev, "out of memory in extcon_set_state\n"); kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE); - return 0; + return -ENOMEM; } length = name_show(&edev->dev, NULL, prop_buf); -- cgit From 01b4c9a1ae07a25d208cad0da7dd288007a22984 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 19 Dec 2016 21:02:33 +0900 Subject: extcon: Remove potential problem when calling extcon_register_notifier() This patch removes the potential problem of extcon_register_notifier() when edev parameter is NULL. When edev is NULL, this function returns the first extcon device which includes the sepecific external connector of second paramter. But, it don't guarantee the same operation in all cases. To remove this confusion and potential problem, this patch fixes it. Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) (limited to 'drivers/extcon/extcon.c') diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 7c1e3a7b14e0..d0e367959c91 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -906,35 +906,16 @@ int extcon_register_notifier(struct extcon_dev *edev, unsigned int id, unsigned long flags; int ret, idx = -EINVAL; - if (!nb) + if (!edev || !nb) return -EINVAL; - if (edev) { - idx = find_cable_index_by_id(edev, id); - if (idx < 0) - return idx; - - spin_lock_irqsave(&edev->lock, flags); - ret = raw_notifier_chain_register(&edev->nh[idx], nb); - spin_unlock_irqrestore(&edev->lock, flags); - } else { - struct extcon_dev *extd; - - mutex_lock(&extcon_dev_list_lock); - list_for_each_entry(extd, &extcon_dev_list, entry) { - idx = find_cable_index_by_id(extd, id); - if (idx >= 0) - break; - } - mutex_unlock(&extcon_dev_list_lock); + idx = find_cable_index_by_id(edev, id); + if (idx < 0) + return idx; - if (idx >= 0) { - edev = extd; - return extcon_register_notifier(extd, id, nb); - } else { - ret = -ENODEV; - } - } + spin_lock_irqsave(&edev->lock, flags); + ret = raw_notifier_chain_register(&edev->nh[idx], nb); + spin_unlock_irqrestore(&edev->lock, flags); return ret; } -- cgit From e6cf046543763878614d51e8283abd40d5e5327e Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 26 Dec 2016 20:37:38 +0900 Subject: extcon: Move defintion of struct extcon_dev to driver/extcon directory This patch moves the 'struct extcon_dev' of extcon subsystem to driver/extcon/extcon.h header file because the struct extcon_dev have to be handled by extcon API to guarantee the consistency of strcut extcon_dev. If external drivers are able to touch the struct extcon_dev directly, it might cause the critical and unknown problem. Signed-off-by: Chanwoo Choi --- drivers/extcon/devres.c | 2 +- drivers/extcon/extcon.c | 3 ++- drivers/extcon/extcon.h | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/extcon.h | 57 +-------------------------------------------- 4 files changed, 66 insertions(+), 58 deletions(-) create mode 100644 drivers/extcon/extcon.h (limited to 'drivers/extcon/extcon.c') diff --git a/drivers/extcon/devres.c b/drivers/extcon/devres.c index e686acd1c459..b40eb1805927 100644 --- a/drivers/extcon/devres.c +++ b/drivers/extcon/devres.c @@ -14,7 +14,7 @@ * GNU General Public License for more details. */ -#include +#include "extcon.h" static int devm_extcon_dev_match(struct device *dev, void *res, void *data) { diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index d0e367959c91..591582b0d2b7 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -30,11 +30,12 @@ #include #include #include -#include #include #include #include +#include "extcon.h" + #define SUPPORTED_CABLE_MAX 32 #define CABLE_NAME_MAX 30 diff --git a/drivers/extcon/extcon.h b/drivers/extcon/extcon.h new file mode 100644 index 000000000000..993ddccafe11 --- /dev/null +++ b/drivers/extcon/extcon.h @@ -0,0 +1,62 @@ +#ifndef __LINUX_EXTCON_INTERNAL_H__ +#define __LINUX_EXTCON_INTERNAL_H__ + +#include + +/** + * struct extcon_dev - An extcon device represents one external connector. + * @name: The name of this extcon device. Parent device name is + * used if NULL. + * @supported_cable: Array of supported cable names ending with EXTCON_NONE. + * If supported_cable is NULL, cable name related APIs + * are disabled. + * @mutually_exclusive: Array of mutually exclusive set of cables that cannot + * be attached simultaneously. The array should be + * ending with NULL or be NULL (no mutually exclusive + * cables). For example, if it is { 0x7, 0x30, 0}, then, + * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot + * be attached simulataneously. {0x7, 0} is equivalent to + * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there + * can be no simultaneous connections. + * @dev: Device of this extcon. + * @state: Attach/detach state of this extcon. Do not provide at + * register-time. + * @nh: Notifier for the state change events from this extcon + * @entry: To support list of extcon devices so that users can + * search for extcon devices based on the extcon name. + * @lock: + * @max_supported: Internal value to store the number of cables. + * @extcon_dev_type: Device_type struct to provide attribute_groups + * customized for each extcon device. + * @cables: Sysfs subdirectories. Each represents one cable. + * + * In most cases, users only need to provide "User initializing data" of + * this struct when registering an extcon. In some exceptional cases, + * optional callbacks may be needed. However, the values in "internal data" + * are overwritten by register function. + */ +struct extcon_dev { + /* Optional user initializing data */ + const char *name; + const unsigned int *supported_cable; + const u32 *mutually_exclusive; + + /* Internal data. Please do not set. */ + struct device dev; + struct raw_notifier_head *nh; + struct list_head entry; + int max_supported; + spinlock_t lock; /* could be called by irq handler */ + u32 state; + + /* /sys/class/extcon/.../cable.n/... */ + struct device_type extcon_dev_type; + struct extcon_cable *cables; + + /* /sys/class/extcon/.../mutually_exclusive/... */ + struct attribute_group attr_g_muex; + struct attribute **attrs_muex; + struct device_attribute *d_attrs_muex; +}; + +#endif /* __LINUX_EXTCON_INTERNAL_H__ */ diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 00201230bea5..d57e52443841 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -167,62 +167,7 @@ union extcon_property_value { }; struct extcon_cable; - -/** - * struct extcon_dev - An extcon device represents one external connector. - * @name: The name of this extcon device. Parent device name is - * used if NULL. - * @supported_cable: Array of supported cable names ending with EXTCON_NONE. - * If supported_cable is NULL, cable name related APIs - * are disabled. - * @mutually_exclusive: Array of mutually exclusive set of cables that cannot - * be attached simultaneously. The array should be - * ending with NULL or be NULL (no mutually exclusive - * cables). For example, if it is { 0x7, 0x30, 0}, then, - * {0, 1}, {0, 1, 2}, {0, 2}, {1, 2}, or {4, 5} cannot - * be attached simulataneously. {0x7, 0} is equivalent to - * {0x3, 0x6, 0x5, 0}. If it is {0xFFFFFFFF, 0}, there - * can be no simultaneous connections. - * @dev: Device of this extcon. - * @state: Attach/detach state of this extcon. Do not provide at - * register-time. - * @nh: Notifier for the state change events from this extcon - * @entry: To support list of extcon devices so that users can - * search for extcon devices based on the extcon name. - * @lock: - * @max_supported: Internal value to store the number of cables. - * @extcon_dev_type: Device_type struct to provide attribute_groups - * customized for each extcon device. - * @cables: Sysfs subdirectories. Each represents one cable. - * - * In most cases, users only need to provide "User initializing data" of - * this struct when registering an extcon. In some exceptional cases, - * optional callbacks may be needed. However, the values in "internal data" - * are overwritten by register function. - */ -struct extcon_dev { - /* Optional user initializing data */ - const char *name; - const unsigned int *supported_cable; - const u32 *mutually_exclusive; - - /* Internal data. Please do not set. */ - struct device dev; - struct raw_notifier_head *nh; - struct list_head entry; - int max_supported; - spinlock_t lock; /* could be called by irq handler */ - u32 state; - - /* /sys/class/extcon/.../cable.n/... */ - struct device_type extcon_dev_type; - struct extcon_cable *cables; - - /* /sys/class/extcon/.../mutually_exclusive/... */ - struct attribute_group attr_g_muex; - struct attribute **attrs_muex; - struct device_attribute *d_attrs_muex; -}; +struct extcon_dev; #if IS_ENABLED(CONFIG_EXTCON) -- cgit From 3c5f0e076833c407cca372c663d47499ae4dab45 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 2 Jan 2017 13:03:03 +0900 Subject: extcon: Add new EXTCON_CHG_USB_PD type for USB Power Delivery This patch adds the new EXTCON_CHG_USB_PD for USB PD (Power Delivery)[1]. The USB Power Delivery specification specifies that USB cable provides the increased power more than 7.5W to device with larger power demand. The EXTCON_CHG_USB_PD has the EXTCON_TYPE_CHG and EXTCON_TYPE_USB type. [1] https://en.wikipedia.org/wiki/USB#PD Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon.c | 5 +++++ include/linux/extcon.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers/extcon/extcon.c') diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 591582b0d2b7..768e36769870 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -99,6 +99,11 @@ struct __extcon_info { .id = EXTCON_CHG_WPT, .name = "WPT", }, + [EXTCON_CHG_USB_PD] = { + .type = EXTCON_TYPE_CHG | EXTCON_TYPE_USB, + .id = EXTCON_CHG_USB_PD, + .name = "PD", + }, /* Jack external connector */ [EXTCON_JACK_MICROPHONE] = { diff --git a/include/linux/extcon.h b/include/linux/extcon.h index 242157cad25d..7010fb01a81a 100644 --- a/include/linux/extcon.h +++ b/include/linux/extcon.h @@ -65,6 +65,7 @@ #define EXTCON_CHG_USB_FAST 9 #define EXTCON_CHG_USB_SLOW 10 #define EXTCON_CHG_WPT 11 /* Wireless Power Transfer */ +#define EXTCON_CHG_USB_PD 12 /* USB Power Delivery */ /* Jack external connector */ #define EXTCON_JACK_MICROPHONE 20 -- cgit From 86d6cda68f371744a28003cb32b51aaf231b7ca5 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Sat, 7 Jan 2017 05:17:36 +0900 Subject: extcon: Modify the name of EXTCON_USB_HOST connector This patch renames the EXTCON_USB_HOST by using '-' char because the name of all external connector use the '-' char instead of '_' char. - "USB_HOST" -> "USB-HOST" Signed-off-by: Chanwoo Choi --- drivers/extcon/extcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/extcon/extcon.c') diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index 768e36769870..09ac5e70c2f3 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -60,7 +60,7 @@ struct __extcon_info { [EXTCON_USB_HOST] = { .type = EXTCON_TYPE_USB, .id = EXTCON_USB_HOST, - .name = "USB_HOST", + .name = "USB-HOST", }, /* Charging external connector */ -- cgit