diff options
author | Roger Quadros <rogerq@ti.com> | 2015-05-29 10:01:46 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-31 02:45:30 -0400 |
commit | cd33a32157e42483ffea31e32b1cee4f11ff9592 (patch) | |
tree | c2e6c1cd26bf9e96259ed06d62e9059e214df808 | |
parent | 2cfef79ddce42e9604293424381b2e59913f600c (diff) |
usb: xhci: cleanup xhci_hcd allocation
HCD core allocates memory for HCD private data in
usb_create_[shared_]hcd() so make use of that
mechanism to allocate the struct xhci_hcd.
Introduce struct xhci_driver_overrides to provide
the size of HCD private data and hc_driver operation
overrides. As of now we only need to override the
reset and start methods.
Signed-off-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/xhci-plat.c | 18 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 30 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 19 |
4 files changed, 52 insertions, 32 deletions
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 2af32e26fafc..4a4cb1d91ac8 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -45,6 +45,13 @@ static const char hcd_name[] = "xhci_hcd"; | |||
45 | 45 | ||
46 | static struct hc_driver __read_mostly xhci_pci_hc_driver; | 46 | static struct hc_driver __read_mostly xhci_pci_hc_driver; |
47 | 47 | ||
48 | static int xhci_pci_setup(struct usb_hcd *hcd); | ||
49 | |||
50 | static const struct xhci_driver_overrides xhci_pci_overrides __initconst = { | ||
51 | .extra_priv_size = sizeof(struct xhci_hcd), | ||
52 | .reset = xhci_pci_setup, | ||
53 | }; | ||
54 | |||
48 | /* called after powerup, by probe or system-pm "wakeup" */ | 55 | /* called after powerup, by probe or system-pm "wakeup" */ |
49 | static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) | 56 | static int xhci_pci_reinit(struct xhci_hcd *xhci, struct pci_dev *pdev) |
50 | { | 57 | { |
@@ -206,7 +213,6 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
206 | if (!retval) | 213 | if (!retval) |
207 | return retval; | 214 | return retval; |
208 | 215 | ||
209 | kfree(xhci); | ||
210 | return retval; | 216 | return retval; |
211 | } | 217 | } |
212 | 218 | ||
@@ -247,11 +253,6 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
247 | goto dealloc_usb2_hcd; | 253 | goto dealloc_usb2_hcd; |
248 | } | 254 | } |
249 | 255 | ||
250 | /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset) | ||
251 | * is called by usb_add_hcd(). | ||
252 | */ | ||
253 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | ||
254 | |||
255 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, | 256 | retval = usb_add_hcd(xhci->shared_hcd, dev->irq, |
256 | IRQF_SHARED); | 257 | IRQF_SHARED); |
257 | if (retval) | 258 | if (retval) |
@@ -290,8 +291,6 @@ static void xhci_pci_remove(struct pci_dev *dev) | |||
290 | /* Workaround for spurious wakeups at shutdown with HSW */ | 291 | /* Workaround for spurious wakeups at shutdown with HSW */ |
291 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) | 292 | if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) |
292 | pci_set_power_state(dev, PCI_D3hot); | 293 | pci_set_power_state(dev, PCI_D3hot); |
293 | |||
294 | kfree(xhci); | ||
295 | } | 294 | } |
296 | 295 | ||
297 | #ifdef CONFIG_PM | 296 | #ifdef CONFIG_PM |
@@ -379,7 +378,7 @@ static struct pci_driver xhci_pci_driver = { | |||
379 | 378 | ||
380 | static int __init xhci_pci_init(void) | 379 | static int __init xhci_pci_init(void) |
381 | { | 380 | { |
382 | xhci_init_driver(&xhci_pci_hc_driver, xhci_pci_setup); | 381 | xhci_init_driver(&xhci_pci_hc_driver, &xhci_pci_overrides); |
383 | #ifdef CONFIG_PM | 382 | #ifdef CONFIG_PM |
384 | xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; | 383 | xhci_pci_hc_driver.pci_suspend = xhci_pci_suspend; |
385 | xhci_pci_hc_driver.pci_resume = xhci_pci_resume; | 384 | xhci_pci_hc_driver.pci_resume = xhci_pci_resume; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 783e819139a7..0bc4309cb8a8 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -26,6 +26,15 @@ | |||
26 | 26 | ||
27 | static struct hc_driver __read_mostly xhci_plat_hc_driver; | 27 | static struct hc_driver __read_mostly xhci_plat_hc_driver; |
28 | 28 | ||
29 | static int xhci_plat_setup(struct usb_hcd *hcd); | ||
30 | static int xhci_plat_start(struct usb_hcd *hcd); | ||
31 | |||
32 | static const struct xhci_driver_overrides xhci_plat_overrides __initconst = { | ||
33 | .extra_priv_size = sizeof(struct xhci_hcd), | ||
34 | .reset = xhci_plat_setup, | ||
35 | .start = xhci_plat_start, | ||
36 | }; | ||
37 | |||
29 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) | 38 | static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci) |
30 | { | 39 | { |
31 | /* | 40 | /* |
@@ -147,11 +156,6 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
147 | if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || | 156 | if ((node && of_property_read_bool(node, "usb3-lpm-capable")) || |
148 | (pdata && pdata->usb3_lpm_capable)) | 157 | (pdata && pdata->usb3_lpm_capable)) |
149 | xhci->quirks |= XHCI_LPM_SUPPORT; | 158 | xhci->quirks |= XHCI_LPM_SUPPORT; |
150 | /* | ||
151 | * Set the xHCI pointer before xhci_plat_setup() (aka hcd_driver.reset) | ||
152 | * is called by usb_add_hcd(). | ||
153 | */ | ||
154 | *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; | ||
155 | 159 | ||
156 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) | 160 | if (HCC_MAX_PSA(xhci->hcc_params) >= 4) |
157 | xhci->shared_hcd->can_do_streams = 1; | 161 | xhci->shared_hcd->can_do_streams = 1; |
@@ -207,7 +211,6 @@ static int xhci_plat_remove(struct platform_device *dev) | |||
207 | if (!IS_ERR(clk)) | 211 | if (!IS_ERR(clk)) |
208 | clk_disable_unprepare(clk); | 212 | clk_disable_unprepare(clk); |
209 | usb_put_hcd(hcd); | 213 | usb_put_hcd(hcd); |
210 | kfree(xhci); | ||
211 | 214 | ||
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
@@ -271,8 +274,7 @@ MODULE_ALIAS("platform:xhci-hcd"); | |||
271 | 274 | ||
272 | static int __init xhci_plat_init(void) | 275 | static int __init xhci_plat_init(void) |
273 | { | 276 | { |
274 | xhci_init_driver(&xhci_plat_hc_driver, xhci_plat_setup); | 277 | xhci_init_driver(&xhci_plat_hc_driver, &xhci_plat_overrides); |
275 | xhci_plat_hc_driver.start = xhci_plat_start; | ||
276 | return platform_driver_register(&usb_xhci_driver); | 278 | return platform_driver_register(&usb_xhci_driver); |
277 | } | 279 | } |
278 | module_init(xhci_plat_init); | 280 | module_init(xhci_plat_init); |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac1674854..01118f734436 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -4832,10 +4832,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4832 | hcd->self.no_stop_on_short = 1; | 4832 | hcd->self.no_stop_on_short = 1; |
4833 | 4833 | ||
4834 | if (usb_hcd_is_primary_hcd(hcd)) { | 4834 | if (usb_hcd_is_primary_hcd(hcd)) { |
4835 | xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); | 4835 | xhci = hcd_to_xhci(hcd); |
4836 | if (!xhci) | ||
4837 | return -ENOMEM; | ||
4838 | *((struct xhci_hcd **) hcd->hcd_priv) = xhci; | ||
4839 | xhci->main_hcd = hcd; | 4836 | xhci->main_hcd = hcd; |
4840 | /* Mark the first roothub as being USB 2.0. | 4837 | /* Mark the first roothub as being USB 2.0. |
4841 | * The xHCI driver will register the USB 3.0 roothub. | 4838 | * The xHCI driver will register the USB 3.0 roothub. |
@@ -4883,13 +4880,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4883 | /* Make sure the HC is halted. */ | 4880 | /* Make sure the HC is halted. */ |
4884 | retval = xhci_halt(xhci); | 4881 | retval = xhci_halt(xhci); |
4885 | if (retval) | 4882 | if (retval) |
4886 | goto error; | 4883 | return retval; |
4887 | 4884 | ||
4888 | xhci_dbg(xhci, "Resetting HCD\n"); | 4885 | xhci_dbg(xhci, "Resetting HCD\n"); |
4889 | /* Reset the internal HC memory state and registers. */ | 4886 | /* Reset the internal HC memory state and registers. */ |
4890 | retval = xhci_reset(xhci); | 4887 | retval = xhci_reset(xhci); |
4891 | if (retval) | 4888 | if (retval) |
4892 | goto error; | 4889 | return retval; |
4893 | xhci_dbg(xhci, "Reset complete\n"); | 4890 | xhci_dbg(xhci, "Reset complete\n"); |
4894 | 4891 | ||
4895 | /* Set dma_mask and coherent_dma_mask to 64-bits, | 4892 | /* Set dma_mask and coherent_dma_mask to 64-bits, |
@@ -4904,16 +4901,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) | |||
4904 | /* Initialize HCD and host controller data structures. */ | 4901 | /* Initialize HCD and host controller data structures. */ |
4905 | retval = xhci_init(hcd); | 4902 | retval = xhci_init(hcd); |
4906 | if (retval) | 4903 | if (retval) |
4907 | goto error; | 4904 | return retval; |
4908 | xhci_dbg(xhci, "Called HCD init\n"); | 4905 | xhci_dbg(xhci, "Called HCD init\n"); |
4909 | 4906 | ||
4910 | xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", | 4907 | xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n", |
4911 | xhci->hcc_params, xhci->hci_version, xhci->quirks); | 4908 | xhci->hcc_params, xhci->hci_version, xhci->quirks); |
4912 | 4909 | ||
4913 | return 0; | 4910 | return 0; |
4914 | error: | ||
4915 | kfree(xhci); | ||
4916 | return retval; | ||
4917 | } | 4911 | } |
4918 | EXPORT_SYMBOL_GPL(xhci_gen_setup); | 4912 | EXPORT_SYMBOL_GPL(xhci_gen_setup); |
4919 | 4913 | ||
@@ -4978,11 +4972,21 @@ static const struct hc_driver xhci_hc_driver = { | |||
4978 | .find_raw_port_number = xhci_find_raw_port_number, | 4972 | .find_raw_port_number = xhci_find_raw_port_number, |
4979 | }; | 4973 | }; |
4980 | 4974 | ||
4981 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)) | 4975 | void xhci_init_driver(struct hc_driver *drv, |
4976 | const struct xhci_driver_overrides *over) | ||
4982 | { | 4977 | { |
4983 | BUG_ON(!setup_fn); | 4978 | BUG_ON(!over); |
4979 | |||
4980 | /* Copy the generic table to drv then apply the overrides */ | ||
4984 | *drv = xhci_hc_driver; | 4981 | *drv = xhci_hc_driver; |
4985 | drv->reset = setup_fn; | 4982 | |
4983 | if (over) { | ||
4984 | drv->hcd_priv_size += over->extra_priv_size; | ||
4985 | if (over->reset) | ||
4986 | drv->reset = over->reset; | ||
4987 | if (over->start) | ||
4988 | drv->start = over->start; | ||
4989 | } | ||
4986 | } | 4990 | } |
4987 | EXPORT_SYMBOL_GPL(xhci_init_driver); | 4991 | EXPORT_SYMBOL_GPL(xhci_init_driver); |
4988 | 4992 | ||
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index ea75e8ccd3c1..11a231d61409 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1591,10 +1591,24 @@ struct xhci_hcd { | |||
1591 | #define COMP_MODE_RCVRY_MSECS 2000 | 1591 | #define COMP_MODE_RCVRY_MSECS 2000 |
1592 | }; | 1592 | }; |
1593 | 1593 | ||
1594 | /* Platform specific overrides to generic XHCI hc_driver ops */ | ||
1595 | struct xhci_driver_overrides { | ||
1596 | size_t extra_priv_size; | ||
1597 | int (*reset)(struct usb_hcd *hcd); | ||
1598 | int (*start)(struct usb_hcd *hcd); | ||
1599 | }; | ||
1600 | |||
1594 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 1601 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
1595 | static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) | 1602 | static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) |
1596 | { | 1603 | { |
1597 | return *((struct xhci_hcd **) (hcd->hcd_priv)); | 1604 | struct usb_hcd *primary_hcd; |
1605 | |||
1606 | if (usb_hcd_is_primary_hcd(hcd)) | ||
1607 | primary_hcd = hcd; | ||
1608 | else | ||
1609 | primary_hcd = hcd->primary_hcd; | ||
1610 | |||
1611 | return (struct xhci_hcd *) (primary_hcd->hcd_priv); | ||
1598 | } | 1612 | } |
1599 | 1613 | ||
1600 | static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | 1614 | static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) |
@@ -1748,7 +1762,8 @@ int xhci_run(struct usb_hcd *hcd); | |||
1748 | void xhci_stop(struct usb_hcd *hcd); | 1762 | void xhci_stop(struct usb_hcd *hcd); |
1749 | void xhci_shutdown(struct usb_hcd *hcd); | 1763 | void xhci_shutdown(struct usb_hcd *hcd); |
1750 | int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); | 1764 | int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks); |
1751 | void xhci_init_driver(struct hc_driver *drv, int (*setup_fn)(struct usb_hcd *)); | 1765 | void xhci_init_driver(struct hc_driver *drv, |
1766 | const struct xhci_driver_overrides *over); | ||
1752 | 1767 | ||
1753 | #ifdef CONFIG_PM | 1768 | #ifdef CONFIG_PM |
1754 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); | 1769 | int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup); |