@@ -924,49 +924,6 @@ static void xhci_do_dbc_exit(struct xhci_hcd *xhci)
924924 spin_unlock_irqrestore (& xhci -> lock , flags );
925925}
926926
927- static int xhci_do_dbc_init (struct xhci_hcd * xhci )
928- {
929- u32 reg ;
930- struct xhci_dbc * dbc ;
931- unsigned long flags ;
932- void __iomem * base ;
933- int dbc_cap_offs ;
934-
935- base = & xhci -> cap_regs -> hc_capbase ;
936- dbc_cap_offs = xhci_find_next_ext_cap (base , 0 , XHCI_EXT_CAPS_DEBUG );
937- if (!dbc_cap_offs )
938- return - ENODEV ;
939-
940- dbc = kzalloc (sizeof (* dbc ), GFP_KERNEL );
941- if (!dbc )
942- return - ENOMEM ;
943-
944- dbc -> regs = base + dbc_cap_offs ;
945-
946- /* We will avoid using DbC in xhci driver if it's in use. */
947- reg = readl (& dbc -> regs -> control );
948- if (reg & DBC_CTRL_DBC_ENABLE ) {
949- kfree (dbc );
950- return - EBUSY ;
951- }
952-
953- spin_lock_irqsave (& xhci -> lock , flags );
954- if (xhci -> dbc ) {
955- spin_unlock_irqrestore (& xhci -> lock , flags );
956- kfree (dbc );
957- return - EBUSY ;
958- }
959- xhci -> dbc = dbc ;
960- spin_unlock_irqrestore (& xhci -> lock , flags );
961-
962- dbc -> xhci = xhci ;
963- dbc -> dev = xhci_to_hcd (xhci )-> self .sysdev ;
964- INIT_DELAYED_WORK (& dbc -> event_work , xhci_dbc_handle_events );
965- spin_lock_init (& dbc -> lock );
966-
967- return 0 ;
968- }
969-
970927static ssize_t dbc_show (struct device * dev ,
971928 struct device_attribute * attr ,
972929 char * buf )
@@ -1026,44 +983,95 @@ static ssize_t dbc_store(struct device *dev,
1026983
1027984static DEVICE_ATTR_RW (dbc );
1028985
1029- int xhci_dbc_init (struct xhci_hcd * xhci )
986+ struct xhci_dbc *
987+ xhci_alloc_dbc (struct device * dev , void __iomem * base )
1030988{
989+ struct xhci_dbc * dbc ;
1031990 int ret ;
1032- struct device * dev = xhci_to_hcd (xhci )-> self .controller ;
1033991
1034- ret = xhci_do_dbc_init (xhci );
992+ dbc = kzalloc (sizeof (* dbc ), GFP_KERNEL );
993+ if (!dbc )
994+ return NULL ;
995+
996+ dbc -> regs = base ;
997+ dbc -> dev = dev ;
998+
999+ if (readl (& dbc -> regs -> control ) & DBC_CTRL_DBC_ENABLE )
1000+ return NULL ;
1001+
1002+ INIT_DELAYED_WORK (& dbc -> event_work , xhci_dbc_handle_events );
1003+ spin_lock_init (& dbc -> lock );
1004+
1005+ ret = device_create_file (dev , & dev_attr_dbc );
10351006 if (ret )
1036- goto init_err3 ;
1007+ goto err ;
1008+
1009+ return dbc ;
1010+ err :
1011+ kfree (dbc );
1012+ return NULL ;
1013+ }
1014+
1015+ /* undo what xhci_alloc_dbc() did */
1016+ void xhci_dbc_remove (struct xhci_dbc * dbc )
1017+ {
1018+ if (!dbc )
1019+ return ;
1020+ /* stop hw, stop wq and call dbc->ops->stop() */
1021+ xhci_dbc_stop (dbc );
1022+
1023+ /* remove sysfs files */
1024+ device_remove_file (dbc -> dev , & dev_attr_dbc );
1025+
1026+ kfree (dbc );
1027+ }
1028+
1029+ int xhci_dbc_init (struct xhci_hcd * xhci )
1030+ {
1031+ struct device * dev ;
1032+ void __iomem * base ;
1033+ int ret ;
1034+ int dbc_cap_offs ;
1035+
1036+ /* create all parameters needed resembling a dbc device */
1037+ dev = xhci_to_hcd (xhci )-> self .controller ;
1038+ base = & xhci -> cap_regs -> hc_capbase ;
1039+
1040+ dbc_cap_offs = xhci_find_next_ext_cap (base , 0 , XHCI_EXT_CAPS_DEBUG );
1041+ if (!dbc_cap_offs )
1042+ return - ENODEV ;
1043+
1044+ /* already allocated and in use */
1045+ if (xhci -> dbc )
1046+ return - EBUSY ;
1047+
1048+ xhci -> dbc = xhci_alloc_dbc (dev , base );
1049+ if (!xhci -> dbc )
1050+ return - ENOMEM ;
10371051
10381052 ret = xhci_dbc_tty_probe (xhci );
10391053 if (ret )
10401054 goto init_err2 ;
10411055
1042- ret = device_create_file (dev , & dev_attr_dbc );
1043- if (ret )
1044- goto init_err1 ;
1045-
10461056 return 0 ;
10471057
1048- init_err1 :
1049- xhci_dbc_tty_remove (xhci -> dbc );
10501058init_err2 :
10511059 xhci_do_dbc_exit (xhci );
1052- init_err3 :
10531060 return ret ;
10541061}
10551062
10561063void xhci_dbc_exit (struct xhci_hcd * xhci )
10571064{
1058- struct device * dev = xhci_to_hcd ( xhci ) -> self . controller ;
1065+ unsigned long flags ;
10591066
10601067 if (!xhci -> dbc )
10611068 return ;
10621069
1063- device_remove_file (dev , & dev_attr_dbc );
10641070 xhci_dbc_tty_remove (xhci -> dbc );
1065- xhci_dbc_stop (xhci -> dbc );
1066- xhci_do_dbc_exit (xhci );
1071+ xhci_dbc_remove (xhci -> dbc );
1072+ spin_lock_irqsave (& xhci -> lock , flags );
1073+ xhci -> dbc = NULL ;
1074+ spin_unlock_irqrestore (& xhci -> lock , flags );
10671075}
10681076
10691077#ifdef CONFIG_PM
0 commit comments