Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xhci: dbc: Don't call dbc_tty_init() on every dbc tty probe

The current workaround to call the dbc_tty_init() in probe is
not working in case we have several xhci devices with dbc enabled.

dbc_tty_init() should be called only once by a module init call when
module is loaded.

until dbgtty is its own module call dbc_tty_init() from xhci
module init call.

Same is true for unloading and dbc_tty_exit()

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20220216095153.1303105-5-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Mathias Nyman and committed by
Greg Kroah-Hartman
6aec5000 5c44d9d7

+30 -20
+10
drivers/usb/host/xhci-dbgcap.c
··· 1087 1087 return ret; 1088 1088 } 1089 1089 #endif /* CONFIG_PM */ 1090 + 1091 + int xhci_dbc_init(void) 1092 + { 1093 + return dbc_tty_init(); 1094 + } 1095 + 1096 + void xhci_dbc_exit(void) 1097 + { 1098 + dbc_tty_exit(); 1099 + }
+11 -1
drivers/usb/host/xhci-dbgcap.h
··· 196 196 #ifdef CONFIG_USB_XHCI_DBGCAP 197 197 int xhci_create_dbc_dev(struct xhci_hcd *xhci); 198 198 void xhci_remove_dbc_dev(struct xhci_hcd *xhci); 199 + int xhci_dbc_init(void); 200 + void xhci_dbc_exit(void); 201 + int dbc_tty_init(void); 202 + void dbc_tty_exit(void); 199 203 int xhci_dbc_tty_probe(struct device *dev, void __iomem *res, struct xhci_hcd *xhci); 200 204 void xhci_dbc_tty_remove(struct xhci_dbc *dbc); 201 205 struct xhci_dbc *xhci_alloc_dbc(struct device *dev, void __iomem *res, ··· 223 219 static inline void xhci_remove_dbc_dev(struct xhci_hcd *xhci) 224 220 { 225 221 } 226 - 222 + static inline int xhci_dbc_init(void) 223 + { 224 + return 0; 225 + } 226 + static inline void xhci_dbc_exit(void) 227 + { 228 + } 227 229 static inline int xhci_dbc_suspend(struct xhci_hcd *xhci) 228 230 { 229 231 return 0;
+7 -19
drivers/usb/host/xhci-dbgtty.c
··· 14 14 #include "xhci.h" 15 15 #include "xhci-dbgcap.h" 16 16 17 - static int dbc_tty_init(void); 18 - static void dbc_tty_exit(void); 19 - 20 17 static struct tty_driver *dbc_tty_driver; 21 18 22 19 static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc) ··· 471 474 struct dbc_port *port; 472 475 int status; 473 476 474 - /* dbc_tty_init will be called by module init() in the future */ 475 - status = dbc_tty_init(); 476 - if (status) 477 - return status; 477 + if (!dbc_tty_driver) 478 + return -ENODEV; 478 479 479 480 port = kzalloc(sizeof(*port), GFP_KERNEL); 480 - if (!port) { 481 - status = -ENOMEM; 482 - goto out; 483 - } 481 + if (!port) 482 + return -ENOMEM; 484 483 485 484 dbc_tty_driver->driver_state = port; 486 485 ··· 494 501 return 0; 495 502 out2: 496 503 kfree(port); 497 - out: 498 - /* dbc_tty_exit will be called by module_exit() in the future */ 499 - dbc_tty_exit(); 504 + 500 505 return status; 501 506 } 502 507 ··· 508 517 509 518 xhci_dbc_remove(dbc); 510 519 kfree(port); 511 - 512 - /* dbc_tty_exit will be called by module_exit() in the future */ 513 - dbc_tty_exit(); 514 520 } 515 521 516 - static int dbc_tty_init(void) 522 + int dbc_tty_init(void) 517 523 { 518 524 int ret; 519 525 ··· 540 552 return ret; 541 553 } 542 554 543 - static void dbc_tty_exit(void) 555 + void dbc_tty_exit(void) 544 556 { 545 557 if (dbc_tty_driver) { 546 558 tty_unregister_driver(dbc_tty_driver);
+2
drivers/usb/host/xhci.c
··· 5495 5495 return -ENODEV; 5496 5496 5497 5497 xhci_debugfs_create_root(); 5498 + xhci_dbc_init(); 5498 5499 5499 5500 return 0; 5500 5501 } ··· 5507 5506 static void __exit xhci_hcd_fini(void) 5508 5507 { 5509 5508 xhci_debugfs_remove_root(); 5509 + xhci_dbc_exit(); 5510 5510 } 5511 5511 5512 5512 module_init(xhci_hcd_init);