diff options
Diffstat (limited to 'drivers/usb/phy/phy.c')
| -rw-r--r-- | drivers/usb/phy/phy.c | 147 |
1 files changed, 91 insertions, 56 deletions
diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 0277f62739a2..5a9b9353f343 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -34,6 +34,20 @@ struct phy_devm { struct notifier_block *nb; }; +static const char *const usb_chger_type[] = { + [UNKNOWN_TYPE] = "USB_CHARGER_UNKNOWN_TYPE", + [SDP_TYPE] = "USB_CHARGER_SDP_TYPE", + [CDP_TYPE] = "USB_CHARGER_CDP_TYPE", + [DCP_TYPE] = "USB_CHARGER_DCP_TYPE", + [ACA_TYPE] = "USB_CHARGER_ACA_TYPE", +}; + +static const char *const usb_chger_state[] = { + [USB_CHARGER_DEFAULT] = "USB_CHARGER_DEFAULT", + [USB_CHARGER_PRESENT] = "USB_CHARGER_PRESENT", + [USB_CHARGER_ABSENT] = "USB_CHARGER_ABSENT", +}; + static struct usb_phy *__usb_find_phy(struct list_head *list, enum usb_phy_type type) { @@ -66,6 +80,18 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node) return ERR_PTR(-EPROBE_DEFER); } +static struct usb_phy *__device_to_usb_phy(const struct device *dev) +{ + struct usb_phy *usb_phy; + + list_for_each_entry(usb_phy, &phy_list, head) { + if (usb_phy->dev == dev) + return usb_phy; + } + + return NULL; +} + static void usb_phy_set_default_current(struct usb_phy *usb_phy) { usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN; @@ -80,7 +106,7 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy) /** * usb_phy_notify_charger_work - notify the USB charger state - * @work - the charger work to notify the USB charger state + * @work: the charger work to notify the USB charger state * * This work can be issued when USB charger state has been changed or * USB charger current has been changed, then we can notify the current @@ -97,8 +123,6 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy) static void usb_phy_notify_charger_work(struct work_struct *work) { struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work); - char uchger_state[50] = { 0 }; - char *envp[] = { uchger_state, NULL }; unsigned int min, max; switch (usb_phy->chg_state) { @@ -106,15 +130,11 @@ static void usb_phy_notify_charger_work(struct work_struct *work) usb_phy_get_charger_current(usb_phy, &min, &max); atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy); - snprintf(uchger_state, ARRAY_SIZE(uchger_state), - "USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT"); break; case USB_CHARGER_ABSENT: usb_phy_set_default_current(usb_phy); atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy); - snprintf(uchger_state, ARRAY_SIZE(uchger_state), - "USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT"); break; default: dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n", @@ -122,7 +142,36 @@ static void usb_phy_notify_charger_work(struct work_struct *work) return; } - kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp); + kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE); +} + +static int usb_phy_uevent(const struct device *dev, struct kobj_uevent_env *env) +{ + const struct usb_phy *usb_phy; + char uchger_state[50] = { 0 }; + char uchger_type[50] = { 0 }; + unsigned long flags; + + spin_lock_irqsave(&phy_lock, flags); + usb_phy = __device_to_usb_phy(dev); + spin_unlock_irqrestore(&phy_lock, flags); + + if (!usb_phy) + return -ENODEV; + + snprintf(uchger_state, ARRAY_SIZE(uchger_state), + "USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]); + + snprintf(uchger_type, ARRAY_SIZE(uchger_type), + "USB_CHARGER_TYPE=%s", usb_chger_type[usb_phy->chg_type]); + + if (add_uevent_var(env, uchger_state)) + return -ENOMEM; + + if (add_uevent_var(env, uchger_type)) + return -ENOMEM; + + return 0; } static void __usb_phy_get_charger_type(struct usb_phy *usb_phy) @@ -149,9 +198,9 @@ static void __usb_phy_get_charger_type(struct usb_phy *usb_phy) /** * usb_phy_get_charger_type - get charger type from extcon subsystem - * @nb -the notifier block to determine charger type - * @state - the cable state - * @data - private data + * @nb: the notifier block to determine charger type + * @state: the cable state + * @data: private data * * Determin the charger type from extcon subsystem which also means the * charger state has been chaned, then we should notify this event. @@ -167,8 +216,8 @@ static int usb_phy_get_charger_type(struct notifier_block *nb, /** * usb_phy_set_charger_current - set the USB charger current - * @usb_phy - the USB phy to be used - * @mA - the current need to be set + * @usb_phy: the USB phy to be used + * @mA: the current need to be set * * Usually we only change the charger default current when USB finished the * enumeration as one SDP charger. As one SDP charger, usb_phy_set_power() @@ -220,9 +269,9 @@ EXPORT_SYMBOL_GPL(usb_phy_set_charger_current); /** * usb_phy_get_charger_current - get the USB charger current - * @usb_phy - the USB phy to be used - * @min - the minimum current - * @max - the maximum current + * @usb_phy: the USB phy to be used + * @min: the minimum current + * @max: the maximum current * * Usually we will notify the maximum current to power user, but for some * special case, power user also need the minimum current value. Then the @@ -258,8 +307,8 @@ EXPORT_SYMBOL_GPL(usb_phy_get_charger_current); /** * usb_phy_set_charger_state - set the USB charger state - * @usb_phy - the USB phy to be used - * @state - the new state need to be set for charger + * @usb_phy: the USB phy to be used + * @state: the new state need to be set for charger * * The usb phy driver can issue this function when the usb phy driver * detected the charger state has been changed, in this case the charger @@ -297,13 +346,6 @@ static void devm_usb_phy_release2(struct device *dev, void *_res) usb_put_phy(res->phy); } -static int devm_usb_phy_match(struct device *dev, void *res, void *match_data) -{ - struct usb_phy **phy = res; - - return *phy == match_data; -} - static void usb_charger_init(struct usb_phy *usb_phy) { usb_phy->chg_type = UNKNOWN_TYPE; @@ -316,7 +358,7 @@ static int usb_add_extcon(struct usb_phy *x) { int ret; - if (of_property_read_bool(x->dev->of_node, "extcon")) { + if (of_property_present(x->dev->of_node, "extcon")) { x->edev = extcon_get_edev_by_phandle(x->dev, 0); if (IS_ERR(x->edev)) return PTR_ERR(x->edev); @@ -403,8 +445,8 @@ static int usb_add_extcon(struct usb_phy *x) /** * devm_usb_get_phy - find the USB PHY - * @dev - device that requests this phy - * @type - the type of the phy the controller requires + * @dev: device that requests this phy + * @type: the type of the phy the controller requires * * Gets the phy using usb_get_phy(), and associates a device with it using * devres. On driver detach, release function is invoked on the devres data, @@ -433,7 +475,7 @@ EXPORT_SYMBOL_GPL(devm_usb_get_phy); /** * usb_get_phy - find the USB PHY - * @type - the type of the phy the controller requires + * @type: the type of the phy the controller requires * * Returns the phy driver, after getting a refcount to it; or * -ENODEV if there is no such phy. The caller is responsible for @@ -469,9 +511,9 @@ EXPORT_SYMBOL_GPL(usb_get_phy); /** * devm_usb_get_phy_by_node - find the USB PHY by device_node - * @dev - device that requests this phy - * @node - the device_node for the phy device. - * @nb - a notifier_block to register with the phy. + * @dev: device that requests this phy + * @node: the device_node for the phy device. + * @nb: a notifier_block to register with the phy. * * Returns the phy driver associated with the given device_node, * after getting a refcount to it, -ENODEV if there is no such phy or @@ -529,9 +571,9 @@ EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_node); /** * devm_usb_get_phy_by_phandle - find the USB PHY by phandle - * @dev - device that requests this phy - * @phandle - name of the property holding the phy phandle value - * @index - the index of the phy + * @dev: device that requests this phy + * @phandle: name of the property holding the phy phandle value + * @index: the index of the phy * * Returns the phy driver associated with the given phandle value, * after getting a refcount to it, -ENODEV if there is no such phy or @@ -566,25 +608,6 @@ struct usb_phy *devm_usb_get_phy_by_phandle(struct device *dev, EXPORT_SYMBOL_GPL(devm_usb_get_phy_by_phandle); /** - * devm_usb_put_phy - release the USB PHY - * @dev - device that wants to release this phy - * @phy - the phy returned by devm_usb_get_phy() - * - * destroys the devres associated with this phy and invokes usb_put_phy - * to release the phy. - * - * For use by USB host and peripheral drivers. - */ -void devm_usb_put_phy(struct device *dev, struct usb_phy *phy) -{ - int r; - - r = devres_destroy(dev, devm_usb_phy_release, devm_usb_phy_match, phy); - dev_WARN_ONCE(dev, r, "couldn't find PHY resource\n"); -} -EXPORT_SYMBOL_GPL(devm_usb_put_phy); - -/** * usb_put_phy - release the USB PHY * @x: the phy returned by usb_get_phy() * @@ -604,9 +627,9 @@ void usb_put_phy(struct usb_phy *x) EXPORT_SYMBOL_GPL(usb_put_phy); /** - * usb_add_phy - declare the USB PHY + * usb_add_phy: declare the USB PHY * @x: the USB phy to be used; or NULL - * @type - the type of this PHY + * @type: the type of this PHY * * This call is exclusively for use by phy drivers, which * coordinate the activities of drivers for host and peripheral @@ -623,6 +646,8 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type) return -EINVAL; } + INIT_LIST_HEAD(&x->head); + usb_charger_init(x); ret = usb_add_extcon(x); if (ret) @@ -650,6 +675,11 @@ out: } EXPORT_SYMBOL_GPL(usb_add_phy); +static const struct device_type usb_phy_dev_type = { + .name = "usb_phy", + .uevent = usb_phy_uevent, +}; + /** * usb_add_phy_dev - declare the USB PHY * @x: the USB phy to be used; or NULL @@ -668,11 +698,15 @@ int usb_add_phy_dev(struct usb_phy *x) return -EINVAL; } + INIT_LIST_HEAD(&x->head); + usb_charger_init(x); ret = usb_add_extcon(x); if (ret) return ret; + x->dev->type = &usb_phy_dev_type; + ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier); spin_lock_irqsave(&phy_lock, flags); @@ -703,6 +737,7 @@ EXPORT_SYMBOL_GPL(usb_remove_phy); /** * usb_phy_set_event - set event to phy event * @x: the phy returned by usb_get_phy(); + * @event: event to set * * This sets event to phy event */ |
