Skip to content

Commit 5346759

Browse files
matnymangregkh
authored andcommitted
xhci: dbc: refactor xhci_dbc_init()
Refactor xhci_dbc_init(), splitting it into logical parts closer to the Linux device model. - Create the fake dbc device, depends on xhci strucure - Allocate a dbc structure, xhci agnostic - Call xhci_dbc_tty_probe(), similar to actual probe. Adjustments to xhci_dbc_exit and xhci_dbc_remove are also needed as a result to the xhci_dbc_init() changes Mostly non-functional changes, except for creating the dbc sysfs entry earlier, together with the dbc structure. Signed-off-by: Mathias Nyman <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e51879d commit 5346759

File tree

1 file changed

+66
-58
lines changed

1 file changed

+66
-58
lines changed

drivers/usb/host/xhci-dbgcap.c

Lines changed: 66 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
970927
static 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

1027984
static 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);
10501058
init_err2:
10511059
xhci_do_dbc_exit(xhci);
1052-
init_err3:
10531060
return ret;
10541061
}
10551062

10561063
void 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

Comments
 (0)