diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 13:03:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-08 13:03:52 -0400 |
commit | 132d68d37d33f1d0b9c1f507c8b4d64c27ecec8a (patch) | |
tree | b3c05972e5579e1574873fe745fb1358c62a269c /drivers/usb/mtu3/mtu3_dr.c | |
parent | 80f232121b69cc69a31ccb2b38c1665d770b0710 (diff) | |
parent | 3515468a87a47781f6af818773650513ff14656a (diff) |
Merge tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH:
"Here is the big set of USB and PHY driver patches for 5.2-rc1
There is the usual set of:
- USB gadget updates
- PHY driver updates and additions
- USB serial driver updates and fixes
- typec updates and new chips supported
- mtu3 driver updates
- xhci driver updates
- other tiny driver updates
Nothing really interesting, just constant forward progress.
All of these have been in linux-next for a while with no reported
issues. The usb-gadget and usb-serial trees were merged a bit "late",
but both of them had been in linux-next before they got merged here
last Friday"
* tag 'usb-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (206 commits)
USB: serial: f81232: implement break control
USB: serial: f81232: add high baud rate support
USB: serial: f81232: clear overrun flag
USB: serial: f81232: fix interrupt worker not stop
usb: dwc3: Rename DWC3_DCTL_LPM_ERRATA
usb: dwc3: Fix default lpm_nyet_threshold value
usb: dwc3: debug: Print GET_STATUS(device) tracepoint
usb: dwc3: Do core validation early on probe
usb: dwc3: gadget: Set lpm_capable
usb: gadget: atmel: tie wake lock to running clock
usb: gadget: atmel: support USB suspend
usb: gadget: atmel_usba_udc: simplify setting of interrupt-enabled mask
dwc2: gadget: Fix completed transfer size calculation in DDMA
usb: dwc2: Set lpm mode parameters depend on HW configuration
usb: dwc2: Fix channel disable flow
usb: dwc2: Set actual frame number for completed ISOC transfer
usb: gadget: do not use __constant_cpu_to_le16
usb: dwc2: gadget: Increase descriptors count for ISOC's
usb: introduce usb_ep_type_string() function
usb: dwc3: move synchronize_irq() out of the spinlock protected block
...
Diffstat (limited to 'drivers/usb/mtu3/mtu3_dr.c')
-rw-r--r-- | drivers/usb/mtu3/mtu3_dr.c | 156 |
1 files changed, 30 insertions, 126 deletions
diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index ac60e9c8564e..5fcb71af875a 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c | |||
@@ -7,16 +7,9 @@ | |||
7 | * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> | 7 | * Author: Chunfeng Yun <chunfeng.yun@mediatek.com> |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/debugfs.h> | ||
11 | #include <linux/irq.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/of_device.h> | ||
14 | #include <linux/pinctrl/consumer.h> | ||
15 | #include <linux/seq_file.h> | ||
16 | #include <linux/uaccess.h> | ||
17 | |||
18 | #include "mtu3.h" | 10 | #include "mtu3.h" |
19 | #include "mtu3_dr.h" | 11 | #include "mtu3_dr.h" |
12 | #include "mtu3_debug.h" | ||
20 | 13 | ||
21 | #define USB2_PORT 2 | 14 | #define USB2_PORT 2 |
22 | #define USB3_PORT 3 | 15 | #define USB3_PORT 3 |
@@ -28,6 +21,22 @@ enum mtu3_vbus_id_state { | |||
28 | MTU3_VBUS_VALID, | 21 | MTU3_VBUS_VALID, |
29 | }; | 22 | }; |
30 | 23 | ||
24 | static char *mailbox_state_string(enum mtu3_vbus_id_state state) | ||
25 | { | ||
26 | switch (state) { | ||
27 | case MTU3_ID_FLOAT: | ||
28 | return "ID_FLOAT"; | ||
29 | case MTU3_ID_GROUND: | ||
30 | return "ID_GROUND"; | ||
31 | case MTU3_VBUS_OFF: | ||
32 | return "VBUS_OFF"; | ||
33 | case MTU3_VBUS_VALID: | ||
34 | return "VBUS_VALID"; | ||
35 | default: | ||
36 | return "UNKNOWN"; | ||
37 | } | ||
38 | } | ||
39 | |||
31 | static void toggle_opstate(struct ssusb_mtk *ssusb) | 40 | static void toggle_opstate(struct ssusb_mtk *ssusb) |
32 | { | 41 | { |
33 | if (!ssusb->otg_switch.is_u3_drd) { | 42 | if (!ssusb->otg_switch.is_u3_drd) { |
@@ -147,7 +156,8 @@ static void ssusb_set_mailbox(struct otg_switch_mtk *otg_sx, | |||
147 | container_of(otg_sx, struct ssusb_mtk, otg_switch); | 156 | container_of(otg_sx, struct ssusb_mtk, otg_switch); |
148 | struct mtu3 *mtu = ssusb->u3d; | 157 | struct mtu3 *mtu = ssusb->u3d; |
149 | 158 | ||
150 | dev_dbg(ssusb->dev, "mailbox state(%d)\n", status); | 159 | dev_dbg(ssusb->dev, "mailbox %s\n", mailbox_state_string(status)); |
160 | mtu3_dbg_trace(ssusb->dev, "mailbox %s", mailbox_state_string(status)); | ||
151 | 161 | ||
152 | switch (status) { | 162 | switch (status) { |
153 | case MTU3_ID_GROUND: | 163 | case MTU3_ID_GROUND: |
@@ -238,14 +248,18 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) | |||
238 | otg_sx->vbus_nb.notifier_call = ssusb_vbus_notifier; | 248 | otg_sx->vbus_nb.notifier_call = ssusb_vbus_notifier; |
239 | ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB, | 249 | ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB, |
240 | &otg_sx->vbus_nb); | 250 | &otg_sx->vbus_nb); |
241 | if (ret < 0) | 251 | if (ret < 0) { |
242 | dev_err(ssusb->dev, "failed to register notifier for USB\n"); | 252 | dev_err(ssusb->dev, "failed to register notifier for USB\n"); |
253 | return ret; | ||
254 | } | ||
243 | 255 | ||
244 | otg_sx->id_nb.notifier_call = ssusb_id_notifier; | 256 | otg_sx->id_nb.notifier_call = ssusb_id_notifier; |
245 | ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, | 257 | ret = devm_extcon_register_notifier(ssusb->dev, edev, EXTCON_USB_HOST, |
246 | &otg_sx->id_nb); | 258 | &otg_sx->id_nb); |
247 | if (ret < 0) | 259 | if (ret < 0) { |
248 | dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); | 260 | dev_err(ssusb->dev, "failed to register notifier for USB-HOST\n"); |
261 | return ret; | ||
262 | } | ||
249 | 263 | ||
250 | dev_dbg(ssusb->dev, "EXTCON_USB: %d, EXTCON_USB_HOST: %d\n", | 264 | dev_dbg(ssusb->dev, "EXTCON_USB: %d, EXTCON_USB_HOST: %d\n", |
251 | extcon_get_state(edev, EXTCON_USB), | 265 | extcon_get_state(edev, EXTCON_USB), |
@@ -266,7 +280,7 @@ static int ssusb_extcon_register(struct otg_switch_mtk *otg_sx) | |||
266 | * This is useful in special cases, such as uses TYPE-A receptacle but also | 280 | * This is useful in special cases, such as uses TYPE-A receptacle but also |
267 | * wants to support dual-role mode. | 281 | * wants to support dual-role mode. |
268 | */ | 282 | */ |
269 | static void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) | 283 | void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) |
270 | { | 284 | { |
271 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; | 285 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; |
272 | 286 | ||
@@ -281,114 +295,6 @@ static void ssusb_mode_manual_switch(struct ssusb_mtk *ssusb, int to_host) | |||
281 | } | 295 | } |
282 | } | 296 | } |
283 | 297 | ||
284 | static int ssusb_mode_show(struct seq_file *sf, void *unused) | ||
285 | { | ||
286 | struct ssusb_mtk *ssusb = sf->private; | ||
287 | |||
288 | seq_printf(sf, "current mode: %s(%s drd)\n(echo device/host)\n", | ||
289 | ssusb->is_host ? "host" : "device", | ||
290 | ssusb->otg_switch.manual_drd_enabled ? "manual" : "auto"); | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int ssusb_mode_open(struct inode *inode, struct file *file) | ||
296 | { | ||
297 | return single_open(file, ssusb_mode_show, inode->i_private); | ||
298 | } | ||
299 | |||
300 | static ssize_t ssusb_mode_write(struct file *file, | ||
301 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
302 | { | ||
303 | struct seq_file *sf = file->private_data; | ||
304 | struct ssusb_mtk *ssusb = sf->private; | ||
305 | char buf[16]; | ||
306 | |||
307 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
308 | return -EFAULT; | ||
309 | |||
310 | if (!strncmp(buf, "host", 4) && !ssusb->is_host) { | ||
311 | ssusb_mode_manual_switch(ssusb, 1); | ||
312 | } else if (!strncmp(buf, "device", 6) && ssusb->is_host) { | ||
313 | ssusb_mode_manual_switch(ssusb, 0); | ||
314 | } else { | ||
315 | dev_err(ssusb->dev, "wrong or duplicated setting\n"); | ||
316 | return -EINVAL; | ||
317 | } | ||
318 | |||
319 | return count; | ||
320 | } | ||
321 | |||
322 | static const struct file_operations ssusb_mode_fops = { | ||
323 | .open = ssusb_mode_open, | ||
324 | .write = ssusb_mode_write, | ||
325 | .read = seq_read, | ||
326 | .llseek = seq_lseek, | ||
327 | .release = single_release, | ||
328 | }; | ||
329 | |||
330 | static int ssusb_vbus_show(struct seq_file *sf, void *unused) | ||
331 | { | ||
332 | struct ssusb_mtk *ssusb = sf->private; | ||
333 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; | ||
334 | |||
335 | seq_printf(sf, "vbus state: %s\n(echo on/off)\n", | ||
336 | regulator_is_enabled(otg_sx->vbus) ? "on" : "off"); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int ssusb_vbus_open(struct inode *inode, struct file *file) | ||
342 | { | ||
343 | return single_open(file, ssusb_vbus_show, inode->i_private); | ||
344 | } | ||
345 | |||
346 | static ssize_t ssusb_vbus_write(struct file *file, | ||
347 | const char __user *ubuf, size_t count, loff_t *ppos) | ||
348 | { | ||
349 | struct seq_file *sf = file->private_data; | ||
350 | struct ssusb_mtk *ssusb = sf->private; | ||
351 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; | ||
352 | char buf[16]; | ||
353 | bool enable; | ||
354 | |||
355 | if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) | ||
356 | return -EFAULT; | ||
357 | |||
358 | if (kstrtobool(buf, &enable)) { | ||
359 | dev_err(ssusb->dev, "wrong setting\n"); | ||
360 | return -EINVAL; | ||
361 | } | ||
362 | |||
363 | ssusb_set_vbus(otg_sx, enable); | ||
364 | |||
365 | return count; | ||
366 | } | ||
367 | |||
368 | static const struct file_operations ssusb_vbus_fops = { | ||
369 | .open = ssusb_vbus_open, | ||
370 | .write = ssusb_vbus_write, | ||
371 | .read = seq_read, | ||
372 | .llseek = seq_lseek, | ||
373 | .release = single_release, | ||
374 | }; | ||
375 | |||
376 | static void ssusb_debugfs_init(struct ssusb_mtk *ssusb) | ||
377 | { | ||
378 | struct dentry *root; | ||
379 | |||
380 | root = debugfs_create_dir(dev_name(ssusb->dev), usb_debug_root); | ||
381 | ssusb->dbgfs_root = root; | ||
382 | |||
383 | debugfs_create_file("mode", 0644, root, ssusb, &ssusb_mode_fops); | ||
384 | debugfs_create_file("vbus", 0644, root, ssusb, &ssusb_vbus_fops); | ||
385 | } | ||
386 | |||
387 | static void ssusb_debugfs_exit(struct ssusb_mtk *ssusb) | ||
388 | { | ||
389 | debugfs_remove_recursive(ssusb->dbgfs_root); | ||
390 | } | ||
391 | |||
392 | void ssusb_set_force_mode(struct ssusb_mtk *ssusb, | 298 | void ssusb_set_force_mode(struct ssusb_mtk *ssusb, |
393 | enum mtu3_dr_force_mode mode) | 299 | enum mtu3_dr_force_mode mode) |
394 | { | 300 | { |
@@ -415,25 +321,23 @@ void ssusb_set_force_mode(struct ssusb_mtk *ssusb, | |||
415 | int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) | 321 | int ssusb_otg_switch_init(struct ssusb_mtk *ssusb) |
416 | { | 322 | { |
417 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; | 323 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; |
324 | int ret = 0; | ||
418 | 325 | ||
419 | INIT_WORK(&otg_sx->id_work, ssusb_id_work); | 326 | INIT_WORK(&otg_sx->id_work, ssusb_id_work); |
420 | INIT_WORK(&otg_sx->vbus_work, ssusb_vbus_work); | 327 | INIT_WORK(&otg_sx->vbus_work, ssusb_vbus_work); |
421 | 328 | ||
422 | if (otg_sx->manual_drd_enabled) | 329 | if (otg_sx->manual_drd_enabled) |
423 | ssusb_debugfs_init(ssusb); | 330 | ssusb_dr_debugfs_init(ssusb); |
424 | else | 331 | else |
425 | ssusb_extcon_register(otg_sx); | 332 | ret = ssusb_extcon_register(otg_sx); |
426 | 333 | ||
427 | return 0; | 334 | return ret; |
428 | } | 335 | } |
429 | 336 | ||
430 | void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) | 337 | void ssusb_otg_switch_exit(struct ssusb_mtk *ssusb) |
431 | { | 338 | { |
432 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; | 339 | struct otg_switch_mtk *otg_sx = &ssusb->otg_switch; |
433 | 340 | ||
434 | if (otg_sx->manual_drd_enabled) | ||
435 | ssusb_debugfs_exit(ssusb); | ||
436 | |||
437 | cancel_work_sync(&otg_sx->id_work); | 341 | cancel_work_sync(&otg_sx->id_work); |
438 | cancel_work_sync(&otg_sx->vbus_work); | 342 | cancel_work_sync(&otg_sx->vbus_work); |
439 | } | 343 | } |