Skip to content

Commit a8534cb

Browse files
Grzegorz-Jgregkh
authored andcommitted
usb: phy: introduce usb_phy device type with its own uevent handler
The USB charger type and status was already propagated to userspace through kobject_uevent_env during charger notify work. Nevertheless the uevent could be lost e.g. because it could be fired at an early kernel boot stage, way before udev daemon or any other user-space app was able to catch it. Registering uevent hook for introduced usb_phy_dev_type will allow to query sysfs 'uevent' file to restore that information at any time. Reviewed-by: Peter Chen <[email protected]> Signed-off-by: Grzegorz Jaszczyk <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 309f5d7 commit a8534cb

File tree

1 file changed

+47
-8
lines changed

1 file changed

+47
-8
lines changed

drivers/usb/phy/phy.c

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ static const char *const usb_chger_type[] = {
4242
[ACA_TYPE] = "USB_CHARGER_ACA_TYPE",
4343
};
4444

45+
static const char *const usb_chger_state[] = {
46+
[USB_CHARGER_DEFAULT] = "USB_CHARGER_DEFAULT",
47+
[USB_CHARGER_PRESENT] = "USB_CHARGER_PRESENT",
48+
[USB_CHARGER_ABSENT] = "USB_CHARGER_ABSENT",
49+
};
50+
4551
static struct usb_phy *__usb_find_phy(struct list_head *list,
4652
enum usb_phy_type type)
4753
{
@@ -74,6 +80,18 @@ static struct usb_phy *__of_usb_find_phy(struct device_node *node)
7480
return ERR_PTR(-EPROBE_DEFER);
7581
}
7682

83+
static struct usb_phy *__device_to_usb_phy(struct device *dev)
84+
{
85+
struct usb_phy *usb_phy;
86+
87+
list_for_each_entry(usb_phy, &phy_list, head) {
88+
if (usb_phy->dev == dev)
89+
break;
90+
}
91+
92+
return usb_phy;
93+
}
94+
7795
static void usb_phy_set_default_current(struct usb_phy *usb_phy)
7896
{
7997
usb_phy->chg_cur.sdp_min = DEFAULT_SDP_CUR_MIN;
@@ -105,35 +123,49 @@ static void usb_phy_set_default_current(struct usb_phy *usb_phy)
105123
static void usb_phy_notify_charger_work(struct work_struct *work)
106124
{
107125
struct usb_phy *usb_phy = container_of(work, struct usb_phy, chg_work);
108-
char uchger_state[50] = { 0 };
109-
char uchger_type[50] = { 0 };
110-
char *envp[] = { uchger_state, uchger_type, NULL };
111126
unsigned int min, max;
112127

113128
switch (usb_phy->chg_state) {
114129
case USB_CHARGER_PRESENT:
115130
usb_phy_get_charger_current(usb_phy, &min, &max);
116131

117132
atomic_notifier_call_chain(&usb_phy->notifier, max, usb_phy);
118-
snprintf(uchger_state, ARRAY_SIZE(uchger_state),
119-
"USB_CHARGER_STATE=%s", "USB_CHARGER_PRESENT");
120133
break;
121134
case USB_CHARGER_ABSENT:
122135
usb_phy_set_default_current(usb_phy);
123136

124137
atomic_notifier_call_chain(&usb_phy->notifier, 0, usb_phy);
125-
snprintf(uchger_state, ARRAY_SIZE(uchger_state),
126-
"USB_CHARGER_STATE=%s", "USB_CHARGER_ABSENT");
127138
break;
128139
default:
129140
dev_warn(usb_phy->dev, "Unknown USB charger state: %d\n",
130141
usb_phy->chg_state);
131142
return;
132143
}
133144

145+
kobject_uevent(&usb_phy->dev->kobj, KOBJ_CHANGE);
146+
}
147+
148+
static int usb_phy_uevent(struct device *dev, struct kobj_uevent_env *env)
149+
{
150+
struct usb_phy *usb_phy;
151+
char uchger_state[50] = { 0 };
152+
char uchger_type[50] = { 0 };
153+
154+
usb_phy = __device_to_usb_phy(dev);
155+
156+
snprintf(uchger_state, ARRAY_SIZE(uchger_state),
157+
"USB_CHARGER_STATE=%s", usb_chger_state[usb_phy->chg_state]);
158+
134159
snprintf(uchger_type, ARRAY_SIZE(uchger_type),
135160
"USB_CHARGER_TYPE=%s", usb_chger_type[usb_phy->chg_type]);
136-
kobject_uevent_env(&usb_phy->dev->kobj, KOBJ_CHANGE, envp);
161+
162+
if (add_uevent_var(env, uchger_state))
163+
return -ENOMEM;
164+
165+
if (add_uevent_var(env, uchger_type))
166+
return -ENOMEM;
167+
168+
return 0;
137169
}
138170

139171
static void __usb_phy_get_charger_type(struct usb_phy *usb_phy)
@@ -661,6 +693,11 @@ int usb_add_phy(struct usb_phy *x, enum usb_phy_type type)
661693
}
662694
EXPORT_SYMBOL_GPL(usb_add_phy);
663695

696+
static struct device_type usb_phy_dev_type = {
697+
.name = "usb_phy",
698+
.uevent = usb_phy_uevent,
699+
};
700+
664701
/**
665702
* usb_add_phy_dev - declare the USB PHY
666703
* @x: the USB phy to be used; or NULL
@@ -684,6 +721,8 @@ int usb_add_phy_dev(struct usb_phy *x)
684721
if (ret)
685722
return ret;
686723

724+
x->dev->type = &usb_phy_dev_type;
725+
687726
ATOMIC_INIT_NOTIFIER_HEAD(&x->notifier);
688727

689728
spin_lock_irqsave(&phy_lock, flags);

0 commit comments

Comments
 (0)