Merge tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg KH: "Here's the big pull request for the USB driver tree for 3.20-rc1. Nothing major happening here, just lots of gadget driver updates, new device ids, and a bunch of cleanups. All of these have been in linux-next for a while with no reported issues" * tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (299 commits) usb: musb: fix device hotplug behind hub usb: dwc2: Fix a bug in reading the endpoint directions from reg. staging: emxx_udc: fix the build error usb: Retry port status check on resume to work around RH bugs Revert "usb: Reset USB-3 devices on USB-3 link bounce" uhci-hub: use HUB_CHAR_* usb: kconfig: replace PPC_OF with PPC ehci-pci: disable for Intel MID platforms (update) usb: gadget: Kconfig: use bool instead of boolean usb: musb: blackfin: remove incorrect __exit_p() USB: fix use-after-free bug in usb_hcd_unlink_urb() ehci-pci: disable for Intel MID platforms usb: host: pci_quirks: joing string literals USB: add flag for HCDs that can't receive wakeup requests (isp1760-hcd) USB: usbfs: allow URBs to be reaped after disconnection cdc-acm: kill unnecessary messages cdc-acm: add sanity checks usb: phy: phy-generic: Fix USB PHY gpio reset usb: dwc2: fix USB core dependencies usb: renesas_usbhs: fix NULL pointer dereference in dma_release_channel() ...
This commit is contained in:
@@ -219,7 +219,7 @@ config USB_EHCI_TEGRA
|
||||
|
||||
config USB_EHCI_HCD_PPC_OF
|
||||
bool "EHCI support for PPC USB controller on OF platform bus"
|
||||
depends on PPC_OF
|
||||
depends on PPC
|
||||
default y
|
||||
---help---
|
||||
Enables support for the USB controller present on the PowerPC
|
||||
@@ -331,20 +331,6 @@ config USB_ISP116X_HCD
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called isp116x-hcd.
|
||||
|
||||
config USB_ISP1760_HCD
|
||||
tristate "ISP 1760 HCD support"
|
||||
---help---
|
||||
The ISP1760 chip is a USB 2.0 host controller.
|
||||
|
||||
This driver does not support isochronous transfers or OTG.
|
||||
This USB controller is usually attached to a non-DMA-Master
|
||||
capable bus. NXP's eval kit brings this chip on PCI card
|
||||
where the chip itself is behind a PLB to simulate such
|
||||
a bus.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called isp1760.
|
||||
|
||||
config USB_ISP1362_HCD
|
||||
tristate "ISP1362 HCD support"
|
||||
---help---
|
||||
@@ -494,7 +480,7 @@ config USB_OHCI_ATH79
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF_BE
|
||||
bool "OHCI support for OF platform bus (big endian)"
|
||||
depends on PPC_OF
|
||||
depends on PPC
|
||||
select USB_OHCI_BIG_ENDIAN_DESC
|
||||
select USB_OHCI_BIG_ENDIAN_MMIO
|
||||
---help---
|
||||
@@ -503,7 +489,7 @@ config USB_OHCI_HCD_PPC_OF_BE
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF_LE
|
||||
bool "OHCI support for OF platform bus (little endian)"
|
||||
depends on PPC_OF
|
||||
depends on PPC
|
||||
select USB_OHCI_LITTLE_ENDIAN
|
||||
---help---
|
||||
Enables support for little-endian USB controllers present on the
|
||||
@@ -511,7 +497,7 @@ config USB_OHCI_HCD_PPC_OF_LE
|
||||
|
||||
config USB_OHCI_HCD_PPC_OF
|
||||
bool
|
||||
depends on PPC_OF
|
||||
depends on PPC
|
||||
default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
|
||||
|
||||
config USB_OHCI_HCD_PCI
|
||||
|
@@ -5,8 +5,6 @@
|
||||
# tell define_trace.h where to find the xhci trace header
|
||||
CFLAGS_xhci-trace.o := -I$(src)
|
||||
|
||||
isp1760-y := isp1760-hcd.o isp1760-if.o
|
||||
|
||||
fhci-y := fhci-hcd.o fhci-hub.o fhci-q.o
|
||||
fhci-y += fhci-mem.o fhci-tds.o fhci-sched.o
|
||||
|
||||
@@ -69,7 +67,6 @@ obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o
|
||||
obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o
|
||||
obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o
|
||||
obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o
|
||||
obj-$(CONFIG_USB_ISP1760_HCD) += isp1760.o
|
||||
obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
|
||||
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
|
||||
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
|
||||
|
@@ -27,44 +27,66 @@
|
||||
#define DRIVER_DESC "EHCI Atmel driver"
|
||||
|
||||
static const char hcd_name[] = "ehci-atmel";
|
||||
static struct hc_driver __read_mostly ehci_atmel_hc_driver;
|
||||
|
||||
/* interface and function clocks */
|
||||
static struct clk *iclk, *fclk, *uclk;
|
||||
static int clocked;
|
||||
#define hcd_to_atmel_ehci_priv(h) \
|
||||
((struct atmel_ehci_priv *)hcd_to_ehci(h)->priv)
|
||||
|
||||
struct atmel_ehci_priv {
|
||||
struct clk *iclk;
|
||||
struct clk *fclk;
|
||||
struct clk *uclk;
|
||||
bool clocked;
|
||||
};
|
||||
|
||||
static struct hc_driver __read_mostly ehci_atmel_hc_driver;
|
||||
|
||||
static const struct ehci_driver_overrides ehci_atmel_drv_overrides __initconst = {
|
||||
.extra_priv_size = sizeof(struct atmel_ehci_priv),
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void atmel_start_clock(void)
|
||||
static void atmel_start_clock(struct atmel_ehci_priv *atmel_ehci)
|
||||
{
|
||||
if (atmel_ehci->clocked)
|
||||
return;
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
|
||||
clk_set_rate(uclk, 48000000);
|
||||
clk_prepare_enable(uclk);
|
||||
clk_set_rate(atmel_ehci->uclk, 48000000);
|
||||
clk_prepare_enable(atmel_ehci->uclk);
|
||||
}
|
||||
clk_prepare_enable(iclk);
|
||||
clk_prepare_enable(fclk);
|
||||
clocked = 1;
|
||||
clk_prepare_enable(atmel_ehci->iclk);
|
||||
clk_prepare_enable(atmel_ehci->fclk);
|
||||
atmel_ehci->clocked = true;
|
||||
}
|
||||
|
||||
static void atmel_stop_clock(void)
|
||||
static void atmel_stop_clock(struct atmel_ehci_priv *atmel_ehci)
|
||||
{
|
||||
clk_disable_unprepare(fclk);
|
||||
clk_disable_unprepare(iclk);
|
||||
if (!atmel_ehci->clocked)
|
||||
return;
|
||||
clk_disable_unprepare(atmel_ehci->fclk);
|
||||
clk_disable_unprepare(atmel_ehci->iclk);
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK))
|
||||
clk_disable_unprepare(uclk);
|
||||
clocked = 0;
|
||||
clk_disable_unprepare(atmel_ehci->uclk);
|
||||
atmel_ehci->clocked = false;
|
||||
}
|
||||
|
||||
static void atmel_start_ehci(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
|
||||
|
||||
dev_dbg(&pdev->dev, "start\n");
|
||||
atmel_start_clock();
|
||||
atmel_start_clock(atmel_ehci);
|
||||
}
|
||||
|
||||
static void atmel_stop_ehci(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
|
||||
|
||||
dev_dbg(&pdev->dev, "stop\n");
|
||||
atmel_stop_clock();
|
||||
atmel_stop_clock(atmel_ehci);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -75,6 +97,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
||||
const struct hc_driver *driver = &ehci_atmel_hc_driver;
|
||||
struct resource *res;
|
||||
struct ehci_hcd *ehci;
|
||||
struct atmel_ehci_priv *atmel_ehci;
|
||||
int irq;
|
||||
int retval;
|
||||
|
||||
@@ -105,6 +128,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
||||
retval = -ENOMEM;
|
||||
goto fail_create_hcd;
|
||||
}
|
||||
atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
hcd->regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
@@ -116,23 +140,23 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)
|
||||
hcd->rsrc_start = res->start;
|
||||
hcd->rsrc_len = resource_size(res);
|
||||
|
||||
iclk = devm_clk_get(&pdev->dev, "ehci_clk");
|
||||
if (IS_ERR(iclk)) {
|
||||
atmel_ehci->iclk = devm_clk_get(&pdev->dev, "ehci_clk");
|
||||
if (IS_ERR(atmel_ehci->iclk)) {
|
||||
dev_err(&pdev->dev, "Error getting interface clock\n");
|
||||
retval = -ENOENT;
|
||||
goto fail_request_resource;
|
||||
}
|
||||
fclk = devm_clk_get(&pdev->dev, "uhpck");
|
||||
if (IS_ERR(fclk)) {
|
||||
atmel_ehci->fclk = devm_clk_get(&pdev->dev, "uhpck");
|
||||
if (IS_ERR(atmel_ehci->fclk)) {
|
||||
dev_err(&pdev->dev, "Error getting function clock\n");
|
||||
retval = -ENOENT;
|
||||
goto fail_request_resource;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
|
||||
uclk = devm_clk_get(&pdev->dev, "usb_clk");
|
||||
if (IS_ERR(uclk)) {
|
||||
atmel_ehci->uclk = devm_clk_get(&pdev->dev, "usb_clk");
|
||||
if (IS_ERR(atmel_ehci->uclk)) {
|
||||
dev_err(&pdev->dev, "failed to get uclk\n");
|
||||
retval = PTR_ERR(uclk);
|
||||
retval = PTR_ERR(atmel_ehci->uclk);
|
||||
goto fail_request_resource;
|
||||
}
|
||||
}
|
||||
@@ -169,11 +193,35 @@ static int ehci_atmel_drv_remove(struct platform_device *pdev)
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
atmel_stop_ehci(pdev);
|
||||
fclk = iclk = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int ehci_atmel_drv_suspend(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
|
||||
int ret;
|
||||
|
||||
ret = ehci_suspend(hcd, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
atmel_stop_clock(atmel_ehci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ehci_atmel_drv_resume(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd);
|
||||
|
||||
atmel_start_clock(atmel_ehci);
|
||||
return ehci_resume(hcd, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id atmel_ehci_dt_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9g45-ehci" },
|
||||
@@ -183,12 +231,16 @@ static const struct of_device_id atmel_ehci_dt_ids[] = {
|
||||
MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids);
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ehci_atmel_pm_ops, ehci_atmel_drv_suspend,
|
||||
ehci_atmel_drv_resume);
|
||||
|
||||
static struct platform_driver ehci_atmel_driver = {
|
||||
.probe = ehci_atmel_drv_probe,
|
||||
.remove = ehci_atmel_drv_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "atmel-ehci",
|
||||
.pm = &ehci_atmel_pm_ops,
|
||||
.of_match_table = of_match_ptr(atmel_ehci_dt_ids),
|
||||
},
|
||||
};
|
||||
@@ -199,7 +251,7 @@ static int __init ehci_atmel_init(void)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
|
||||
ehci_init_driver(&ehci_atmel_hc_driver, NULL);
|
||||
ehci_init_driver(&ehci_atmel_hc_driver, &ehci_atmel_drv_overrides);
|
||||
return platform_driver_register(&ehci_atmel_driver);
|
||||
}
|
||||
module_init(ehci_atmel_init);
|
||||
|
@@ -709,7 +709,6 @@ static struct platform_driver ehci_fsl_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "fsl-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = EHCI_FSL_PM_OPS,
|
||||
},
|
||||
};
|
||||
|
@@ -187,7 +187,6 @@ static struct platform_driver ehci_grlib_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "grlib-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ehci_hcd_grlib_of_match,
|
||||
},
|
||||
};
|
||||
|
@@ -1110,7 +1110,7 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
||||
EXPORT_SYMBOL_GPL(ehci_suspend);
|
||||
|
||||
/* Returns 0 if power was preserved, 1 if power was lost */
|
||||
int ehci_resume(struct usb_hcd *hcd, bool hibernated)
|
||||
int ehci_resume(struct usb_hcd *hcd, bool force_reset)
|
||||
{
|
||||
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
|
||||
|
||||
@@ -1124,12 +1124,12 @@ int ehci_resume(struct usb_hcd *hcd, bool hibernated)
|
||||
return 0; /* Controller is dead */
|
||||
|
||||
/*
|
||||
* If CF is still set and we aren't resuming from hibernation
|
||||
* If CF is still set and reset isn't forced
|
||||
* then we maintained suspend power.
|
||||
* Just undo the effect of ehci_suspend().
|
||||
*/
|
||||
if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF &&
|
||||
!hibernated) {
|
||||
!force_reset) {
|
||||
int mask = INTR_MASK;
|
||||
|
||||
ehci_prepare_ports_for_controller_resume(ehci);
|
||||
|
@@ -700,15 +700,15 @@ ehci_hub_descriptor (
|
||||
memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
|
||||
memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
|
||||
|
||||
temp = 0x0008; /* per-port overcurrent reporting */
|
||||
temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
|
||||
if (HCS_PPC (ehci->hcs_params))
|
||||
temp |= 0x0001; /* per-port power control */
|
||||
temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */
|
||||
else
|
||||
temp |= 0x0002; /* no power switching */
|
||||
temp |= HUB_CHAR_NO_LPSM; /* no power switching */
|
||||
#if 0
|
||||
// re-enable when we support USB_PORT_FEAT_INDICATOR below.
|
||||
if (HCS_INDICATOR (ehci->hcs_params))
|
||||
temp |= 0x0080; /* per-port indicators (LEDs) */
|
||||
temp |= HUB_CHAR_PORTIND; /* per-port indicators (LEDs) */
|
||||
#endif
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
}
|
||||
|
@@ -42,6 +42,24 @@ static inline bool is_intel_quark_x1000(struct pci_dev *pdev)
|
||||
pdev->device == PCI_DEVICE_ID_INTEL_QUARK_X1000_SOC;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the list of PCI IDs for the devices that have EHCI USB class and
|
||||
* specific drivers for that. One of the example is a ChipIdea device installed
|
||||
* on some Intel MID platforms.
|
||||
*/
|
||||
static const struct pci_device_id bypass_pci_id_table[] = {
|
||||
/* ChipIdea on Intel MID platform */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0811), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0829), },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe006), },
|
||||
{}
|
||||
};
|
||||
|
||||
static inline bool is_bypassed_id(struct pci_dev *pdev)
|
||||
{
|
||||
return !!pci_match_id(bypass_pci_id_table, pdev);
|
||||
}
|
||||
|
||||
/*
|
||||
* 0x84 is the offset of in/out threshold register,
|
||||
* and it is the same offset as the register of 'hostpc'.
|
||||
@@ -352,6 +370,13 @@ static const struct ehci_driver_overrides pci_overrides __initconst = {
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
if (is_bypassed_id(pdev))
|
||||
return -ENODEV;
|
||||
return usb_hcd_pci_probe(pdev, id);
|
||||
}
|
||||
|
||||
/* PCI driver selection metadata; PCI hotplugging uses this */
|
||||
static const struct pci_device_id pci_ids [] = { {
|
||||
/* handle any USB 2.0 EHCI controller */
|
||||
@@ -370,7 +395,7 @@ static struct pci_driver ehci_pci_driver = {
|
||||
.name = (char *) hcd_name,
|
||||
.id_table = pci_ids,
|
||||
|
||||
.probe = usb_hcd_pci_probe,
|
||||
.probe = ehci_pci_probe,
|
||||
.remove = usb_hcd_pci_remove,
|
||||
.shutdown = usb_hcd_pci_shutdown,
|
||||
|
||||
|
@@ -43,7 +43,8 @@
|
||||
struct ehci_platform_priv {
|
||||
struct clk *clks[EHCI_MAX_CLKS];
|
||||
struct reset_control *rst;
|
||||
struct phy *phy;
|
||||
struct phy **phys;
|
||||
int num_phys;
|
||||
};
|
||||
|
||||
static const char hcd_name[] = "ehci-platform";
|
||||
@@ -78,7 +79,7 @@ static int ehci_platform_power_on(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
|
||||
int clk, ret;
|
||||
int clk, ret, phy_num;
|
||||
|
||||
for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
|
||||
ret = clk_prepare_enable(priv->clks[clk]);
|
||||
@@ -86,20 +87,28 @@ static int ehci_platform_power_on(struct platform_device *dev)
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
if (priv->phy) {
|
||||
ret = phy_init(priv->phy);
|
||||
if (ret)
|
||||
goto err_disable_clks;
|
||||
|
||||
ret = phy_power_on(priv->phy);
|
||||
if (ret)
|
||||
goto err_exit_phy;
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
if (priv->phys[phy_num]) {
|
||||
ret = phy_init(priv->phys[phy_num]);
|
||||
if (ret)
|
||||
goto err_exit_phy;
|
||||
ret = phy_power_on(priv->phys[phy_num]);
|
||||
if (ret) {
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
goto err_exit_phy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit_phy:
|
||||
phy_exit(priv->phy);
|
||||
while (--phy_num >= 0) {
|
||||
if (priv->phys[phy_num]) {
|
||||
phy_power_off(priv->phys[phy_num]);
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
}
|
||||
}
|
||||
err_disable_clks:
|
||||
while (--clk >= 0)
|
||||
clk_disable_unprepare(priv->clks[clk]);
|
||||
@@ -111,11 +120,13 @@ static void ehci_platform_power_off(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
|
||||
int clk;
|
||||
int clk, phy_num;
|
||||
|
||||
if (priv->phy) {
|
||||
phy_power_off(priv->phy);
|
||||
phy_exit(priv->phy);
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
if (priv->phys[phy_num]) {
|
||||
phy_power_off(priv->phys[phy_num]);
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
}
|
||||
}
|
||||
|
||||
for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
@@ -143,7 +154,8 @@ static int ehci_platform_probe(struct platform_device *dev)
|
||||
struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
|
||||
struct ehci_platform_priv *priv;
|
||||
struct ehci_hcd *ehci;
|
||||
int err, irq, clk = 0;
|
||||
const char *phy_name;
|
||||
int err, irq, phy_num, clk = 0;
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
@@ -155,7 +167,8 @@ static int ehci_platform_probe(struct platform_device *dev)
|
||||
if (!pdata)
|
||||
pdata = &ehci_platform_defaults;
|
||||
|
||||
err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
|
||||
err = dma_coerce_mask_and_coherent(&dev->dev,
|
||||
pdata->dma_mask_64 ? DMA_BIT_MASK(64) : DMA_BIT_MASK(32));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -185,12 +198,42 @@ static int ehci_platform_probe(struct platform_device *dev)
|
||||
if (of_property_read_bool(dev->dev.of_node, "big-endian"))
|
||||
ehci->big_endian_mmio = ehci->big_endian_desc = 1;
|
||||
|
||||
priv->phy = devm_phy_get(&dev->dev, "usb");
|
||||
if (IS_ERR(priv->phy)) {
|
||||
err = PTR_ERR(priv->phy);
|
||||
if (err == -EPROBE_DEFER)
|
||||
goto err_put_hcd;
|
||||
priv->phy = NULL;
|
||||
if (of_property_read_bool(dev->dev.of_node,
|
||||
"needs-reset-on-resume"))
|
||||
pdata->reset_on_resume = 1;
|
||||
|
||||
priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
|
||||
"phys", "#phy-cells");
|
||||
priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1;
|
||||
|
||||
priv->phys = devm_kcalloc(&dev->dev, priv->num_phys,
|
||||
sizeof(struct phy *), GFP_KERNEL);
|
||||
if (!priv->phys)
|
||||
return -ENOMEM;
|
||||
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
err = of_property_read_string_index(
|
||||
dev->dev.of_node,
|
||||
"phy-names", phy_num,
|
||||
&phy_name);
|
||||
|
||||
if (err < 0) {
|
||||
if (priv->num_phys > 1) {
|
||||
dev_err(&dev->dev, "phy-names not provided");
|
||||
goto err_put_hcd;
|
||||
} else
|
||||
phy_name = "usb";
|
||||
}
|
||||
|
||||
priv->phys[phy_num] = devm_phy_get(&dev->dev,
|
||||
phy_name);
|
||||
if (IS_ERR(priv->phys[phy_num])) {
|
||||
err = PTR_ERR(priv->phys[phy_num]);
|
||||
if ((priv->num_phys > 1) ||
|
||||
(err == -EPROBE_DEFER))
|
||||
goto err_put_hcd;
|
||||
priv->phys[phy_num] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
|
||||
@@ -340,7 +383,7 @@ static int ehci_platform_resume(struct device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
ehci_resume(hcd, false);
|
||||
ehci_resume(hcd, pdata->reset_on_resume);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
@@ -349,6 +392,7 @@ static const struct of_device_id vt8500_ehci_ids[] = {
|
||||
{ .compatible = "via,vt8500-ehci", },
|
||||
{ .compatible = "wm,prizm-ehci", },
|
||||
{ .compatible = "generic-ehci", },
|
||||
{ .compatible = "cavium,octeon-6335-ehci", },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
|
||||
|
@@ -325,6 +325,5 @@ static struct platform_driver ehci_hcd_msp_driver = {
|
||||
.remove = ehci_hcd_msp_drv_remove,
|
||||
.driver = {
|
||||
.name = "pmcmsp-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
@@ -234,7 +234,6 @@ static struct platform_driver ehci_hcd_ppc_of_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "ppc-of-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ehci_hcd_ppc_of_match,
|
||||
},
|
||||
};
|
||||
|
@@ -178,7 +178,6 @@ static struct platform_driver ehci_hcd_sead3_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "sead3-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = SEAD3_EHCI_PMOPS,
|
||||
}
|
||||
};
|
||||
|
@@ -189,7 +189,6 @@ static struct platform_driver ehci_hcd_sh_driver = {
|
||||
.shutdown = ehci_hcd_sh_shutdown,
|
||||
.driver = {
|
||||
.name = "sh_ehci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -210,7 +210,6 @@ static struct platform_driver ehci_hcd_tilegx_driver = {
|
||||
.shutdown = ehci_hcd_tilegx_drv_shutdown,
|
||||
.driver = {
|
||||
.name = "tilegx-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -236,7 +236,6 @@ static struct platform_driver ehci_hcd_xilinx_of_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "xilinx-of-ehci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ehci_hcd_xilinx_of_match,
|
||||
},
|
||||
};
|
||||
|
@@ -871,7 +871,7 @@ extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr,
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);
|
||||
extern int ehci_resume(struct usb_hcd *hcd, bool hibernated);
|
||||
extern int ehci_resume(struct usb_hcd *hcd, bool force_reset);
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
|
@@ -32,8 +32,8 @@ static u8 root_hub_des[] = {
|
||||
0x09, /* blength */
|
||||
0x29, /* bDescriptorType;hub-descriptor */
|
||||
0x01, /* bNbrPorts */
|
||||
0x00, /* wHubCharacteristics */
|
||||
0x00,
|
||||
HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM, /* wHubCharacteristics */
|
||||
0x00, /* per-port power, no overcurrent */
|
||||
0x01, /* bPwrOn2pwrGood;2ms */
|
||||
0x00, /* bHubContrCurrent;0mA */
|
||||
0x00, /* DeviceRemoveable */
|
||||
@@ -208,7 +208,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
{
|
||||
struct fhci_hcd *fhci = hcd_to_fhci(hcd);
|
||||
int retval = 0;
|
||||
int len = 0;
|
||||
struct usb_hub_status *hub_status;
|
||||
struct usb_port_status *port_status;
|
||||
unsigned long flags;
|
||||
@@ -272,8 +271,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
break;
|
||||
case GetHubDescriptor:
|
||||
memcpy(buf, root_hub_des, sizeof(root_hub_des));
|
||||
buf[3] = 0x11; /* per-port power, no ovrcrnt */
|
||||
len = (buf[0] < wLength) ? buf[0] : wLength;
|
||||
break;
|
||||
case GetHubStatus:
|
||||
hub_status = (struct usb_hub_status *)buf;
|
||||
@@ -281,7 +278,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
cpu_to_le16(fhci->vroot_hub->hub.wHubStatus);
|
||||
hub_status->wHubChange =
|
||||
cpu_to_le16(fhci->vroot_hub->hub.wHubChange);
|
||||
len = 4;
|
||||
break;
|
||||
case GetPortStatus:
|
||||
port_status = (struct usb_port_status *)buf;
|
||||
@@ -289,7 +285,6 @@ int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
cpu_to_le16(fhci->vroot_hub->port.wPortStatus);
|
||||
port_status->wPortChange =
|
||||
cpu_to_le16(fhci->vroot_hub->port.wPortChange);
|
||||
len = 4;
|
||||
break;
|
||||
case SetHubFeature:
|
||||
switch (wValue) {
|
||||
|
@@ -1521,8 +1521,8 @@ fotg210_hub_descriptor(
|
||||
memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
|
||||
memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
|
||||
|
||||
temp = 0x0008; /* per-port overcurrent reporting */
|
||||
temp |= 0x0002; /* no power switching */
|
||||
temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
|
||||
temp |= HUB_CHAR_NO_LPSM; /* no power switching */
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
}
|
||||
|
||||
|
@@ -1479,8 +1479,8 @@ fusbh200_hub_descriptor (
|
||||
memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
|
||||
memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
|
||||
|
||||
temp = 0x0008; /* per-port overcurrent reporting */
|
||||
temp |= 0x0002; /* no power switching */
|
||||
temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
|
||||
temp |= HUB_CHAR_NO_LPSM; /* no power switching */
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
}
|
||||
|
||||
|
@@ -1482,9 +1482,8 @@ static int get_hub_descriptor(struct usb_hcd *hcd,
|
||||
desc->bDescLength = 9;
|
||||
desc->bPwrOn2PwrGood = 0;
|
||||
desc->wHubCharacteristics = (__force __u16) cpu_to_le16(
|
||||
0x0002 | /* No power switching */
|
||||
0x0010 | /* No over current protection */
|
||||
0);
|
||||
HUB_CHAR_NO_LPSM | /* No power switching */
|
||||
HUB_CHAR_NO_OCPM); /* No over current protection */
|
||||
|
||||
desc->u.hs.DeviceRemovable[0] = 1 << 1;
|
||||
desc->u.hs.DeviceRemovable[1] = ~0;
|
||||
|
@@ -948,7 +948,10 @@ static void isp116x_hub_descriptor(struct isp116x *isp116x,
|
||||
desc->bHubContrCurrent = 0;
|
||||
desc->bNbrPorts = (u8) (reg & 0x3);
|
||||
/* Power switching, device type, overcurrent. */
|
||||
desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) & 0x1f));
|
||||
desc->wHubCharacteristics = cpu_to_le16((u16) ((reg >> 8) &
|
||||
(HUB_CHAR_LPSM |
|
||||
HUB_CHAR_COMPOUND |
|
||||
HUB_CHAR_OCPM)));
|
||||
desc->bPwrOn2PwrGood = (u8) ((reg >> 24) & 0xff);
|
||||
/* ports removable, and legacy PortPwrCtrlMask */
|
||||
desc->u.hs.DeviceRemovable[0] = 0;
|
||||
|
@@ -1543,8 +1543,12 @@ static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd,
|
||||
desc->bHubContrCurrent = 0;
|
||||
desc->bNbrPorts = reg & 0x3;
|
||||
/* Power switching, device type, overcurrent. */
|
||||
desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & 0x1f);
|
||||
DBG(0, "%s: hubcharacteristics = %02x\n", __func__, cpu_to_le16((reg >> 8) & 0x1f));
|
||||
desc->wHubCharacteristics = cpu_to_le16((reg >> 8) &
|
||||
(HUB_CHAR_LPSM |
|
||||
HUB_CHAR_COMPOUND |
|
||||
HUB_CHAR_OCPM));
|
||||
DBG(0, "%s: hubcharacteristics = %02x\n", __func__,
|
||||
desc->wHubCharacteristics);
|
||||
desc->bPwrOn2PwrGood = (reg >> 24) & 0xff;
|
||||
/* ports removable, and legacy PortPwrCtrlMask */
|
||||
desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,208 +0,0 @@
|
||||
#ifndef _ISP1760_HCD_H_
|
||||
#define _ISP1760_HCD_H_
|
||||
|
||||
/* exports for if */
|
||||
struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,
|
||||
int irq, unsigned long irqflags,
|
||||
int rst_gpio,
|
||||
struct device *dev, const char *busname,
|
||||
unsigned int devflags);
|
||||
int init_kmem_once(void);
|
||||
void deinit_kmem_cache(void);
|
||||
|
||||
/* EHCI capability registers */
|
||||
#define HC_CAPLENGTH 0x00
|
||||
#define HC_HCSPARAMS 0x04
|
||||
#define HC_HCCPARAMS 0x08
|
||||
|
||||
/* EHCI operational registers */
|
||||
#define HC_USBCMD 0x20
|
||||
#define HC_USBSTS 0x24
|
||||
#define HC_FRINDEX 0x2c
|
||||
#define HC_CONFIGFLAG 0x60
|
||||
#define HC_PORTSC1 0x64
|
||||
#define HC_ISO_PTD_DONEMAP_REG 0x130
|
||||
#define HC_ISO_PTD_SKIPMAP_REG 0x134
|
||||
#define HC_ISO_PTD_LASTPTD_REG 0x138
|
||||
#define HC_INT_PTD_DONEMAP_REG 0x140
|
||||
#define HC_INT_PTD_SKIPMAP_REG 0x144
|
||||
#define HC_INT_PTD_LASTPTD_REG 0x148
|
||||
#define HC_ATL_PTD_DONEMAP_REG 0x150
|
||||
#define HC_ATL_PTD_SKIPMAP_REG 0x154
|
||||
#define HC_ATL_PTD_LASTPTD_REG 0x158
|
||||
|
||||
/* Configuration Register */
|
||||
#define HC_HW_MODE_CTRL 0x300
|
||||
#define ALL_ATX_RESET (1 << 31)
|
||||
#define HW_ANA_DIGI_OC (1 << 15)
|
||||
#define HW_DATA_BUS_32BIT (1 << 8)
|
||||
#define HW_DACK_POL_HIGH (1 << 6)
|
||||
#define HW_DREQ_POL_HIGH (1 << 5)
|
||||
#define HW_INTR_HIGH_ACT (1 << 2)
|
||||
#define HW_INTR_EDGE_TRIG (1 << 1)
|
||||
#define HW_GLOBAL_INTR_EN (1 << 0)
|
||||
|
||||
#define HC_CHIP_ID_REG 0x304
|
||||
#define HC_SCRATCH_REG 0x308
|
||||
|
||||
#define HC_RESET_REG 0x30c
|
||||
#define SW_RESET_RESET_HC (1 << 1)
|
||||
#define SW_RESET_RESET_ALL (1 << 0)
|
||||
|
||||
#define HC_BUFFER_STATUS_REG 0x334
|
||||
#define ISO_BUF_FILL (1 << 2)
|
||||
#define INT_BUF_FILL (1 << 1)
|
||||
#define ATL_BUF_FILL (1 << 0)
|
||||
|
||||
#define HC_MEMORY_REG 0x33c
|
||||
#define ISP_BANK(x) ((x) << 16)
|
||||
|
||||
#define HC_PORT1_CTRL 0x374
|
||||
#define PORT1_POWER (3 << 3)
|
||||
#define PORT1_INIT1 (1 << 7)
|
||||
#define PORT1_INIT2 (1 << 23)
|
||||
#define HW_OTG_CTRL_SET 0x374
|
||||
#define HW_OTG_CTRL_CLR 0x376
|
||||
|
||||
/* Interrupt Register */
|
||||
#define HC_INTERRUPT_REG 0x310
|
||||
|
||||
#define HC_INTERRUPT_ENABLE 0x314
|
||||
#define HC_ISO_INT (1 << 9)
|
||||
#define HC_ATL_INT (1 << 8)
|
||||
#define HC_INTL_INT (1 << 7)
|
||||
#define HC_EOT_INT (1 << 3)
|
||||
#define HC_SOT_INT (1 << 1)
|
||||
#define INTERRUPT_ENABLE_MASK (HC_INTL_INT | HC_ATL_INT)
|
||||
|
||||
#define HC_ISO_IRQ_MASK_OR_REG 0x318
|
||||
#define HC_INT_IRQ_MASK_OR_REG 0x31C
|
||||
#define HC_ATL_IRQ_MASK_OR_REG 0x320
|
||||
#define HC_ISO_IRQ_MASK_AND_REG 0x324
|
||||
#define HC_INT_IRQ_MASK_AND_REG 0x328
|
||||
#define HC_ATL_IRQ_MASK_AND_REG 0x32C
|
||||
|
||||
/* urb state*/
|
||||
#define DELETE_URB (0x0008)
|
||||
#define NO_TRANSFER_ACTIVE (0xffffffff)
|
||||
|
||||
/* Philips Proprietary Transfer Descriptor (PTD) */
|
||||
typedef __u32 __bitwise __dw;
|
||||
struct ptd {
|
||||
__dw dw0;
|
||||
__dw dw1;
|
||||
__dw dw2;
|
||||
__dw dw3;
|
||||
__dw dw4;
|
||||
__dw dw5;
|
||||
__dw dw6;
|
||||
__dw dw7;
|
||||
};
|
||||
#define PTD_OFFSET 0x0400
|
||||
#define ISO_PTD_OFFSET 0x0400
|
||||
#define INT_PTD_OFFSET 0x0800
|
||||
#define ATL_PTD_OFFSET 0x0c00
|
||||
#define PAYLOAD_OFFSET 0x1000
|
||||
|
||||
struct slotinfo {
|
||||
struct isp1760_qh *qh;
|
||||
struct isp1760_qtd *qtd;
|
||||
unsigned long timestamp;
|
||||
};
|
||||
|
||||
|
||||
typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
|
||||
struct isp1760_qtd *qtd);
|
||||
|
||||
/*
|
||||
* Device flags that can vary from board to board. All of these
|
||||
* indicate the most "atypical" case, so that a devflags of 0 is
|
||||
* a sane default configuration.
|
||||
*/
|
||||
#define ISP1760_FLAG_BUS_WIDTH_16 0x00000002 /* 16-bit data bus width */
|
||||
#define ISP1760_FLAG_OTG_EN 0x00000004 /* Port 1 supports OTG */
|
||||
#define ISP1760_FLAG_ANALOG_OC 0x00000008 /* Analog overcurrent */
|
||||
#define ISP1760_FLAG_DACK_POL_HIGH 0x00000010 /* DACK active high */
|
||||
#define ISP1760_FLAG_DREQ_POL_HIGH 0x00000020 /* DREQ active high */
|
||||
#define ISP1760_FLAG_ISP1761 0x00000040 /* Chip is ISP1761 */
|
||||
#define ISP1760_FLAG_INTR_POL_HIGH 0x00000080 /* Interrupt polarity active high */
|
||||
#define ISP1760_FLAG_INTR_EDGE_TRIG 0x00000100 /* Interrupt edge triggered */
|
||||
#define ISP1760_FLAG_RESET_ACTIVE_HIGH 0x80000000 /* RESET GPIO active high */
|
||||
|
||||
/* chip memory management */
|
||||
struct memory_chunk {
|
||||
unsigned int start;
|
||||
unsigned int size;
|
||||
unsigned int free;
|
||||
};
|
||||
|
||||
/*
|
||||
* 60kb divided in:
|
||||
* - 32 blocks @ 256 bytes
|
||||
* - 20 blocks @ 1024 bytes
|
||||
* - 4 blocks @ 8192 bytes
|
||||
*/
|
||||
|
||||
#define BLOCK_1_NUM 32
|
||||
#define BLOCK_2_NUM 20
|
||||
#define BLOCK_3_NUM 4
|
||||
|
||||
#define BLOCK_1_SIZE 256
|
||||
#define BLOCK_2_SIZE 1024
|
||||
#define BLOCK_3_SIZE 8192
|
||||
#define BLOCKS (BLOCK_1_NUM + BLOCK_2_NUM + BLOCK_3_NUM)
|
||||
#define MAX_PAYLOAD_SIZE BLOCK_3_SIZE
|
||||
#define PAYLOAD_AREA_SIZE 0xf000
|
||||
|
||||
/* ATL */
|
||||
/* DW0 */
|
||||
#define DW0_VALID_BIT 1
|
||||
#define FROM_DW0_VALID(x) ((x) & 0x01)
|
||||
#define TO_DW0_LENGTH(x) (((u32) x) << 3)
|
||||
#define TO_DW0_MAXPACKET(x) (((u32) x) << 18)
|
||||
#define TO_DW0_MULTI(x) (((u32) x) << 29)
|
||||
#define TO_DW0_ENDPOINT(x) (((u32) x) << 31)
|
||||
/* DW1 */
|
||||
#define TO_DW1_DEVICE_ADDR(x) (((u32) x) << 3)
|
||||
#define TO_DW1_PID_TOKEN(x) (((u32) x) << 10)
|
||||
#define DW1_TRANS_BULK ((u32) 2 << 12)
|
||||
#define DW1_TRANS_INT ((u32) 3 << 12)
|
||||
#define DW1_TRANS_SPLIT ((u32) 1 << 14)
|
||||
#define DW1_SE_USB_LOSPEED ((u32) 2 << 16)
|
||||
#define TO_DW1_PORT_NUM(x) (((u32) x) << 18)
|
||||
#define TO_DW1_HUB_NUM(x) (((u32) x) << 25)
|
||||
/* DW2 */
|
||||
#define TO_DW2_DATA_START_ADDR(x) (((u32) x) << 8)
|
||||
#define TO_DW2_RL(x) ((x) << 25)
|
||||
#define FROM_DW2_RL(x) (((x) >> 25) & 0xf)
|
||||
/* DW3 */
|
||||
#define FROM_DW3_NRBYTESTRANSFERRED(x) ((x) & 0x7fff)
|
||||
#define FROM_DW3_SCS_NRBYTESTRANSFERRED(x) ((x) & 0x07ff)
|
||||
#define TO_DW3_NAKCOUNT(x) ((x) << 19)
|
||||
#define FROM_DW3_NAKCOUNT(x) (((x) >> 19) & 0xf)
|
||||
#define TO_DW3_CERR(x) ((x) << 23)
|
||||
#define FROM_DW3_CERR(x) (((x) >> 23) & 0x3)
|
||||
#define TO_DW3_DATA_TOGGLE(x) ((x) << 25)
|
||||
#define FROM_DW3_DATA_TOGGLE(x) (((x) >> 25) & 0x1)
|
||||
#define TO_DW3_PING(x) ((x) << 26)
|
||||
#define FROM_DW3_PING(x) (((x) >> 26) & 0x1)
|
||||
#define DW3_ERROR_BIT (1 << 28)
|
||||
#define DW3_BABBLE_BIT (1 << 29)
|
||||
#define DW3_HALT_BIT (1 << 30)
|
||||
#define DW3_ACTIVE_BIT (1 << 31)
|
||||
#define FROM_DW3_ACTIVE(x) (((x) >> 31) & 0x01)
|
||||
|
||||
#define INT_UNDERRUN (1 << 2)
|
||||
#define INT_BABBLE (1 << 1)
|
||||
#define INT_EXACT (1 << 0)
|
||||
|
||||
#define SETUP_PID (2)
|
||||
#define IN_PID (1)
|
||||
#define OUT_PID (0)
|
||||
|
||||
/* Errata 1 */
|
||||
#define RL_COUNTER (0)
|
||||
#define NAK_COUNTER (0)
|
||||
#define ERR_COUNTER (2)
|
||||
|
||||
#endif /* _ISP1760_HCD_H_ */
|
@@ -1,477 +0,0 @@
|
||||
/*
|
||||
* Glue code for the ISP1760 driver and bus
|
||||
* Currently there is support for
|
||||
* - OpenFirmware
|
||||
* - PCI
|
||||
* - PDEV (generic platform device centralized driver model)
|
||||
*
|
||||
* (c) 2007 Sebastian Siewior <bigeasy@linutronix.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/usb.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/isp1760.h>
|
||||
#include <linux/usb/hcd.h>
|
||||
|
||||
#include "isp1760-hcd.h"
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#include <linux/pci.h>
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
|
||||
struct isp1760 {
|
||||
struct usb_hcd *hcd;
|
||||
int rst_gpio;
|
||||
};
|
||||
|
||||
static int of_isp1760_probe(struct platform_device *dev)
|
||||
{
|
||||
struct isp1760 *drvdata;
|
||||
struct device_node *dp = dev->dev.of_node;
|
||||
struct resource *res;
|
||||
struct resource memory;
|
||||
int virq;
|
||||
resource_size_t res_len;
|
||||
int ret;
|
||||
unsigned int devflags = 0;
|
||||
enum of_gpio_flags gpio_flags;
|
||||
u32 bus_width = 0;
|
||||
|
||||
drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
|
||||
if (!drvdata)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = of_address_to_resource(dp, 0, &memory);
|
||||
if (ret) {
|
||||
ret = -ENXIO;
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
res_len = resource_size(&memory);
|
||||
|
||||
res = request_mem_region(memory.start, res_len, dev_name(&dev->dev));
|
||||
if (!res) {
|
||||
ret = -EBUSY;
|
||||
goto free_data;
|
||||
}
|
||||
|
||||
virq = irq_of_parse_and_map(dp, 0);
|
||||
if (!virq) {
|
||||
ret = -ENODEV;
|
||||
goto release_reg;
|
||||
}
|
||||
|
||||
if (of_device_is_compatible(dp, "nxp,usb-isp1761"))
|
||||
devflags |= ISP1760_FLAG_ISP1761;
|
||||
|
||||
/* Some systems wire up only 16 of the 32 data lines */
|
||||
of_property_read_u32(dp, "bus-width", &bus_width);
|
||||
if (bus_width == 16)
|
||||
devflags |= ISP1760_FLAG_BUS_WIDTH_16;
|
||||
|
||||
if (of_get_property(dp, "port1-otg", NULL) != NULL)
|
||||
devflags |= ISP1760_FLAG_OTG_EN;
|
||||
|
||||
if (of_get_property(dp, "analog-oc", NULL) != NULL)
|
||||
devflags |= ISP1760_FLAG_ANALOG_OC;
|
||||
|
||||
if (of_get_property(dp, "dack-polarity", NULL) != NULL)
|
||||
devflags |= ISP1760_FLAG_DACK_POL_HIGH;
|
||||
|
||||
if (of_get_property(dp, "dreq-polarity", NULL) != NULL)
|
||||
devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
|
||||
|
||||
drvdata->rst_gpio = of_get_gpio_flags(dp, 0, &gpio_flags);
|
||||
if (gpio_is_valid(drvdata->rst_gpio)) {
|
||||
ret = gpio_request(drvdata->rst_gpio, dev_name(&dev->dev));
|
||||
if (!ret) {
|
||||
if (!(gpio_flags & OF_GPIO_ACTIVE_LOW)) {
|
||||
devflags |= ISP1760_FLAG_RESET_ACTIVE_HIGH;
|
||||
gpio_direction_output(drvdata->rst_gpio, 0);
|
||||
} else {
|
||||
gpio_direction_output(drvdata->rst_gpio, 1);
|
||||
}
|
||||
} else {
|
||||
drvdata->rst_gpio = ret;
|
||||
}
|
||||
}
|
||||
|
||||
drvdata->hcd = isp1760_register(memory.start, res_len, virq,
|
||||
IRQF_SHARED, drvdata->rst_gpio,
|
||||
&dev->dev, dev_name(&dev->dev),
|
||||
devflags);
|
||||
if (IS_ERR(drvdata->hcd)) {
|
||||
ret = PTR_ERR(drvdata->hcd);
|
||||
goto free_gpio;
|
||||
}
|
||||
|
||||
platform_set_drvdata(dev, drvdata);
|
||||
return ret;
|
||||
|
||||
free_gpio:
|
||||
if (gpio_is_valid(drvdata->rst_gpio))
|
||||
gpio_free(drvdata->rst_gpio);
|
||||
release_reg:
|
||||
release_mem_region(memory.start, res_len);
|
||||
free_data:
|
||||
kfree(drvdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int of_isp1760_remove(struct platform_device *dev)
|
||||
{
|
||||
struct isp1760 *drvdata = platform_get_drvdata(dev);
|
||||
|
||||
usb_remove_hcd(drvdata->hcd);
|
||||
iounmap(drvdata->hcd->regs);
|
||||
release_mem_region(drvdata->hcd->rsrc_start, drvdata->hcd->rsrc_len);
|
||||
usb_put_hcd(drvdata->hcd);
|
||||
|
||||
if (gpio_is_valid(drvdata->rst_gpio))
|
||||
gpio_free(drvdata->rst_gpio);
|
||||
|
||||
kfree(drvdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_isp1760_match[] = {
|
||||
{
|
||||
.compatible = "nxp,usb-isp1760",
|
||||
},
|
||||
{
|
||||
.compatible = "nxp,usb-isp1761",
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_isp1760_match);
|
||||
|
||||
static struct platform_driver isp1760_of_driver = {
|
||||
.driver = {
|
||||
.name = "nxp-isp1760",
|
||||
.of_match_table = of_isp1760_match,
|
||||
},
|
||||
.probe = of_isp1760_probe,
|
||||
.remove = of_isp1760_remove,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static int isp1761_pci_probe(struct pci_dev *dev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
u8 latency, limit;
|
||||
__u32 reg_data;
|
||||
int retry_count;
|
||||
struct usb_hcd *hcd;
|
||||
unsigned int devflags = 0;
|
||||
int ret_status = 0;
|
||||
|
||||
resource_size_t pci_mem_phy0;
|
||||
resource_size_t memlength;
|
||||
|
||||
u8 __iomem *chip_addr;
|
||||
u8 __iomem *iobase;
|
||||
resource_size_t nxp_pci_io_base;
|
||||
resource_size_t iolength;
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
if (pci_enable_device(dev) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dev->irq)
|
||||
return -ENODEV;
|
||||
|
||||
/* Grab the PLX PCI mem maped port start address we need */
|
||||
nxp_pci_io_base = pci_resource_start(dev, 0);
|
||||
iolength = pci_resource_len(dev, 0);
|
||||
|
||||
if (!request_mem_region(nxp_pci_io_base, iolength, "ISP1761 IO MEM")) {
|
||||
printk(KERN_ERR "request region #1\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
iobase = ioremap_nocache(nxp_pci_io_base, iolength);
|
||||
if (!iobase) {
|
||||
printk(KERN_ERR "ioremap #1\n");
|
||||
ret_status = -ENOMEM;
|
||||
goto cleanup1;
|
||||
}
|
||||
/* Grab the PLX PCI shared memory of the ISP 1761 we need */
|
||||
pci_mem_phy0 = pci_resource_start(dev, 3);
|
||||
memlength = pci_resource_len(dev, 3);
|
||||
if (memlength < 0xffff) {
|
||||
printk(KERN_ERR "memory length for this resource is wrong\n");
|
||||
ret_status = -ENOMEM;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
if (!request_mem_region(pci_mem_phy0, memlength, "ISP-PCI")) {
|
||||
printk(KERN_ERR "host controller already in use\n");
|
||||
ret_status = -EBUSY;
|
||||
goto cleanup2;
|
||||
}
|
||||
|
||||
/* map available memory */
|
||||
chip_addr = ioremap_nocache(pci_mem_phy0,memlength);
|
||||
if (!chip_addr) {
|
||||
printk(KERN_ERR "Error ioremap failed\n");
|
||||
ret_status = -ENOMEM;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* bad pci latencies can contribute to overruns */
|
||||
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);
|
||||
if (latency) {
|
||||
pci_read_config_byte(dev, PCI_MAX_LAT, &limit);
|
||||
if (limit && limit < latency)
|
||||
pci_write_config_byte(dev, PCI_LATENCY_TIMER, limit);
|
||||
}
|
||||
|
||||
/* Try to check whether we can access Scratch Register of
|
||||
* Host Controller or not. The initial PCI access is retried until
|
||||
* local init for the PCI bridge is completed
|
||||
*/
|
||||
retry_count = 20;
|
||||
reg_data = 0;
|
||||
while ((reg_data != 0xFACE) && retry_count) {
|
||||
/*by default host is in 16bit mode, so
|
||||
* io operations at this stage must be 16 bit
|
||||
* */
|
||||
writel(0xface, chip_addr + HC_SCRATCH_REG);
|
||||
udelay(100);
|
||||
reg_data = readl(chip_addr + HC_SCRATCH_REG) & 0x0000ffff;
|
||||
retry_count--;
|
||||
}
|
||||
|
||||
iounmap(chip_addr);
|
||||
|
||||
/* Host Controller presence is detected by writing to scratch register
|
||||
* and reading back and checking the contents are same or not
|
||||
*/
|
||||
if (reg_data != 0xFACE) {
|
||||
dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
|
||||
ret_status = -ENOMEM;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
pci_set_master(dev);
|
||||
|
||||
/* configure PLX PCI chip to pass interrupts */
|
||||
#define PLX_INT_CSR_REG 0x68
|
||||
reg_data = readl(iobase + PLX_INT_CSR_REG);
|
||||
reg_data |= 0x900;
|
||||
writel(reg_data, iobase + PLX_INT_CSR_REG);
|
||||
|
||||
dev->dev.dma_mask = NULL;
|
||||
hcd = isp1760_register(pci_mem_phy0, memlength, dev->irq,
|
||||
IRQF_SHARED, -ENOENT, &dev->dev, dev_name(&dev->dev),
|
||||
devflags);
|
||||
if (IS_ERR(hcd)) {
|
||||
ret_status = -ENODEV;
|
||||
goto cleanup3;
|
||||
}
|
||||
|
||||
/* done with PLX IO access */
|
||||
iounmap(iobase);
|
||||
release_mem_region(nxp_pci_io_base, iolength);
|
||||
|
||||
pci_set_drvdata(dev, hcd);
|
||||
return 0;
|
||||
|
||||
cleanup3:
|
||||
release_mem_region(pci_mem_phy0, memlength);
|
||||
cleanup2:
|
||||
iounmap(iobase);
|
||||
cleanup1:
|
||||
release_mem_region(nxp_pci_io_base, iolength);
|
||||
return ret_status;
|
||||
}
|
||||
|
||||
static void isp1761_pci_remove(struct pci_dev *dev)
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
|
||||
hcd = pci_get_drvdata(dev);
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
iounmap(hcd->regs);
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
pci_disable_device(dev);
|
||||
}
|
||||
|
||||
static void isp1761_pci_shutdown(struct pci_dev *dev)
|
||||
{
|
||||
printk(KERN_ERR "ips1761_pci_shutdown\n");
|
||||
}
|
||||
|
||||
static const struct pci_device_id isp1760_plx [] = {
|
||||
{
|
||||
.class = PCI_CLASS_BRIDGE_OTHER << 8,
|
||||
.class_mask = ~0,
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = 0x5406,
|
||||
.subvendor = PCI_VENDOR_ID_PLX,
|
||||
.subdevice = 0x9054,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, isp1760_plx);
|
||||
|
||||
static struct pci_driver isp1761_pci_driver = {
|
||||
.name = "isp1760",
|
||||
.id_table = isp1760_plx,
|
||||
.probe = isp1761_pci_probe,
|
||||
.remove = isp1761_pci_remove,
|
||||
.shutdown = isp1761_pci_shutdown,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int isp1760_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct usb_hcd *hcd;
|
||||
struct resource *mem_res;
|
||||
struct resource *irq_res;
|
||||
resource_size_t mem_size;
|
||||
struct isp1760_platform_data *priv = dev_get_platdata(&pdev->dev);
|
||||
unsigned int devflags = 0;
|
||||
unsigned long irqflags = IRQF_SHARED;
|
||||
|
||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!mem_res) {
|
||||
pr_warning("isp1760: Memory resource not available\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
mem_size = resource_size(mem_res);
|
||||
if (!request_mem_region(mem_res->start, mem_size, "isp1760")) {
|
||||
pr_warning("isp1760: Cannot reserve the memory resource\n");
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (!irq_res) {
|
||||
pr_warning("isp1760: IRQ resource not available\n");
|
||||
ret = -ENODEV;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
irqflags |= irq_res->flags & IRQF_TRIGGER_MASK;
|
||||
|
||||
if (priv) {
|
||||
if (priv->is_isp1761)
|
||||
devflags |= ISP1760_FLAG_ISP1761;
|
||||
if (priv->bus_width_16)
|
||||
devflags |= ISP1760_FLAG_BUS_WIDTH_16;
|
||||
if (priv->port1_otg)
|
||||
devflags |= ISP1760_FLAG_OTG_EN;
|
||||
if (priv->analog_oc)
|
||||
devflags |= ISP1760_FLAG_ANALOG_OC;
|
||||
if (priv->dack_polarity_high)
|
||||
devflags |= ISP1760_FLAG_DACK_POL_HIGH;
|
||||
if (priv->dreq_polarity_high)
|
||||
devflags |= ISP1760_FLAG_DREQ_POL_HIGH;
|
||||
}
|
||||
|
||||
hcd = isp1760_register(mem_res->start, mem_size, irq_res->start,
|
||||
irqflags, -ENOENT,
|
||||
&pdev->dev, dev_name(&pdev->dev), devflags);
|
||||
|
||||
platform_set_drvdata(pdev, hcd);
|
||||
|
||||
if (IS_ERR(hcd)) {
|
||||
pr_warning("isp1760: Failed to register the HCD device\n");
|
||||
ret = -ENODEV;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pr_info("ISP1760 USB device initialised\n");
|
||||
return ret;
|
||||
|
||||
cleanup:
|
||||
release_mem_region(mem_res->start, mem_size);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int isp1760_plat_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *mem_res;
|
||||
resource_size_t mem_size;
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
|
||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mem_size = resource_size(mem_res);
|
||||
release_mem_region(mem_res->start, mem_size);
|
||||
|
||||
usb_put_hcd(hcd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver isp1760_plat_driver = {
|
||||
.probe = isp1760_plat_probe,
|
||||
.remove = isp1760_plat_remove,
|
||||
.driver = {
|
||||
.name = "isp1760",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init isp1760_init(void)
|
||||
{
|
||||
int ret, any_ret = -ENODEV;
|
||||
|
||||
init_kmem_once();
|
||||
|
||||
ret = platform_driver_register(&isp1760_plat_driver);
|
||||
if (!ret)
|
||||
any_ret = 0;
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
|
||||
ret = platform_driver_register(&isp1760_of_driver);
|
||||
if (!ret)
|
||||
any_ret = 0;
|
||||
#endif
|
||||
#ifdef CONFIG_PCI
|
||||
ret = pci_register_driver(&isp1761_pci_driver);
|
||||
if (!ret)
|
||||
any_ret = 0;
|
||||
#endif
|
||||
|
||||
if (any_ret)
|
||||
deinit_kmem_cache();
|
||||
return any_ret;
|
||||
}
|
||||
module_init(isp1760_init);
|
||||
|
||||
static void __exit isp1760_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&isp1760_plat_driver);
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
|
||||
platform_driver_unregister(&isp1760_of_driver);
|
||||
#endif
|
||||
#ifdef CONFIG_PCI
|
||||
pci_unregister_driver(&isp1761_pci_driver);
|
||||
#endif
|
||||
deinit_kmem_cache();
|
||||
}
|
||||
module_exit(isp1760_exit);
|
@@ -55,6 +55,7 @@
|
||||
* single thread (max3421_spi_thread).
|
||||
*/
|
||||
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/usb.h>
|
||||
@@ -1291,7 +1292,7 @@ max3421_handle_irqs(struct usb_hcd *hcd)
|
||||
char sbuf[16 * 16], *dp, *end;
|
||||
int i;
|
||||
|
||||
if (jiffies - last_time > 5*HZ) {
|
||||
if (time_after(jiffies, last_time + 5*HZ)) {
|
||||
dp = sbuf;
|
||||
end = sbuf + sizeof(sbuf);
|
||||
*dp = '\0';
|
||||
@@ -1660,7 +1661,8 @@ hub_descriptor(struct usb_hub_descriptor *desc)
|
||||
*/
|
||||
desc->bDescriptorType = 0x29; /* hub descriptor */
|
||||
desc->bDescLength = 9;
|
||||
desc->wHubCharacteristics = cpu_to_le16(0x0001);
|
||||
desc->wHubCharacteristics = cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM |
|
||||
HUB_CHAR_COMMON_OCPM);
|
||||
desc->bNbrPorts = 1;
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,17 @@
|
||||
for ((index) = 0; (index) < AT91_MAX_USBH_PORTS; (index)++)
|
||||
|
||||
/* interface, function and usb clocks; sometimes also an AHB clock */
|
||||
static struct clk *iclk, *fclk, *uclk, *hclk;
|
||||
#define hcd_to_ohci_at91_priv(h) \
|
||||
((struct ohci_at91_priv *)hcd_to_ohci(h)->priv)
|
||||
|
||||
struct ohci_at91_priv {
|
||||
struct clk *iclk;
|
||||
struct clk *fclk;
|
||||
struct clk *uclk;
|
||||
struct clk *hclk;
|
||||
bool clocked;
|
||||
bool wakeup; /* Saved wake-up state for resume */
|
||||
};
|
||||
/* interface and function clocks; sometimes also an AHB clock */
|
||||
|
||||
#define DRIVER_DESC "OHCI Atmel driver"
|
||||
@@ -41,45 +51,53 @@ static struct clk *iclk, *fclk, *uclk, *hclk;
|
||||
static const char hcd_name[] = "ohci-atmel";
|
||||
|
||||
static struct hc_driver __read_mostly ohci_at91_hc_driver;
|
||||
static int clocked;
|
||||
|
||||
static const struct ohci_driver_overrides ohci_at91_drv_overrides __initconst = {
|
||||
.extra_priv_size = sizeof(struct ohci_at91_priv),
|
||||
};
|
||||
|
||||
extern int usb_disabled(void);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void at91_start_clock(void)
|
||||
static void at91_start_clock(struct ohci_at91_priv *ohci_at91)
|
||||
{
|
||||
if (ohci_at91->clocked)
|
||||
return;
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
|
||||
clk_set_rate(uclk, 48000000);
|
||||
clk_prepare_enable(uclk);
|
||||
clk_set_rate(ohci_at91->uclk, 48000000);
|
||||
clk_prepare_enable(ohci_at91->uclk);
|
||||
}
|
||||
clk_prepare_enable(hclk);
|
||||
clk_prepare_enable(iclk);
|
||||
clk_prepare_enable(fclk);
|
||||
clocked = 1;
|
||||
clk_prepare_enable(ohci_at91->hclk);
|
||||
clk_prepare_enable(ohci_at91->iclk);
|
||||
clk_prepare_enable(ohci_at91->fclk);
|
||||
ohci_at91->clocked = true;
|
||||
}
|
||||
|
||||
static void at91_stop_clock(void)
|
||||
static void at91_stop_clock(struct ohci_at91_priv *ohci_at91)
|
||||
{
|
||||
clk_disable_unprepare(fclk);
|
||||
clk_disable_unprepare(iclk);
|
||||
clk_disable_unprepare(hclk);
|
||||
if (!ohci_at91->clocked)
|
||||
return;
|
||||
clk_disable_unprepare(ohci_at91->fclk);
|
||||
clk_disable_unprepare(ohci_at91->iclk);
|
||||
clk_disable_unprepare(ohci_at91->hclk);
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK))
|
||||
clk_disable_unprepare(uclk);
|
||||
clocked = 0;
|
||||
clk_disable_unprepare(ohci_at91->uclk);
|
||||
ohci_at91->clocked = false;
|
||||
}
|
||||
|
||||
static void at91_start_hc(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct ohci_regs __iomem *regs = hcd->regs;
|
||||
struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
|
||||
dev_dbg(&pdev->dev, "start\n");
|
||||
|
||||
/*
|
||||
* Start the USB clocks.
|
||||
*/
|
||||
at91_start_clock();
|
||||
at91_start_clock(ohci_at91);
|
||||
|
||||
/*
|
||||
* The USB host controller must remain in reset.
|
||||
@@ -91,6 +109,7 @@ static void at91_stop_hc(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct ohci_regs __iomem *regs = hcd->regs;
|
||||
struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
|
||||
dev_dbg(&pdev->dev, "stop\n");
|
||||
|
||||
@@ -102,7 +121,7 @@ static void at91_stop_hc(struct platform_device *pdev)
|
||||
/*
|
||||
* Stop the USB clocks.
|
||||
*/
|
||||
at91_stop_clock();
|
||||
at91_stop_clock(ohci_at91);
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +147,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
|
||||
struct at91_usbh_data *board;
|
||||
struct ohci_hcd *ohci;
|
||||
int retval;
|
||||
struct usb_hcd *hcd = NULL;
|
||||
struct usb_hcd *hcd;
|
||||
struct ohci_at91_priv *ohci_at91;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
int irq;
|
||||
@@ -142,6 +162,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
|
||||
hcd = usb_create_hcd(driver, dev, "at91");
|
||||
if (!hcd)
|
||||
return -ENOMEM;
|
||||
ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
hcd->regs = devm_ioremap_resource(dev, res);
|
||||
@@ -152,29 +173,29 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
|
||||
hcd->rsrc_start = res->start;
|
||||
hcd->rsrc_len = resource_size(res);
|
||||
|
||||
iclk = devm_clk_get(dev, "ohci_clk");
|
||||
if (IS_ERR(iclk)) {
|
||||
ohci_at91->iclk = devm_clk_get(dev, "ohci_clk");
|
||||
if (IS_ERR(ohci_at91->iclk)) {
|
||||
dev_err(dev, "failed to get ohci_clk\n");
|
||||
retval = PTR_ERR(iclk);
|
||||
retval = PTR_ERR(ohci_at91->iclk);
|
||||
goto err;
|
||||
}
|
||||
fclk = devm_clk_get(dev, "uhpck");
|
||||
if (IS_ERR(fclk)) {
|
||||
ohci_at91->fclk = devm_clk_get(dev, "uhpck");
|
||||
if (IS_ERR(ohci_at91->fclk)) {
|
||||
dev_err(dev, "failed to get uhpck\n");
|
||||
retval = PTR_ERR(fclk);
|
||||
retval = PTR_ERR(ohci_at91->fclk);
|
||||
goto err;
|
||||
}
|
||||
hclk = devm_clk_get(dev, "hclk");
|
||||
if (IS_ERR(hclk)) {
|
||||
ohci_at91->hclk = devm_clk_get(dev, "hclk");
|
||||
if (IS_ERR(ohci_at91->hclk)) {
|
||||
dev_err(dev, "failed to get hclk\n");
|
||||
retval = PTR_ERR(hclk);
|
||||
retval = PTR_ERR(ohci_at91->hclk);
|
||||
goto err;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_COMMON_CLK)) {
|
||||
uclk = devm_clk_get(dev, "usb_clk");
|
||||
if (IS_ERR(uclk)) {
|
||||
ohci_at91->uclk = devm_clk_get(dev, "usb_clk");
|
||||
if (IS_ERR(ohci_at91->uclk)) {
|
||||
dev_err(dev, "failed to get uclk\n");
|
||||
retval = PTR_ERR(uclk);
|
||||
retval = PTR_ERR(ohci_at91->uclk);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -347,11 +368,13 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
||||
*/
|
||||
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(0x0001);
|
||||
desc->wHubCharacteristics |=
|
||||
cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM);
|
||||
|
||||
if (pdata->overcurrent_supported) {
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001);
|
||||
desc->wHubCharacteristics |=
|
||||
cpu_to_le16(HUB_CHAR_INDV_PORT_OCPM);
|
||||
}
|
||||
|
||||
dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
|
||||
@@ -593,19 +616,27 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int
|
||||
ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
ohci_hcd_at91_drv_suspend(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||
bool do_wakeup = device_may_wakeup(&pdev->dev);
|
||||
struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
int ret;
|
||||
|
||||
if (do_wakeup)
|
||||
/*
|
||||
* Disable wakeup if we are going to sleep with slow clock mode
|
||||
* enabled.
|
||||
*/
|
||||
ohci_at91->wakeup = device_may_wakeup(dev)
|
||||
&& !at91_suspend_entering_slow_clock();
|
||||
|
||||
if (ohci_at91->wakeup)
|
||||
enable_irq_wake(hcd->irq);
|
||||
|
||||
ret = ohci_suspend(hcd, do_wakeup);
|
||||
ret = ohci_suspend(hcd, ohci_at91->wakeup);
|
||||
if (ret) {
|
||||
disable_irq_wake(hcd->irq);
|
||||
if (ohci_at91->wakeup)
|
||||
disable_irq_wake(hcd->irq);
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
@@ -615,7 +646,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
*
|
||||
* REVISIT: some boards will be able to turn VBUS off...
|
||||
*/
|
||||
if (at91_suspend_entering_slow_clock()) {
|
||||
if (!ohci_at91->wakeup) {
|
||||
ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
|
||||
ohci->hc_control &= OHCI_CTRL_RWC;
|
||||
ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
|
||||
@@ -623,38 +654,37 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
|
||||
|
||||
/* flush the writes */
|
||||
(void) ohci_readl (ohci, &ohci->regs->control);
|
||||
at91_stop_clock();
|
||||
at91_stop_clock(ohci_at91);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
|
||||
static int ohci_hcd_at91_drv_resume(struct device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(pdev);
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd);
|
||||
|
||||
if (device_may_wakeup(&pdev->dev))
|
||||
if (ohci_at91->wakeup)
|
||||
disable_irq_wake(hcd->irq);
|
||||
|
||||
if (!clocked)
|
||||
at91_start_clock();
|
||||
at91_start_clock(ohci_at91);
|
||||
|
||||
ohci_resume(hcd, false);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define ohci_hcd_at91_drv_suspend NULL
|
||||
#define ohci_hcd_at91_drv_resume NULL
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(ohci_hcd_at91_pm_ops, ohci_hcd_at91_drv_suspend,
|
||||
ohci_hcd_at91_drv_resume);
|
||||
|
||||
static struct platform_driver ohci_hcd_at91_driver = {
|
||||
.probe = ohci_hcd_at91_drv_probe,
|
||||
.remove = ohci_hcd_at91_drv_remove,
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.suspend = ohci_hcd_at91_drv_suspend,
|
||||
.resume = ohci_hcd_at91_drv_resume,
|
||||
.driver = {
|
||||
.name = "at91_ohci",
|
||||
.pm = &ohci_hcd_at91_pm_ops,
|
||||
.of_match_table = of_match_ptr(at91_ohci_dt_ids),
|
||||
},
|
||||
};
|
||||
@@ -665,7 +695,7 @@ static int __init ohci_at91_init(void)
|
||||
return -ENODEV;
|
||||
|
||||
pr_info("%s: " DRIVER_DESC "\n", hcd_name);
|
||||
ohci_init_driver(&ohci_at91_hc_driver, NULL);
|
||||
ohci_init_driver(&ohci_at91_hc_driver, &ohci_at91_drv_overrides);
|
||||
|
||||
/*
|
||||
* The Atmel HW has some unusual quirks, which require Atmel-specific
|
||||
|
@@ -431,7 +431,6 @@ static struct platform_driver ohci_hcd_da8xx_driver = {
|
||||
.resume = ohci_da8xx_resume,
|
||||
#endif
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ohci",
|
||||
},
|
||||
};
|
||||
|
@@ -544,15 +544,15 @@ ohci_hub_descriptor (
|
||||
temp = 1 + (ohci->num_ports / 8);
|
||||
desc->bDescLength = 7 + 2 * temp;
|
||||
|
||||
temp = 0;
|
||||
temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM;
|
||||
if (rh & RH_A_NPS) /* no power switching? */
|
||||
temp |= 0x0002;
|
||||
temp |= HUB_CHAR_NO_LPSM;
|
||||
if (rh & RH_A_PSM) /* per-port power switching? */
|
||||
temp |= 0x0001;
|
||||
temp |= HUB_CHAR_INDV_PORT_LPSM;
|
||||
if (rh & RH_A_NOCP) /* no overcurrent reporting? */
|
||||
temp |= 0x0010;
|
||||
temp |= HUB_CHAR_NO_OCPM;
|
||||
else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */
|
||||
temp |= 0x0008;
|
||||
temp |= HUB_CHAR_INDV_PORT_OCPM;
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
|
||||
/* ports removable, and usb 1.0 legacy PortPwrCtrlMask */
|
||||
|
@@ -239,7 +239,6 @@ static struct platform_driver ohci_hcd_jz4740_driver = {
|
||||
.remove = jz4740_ohci_remove,
|
||||
.driver = {
|
||||
.name = "jz4740-ohci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -38,7 +38,8 @@
|
||||
struct ohci_platform_priv {
|
||||
struct clk *clks[OHCI_MAX_CLKS];
|
||||
struct reset_control *rst;
|
||||
struct phy *phy;
|
||||
struct phy **phys;
|
||||
int num_phys;
|
||||
};
|
||||
|
||||
static const char hcd_name[] = "ohci-platform";
|
||||
@@ -47,7 +48,7 @@ static int ohci_platform_power_on(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
|
||||
int clk, ret;
|
||||
int clk, ret, phy_num;
|
||||
|
||||
for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) {
|
||||
ret = clk_prepare_enable(priv->clks[clk]);
|
||||
@@ -55,20 +56,28 @@ static int ohci_platform_power_on(struct platform_device *dev)
|
||||
goto err_disable_clks;
|
||||
}
|
||||
|
||||
if (priv->phy) {
|
||||
ret = phy_init(priv->phy);
|
||||
if (ret)
|
||||
goto err_disable_clks;
|
||||
|
||||
ret = phy_power_on(priv->phy);
|
||||
if (ret)
|
||||
goto err_exit_phy;
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
if (priv->phys[phy_num]) {
|
||||
ret = phy_init(priv->phys[phy_num]);
|
||||
if (ret)
|
||||
goto err_exit_phy;
|
||||
ret = phy_power_on(priv->phys[phy_num]);
|
||||
if (ret) {
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
goto err_exit_phy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_exit_phy:
|
||||
phy_exit(priv->phy);
|
||||
while (--phy_num >= 0) {
|
||||
if (priv->phys[phy_num]) {
|
||||
phy_power_off(priv->phys[phy_num]);
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
}
|
||||
}
|
||||
err_disable_clks:
|
||||
while (--clk >= 0)
|
||||
clk_disable_unprepare(priv->clks[clk]);
|
||||
@@ -80,11 +89,13 @@ static void ohci_platform_power_off(struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = platform_get_drvdata(dev);
|
||||
struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
|
||||
int clk;
|
||||
int clk, phy_num;
|
||||
|
||||
if (priv->phy) {
|
||||
phy_power_off(priv->phy);
|
||||
phy_exit(priv->phy);
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
if (priv->phys[phy_num]) {
|
||||
phy_power_off(priv->phys[phy_num]);
|
||||
phy_exit(priv->phys[phy_num]);
|
||||
}
|
||||
}
|
||||
|
||||
for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--)
|
||||
@@ -112,7 +123,8 @@ static int ohci_platform_probe(struct platform_device *dev)
|
||||
struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
|
||||
struct ohci_platform_priv *priv;
|
||||
struct ohci_hcd *ohci;
|
||||
int err, irq, clk = 0;
|
||||
const char *phy_name;
|
||||
int err, irq, phy_num, clk = 0;
|
||||
|
||||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
@@ -160,12 +172,38 @@ static int ohci_platform_probe(struct platform_device *dev)
|
||||
of_property_read_u32(dev->dev.of_node, "num-ports",
|
||||
&ohci->num_ports);
|
||||
|
||||
priv->phy = devm_phy_get(&dev->dev, "usb");
|
||||
if (IS_ERR(priv->phy)) {
|
||||
err = PTR_ERR(priv->phy);
|
||||
if (err == -EPROBE_DEFER)
|
||||
goto err_put_hcd;
|
||||
priv->phy = NULL;
|
||||
priv->num_phys = of_count_phandle_with_args(dev->dev.of_node,
|
||||
"phys", "#phy-cells");
|
||||
priv->num_phys = priv->num_phys > 0 ? priv->num_phys : 1;
|
||||
|
||||
priv->phys = devm_kcalloc(&dev->dev, priv->num_phys,
|
||||
sizeof(struct phy *), GFP_KERNEL);
|
||||
if (!priv->phys)
|
||||
return -ENOMEM;
|
||||
|
||||
for (phy_num = 0; phy_num < priv->num_phys; phy_num++) {
|
||||
err = of_property_read_string_index(
|
||||
dev->dev.of_node,
|
||||
"phy-names", phy_num,
|
||||
&phy_name);
|
||||
|
||||
if (err < 0) {
|
||||
if (priv->num_phys > 1) {
|
||||
dev_err(&dev->dev, "phy-names not provided");
|
||||
goto err_put_hcd;
|
||||
} else
|
||||
phy_name = "usb";
|
||||
}
|
||||
|
||||
priv->phys[phy_num] = devm_phy_get(&dev->dev,
|
||||
phy_name);
|
||||
if (IS_ERR(priv->phys[phy_num])) {
|
||||
err = PTR_ERR(priv->phys[phy_num]);
|
||||
if ((priv->num_phys > 1) ||
|
||||
(err == -EPROBE_DEFER))
|
||||
goto err_put_hcd;
|
||||
priv->phys[phy_num] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (clk = 0; clk < OHCI_MAX_CLKS; clk++) {
|
||||
@@ -328,6 +366,7 @@ static int ohci_platform_resume(struct device *dev)
|
||||
|
||||
static const struct of_device_id ohci_platform_ids[] = {
|
||||
{ .compatible = "generic-ohci", },
|
||||
{ .compatible = "cavium,octeon-6335-ohci", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ohci_platform_ids);
|
||||
|
@@ -229,7 +229,6 @@ static struct platform_driver ohci_hcd_ppc_of_driver = {
|
||||
.shutdown = usb_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "ppc-of-ohci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = ohci_hcd_ppc_of_match,
|
||||
},
|
||||
};
|
||||
|
@@ -249,14 +249,14 @@ static int ohci_s3c2410_hub_control(
|
||||
*/
|
||||
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(0x0001);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(
|
||||
HUB_CHAR_INDV_PORT_LPSM);
|
||||
|
||||
if (info->enable_oc) {
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(
|
||||
HUB_CHAR_OCPM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(
|
||||
0x0008 |
|
||||
0x0001);
|
||||
HUB_CHAR_INDV_PORT_OCPM);
|
||||
}
|
||||
|
||||
dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
|
||||
|
@@ -265,7 +265,6 @@ static struct platform_driver ohci_hcd_sm501_driver = {
|
||||
.suspend = ohci_sm501_suspend,
|
||||
.resume = ohci_sm501_resume,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "sm501-usb",
|
||||
},
|
||||
};
|
||||
|
@@ -199,7 +199,6 @@ static struct platform_driver ohci_hcd_tilegx_driver = {
|
||||
.shutdown = ohci_hcd_tilegx_drv_shutdown,
|
||||
.driver = {
|
||||
.name = "tilegx-ohci",
|
||||
.owner = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -368,6 +368,5 @@ static struct platform_driver ohci_hcd_tmio_driver = {
|
||||
.resume = ohci_hcd_tmio_drv_resume,
|
||||
.driver = {
|
||||
.name = "tmio-ohci",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
@@ -457,11 +457,11 @@ static void ehci_hub_descriptor(struct oxu_hcd *oxu,
|
||||
memset(&desc->u.hs.DeviceRemovable[0], 0, temp);
|
||||
memset(&desc->u.hs.DeviceRemovable[temp], 0xff, temp);
|
||||
|
||||
temp = 0x0008; /* per-port overcurrent reporting */
|
||||
temp = HUB_CHAR_INDV_PORT_OCPM; /* per-port overcurrent reporting */
|
||||
if (HCS_PPC(oxu->hcs_params))
|
||||
temp |= 0x0001; /* per-port power control */
|
||||
temp |= HUB_CHAR_INDV_PORT_LPSM; /* per-port power control */
|
||||
else
|
||||
temp |= 0x0002; /* no power switching */
|
||||
temp |= HUB_CHAR_NO_LPSM; /* no power switching */
|
||||
desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp);
|
||||
}
|
||||
|
||||
@@ -2598,9 +2598,7 @@ static int oxu_hcd_init(struct usb_hcd *hcd)
|
||||
|
||||
spin_lock_init(&oxu->lock);
|
||||
|
||||
init_timer(&oxu->watchdog);
|
||||
oxu->watchdog.function = oxu_watchdog;
|
||||
oxu->watchdog.data = (unsigned long) oxu;
|
||||
setup_timer(&oxu->watchdog, oxu_watchdog, (unsigned long)oxu);
|
||||
|
||||
/*
|
||||
* hw default: 1K periodic list heads, one per frame.
|
||||
|
@@ -603,9 +603,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
||||
msleep(10);
|
||||
}
|
||||
if (wait_time <= 0)
|
||||
dev_warn(&pdev->dev, "OHCI: BIOS handoff failed"
|
||||
" (BIOS bug?) %08x\n",
|
||||
readl(base + OHCI_CONTROL));
|
||||
dev_warn(&pdev->dev,
|
||||
"OHCI: BIOS handoff failed (BIOS bug?) %08x\n",
|
||||
readl(base + OHCI_CONTROL));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -733,8 +733,9 @@ static void ehci_bios_handoff(struct pci_dev *pdev,
|
||||
* and hope nothing goes too wrong
|
||||
*/
|
||||
if (try_handoff)
|
||||
dev_warn(&pdev->dev, "EHCI: BIOS handoff failed"
|
||||
" (BIOS bug?) %08x\n", cap);
|
||||
dev_warn(&pdev->dev,
|
||||
"EHCI: BIOS handoff failed (BIOS bug?) %08x\n",
|
||||
cap);
|
||||
pci_write_config_byte(pdev, offset + 2, 0);
|
||||
}
|
||||
|
||||
@@ -781,8 +782,9 @@ static void quirk_usb_disable_ehci(struct pci_dev *pdev)
|
||||
case 0: /* Illegal reserved cap, set cap=0 so we exit */
|
||||
cap = 0; /* then fallthrough... */
|
||||
default:
|
||||
dev_warn(&pdev->dev, "EHCI: unrecognized capability "
|
||||
"%02x\n", cap & 0xff);
|
||||
dev_warn(&pdev->dev,
|
||||
"EHCI: unrecognized capability %02x\n",
|
||||
cap & 0xff);
|
||||
}
|
||||
offset = (cap >> 8) & 0xff;
|
||||
}
|
||||
@@ -893,8 +895,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_USB_XHCI_HCD)) {
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"CONFIG_USB_XHCI_HCD is turned off, "
|
||||
"defaulting to EHCI.\n");
|
||||
"CONFIG_USB_XHCI_HCD is turned off, defaulting to EHCI.\n");
|
||||
dev_warn(&xhci_pdev->dev,
|
||||
"USB 3.0 devices will work at USB 2.0 speeds.\n");
|
||||
usb_disable_xhci_ports(xhci_pdev);
|
||||
@@ -919,8 +920,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
|
||||
pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,
|
||||
&ports_available);
|
||||
dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled "
|
||||
"under xHCI: 0x%x\n", ports_available);
|
||||
dev_dbg(&xhci_pdev->dev,
|
||||
"USB 3.0 ports that are now enabled under xHCI: 0x%x\n",
|
||||
ports_available);
|
||||
|
||||
/* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register
|
||||
* Indicate the USB 2.0 ports to be controlled by the xHCI host.
|
||||
@@ -941,8 +943,9 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)
|
||||
|
||||
pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,
|
||||
&ports_available);
|
||||
dev_dbg(&xhci_pdev->dev, "USB 2.0 ports that are now switched over "
|
||||
"to xHCI: 0x%x\n", ports_available);
|
||||
dev_dbg(&xhci_pdev->dev,
|
||||
"USB 2.0 ports that are now switched over to xHCI: 0x%x\n",
|
||||
ports_available);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_enable_intel_xhci_ports);
|
||||
|
||||
@@ -1010,8 +1013,9 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev)
|
||||
|
||||
/* Assume a buggy BIOS and take HC ownership anyway */
|
||||
if (timeout) {
|
||||
dev_warn(&pdev->dev, "xHCI BIOS handoff failed"
|
||||
" (BIOS bug ?) %08x\n", val);
|
||||
dev_warn(&pdev->dev,
|
||||
"xHCI BIOS handoff failed (BIOS bug ?) %08x\n",
|
||||
val);
|
||||
writel(val & ~XHCI_HC_BIOS_OWNED, base + ext_cap_offset);
|
||||
}
|
||||
}
|
||||
@@ -1039,8 +1043,8 @@ hc_init:
|
||||
if (timeout) {
|
||||
val = readl(op_reg_base + XHCI_STS_OFFSET);
|
||||
dev_warn(&pdev->dev,
|
||||
"xHCI HW not ready after 5 sec (HC bug?) "
|
||||
"status = 0x%x\n", val);
|
||||
"xHCI HW not ready after 5 sec (HC bug?) status = 0x%x\n",
|
||||
val);
|
||||
}
|
||||
|
||||
/* Send the halt and disable interrupts command */
|
||||
@@ -1054,8 +1058,8 @@ hc_init:
|
||||
if (timeout) {
|
||||
val = readl(op_reg_base + XHCI_STS_OFFSET);
|
||||
dev_warn(&pdev->dev,
|
||||
"xHCI HW did not halt within %d usec "
|
||||
"status = 0x%x\n", XHCI_MAX_HALT_USEC, val);
|
||||
"xHCI HW did not halt within %d usec status = 0x%x\n",
|
||||
XHCI_MAX_HALT_USEC, val);
|
||||
}
|
||||
|
||||
iounmap(base);
|
||||
@@ -1075,8 +1079,8 @@ static void quirk_usb_early_handoff(struct pci_dev *pdev)
|
||||
return;
|
||||
|
||||
if (pci_enable_device(pdev) < 0) {
|
||||
dev_warn(&pdev->dev, "Can't enable PCI device, "
|
||||
"BIOS handoff failed.\n");
|
||||
dev_warn(&pdev->dev,
|
||||
"Can't enable PCI device, BIOS handoff failed.\n");
|
||||
return;
|
||||
}
|
||||
if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
|
||||
|
@@ -2141,7 +2141,8 @@ static void r8a66597_hub_descriptor(struct r8a66597 *r8a66597,
|
||||
desc->bNbrPorts = r8a66597->max_root_hub;
|
||||
desc->bDescLength = 9;
|
||||
desc->bPwrOn2PwrGood = 0;
|
||||
desc->wHubCharacteristics = cpu_to_le16(0x0011);
|
||||
desc->wHubCharacteristics =
|
||||
cpu_to_le16(HUB_CHAR_INDV_PORT_LPSM | HUB_CHAR_NO_OCPM);
|
||||
desc->u.hs.DeviceRemovable[0] =
|
||||
((1 << r8a66597->max_root_hub) - 1) << 1;
|
||||
desc->u.hs.DeviceRemovable[1] = ~0;
|
||||
@@ -2483,9 +2484,8 @@ static int r8a66597_probe(struct platform_device *pdev)
|
||||
r8a66597->max_root_hub = 2;
|
||||
|
||||
spin_lock_init(&r8a66597->lock);
|
||||
init_timer(&r8a66597->rh_timer);
|
||||
r8a66597->rh_timer.function = r8a66597_timer;
|
||||
r8a66597->rh_timer.data = (unsigned long)r8a66597;
|
||||
setup_timer(&r8a66597->rh_timer, r8a66597_timer,
|
||||
(unsigned long)r8a66597);
|
||||
r8a66597->reg = reg;
|
||||
|
||||
/* make sure no interrupts are pending */
|
||||
@@ -2496,9 +2496,8 @@ static int r8a66597_probe(struct platform_device *pdev)
|
||||
|
||||
for (i = 0; i < R8A66597_MAX_NUM_PIPE; i++) {
|
||||
INIT_LIST_HEAD(&r8a66597->pipe_queue[i]);
|
||||
init_timer(&r8a66597->td_timer[i]);
|
||||
r8a66597->td_timer[i].function = r8a66597_td_timer;
|
||||
r8a66597->td_timer[i].data = (unsigned long)r8a66597;
|
||||
setup_timer(&r8a66597->td_timer[i], r8a66597_td_timer,
|
||||
(unsigned long)r8a66597);
|
||||
setup_timer(&r8a66597->interval_timer[i],
|
||||
r8a66597_interval_timer,
|
||||
(unsigned long)r8a66597);
|
||||
|
@@ -1103,12 +1103,12 @@ sl811h_hub_descriptor (
|
||||
desc->bPwrOn2PwrGood = sl811->board->potpg;
|
||||
if (!desc->bPwrOn2PwrGood)
|
||||
desc->bPwrOn2PwrGood = 10;
|
||||
temp = 0x0001;
|
||||
temp = HUB_CHAR_INDV_PORT_LPSM;
|
||||
} else
|
||||
temp = 0x0002;
|
||||
temp = HUB_CHAR_NO_LPSM;
|
||||
|
||||
/* no overcurrent errors detection/handling */
|
||||
temp |= 0x0010;
|
||||
temp |= HUB_CHAR_NO_OCPM;
|
||||
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
|
||||
@@ -1691,9 +1691,7 @@ sl811h_probe(struct platform_device *dev)
|
||||
spin_lock_init(&sl811->lock);
|
||||
INIT_LIST_HEAD(&sl811->async);
|
||||
sl811->board = dev_get_platdata(&dev->dev);
|
||||
init_timer(&sl811->timer);
|
||||
sl811->timer.function = sl811h_timer;
|
||||
sl811->timer.data = (unsigned long) sl811;
|
||||
setup_timer(&sl811->timer, sl811h_timer, (unsigned long)sl811);
|
||||
sl811->addr_reg = addr_reg;
|
||||
sl811->data_reg = data_reg;
|
||||
|
||||
|
@@ -2590,15 +2590,15 @@ static int u132_roothub_descriptor(struct u132 *u132,
|
||||
desc->bNbrPorts = u132->num_ports;
|
||||
temp = 1 + (u132->num_ports / 8);
|
||||
desc->bDescLength = 7 + 2 * temp;
|
||||
temp = 0;
|
||||
temp = HUB_CHAR_COMMON_LPSM | HUB_CHAR_COMMON_OCPM;
|
||||
if (rh_a & RH_A_NPS)
|
||||
temp |= 0x0002;
|
||||
temp |= HUB_CHAR_NO_LPSM;
|
||||
if (rh_a & RH_A_PSM)
|
||||
temp |= 0x0001;
|
||||
temp |= HUB_CHAR_INDV_PORT_LPSM;
|
||||
if (rh_a & RH_A_NOCP)
|
||||
temp |= 0x0010;
|
||||
temp |= HUB_CHAR_NO_OCPM;
|
||||
else if (rh_a & RH_A_OCPM)
|
||||
temp |= 0x0008;
|
||||
temp |= HUB_CHAR_INDV_PORT_OCPM;
|
||||
desc->wHubCharacteristics = cpu_to_le16(temp);
|
||||
retval = u132_read_pcimem(u132, roothub.b, &rh_b);
|
||||
if (retval)
|
||||
|
@@ -188,7 +188,6 @@ static struct platform_driver uhci_grlib_driver = {
|
||||
.shutdown = uhci_hcd_grlib_shutdown,
|
||||
.driver = {
|
||||
.name = "grlib-uhci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = uhci_hcd_grlib_of_match,
|
||||
},
|
||||
};
|
||||
|
@@ -17,8 +17,9 @@ static const __u8 root_hub_hub_des[] =
|
||||
0x09, /* __u8 bLength; */
|
||||
0x29, /* __u8 bDescriptorType; Hub-descriptor */
|
||||
0x02, /* __u8 bNbrPorts; */
|
||||
0x0a, /* __u16 wHubCharacteristics; */
|
||||
0x00, /* (per-port OC, no power switching) */
|
||||
HUB_CHAR_NO_LPSM | /* __u16 wHubCharacteristics; */
|
||||
HUB_CHAR_INDV_PORT_OCPM, /* (per-port OC, no power switching) */
|
||||
0x00,
|
||||
0x01, /* __u8 bPwrOn2pwrGood; 2ms */
|
||||
0x00, /* __u8 bHubContrCurrent; 0 mA */
|
||||
0x00, /* __u8 DeviceRemovable; *** 7 Ports max */
|
||||
|
@@ -147,7 +147,6 @@ static struct platform_driver uhci_platform_driver = {
|
||||
.shutdown = uhci_hcd_platform_shutdown,
|
||||
.driver = {
|
||||
.name = "platform-uhci",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = platform_uhci_ids,
|
||||
},
|
||||
};
|
||||
|
@@ -552,7 +552,7 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci,
|
||||
|
||||
if (ctx->type == XHCI_CTX_TYPE_INPUT) {
|
||||
struct xhci_input_control_ctx *ctrl_ctx =
|
||||
xhci_get_input_control_ctx(xhci, ctx);
|
||||
xhci_get_input_control_ctx(ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "Could not get input context, bad type.\n");
|
||||
return;
|
||||
|
@@ -535,7 +535,7 @@ static void xhci_free_container_ctx(struct xhci_hcd *xhci,
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
|
||||
struct xhci_input_control_ctx *xhci_get_input_control_ctx(
|
||||
struct xhci_container_ctx *ctx)
|
||||
{
|
||||
if (ctx->type != XHCI_CTX_TYPE_INPUT)
|
||||
@@ -784,8 +784,7 @@ void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci,
|
||||
* Reinstalls the "normal" endpoint ring (at its previous dequeue mark,
|
||||
* not at the beginning of the ring).
|
||||
*/
|
||||
void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci,
|
||||
struct xhci_ep_ctx *ep_ctx,
|
||||
void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx,
|
||||
struct xhci_virt_ep *ep)
|
||||
{
|
||||
dma_addr_t addr;
|
||||
@@ -833,9 +832,8 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,
|
||||
static void xhci_init_endpoint_timer(struct xhci_hcd *xhci,
|
||||
struct xhci_virt_ep *ep)
|
||||
{
|
||||
init_timer(&ep->stop_cmd_timer);
|
||||
ep->stop_cmd_timer.data = (unsigned long) ep;
|
||||
ep->stop_cmd_timer.function = xhci_stop_endpoint_command_watchdog;
|
||||
setup_timer(&ep->stop_cmd_timer, xhci_stop_endpoint_command_watchdog,
|
||||
(unsigned long)ep);
|
||||
ep->xhci = xhci;
|
||||
}
|
||||
|
||||
@@ -1342,8 +1340,7 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev,
|
||||
return ep->ss_ep_comp.bmAttributes;
|
||||
}
|
||||
|
||||
static u32 xhci_get_endpoint_type(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep)
|
||||
{
|
||||
int in;
|
||||
u32 type;
|
||||
@@ -1376,8 +1373,7 @@ static u32 xhci_get_endpoint_type(struct usb_device *udev,
|
||||
* Basically, this is the maxpacket size, multiplied by the burst size
|
||||
* and mult size.
|
||||
*/
|
||||
static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci,
|
||||
struct usb_device *udev,
|
||||
static u32 xhci_get_max_esit_payload(struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
int max_burst;
|
||||
@@ -1418,7 +1414,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
||||
|
||||
endpoint_type = xhci_get_endpoint_type(udev, ep);
|
||||
endpoint_type = xhci_get_endpoint_type(ep);
|
||||
if (!endpoint_type)
|
||||
return -EINVAL;
|
||||
ep_ctx->ep_info2 = cpu_to_le32(endpoint_type);
|
||||
@@ -1484,7 +1480,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||
}
|
||||
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
|
||||
MAX_BURST(max_burst));
|
||||
max_esit_payload = xhci_get_max_esit_payload(xhci, udev, ep);
|
||||
max_esit_payload = xhci_get_max_esit_payload(udev, ep);
|
||||
ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
|
||||
|
||||
/*
|
||||
@@ -1773,7 +1769,7 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
|
||||
return command;
|
||||
}
|
||||
|
||||
void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv)
|
||||
void xhci_urb_free_priv(struct urb_priv *urb_priv)
|
||||
{
|
||||
if (urb_priv) {
|
||||
kfree(urb_priv->td[0]);
|
||||
@@ -1926,7 +1922,7 @@ static int xhci_test_trb_in_td(struct xhci_hcd *xhci,
|
||||
}
|
||||
|
||||
/* TRB math checks for xhci_trb_in_td(), using the command and event rings. */
|
||||
static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci, gfp_t mem_flags)
|
||||
static int xhci_check_trb_in_td_math(struct xhci_hcd *xhci)
|
||||
{
|
||||
struct {
|
||||
dma_addr_t input_dma;
|
||||
@@ -2452,7 +2448,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||
flags);
|
||||
if (!xhci->event_ring)
|
||||
goto fail;
|
||||
if (xhci_check_trb_in_td_math(xhci, flags) < 0)
|
||||
if (xhci_check_trb_in_td_math(xhci) < 0)
|
||||
goto fail;
|
||||
|
||||
xhci->erst.entries = dma_alloc_coherent(dev,
|
||||
@@ -2509,9 +2505,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||
xhci_print_ir_set(xhci, 0);
|
||||
|
||||
/* init command timeout timer */
|
||||
init_timer(&xhci->cmd_timer);
|
||||
xhci->cmd_timer.data = (unsigned long) xhci;
|
||||
xhci->cmd_timer.function = xhci_handle_command_timeout;
|
||||
setup_timer(&xhci->cmd_timer, xhci_handle_command_timeout,
|
||||
(unsigned long)xhci);
|
||||
|
||||
/*
|
||||
* XXX: Might need to set the Interrupter Moderation Register to
|
||||
|
@@ -299,7 +299,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
|
||||
* seconds), then it should assume that the there are
|
||||
* larger problems with the xHC and assert HCRST.
|
||||
*/
|
||||
ret = xhci_handshake(xhci, &xhci->op_regs->cmd_ring,
|
||||
ret = xhci_handshake(&xhci->op_regs->cmd_ring,
|
||||
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
|
||||
if (ret < 0) {
|
||||
xhci_err(xhci, "Stopped the command ring failed, "
|
||||
@@ -609,7 +609,7 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,
|
||||
|
||||
spin_unlock(&xhci->lock);
|
||||
usb_hcd_giveback_urb(hcd, urb, status);
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
spin_lock(&xhci->lock);
|
||||
}
|
||||
}
|
||||
@@ -1110,7 +1110,7 @@ static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id,
|
||||
* is not waiting on the configure endpoint command.
|
||||
*/
|
||||
virt_dev = xhci->devs[slot_id];
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "Could not get input context, bad type.\n");
|
||||
return;
|
||||
@@ -2354,8 +2354,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
xhci_warn(xhci, "ERROR Unknown event condition, HC probably "
|
||||
"busted\n");
|
||||
xhci_warn(xhci, "ERROR Unknown event condition %u, HC probably busted\n",
|
||||
trb_comp_code);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -2497,7 +2497,7 @@ cleanup:
|
||||
urb = td->urb;
|
||||
urb_priv = urb->hcpriv;
|
||||
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
|
||||
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
|
||||
if ((urb->actual_length != urb->transfer_buffer_length &&
|
||||
|
@@ -60,8 +60,7 @@ MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
|
||||
* handshake done). There are two failure modes: "usec" have passed (major
|
||||
* hardware flakeout), or the register reads as all-ones (hardware removed).
|
||||
*/
|
||||
int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
||||
u32 mask, u32 done, int usec)
|
||||
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec)
|
||||
{
|
||||
u32 result;
|
||||
|
||||
@@ -111,7 +110,7 @@ int xhci_halt(struct xhci_hcd *xhci)
|
||||
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Halt the HC");
|
||||
xhci_quiesce(xhci);
|
||||
|
||||
ret = xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
ret = xhci_handshake(&xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
|
||||
if (!ret) {
|
||||
xhci->xhc_state |= XHCI_STATE_HALTED;
|
||||
@@ -140,7 +139,7 @@ static int xhci_start(struct xhci_hcd *xhci)
|
||||
* Wait for the HCHalted Status bit to be 0 to indicate the host is
|
||||
* running.
|
||||
*/
|
||||
ret = xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
ret = xhci_handshake(&xhci->op_regs->status,
|
||||
STS_HALT, 0, XHCI_MAX_HALT_USEC);
|
||||
if (ret == -ETIMEDOUT)
|
||||
xhci_err(xhci, "Host took too long to start, "
|
||||
@@ -175,7 +174,7 @@ int xhci_reset(struct xhci_hcd *xhci)
|
||||
command |= CMD_RESET;
|
||||
writel(command, &xhci->op_regs->command);
|
||||
|
||||
ret = xhci_handshake(xhci, &xhci->op_regs->command,
|
||||
ret = xhci_handshake(&xhci->op_regs->command,
|
||||
CMD_RESET, 0, 10 * 1000 * 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -186,7 +185,7 @@ int xhci_reset(struct xhci_hcd *xhci)
|
||||
* xHCI cannot write to any doorbells or operational registers other
|
||||
* than status until the "Controller Not Ready" flag is cleared.
|
||||
*/
|
||||
ret = xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
ret = xhci_handshake(&xhci->op_regs->status,
|
||||
STS_CNR, 0, 10 * 1000 * 1000);
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
@@ -473,10 +472,8 @@ static void compliance_mode_recovery(unsigned long arg)
|
||||
static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci)
|
||||
{
|
||||
xhci->port_status_u0 = 0;
|
||||
init_timer(&xhci->comp_mode_recovery_timer);
|
||||
|
||||
xhci->comp_mode_recovery_timer.data = (unsigned long) xhci;
|
||||
xhci->comp_mode_recovery_timer.function = compliance_mode_recovery;
|
||||
setup_timer(&xhci->comp_mode_recovery_timer,
|
||||
compliance_mode_recovery, (unsigned long)xhci);
|
||||
xhci->comp_mode_recovery_timer.expires = jiffies +
|
||||
msecs_to_jiffies(COMP_MODE_RCVRY_MSECS);
|
||||
|
||||
@@ -929,7 +926,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
|
||||
/* Some chips from Fresco Logic need an extraordinary delay */
|
||||
delay *= (xhci->quirks & XHCI_SLOW_SUSPEND) ? 10 : 1;
|
||||
|
||||
if (xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
if (xhci_handshake(&xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, delay)) {
|
||||
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
@@ -944,7 +941,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
|
||||
command = readl(&xhci->op_regs->command);
|
||||
command |= CMD_CSS;
|
||||
writel(command, &xhci->op_regs->command);
|
||||
if (xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
if (xhci_handshake(&xhci->op_regs->status,
|
||||
STS_SAVE, 0, 10 * 1000)) {
|
||||
xhci_warn(xhci, "WARN: xHC save state timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
@@ -1011,7 +1008,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
command = readl(&xhci->op_regs->command);
|
||||
command |= CMD_CRS;
|
||||
writel(command, &xhci->op_regs->command);
|
||||
if (xhci_handshake(xhci, &xhci->op_regs->status,
|
||||
if (xhci_handshake(&xhci->op_regs->status,
|
||||
STS_RESTORE, 0, 10 * 1000)) {
|
||||
xhci_warn(xhci, "WARN: xHC restore state timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
@@ -1082,7 +1079,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
||||
command = readl(&xhci->op_regs->command);
|
||||
command |= CMD_RUN;
|
||||
writel(command, &xhci->op_regs->command);
|
||||
xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT,
|
||||
xhci_handshake(&xhci->op_regs->status, STS_HALT,
|
||||
0, 250 * 1000);
|
||||
|
||||
/* step 5: walk topology and initialize portsc,
|
||||
@@ -1276,7 +1273,7 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
|
||||
return -ENOMEM;
|
||||
|
||||
command->in_ctx = xhci->devs[slot_id]->in_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -1374,7 +1371,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
|
||||
ret = xhci_check_maxpacket(xhci, slot_id,
|
||||
ep_index, urb);
|
||||
if (ret < 0) {
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
urb->hcpriv = NULL;
|
||||
return ret;
|
||||
}
|
||||
@@ -1440,7 +1437,7 @@ dying:
|
||||
urb->ep->desc.bEndpointAddress, urb);
|
||||
ret = -ESHUTDOWN;
|
||||
free_priv:
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
urb->hcpriv = NULL;
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return ret;
|
||||
@@ -1553,7 +1550,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||
usb_hcd_unlink_urb_from_ep(hcd, urb);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN);
|
||||
xhci_urb_free_priv(xhci, urb_priv);
|
||||
xhci_urb_free_priv(urb_priv);
|
||||
return ret;
|
||||
}
|
||||
if ((xhci->xhc_state & XHCI_STATE_DYING) ||
|
||||
@@ -1660,7 +1657,7 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
in_ctx = xhci->devs[udev->slot_id]->in_ctx;
|
||||
out_ctx = xhci->devs[udev->slot_id]->out_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -1676,8 +1673,10 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
cpu_to_le32(EP_STATE_DISABLED)) ||
|
||||
le32_to_cpu(ctrl_ctx->drop_flags) &
|
||||
xhci_get_endpoint_flag(&ep->desc)) {
|
||||
xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
|
||||
__func__, ep);
|
||||
/* Do not warn when called after a usb_device_reset */
|
||||
if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL)
|
||||
xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
|
||||
__func__, ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1714,7 +1713,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
struct usb_host_endpoint *ep)
|
||||
{
|
||||
struct xhci_hcd *xhci;
|
||||
struct xhci_container_ctx *in_ctx, *out_ctx;
|
||||
struct xhci_container_ctx *in_ctx;
|
||||
unsigned int ep_index;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
u32 added_ctxs;
|
||||
@@ -1745,8 +1744,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
in_ctx = virt_dev->in_ctx;
|
||||
out_ctx = virt_dev->out_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -1758,8 +1756,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
* to add it again without dropping it, reject the addition.
|
||||
*/
|
||||
if (virt_dev->eps[ep_index].ring &&
|
||||
!(le32_to_cpu(ctrl_ctx->drop_flags) &
|
||||
xhci_get_endpoint_flag(&ep->desc))) {
|
||||
!(le32_to_cpu(ctrl_ctx->drop_flags) & added_ctxs)) {
|
||||
xhci_warn(xhci, "Trying to add endpoint 0x%x "
|
||||
"without dropping it.\n",
|
||||
(unsigned int) ep->desc.bEndpointAddress);
|
||||
@@ -1769,8 +1766,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
/* If the HCD has already noted the endpoint is enabled,
|
||||
* ignore this request.
|
||||
*/
|
||||
if (le32_to_cpu(ctrl_ctx->add_flags) &
|
||||
xhci_get_endpoint_flag(&ep->desc)) {
|
||||
if (le32_to_cpu(ctrl_ctx->add_flags) & added_ctxs) {
|
||||
xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
|
||||
__func__, ep);
|
||||
return 0;
|
||||
@@ -1816,7 +1812,7 @@ static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *vir
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
int i;
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -2542,7 +2538,7 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci,
|
||||
if (virt_dev->tt_info)
|
||||
old_active_eps = virt_dev->tt_info->active_eps;
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -2639,7 +2635,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
@@ -2758,7 +2754,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
command->in_ctx = virt_dev->in_ctx;
|
||||
|
||||
/* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -2883,7 +2879,7 @@ static void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
|
||||
dma_addr_t addr;
|
||||
|
||||
in_ctx = xhci->devs[slot_id]->in_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -3173,7 +3169,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -3328,7 +3324,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
*/
|
||||
ep_index = xhci_get_endpoint_index(&eps[0]->desc);
|
||||
command = vdev->eps[ep_index].stream_info->free_streams_command;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
@@ -3346,7 +3342,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
|
||||
xhci_endpoint_copy(xhci, command->in_ctx,
|
||||
vdev->out_ctx, ep_index);
|
||||
xhci_setup_no_streams_ep_input_ctx(xhci, ep_ctx,
|
||||
xhci_setup_no_streams_ep_input_ctx(ep_ctx,
|
||||
&vdev->eps[ep_index]);
|
||||
}
|
||||
xhci_setup_input_ctx_for_config_ep(xhci, command->in_ctx,
|
||||
@@ -3820,7 +3816,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
command->completion = &xhci->addr_dev;
|
||||
|
||||
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -4003,7 +3999,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci,
|
||||
|
||||
/* Attempt to issue an Evaluate Context command to change the MEL. */
|
||||
command = xhci->lpm_command;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
@@ -4741,7 +4737,7 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
|
||||
xhci_dbg(xhci, "Could not allocate xHCI command structure.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, config_cmd->in_ctx);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(config_cmd->in_ctx);
|
||||
if (!ctrl_ctx) {
|
||||
xhci_warn(xhci, "%s: Could not get input context, bad type.\n",
|
||||
__func__);
|
||||
@@ -4910,6 +4906,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
|
||||
if (retval)
|
||||
goto error;
|
||||
xhci_dbg(xhci, "Called HCD init\n");
|
||||
|
||||
xhci_info(xhci, "hcc params 0x%08x hci version 0x%x quirks 0x%08x\n",
|
||||
xhci->hcc_params, xhci->hci_version, xhci->quirks);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
kfree(xhci);
|
||||
|
@@ -1605,6 +1605,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
|
||||
dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
|
||||
#define xhci_warn_ratelimited(xhci, fmt, args...) \
|
||||
dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
|
||||
#define xhci_info(xhci, fmt, args...) \
|
||||
dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
|
||||
|
||||
/*
|
||||
* Registers should always be accessed with double word or quad word accesses.
|
||||
@@ -1712,8 +1714,7 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,
|
||||
void xhci_setup_streams_ep_input_ctx(struct xhci_hcd *xhci,
|
||||
struct xhci_ep_ctx *ep_ctx,
|
||||
struct xhci_stream_info *stream_info);
|
||||
void xhci_setup_no_streams_ep_input_ctx(struct xhci_hcd *xhci,
|
||||
struct xhci_ep_ctx *ep_ctx,
|
||||
void xhci_setup_no_streams_ep_input_ctx(struct xhci_ep_ctx *ep_ctx,
|
||||
struct xhci_virt_ep *ep);
|
||||
void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci,
|
||||
struct xhci_virt_device *virt_dev, bool drop_control_ep);
|
||||
@@ -1727,14 +1728,13 @@ struct xhci_ring *xhci_stream_id_to_ring(
|
||||
struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,
|
||||
bool allocate_in_ctx, bool allocate_completion,
|
||||
gfp_t mem_flags);
|
||||
void xhci_urb_free_priv(struct xhci_hcd *xhci, struct urb_priv *urb_priv);
|
||||
void xhci_urb_free_priv(struct urb_priv *urb_priv);
|
||||
void xhci_free_command(struct xhci_hcd *xhci,
|
||||
struct xhci_command *command);
|
||||
|
||||
/* xHCI host controller glue */
|
||||
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
|
||||
int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
||||
u32 mask, u32 done, int usec);
|
||||
int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, int usec);
|
||||
void xhci_quiesce(struct xhci_hcd *xhci);
|
||||
int xhci_halt(struct xhci_hcd *xhci);
|
||||
int xhci_reset(struct xhci_hcd *xhci);
|
||||
@@ -1864,7 +1864,7 @@ int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
|
||||
void xhci_ring_device(struct xhci_hcd *xhci, int slot_id);
|
||||
|
||||
/* xHCI contexts */
|
||||
struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
|
||||
struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ctx *ctx);
|
||||
struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
|
||||
struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
|
||||
|
||||
|
Reference in New Issue
Block a user