diff options
Diffstat (limited to 'drivers/usb/common')
| -rw-r--r-- | drivers/usb/common/common.c | 41 | ||||
| -rw-r--r-- | drivers/usb/common/led.c | 4 | ||||
| -rw-r--r-- | drivers/usb/common/ulpi.c | 24 | ||||
| -rw-r--r-- | drivers/usb/common/usb-conn-gpio.c | 40 | ||||
| -rw-r--r-- | drivers/usb/common/usb-otg-fsm.c | 1 |
5 files changed, 73 insertions, 37 deletions
diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index c9bdeb4ddcb5..fc0845f681be 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/platform_device.h> #include <linux/usb/ch9.h> #include <linux/usb/of.h> #include <linux/usb/otg.h> @@ -40,6 +41,12 @@ const char *usb_ep_type_string(int ep_type) } EXPORT_SYMBOL_GPL(usb_ep_type_string); +/** + * usb_otg_state_string() - returns human readable name of OTG state. + * @state: the OTG state to return the human readable name of. If it's not + * any of the states defined in usb_otg_state enum, 'UNDEFINED' will be + * returned. + */ const char *usb_otg_state_string(enum usb_otg_state state) { static const char *const names[] = { @@ -106,19 +113,18 @@ EXPORT_SYMBOL_GPL(usb_speed_string); */ enum usb_device_speed usb_get_maximum_speed(struct device *dev) { - const char *maximum_speed; + const char *p = "maximum-speed"; int ret; - ret = device_property_read_string(dev, "maximum-speed", &maximum_speed); - if (ret < 0) - return USB_SPEED_UNKNOWN; - - ret = match_string(ssp_rate, ARRAY_SIZE(ssp_rate), maximum_speed); + ret = device_property_match_property_string(dev, p, ssp_rate, ARRAY_SIZE(ssp_rate)); if (ret > 0) return USB_SPEED_SUPER_PLUS; - ret = match_string(speed_names, ARRAY_SIZE(speed_names), maximum_speed); - return (ret < 0) ? USB_SPEED_UNKNOWN : ret; + ret = device_property_match_property_string(dev, p, speed_names, ARRAY_SIZE(speed_names)); + if (ret > 0) + return ret; + + return USB_SPEED_UNKNOWN; } EXPORT_SYMBOL_GPL(usb_get_maximum_speed); @@ -179,6 +185,14 @@ static const char *const usb_dr_modes[] = { [USB_DR_MODE_OTG] = "otg", }; +/** + * usb_get_dr_mode_from_string() - Get dual role mode for given string + * @str: String to find the corresponding dual role mode for + * + * This function performs a lookup for the given string and returns the + * corresponding enum usb_dr_mode. If no match for the string could be found, + * 'USB_DR_MODE_UNKNOWN' is returned. + */ static enum usb_dr_mode usb_get_dr_mode_from_string(const char *str) { int ret; @@ -275,14 +289,13 @@ EXPORT_SYMBOL_GPL(usb_decode_interval); */ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0) { - struct device_node *controller = NULL; + struct device_node *controller; struct of_phandle_args args; const char *dr_mode; int index; int err; - do { - controller = of_find_node_with_property(controller, "phys"); + for_each_node_with_property(controller, "phys") { if (!of_device_is_available(controller)) continue; index = 0; @@ -305,7 +318,7 @@ enum usb_dr_mode of_usb_get_dr_mode_by_phy(struct device_node *np, int arg0) goto finish; index++; } while (args.np); - } while (controller); + } finish: err = of_property_read_string(controller, "dr_mode", &dr_mode); @@ -416,6 +429,9 @@ EXPORT_SYMBOL_GPL(usb_of_get_companion_dev); struct dentry *usb_debug_root; EXPORT_SYMBOL_GPL(usb_debug_root); +DEFINE_MUTEX(usb_dynids_lock); +EXPORT_SYMBOL_GPL(usb_dynids_lock); + static int __init usb_common_init(void) { usb_debug_root = debugfs_create_dir("usb", NULL); @@ -432,4 +448,5 @@ static void __exit usb_common_exit(void) subsys_initcall(usb_common_init); module_exit(usb_common_exit); +MODULE_DESCRIPTION("Common code for host and device side USB"); MODULE_LICENSE("GPL"); diff --git a/drivers/usb/common/led.c b/drivers/usb/common/led.c index 0865dd44a80a..1de18d90b134 100644 --- a/drivers/usb/common/led.c +++ b/drivers/usb/common/led.c @@ -14,8 +14,6 @@ #define BLINK_DELAY 30 -static unsigned long usb_blink_delay = BLINK_DELAY; - DEFINE_LED_TRIGGER(ledtrig_usb_gadget); DEFINE_LED_TRIGGER(ledtrig_usb_host); @@ -32,7 +30,7 @@ void usb_led_activity(enum usb_led_event ev) break; } /* led_trigger_blink_oneshot() handles trig == NULL gracefully */ - led_trigger_blink_oneshot(trig, &usb_blink_delay, &usb_blink_delay, 0); + led_trigger_blink_oneshot(trig, BLINK_DELAY, BLINK_DELAY, 0); } EXPORT_SYMBOL_GPL(usb_led_activity); diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index d7c8461976ce..4a2ee447b213 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -34,7 +34,7 @@ EXPORT_SYMBOL_GPL(ulpi_write); /* -------------------------------------------------------------------------- */ -static int ulpi_match(struct device *dev, struct device_driver *driver) +static int ulpi_match(struct device *dev, const struct device_driver *driver) { struct ulpi_driver *drv = to_ulpi_driver(driver); struct ulpi *ulpi = to_ulpi_dev(dev); @@ -55,9 +55,9 @@ static int ulpi_match(struct device *dev, struct device_driver *driver) return 0; } -static int ulpi_uevent(struct device *dev, struct kobj_uevent_env *env) +static int ulpi_uevent(const struct device *dev, struct kobj_uevent_env *env) { - struct ulpi *ulpi = to_ulpi_dev(dev); + const struct ulpi *ulpi = to_ulpi_dev(dev); int ret; ret = of_device_uevent_modalias(dev, env); @@ -90,7 +90,7 @@ static void ulpi_remove(struct device *dev) drv->remove(to_ulpi_dev(dev)); } -static struct bus_type ulpi_bus = { +static const struct bus_type ulpi_bus = { .name = "ulpi", .match = ulpi_match, .uevent = ulpi_uevent, @@ -229,7 +229,7 @@ static int ulpi_read_id(struct ulpi *ulpi) request_module("ulpi:v%04xp%04x", ulpi->id.vendor, ulpi->id.product); return 0; err: - of_device_request_module(&ulpi->dev); + of_request_module(ulpi->dev.of_node); return 0; } @@ -271,7 +271,7 @@ static int ulpi_regs_show(struct seq_file *seq, void *data) } DEFINE_SHOW_ATTRIBUTE(ulpi_regs); -#define ULPI_ROOT debugfs_lookup(KBUILD_MODNAME, NULL) +static struct dentry *ulpi_root; static int ulpi_register(struct device *dev, struct ulpi *ulpi) { @@ -301,7 +301,7 @@ static int ulpi_register(struct device *dev, struct ulpi *ulpi) return ret; } - root = debugfs_create_dir(dev_name(dev), ULPI_ROOT); + root = debugfs_create_dir(dev_name(&ulpi->dev), ulpi_root); debugfs_create_file("regs", 0444, root, ulpi, &ulpi_regs_fops); dev_dbg(&ulpi->dev, "registered ULPI PHY: vendor %04x, product %04x\n", @@ -349,8 +349,7 @@ EXPORT_SYMBOL_GPL(ulpi_register_interface); */ void ulpi_unregister_interface(struct ulpi *ulpi) { - debugfs_remove_recursive(debugfs_lookup(dev_name(&ulpi->dev), - ULPI_ROOT)); + debugfs_lookup_and_remove(dev_name(&ulpi->dev), ulpi_root); device_unregister(&ulpi->dev); } EXPORT_SYMBOL_GPL(ulpi_unregister_interface); @@ -360,12 +359,11 @@ EXPORT_SYMBOL_GPL(ulpi_unregister_interface); static int __init ulpi_init(void) { int ret; - struct dentry *root; - root = debugfs_create_dir(KBUILD_MODNAME, NULL); + ulpi_root = debugfs_create_dir(KBUILD_MODNAME, NULL); ret = bus_register(&ulpi_bus); if (ret) - debugfs_remove(root); + debugfs_remove(ulpi_root); return ret; } subsys_initcall(ulpi_init); @@ -373,7 +371,7 @@ subsys_initcall(ulpi_init); static void __exit ulpi_exit(void) { bus_unregister(&ulpi_bus); - debugfs_remove_recursive(ULPI_ROOT); + debugfs_remove(ulpi_root); } module_exit(ulpi_exit); diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index e20874caba36..421c3af38e06 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -19,7 +19,11 @@ #include <linux/platform_device.h> #include <linux/power_supply.h> #include <linux/regulator/consumer.h> +#include <linux/string_choices.h> #include <linux/usb/role.h> +#include <linux/idr.h> + +static DEFINE_IDA(usb_conn_ida); #define USB_GPIO_DEB_MS 20 /* ms */ #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ @@ -29,6 +33,7 @@ struct usb_conn_info { struct device *dev; + int conn_id; /* store the IDA-allocated ID */ struct usb_role_switch *role_sw; enum usb_role last_role; struct regulator *vbus; @@ -42,6 +47,7 @@ struct usb_conn_info { struct power_supply_desc desc; struct power_supply *charger; + bool initial_detection; }; /* @@ -86,11 +92,13 @@ static void usb_conn_detect_cable(struct work_struct *work) dev_dbg(info->dev, "role %s -> %s, gpios: id %d, vbus %d\n", usb_role_string(info->last_role), usb_role_string(role), id, vbus); - if (info->last_role == role) { + if (!info->initial_detection && info->last_role == role) { dev_warn(info->dev, "repeated role: %s\n", usb_role_string(role)); return; } + info->initial_detection = false; + if (info->last_role == USB_ROLE_HOST && info->vbus) regulator_disable(info->vbus); @@ -108,7 +116,7 @@ static void usb_conn_detect_cable(struct work_struct *work) if (info->vbus) dev_dbg(info->dev, "vbus regulator is %s\n", - regulator_is_enabled(info->vbus) ? "enabled" : "disabled"); + str_enabled_disabled(regulator_is_enabled(info->vbus))); power_supply_changed(info->charger); } @@ -154,10 +162,20 @@ static int usb_conn_psy_register(struct usb_conn_info *info) struct device *dev = info->dev; struct power_supply_desc *desc = &info->desc; struct power_supply_config cfg = { - .of_node = dev->of_node, + .fwnode = dev_fwnode(dev), }; - desc->name = "usb-charger"; + info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); + if (info->conn_id < 0) + return info->conn_id; + + desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", + info->conn_id); + if (!desc->name) { + ida_free(&usb_conn_ida, info->conn_id); + return -ENOMEM; + } + desc->properties = usb_charger_properties; desc->num_properties = ARRAY_SIZE(usb_charger_properties); desc->get_property = usb_charger_get_property; @@ -165,8 +183,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info) cfg.drv_data = info; info->charger = devm_power_supply_register(dev, desc, &cfg); - if (IS_ERR(info->charger)) - dev_err(dev, "Unable to register charger\n"); + if (IS_ERR(info->charger)) { + dev_err(dev, "Unable to register charger %d\n", info->conn_id); + ida_free(&usb_conn_ida, info->conn_id); + } return PTR_ERR_OR_ZERO(info->charger); } @@ -258,6 +278,7 @@ static int usb_conn_probe(struct platform_device *pdev) device_set_wakeup_capable(&pdev->dev, true); /* Perform initial detection */ + info->initial_detection = true; usb_conn_queue_dwork(info, 0); return 0; @@ -267,18 +288,19 @@ put_role_sw: return ret; } -static int usb_conn_remove(struct platform_device *pdev) +static void usb_conn_remove(struct platform_device *pdev) { struct usb_conn_info *info = platform_get_drvdata(pdev); cancel_delayed_work_sync(&info->dw_det); + if (info->charger) + ida_free(&usb_conn_ida, info->conn_id); + if (info->last_role == USB_ROLE_HOST && info->vbus) regulator_disable(info->vbus); usb_role_switch_put(info->role_sw); - - return 0; } static int __maybe_unused usb_conn_suspend(struct device *dev) diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c index 0697fde51d00..e11803225775 100644 --- a/drivers/usb/common/usb-otg-fsm.c +++ b/drivers/usb/common/usb-otg-fsm.c @@ -449,4 +449,5 @@ int otg_statemachine(struct otg_fsm *fsm) return fsm->state_changed; } EXPORT_SYMBOL_GPL(otg_statemachine); +MODULE_DESCRIPTION("OTG Finite State Machine"); MODULE_LICENSE("GPL"); |
