diff options
Diffstat (limited to 'drivers/usb/host')
102 files changed, 6771 insertions, 4360 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index b3f20d7f15d..03314f861be 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -29,6 +29,14 @@ if USB_XHCI_HCD  config USB_XHCI_PLATFORM  	tristate +config USB_XHCI_MVEBU +	tristate "xHCI support for Marvell Armada 375/38x" +	select USB_XHCI_PLATFORM +	depends on ARCH_MVEBU || COMPILE_TEST +	---help--- +	  Say 'Y' to enable the support for the xHCI host controller +	  found in Marvell Armada 375/38x ARM SOCs. +  endif # USB_XHCI_HCD  config USB_EHCI_HCD @@ -54,7 +62,7 @@ config USB_EHCI_HCD  config USB_EHCI_ROOT_HUB_TT  	bool "Root Hub Transaction Translators" -	depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST +	depends on USB_EHCI_HCD  	---help---  	  Some EHCI chips have vendor-specific extensions to integrate  	  transaction translators, so that no OHCI or UHCI companion @@ -66,7 +74,7 @@ config USB_EHCI_ROOT_HUB_TT  config USB_EHCI_TT_NEWSCHED  	bool "Improved Transaction Translator scheduling" -	depends on USB_EHCI_HCD || USB_CHIPIDEA_HOST +	depends on USB_EHCI_HCD  	default y  	---help---  	  This changes the periodic scheduling code to fill more of the low @@ -168,9 +176,8 @@ config USB_EHCI_HCD_AT91  config USB_EHCI_MSM  	tristate "Support for Qualcomm QSD/MSM on-chip EHCI USB controller" -	depends on ARCH_MSM +	depends on ARCH_MSM || ARCH_QCOM  	select USB_EHCI_ROOT_HUB_TT -	select USB_MSM_OTG  	---help---  	  Enables support for the USB Host controller present on the  	  Qualcomm chipsets. Root Hub has inbuilt TT. @@ -203,12 +210,11 @@ config USB_EHCI_SH  	  Enables support for the on-chip EHCI controller on the SuperH.  	  If you use the PCI EHCI controller, this option is not necessary. -config USB_EHCI_S5P +config USB_EHCI_EXYNOS         tristate "EHCI support for Samsung S5P/EXYNOS SoC Series"         depends on PLAT_S5P || ARCH_EXYNOS         help -	Enable support for the Samsung S5Pxxxx and Exynos3/4/5 SOC's -	on-chip EHCI controller. +	Enable support for the Samsung Exynos SOC's on-chip EHCI controller.  config USB_EHCI_MV  	bool "EHCI support for Marvell PXA/MMP USB controller" @@ -224,7 +230,7 @@ config USB_EHCI_MV  	  on-chip EHCI USB controller" for those.  config USB_W90X900_EHCI -	bool "W90X900(W90P910) EHCI support" +	tristate "W90X900(W90P910) EHCI support"  	depends on ARCH_W90X900  	---help---  		Enables support for the W90X900 USB controller @@ -315,7 +321,6 @@ config USB_ISP1760_HCD  config USB_ISP1362_HCD  	tristate "ISP1362 HCD support" -	default N  	---help---  	  Supports the Philips ISP1362 chip as a host controller @@ -327,7 +332,6 @@ config USB_ISP1362_HCD  config USB_FUSBH200_HCD  	tristate "FUSBH200 HCD support"  	depends on USB -	default N  	---help---  	Faraday FUSBH200 is designed to meet USB2.0 EHCI specification  	with minor modification. @@ -338,7 +342,6 @@ config USB_FUSBH200_HCD  config USB_FOTG210_HCD  	tristate "FOTG210 HCD support"  	depends on USB -	default N  	---help---  	  Faraday FOTG210 is an OTG controller which can be configured as  	  an USB2.0 host. It is designed to meet USB2.0 EHCI specification @@ -347,10 +350,19 @@ config USB_FOTG210_HCD  	  To compile this driver as a module, choose M here: the  	  module will be called fotg210-hcd. +config USB_MAX3421_HCD +	tristate "MAX3421 HCD (USB-over-SPI) support" +	depends on USB && SPI +	---help--- +	  The Maxim MAX3421E chip supports standard USB 2.0-compliant +	  full-speed devices either in host or peripheral mode.  This +	  driver supports the host-mode of the MAX3421E only. + +	  To compile this driver as a module, choose M here: the module will +	  be called max3421-hcd. +  config USB_OHCI_HCD  	tristate "OHCI HCD (USB 1.1) support" -	select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 -	depends on USB_ISP1301 || !ARCH_LPC32XX  	---help---  	  The Open Host Controller Interface (OHCI) is a standard for accessing  	  USB 1.1 host controller hardware.  It does more in hardware than Intel's @@ -367,20 +379,72 @@ config USB_OHCI_HCD  if USB_OHCI_HCD  config USB_OHCI_HCD_OMAP1 -	bool "OHCI support for OMAP1/2 chips" +	tristate "OHCI support for OMAP1/2 chips"  	depends on ARCH_OMAP1 +	depends on ISP1301_OMAP || !(MACH_OMAP_H2 || MACH_OMAP_H3)  	default y  	---help---  	  Enables support for the OHCI controller on OMAP1/2 chips. +config USB_OHCI_HCD_SPEAR +        tristate "Support for ST SPEAr on-chip OHCI USB controller" +        depends on USB_OHCI_HCD && PLAT_SPEAR +        default y +        ---help--- +          Enables support for the on-chip OHCI controller on +          ST SPEAr chips. + +config USB_OHCI_HCD_S3C2410 +        tristate "OHCI support for Samsung S3C24xx/S3C64xx SoC series" +        depends on USB_OHCI_HCD && (ARCH_S3C24XX || ARCH_S3C64XX) +        default y +        ---help--- +          Enables support for the on-chip OHCI controller on +          S3C24xx/S3C64xx chips. + +config USB_OHCI_HCD_LPC32XX +	tristate "Support for LPC on-chip OHCI USB controller" +	depends on USB_OHCI_HCD && ARCH_LPC32XX +	depends on USB_ISP1301 +	default y +	---help--- +          Enables support for the on-chip OHCI controller on +          NXP chips. + +config USB_OHCI_HCD_PXA27X +	tristate "Support for PXA27X/PXA3XX on-chip OHCI USB controller" +	depends on USB_OHCI_HCD && (PXA27x || PXA3xx) +	default y +	---help--- +	  Enables support for the on-chip OHCI controller on +	  PXA27x/PXA3xx chips. + +config USB_OHCI_HCD_AT91 +        tristate "Support for Atmel on-chip OHCI USB controller" +        depends on USB_OHCI_HCD && ARCH_AT91 +        default y +        ---help--- +          Enables support for the on-chip OHCI controller on +          Atmel chips. +  config USB_OHCI_HCD_OMAP3 -	bool "OHCI support for OMAP3 and later chips" +	tristate "OHCI support for OMAP3 and later chips"  	depends on (ARCH_OMAP3 || ARCH_OMAP4)  	default y  	---help---  	  Enables support for the on-chip OHCI controller on  	  OMAP3 and later chips. +config USB_OHCI_HCD_DAVINCI +	bool "OHCI support for TI DaVinci DA8xx" +	depends on ARCH_DAVINCI_DA8XX +	depends on USB_OHCI_HCD=y +	default y +	help +	  Enables support for the DaVinci DA8xx integrated OHCI +	  controller. This driver cannot currently be a loadable +	  module because it lacks a proper PHY abstraction. +  config USB_OHCI_ATH79  	bool "USB OHCI support for the Atheros AR71XX/AR7240 SoCs (DEPRECATED)"  	depends on (SOC_AR71XX || SOC_AR724X) @@ -454,8 +518,8 @@ config USB_OHCI_SH  	  If you use the PCI OHCI controller, this option is not necessary.  config USB_OHCI_EXYNOS -	boolean "OHCI support for Samsung EXYNOS SoC Series" -	depends on ARCH_EXYNOS +	tristate "OHCI support for Samsung S5P/EXYNOS SoC Series" +	depends on PLAT_S5P || ARCH_EXYNOS  	help  	 Enable support for the Samsung Exynos SOC's on-chip OHCI controller. @@ -545,7 +609,6 @@ config FHCI_DEBUG  config USB_U132_HCD  	tristate "Elan U132 Adapter Host Controller"  	depends on USB_FTDI_ELAN -	default M  	help  	  The U132 adapter is a USB to CardBus adapter specifically designed  	  for PC cards that contain an OHCI host controller. Typical PC cards diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 50b0041c09a..af89a903d97 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -2,8 +2,6 @@  # Makefile for USB Host Controller Drivers  # -ccflags-$(CONFIG_USB_DEBUG) := -DDEBUG -  # tell define_trace.h where to find the xhci trace header  CFLAGS_xhci-trace.o := -I$(src) @@ -21,6 +19,9 @@ xhci-hcd-$(CONFIG_PCI)	+= xhci-pci.o  ifneq ($(CONFIG_USB_XHCI_PLATFORM), )  	xhci-hcd-y		+= xhci-plat.o +ifneq ($(CONFIG_USB_XHCI_MVEBU), ) +	xhci-hcd-y		+= xhci-mvebu.o +endif  endif  obj-$(CONFIG_USB_WHCI_HCD)	+= whci/ @@ -34,10 +35,11 @@ obj-$(CONFIG_USB_EHCI_MXC)	+= ehci-mxc.o  obj-$(CONFIG_USB_EHCI_HCD_OMAP)	+= ehci-omap.o  obj-$(CONFIG_USB_EHCI_HCD_ORION)	+= ehci-orion.o  obj-$(CONFIG_USB_EHCI_HCD_SPEAR)	+= ehci-spear.o -obj-$(CONFIG_USB_EHCI_S5P)	+= ehci-s5p.o +obj-$(CONFIG_USB_EHCI_EXYNOS)	+= ehci-exynos.o  obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o  obj-$(CONFIG_USB_EHCI_MSM)	+= ehci-msm.o  obj-$(CONFIG_USB_EHCI_TEGRA)	+= ehci-tegra.o +obj-$(CONFIG_USB_W90X900_EHCI)	+= ehci-w90x900.o  obj-$(CONFIG_USB_OXU210HP_HCD)	+= oxu210hp-hcd.o  obj-$(CONFIG_USB_ISP116X_HCD)	+= isp116x-hcd.o @@ -46,6 +48,14 @@ obj-$(CONFIG_USB_ISP1362_HCD)	+= isp1362-hcd.o  obj-$(CONFIG_USB_OHCI_HCD)	+= ohci-hcd.o  obj-$(CONFIG_USB_OHCI_HCD_PCI)	+= ohci-pci.o  obj-$(CONFIG_USB_OHCI_HCD_PLATFORM)	+= ohci-platform.o +obj-$(CONFIG_USB_OHCI_EXYNOS)	+= ohci-exynos.o +obj-$(CONFIG_USB_OHCI_HCD_OMAP1)	+= ohci-omap.o +obj-$(CONFIG_USB_OHCI_HCD_OMAP3)	+= ohci-omap3.o +obj-$(CONFIG_USB_OHCI_HCD_SPEAR)	+= ohci-spear.o +obj-$(CONFIG_USB_OHCI_HCD_AT91)	+= ohci-at91.o +obj-$(CONFIG_USB_OHCI_HCD_S3C2410)	+= ohci-s3c2410.o +obj-$(CONFIG_USB_OHCI_HCD_LPC32XX)	+= ohci-nxp.o +obj-$(CONFIG_USB_OHCI_HCD_PXA27X)	+= ohci-pxa27x.o  obj-$(CONFIG_USB_UHCI_HCD)	+= uhci-hcd.o  obj-$(CONFIG_USB_FHCI_HCD)	+= fhci.o @@ -63,3 +73,4 @@ obj-$(CONFIG_USB_HCD_BCMA)	+= bcma-hcd.o  obj-$(CONFIG_USB_HCD_SSB)	+= ssb-hcd.o  obj-$(CONFIG_USB_FUSBH200_HCD)	+= fusbh200-hcd.o  obj-$(CONFIG_USB_FOTG210_HCD)	+= fotg210-hcd.o +obj-$(CONFIG_USB_MAX3421_HCD)	+= max3421-hcd.o diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index df13d425e9c..205f4a33658 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -227,8 +227,7 @@ static int bcma_hcd_probe(struct bcma_device *dev)  	/* TODO: Probably need checks here; is the core connected? */ -	if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) || -	    dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32))) +	if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))  		return -EOPNOTSUPP;  	usb_dev = kzalloc(sizeof(struct bcma_hcd_device), GFP_KERNEL); diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index 3b645ff46f7..ec9f7b75d49 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -30,13 +30,17 @@ 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; +static struct clk *iclk, *fclk, *uclk;  static int clocked;  /*-------------------------------------------------------------------------*/  static void atmel_start_clock(void)  { +	if (IS_ENABLED(CONFIG_COMMON_CLK)) { +		clk_set_rate(uclk, 48000000); +		clk_prepare_enable(uclk); +	}  	clk_prepare_enable(iclk);  	clk_prepare_enable(fclk);  	clocked = 1; @@ -46,6 +50,8 @@ static void atmel_stop_clock(void)  {  	clk_disable_unprepare(fclk);  	clk_disable_unprepare(iclk); +	if (IS_ENABLED(CONFIG_COMMON_CLK)) +		clk_disable_unprepare(uclk);  	clocked = 0;  } @@ -90,10 +96,9 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (retval) +		goto fail_create_hcd;  	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));  	if (!hcd) { @@ -130,6 +135,14 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)  		retval = -ENOENT;  		goto fail_request_resource;  	} +	if (IS_ENABLED(CONFIG_COMMON_CLK)) { +		uclk = devm_clk_get(&pdev->dev, "usb_clk"); +		if (IS_ERR(uclk)) { +			dev_err(&pdev->dev, "failed to get uclk\n"); +			retval = PTR_ERR(uclk); +			goto fail_request_resource; +		} +	}  	ehci = hcd_to_ehci(hcd);  	/* registers start at offset 0x0 */ @@ -140,6 +153,7 @@ static int ehci_atmel_drv_probe(struct platform_device *pdev)  	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (retval)  		goto fail_add_hcd; +	device_wakeup_enable(hcd->self.controller);  	return retval; diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index aa5b603f393..524cbf26d99 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -18,7 +18,7 @@  /* this file is part of ehci-hcd.c */ -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  /* check the values in the HCSPARAMS register   * (host controller _Structural_ parameters) @@ -62,7 +62,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {}  #endif -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  /* check the values in the HCCPARAMS register   * (host controller _Capability_ parameters) @@ -101,7 +101,7 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}  #endif -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  static void __maybe_unused  dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) @@ -301,7 +301,7 @@ static inline int __maybe_unused  dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)  { return 0; } -#endif	/* DEBUG || CONFIG_DYNAMIC_DEBUG */ +#endif	/* CONFIG_DYNAMIC_DEBUG */  /* functions have the "wrong" filename when they're output... */  #define dbg_status(ehci, label, status) { \ @@ -334,6 +334,7 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }  /* troubleshooting help: expose state in debugfs */  static int debug_async_open(struct inode *, struct file *); +static int debug_bandwidth_open(struct inode *, struct file *);  static int debug_periodic_open(struct inode *, struct file *);  static int debug_registers_open(struct inode *, struct file *); @@ -347,6 +348,13 @@ static const struct file_operations debug_async_fops = {  	.release	= debug_close,  	.llseek		= default_llseek,  }; +static const struct file_operations debug_bandwidth_fops = { +	.owner		= THIS_MODULE, +	.open		= debug_bandwidth_open, +	.read		= debug_output, +	.release	= debug_close, +	.llseek		= default_llseek, +};  static const struct file_operations debug_periodic_fops = {  	.owner		= THIS_MODULE,  	.open		= debug_periodic_open, @@ -379,7 +387,7 @@ struct debug_buffer {  		case QH_LOW_SPEED:  tmp = 'l'; break; \  		case QH_HIGH_SPEED: tmp = 'h'; break; \  		default: tmp = '?'; break; \ -		}; tmp; }) +		} tmp; })  static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)  { @@ -525,6 +533,89 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)  	return strlen(buf->output_buf);  } +static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf) +{ +	struct ehci_hcd		*ehci; +	struct ehci_tt		*tt; +	struct ehci_per_sched	*ps; +	unsigned		temp, size; +	char			*next; +	unsigned		i; +	u8			*bw; +	u16			*bf; +	u8			budget[EHCI_BANDWIDTH_SIZE]; + +	ehci = hcd_to_ehci(bus_to_hcd(buf->bus)); +	next = buf->output_buf; +	size = buf->alloc_size; + +	*next = 0; + +	spin_lock_irq(&ehci->lock); + +	/* Dump the HS bandwidth table */ +	temp = scnprintf(next, size, +			"HS bandwidth allocation (us per microframe)\n"); +	size -= temp; +	next += temp; +	for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) { +		bw = &ehci->bandwidth[i]; +		temp = scnprintf(next, size, +				"%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n", +				i, bw[0], bw[1], bw[2], bw[3], +					bw[4], bw[5], bw[6], bw[7]); +		size -= temp; +		next += temp; +	} + +	/* Dump all the FS/LS tables */ +	list_for_each_entry(tt, &ehci->tt_list, tt_list) { +		temp = scnprintf(next, size, +				"\nTT %s port %d  FS/LS bandwidth allocation (us per frame)\n", +				dev_name(&tt->usb_tt->hub->dev), +				tt->tt_port + !!tt->usb_tt->multi); +		size -= temp; +		next += temp; + +		bf = tt->bandwidth; +		temp = scnprintf(next, size, +				"  %5u%5u%5u%5u%5u%5u%5u%5u\n", +				bf[0], bf[1], bf[2], bf[3], +					bf[4], bf[5], bf[6], bf[7]); +		size -= temp; +		next += temp; + +		temp = scnprintf(next, size, +				"FS/LS budget (us per microframe)\n"); +		size -= temp; +		next += temp; +		compute_tt_budget(budget, tt); +		for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) { +			bw = &budget[i]; +			temp = scnprintf(next, size, +					"%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n", +					i, bw[0], bw[1], bw[2], bw[3], +						bw[4], bw[5], bw[6], bw[7]); +			size -= temp; +			next += temp; +		} +		list_for_each_entry(ps, &tt->ps_list, ps_list) { +			temp = scnprintf(next, size, +					"%s ep %02x:  %4u @ %2u.%u+%u mask %04x\n", +					dev_name(&ps->udev->dev), +					ps->ep->desc.bEndpointAddress, +					ps->tt_usecs, +					ps->bw_phase, ps->phase_uf, +					ps->bw_period, ps->cs_mask); +			size -= temp; +			next += temp; +		} +	} +	spin_unlock_irq(&ehci->lock); + +	return next - buf->output_buf; +} +  #define DBG_SCHED_LIMIT 64  static ssize_t fill_periodic_buffer(struct debug_buffer *buf)  { @@ -571,7 +662,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)  			case Q_TYPE_QH:  				hw = p.qh->hw;  				temp = scnprintf (next, size, " qh%d-%04x/%p", -						p.qh->period, +						p.qh->ps.period,  						hc32_to_cpup(ehci,  							&hw->hw_info2)  							/* uframe masks */ @@ -618,7 +709,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)  						speed_char (scratch),  						scratch & 0x007f,  						(scratch >> 8) & 0x000f, type, -						p.qh->usecs, p.qh->c_usecs, +						p.qh->ps.usecs, +						p.qh->ps.c_usecs,  						temp,  						0x7ff & (scratch >> 16)); @@ -645,7 +737,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)  			case Q_TYPE_SITD:  				temp = scnprintf (next, size,  					" sitd%d-%04x/%p", -					p.sitd->stream->interval, +					p.sitd->stream->ps.period,  					hc32_to_cpup(ehci, &p.sitd->hw_uframe)  						& 0x0000ffff,  					p.sitd); @@ -726,7 +818,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)  #ifdef	CONFIG_PCI  	/* EHCI 0.96 and later may have "extended capabilities" */ -	if (hcd->self.controller->bus == &pci_bus_type) { +	if (dev_is_pci(hcd->self.controller)) {  		struct pci_dev	*pdev;  		u32		offset, cap, cap2;  		unsigned	count = 256/4; @@ -918,6 +1010,7 @@ static int debug_close(struct inode *inode, struct file *file)  	return 0;  } +  static int debug_async_open(struct inode *inode, struct file *file)  {  	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer); @@ -925,6 +1018,14 @@ static int debug_async_open(struct inode *inode, struct file *file)  	return file->private_data ? 0 : -ENOMEM;  } +static int debug_bandwidth_open(struct inode *inode, struct file *file) +{ +	file->private_data = alloc_buffer(inode->i_private, +			fill_bandwidth_buffer); + +	return file->private_data ? 0 : -ENOMEM; +} +  static int debug_periodic_open(struct inode *inode, struct file *file)  {  	struct debug_buffer *buf; @@ -957,6 +1058,10 @@ static inline void create_debug_files (struct ehci_hcd *ehci)  						&debug_async_fops))  		goto file_error; +	if (!debugfs_create_file("bandwidth", S_IRUGO, ehci->debug_dir, bus, +						&debug_bandwidth_fops)) +		goto file_error; +  	if (!debugfs_create_file("periodic", S_IRUGO, ehci->debug_dir, bus,  						&debug_periodic_fops))  		goto file_error; diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c new file mode 100644 index 00000000000..d1c76216350 --- /dev/null +++ b/drivers/usb/host/ehci-exynos.c @@ -0,0 +1,390 @@ +/* + * SAMSUNG EXYNOS USB HOST EHCI Controller + * + * Copyright (C) 2011 Samsung Electronics Co.Ltd + * Author: Jingoo Han <jg1.han@samsung.com> + * Author: Joonyoung Shim <jy0922.shim@samsung.com> + * + * This program is free software; you can redistribute  it and/or modify it + * under  the terms of  the GNU General  Public License as published by the + * Free Software Foundation;  either version 2 of the  License, or (at your + * option) any later version. + * + */ + +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/usb/phy.h> +#include <linux/usb/samsung_usb_phy.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> +#include <linux/usb/otg.h> + +#include "ehci.h" + +#define DRIVER_DESC "EHCI EXYNOS driver" + +#define EHCI_INSNREG00(base)			(base + 0x90) +#define EHCI_INSNREG00_ENA_INCR16		(0x1 << 25) +#define EHCI_INSNREG00_ENA_INCR8		(0x1 << 24) +#define EHCI_INSNREG00_ENA_INCR4		(0x1 << 23) +#define EHCI_INSNREG00_ENA_INCRX_ALIGN		(0x1 << 22) +#define EHCI_INSNREG00_ENABLE_DMA_BURST	\ +	(EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 |	\ +	 EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN) + +static const char hcd_name[] = "ehci-exynos"; +static struct hc_driver __read_mostly exynos_ehci_hc_driver; + +#define PHY_NUMBER 3 + +struct exynos_ehci_hcd { +	struct clk *clk; +	struct usb_phy *phy; +	struct usb_otg *otg; +	struct phy *phy_g[PHY_NUMBER]; +}; + +#define to_exynos_ehci(hcd) (struct exynos_ehci_hcd *)(hcd_to_ehci(hcd)->priv) + +static int exynos_ehci_get_phy(struct device *dev, +				struct exynos_ehci_hcd *exynos_ehci) +{ +	struct device_node *child; +	struct phy *phy; +	int phy_number; +	int ret = 0; + +	exynos_ehci->phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); +	if (IS_ERR(exynos_ehci->phy)) { +		ret = PTR_ERR(exynos_ehci->phy); +		if (ret != -ENXIO && ret != -ENODEV) { +			dev_err(dev, "no usb2 phy configured\n"); +			return ret; +		} +		dev_dbg(dev, "Failed to get usb2 phy\n"); +	} else { +		exynos_ehci->otg = exynos_ehci->phy->otg; +	} + +	for_each_available_child_of_node(dev->of_node, child) { +		ret = of_property_read_u32(child, "reg", &phy_number); +		if (ret) { +			dev_err(dev, "Failed to parse device tree\n"); +			of_node_put(child); +			return ret; +		} + +		if (phy_number >= PHY_NUMBER) { +			dev_err(dev, "Invalid number of PHYs\n"); +			of_node_put(child); +			return -EINVAL; +		} + +		phy = devm_of_phy_get(dev, child, 0); +		of_node_put(child); +		if (IS_ERR(phy)) { +			ret = PTR_ERR(phy); +			if (ret != -ENOSYS && ret != -ENODEV) { +				dev_err(dev, "no usb2 phy configured\n"); +				return ret; +			} +			dev_dbg(dev, "Failed to get usb2 phy\n"); +		} +		exynos_ehci->phy_g[phy_number] = phy; +	} + +	return ret; +} + +static int exynos_ehci_phy_enable(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); +	int i; +	int ret = 0; + +	if (!IS_ERR(exynos_ehci->phy)) +		return usb_phy_init(exynos_ehci->phy); + +	for (i = 0; ret == 0 && i < PHY_NUMBER; i++) +		if (!IS_ERR(exynos_ehci->phy_g[i])) +			ret = phy_power_on(exynos_ehci->phy_g[i]); +	if (ret) +		for (i--; i >= 0; i--) +			if (!IS_ERR(exynos_ehci->phy_g[i])) +				phy_power_off(exynos_ehci->phy_g[i]); + +	return ret; +} + +static void exynos_ehci_phy_disable(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); +	int i; + +	if (!IS_ERR(exynos_ehci->phy)) { +		usb_phy_shutdown(exynos_ehci->phy); +		return; +	} + +	for (i = 0; i < PHY_NUMBER; i++) +		if (!IS_ERR(exynos_ehci->phy_g[i])) +			phy_power_off(exynos_ehci->phy_g[i]); +} + +static void exynos_setup_vbus_gpio(struct device *dev) +{ +	int err; +	int gpio; + +	if (!dev->of_node) +		return; + +	gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0); +	if (!gpio_is_valid(gpio)) +		return; + +	err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH, +				    "ehci_vbus_gpio"); +	if (err) +		dev_err(dev, "can't request ehci vbus gpio %d", gpio); +} + +static int exynos_ehci_probe(struct platform_device *pdev) +{ +	struct exynos_ehci_hcd *exynos_ehci; +	struct usb_hcd *hcd; +	struct ehci_hcd *ehci; +	struct resource *res; +	int irq; +	int err; + +	/* +	 * Right now device-tree probed devices don't get dma_mask set. +	 * Since shared usb code relies on it, set it here for now. +	 * Once we move to full device tree support this will vanish off. +	 */ +	err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (err) +		return err; + +	exynos_setup_vbus_gpio(&pdev->dev); + +	hcd = usb_create_hcd(&exynos_ehci_hc_driver, +			     &pdev->dev, dev_name(&pdev->dev)); +	if (!hcd) { +		dev_err(&pdev->dev, "Unable to create HCD\n"); +		return -ENOMEM; +	} +	exynos_ehci = to_exynos_ehci(hcd); + +	if (of_device_is_compatible(pdev->dev.of_node, +					"samsung,exynos5440-ehci")) +		goto skip_phy; + +	err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci); +	if (err) +		goto fail_clk; + +skip_phy: + +	exynos_ehci->clk = devm_clk_get(&pdev->dev, "usbhost"); + +	if (IS_ERR(exynos_ehci->clk)) { +		dev_err(&pdev->dev, "Failed to get usbhost clock\n"); +		err = PTR_ERR(exynos_ehci->clk); +		goto fail_clk; +	} + +	err = clk_prepare_enable(exynos_ehci->clk); +	if (err) +		goto fail_clk; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_err(&pdev->dev, "Failed to get I/O memory\n"); +		err = -ENXIO; +		goto fail_io; +	} + +	hcd->rsrc_start = res->start; +	hcd->rsrc_len = resource_size(res); +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		err = PTR_ERR(hcd->regs); +		goto fail_io; +	} + +	irq = platform_get_irq(pdev, 0); +	if (!irq) { +		dev_err(&pdev->dev, "Failed to get IRQ\n"); +		err = -ENODEV; +		goto fail_io; +	} + +	if (exynos_ehci->otg) +		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); + +	err = exynos_ehci_phy_enable(&pdev->dev); +	if (err) { +		dev_err(&pdev->dev, "Failed to enable USB phy\n"); +		goto fail_io; +	} + +	ehci = hcd_to_ehci(hcd); +	ehci->caps = hcd->regs; + +	/* DMA burst Enable */ +	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); + +	err = usb_add_hcd(hcd, irq, IRQF_SHARED); +	if (err) { +		dev_err(&pdev->dev, "Failed to add USB HCD\n"); +		goto fail_add_hcd; +	} +	device_wakeup_enable(hcd->self.controller); + +	platform_set_drvdata(pdev, hcd); + +	return 0; + +fail_add_hcd: +	exynos_ehci_phy_disable(&pdev->dev); +fail_io: +	clk_disable_unprepare(exynos_ehci->clk); +fail_clk: +	usb_put_hcd(hcd); +	return err; +} + +static int exynos_ehci_remove(struct platform_device *pdev) +{ +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); + +	usb_remove_hcd(hcd); + +	if (exynos_ehci->otg) +		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); + +	exynos_ehci_phy_disable(&pdev->dev); + +	clk_disable_unprepare(exynos_ehci->clk); + +	usb_put_hcd(hcd); + +	return 0; +} + +#ifdef CONFIG_PM +static int exynos_ehci_suspend(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); + +	bool do_wakeup = device_may_wakeup(dev); +	int rc; + +	rc = ehci_suspend(hcd, do_wakeup); +	if (rc) +		return rc; + +	if (exynos_ehci->otg) +		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); + +	exynos_ehci_phy_disable(dev); + +	clk_disable_unprepare(exynos_ehci->clk); + +	return rc; +} + +static int exynos_ehci_resume(struct device *dev) +{ +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ehci_hcd *exynos_ehci = to_exynos_ehci(hcd); +	int ret; + +	clk_prepare_enable(exynos_ehci->clk); + +	if (exynos_ehci->otg) +		exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); + +	ret = exynos_ehci_phy_enable(dev); +	if (ret) { +		dev_err(dev, "Failed to enable USB phy\n"); +		clk_disable_unprepare(exynos_ehci->clk); +		return ret; +	} + +	/* DMA burst Enable */ +	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); + +	ehci_resume(hcd, false); +	return 0; +} +#else +#define exynos_ehci_suspend	NULL +#define exynos_ehci_resume	NULL +#endif + +static const struct dev_pm_ops exynos_ehci_pm_ops = { +	.suspend	= exynos_ehci_suspend, +	.resume		= exynos_ehci_resume, +}; + +#ifdef CONFIG_OF +static const struct of_device_id exynos_ehci_match[] = { +	{ .compatible = "samsung,exynos4210-ehci" }, +	{ .compatible = "samsung,exynos5440-ehci" }, +	{}, +}; +MODULE_DEVICE_TABLE(of, exynos_ehci_match); +#endif + +static struct platform_driver exynos_ehci_driver = { +	.probe		= exynos_ehci_probe, +	.remove		= exynos_ehci_remove, +	.shutdown	= usb_hcd_platform_shutdown, +	.driver = { +		.name	= "exynos-ehci", +		.owner	= THIS_MODULE, +		.pm	= &exynos_ehci_pm_ops, +		.of_match_table = of_match_ptr(exynos_ehci_match), +	} +}; +static const struct ehci_driver_overrides exynos_overrides __initdata = { +	.extra_priv_size = sizeof(struct exynos_ehci_hcd), +}; + +static int __init ehci_exynos_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); +	ehci_init_driver(&exynos_ehci_hc_driver, &exynos_overrides); +	return platform_driver_register(&exynos_ehci_driver); +} +module_init(ehci_exynos_init); + +static void __exit ehci_exynos_cleanup(void) +{ +	platform_driver_unregister(&exynos_ehci_driver); +} +module_exit(ehci_exynos_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_ALIAS("platform:exynos-ehci"); +MODULE_AUTHOR("Jingoo Han"); +MODULE_AUTHOR("Joonyoung Shim"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 947b009009f..cf2734b532a 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -57,7 +57,7 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,  	pr_debug("initializing FSL-SOC USB Controller\n");  	/* Need platform data for setup */ -	pdata = (struct fsl_usb2_platform_data *)dev_get_platdata(&pdev->dev); +	pdata = dev_get_platdata(&pdev->dev);  	if (!pdata) {  		dev_err(&pdev->dev,  			"No platform data for %s.\n", dev_name(&pdev->dev)); @@ -102,19 +102,11 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,  	}  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, -				driver->description)) { -		dev_dbg(&pdev->dev, "controller already in use\n"); -		retval = -EBUSY; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs);  		goto err2;  	} -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); - -	if (hcd->regs == NULL) { -		dev_dbg(&pdev->dev, "error mapping memory\n"); -		retval = -EFAULT; -		goto err3; -	}  	pdata->regs = hcd->regs; @@ -126,18 +118,19 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,  	 */  	if (pdata->init && pdata->init(pdev)) {  		retval = -ENODEV; -		goto err4; +		goto err2;  	}  	/* Enable USB controller, 83xx or 8536 */ -	if (pdata->have_sysif_regs) +	if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6)  		setbits32(hcd->regs + FSL_SOC_USB_CTRL, 0x4);  	/* Don't need to set host mode here. It will be done by tdi_reset() */  	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (retval != 0) -		goto err4; +		goto err2; +	device_wakeup_enable(hcd->self.controller);  #ifdef CONFIG_USB_OTG  	if (pdata->operating_mode == FSL_USB2_DR_OTG) { @@ -152,21 +145,17 @@ static int usb_hcd_fsl_probe(const struct hc_driver *driver,  					      &ehci_to_hcd(ehci)->self);  			if (retval) {  				usb_put_phy(hcd->phy); -				goto err4; +				goto err2;  			}  		} else {  			dev_err(&pdev->dev, "can't find phy\n");  			retval = -ENODEV; -			goto err4; +			goto err2;  		}  	}  #endif  	return retval; -      err4: -	iounmap(hcd->regs); -      err3: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);        err2:  	usb_put_hcd(hcd);        err1: @@ -205,8 +194,6 @@ static void usb_hcd_fsl_remove(struct usb_hcd *hcd,  	 */  	if (pdata->exit)  		pdata->exit(pdev); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd);  } @@ -232,15 +219,9 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,  	case FSL_USB2_PHY_ULPI:  		if (pdata->have_sysif_regs && pdata->controller_ver) {  			/* controller version 1.6 or above */ +			clrbits32(non_ehci + FSL_SOC_USB_CTRL, UTMI_PHY_EN);  			setbits32(non_ehci + FSL_SOC_USB_CTRL, -					ULPI_PHY_CLK_SEL); -			/* -			 * Due to controller issue of PHY_CLK_VALID in ULPI -			 * mode, we set USB_CTRL_USB_EN before checking -			 * PHY_CLK_VALID, otherwise PHY_CLK_VALID doesn't work. -			 */ -			clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, -					UTMI_PHY_EN, USB_CTRL_USB_EN); +				ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN);  		}  		portsc |= PORT_PTS_ULPI;  		break; @@ -267,12 +248,14 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,  		break;  	} -	if (pdata->have_sysif_regs && pdata->controller_ver && +	if (pdata->have_sysif_regs && +	    pdata->controller_ver > FSL_USB_VER_1_6 &&  	    (phy_mode == FSL_USB2_PHY_ULPI)) {  		/* check PHY_CLK_VALID to get phy clk valid */ -		if (!spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & -				PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0)) { -			printk(KERN_WARNING "fsl-ehci: USB PHY clock invalid\n"); +		if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & +				PHY_CLK_VALID, FSL_USB_PHY_CLK_TIMEOUT, 0) || +				in_be32(non_ehci + FSL_SOC_USB_PRICTRL))) { +			dev_warn(hcd->self.controller, "USB PHY clock invalid\n");  			return -EINVAL;  		}  	} @@ -418,7 +401,7 @@ static int ehci_fsl_mpc512x_drv_suspend(struct device *dev)  	struct fsl_usb2_platform_data *pdata = dev_get_platdata(dev);  	u32 tmp; -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  	u32 mode = ehci_readl(ehci, hcd->regs + FSL_SOC_USB_USBMODE);  	mode &= USBMODE_CM_MASK;  	tmp = ehci_readl(ehci, hcd->regs + 0x140);	/* usbcmd */ diff --git a/drivers/usb/host/ehci-grlib.c b/drivers/usb/host/ehci-grlib.c index b52a66ce92e..495b6fbcbcd 100644 --- a/drivers/usb/host/ehci-grlib.c +++ b/drivers/usb/host/ehci-grlib.c @@ -113,7 +113,8 @@ static int ehci_hcd_grlib_probe(struct platform_device *op)  	irq = irq_of_parse_and_map(dn, 0);  	if (irq == NO_IRQ) { -		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); +		dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", +			__FILE__);  		rv = -EBUSY;  		goto err_irq;  	} @@ -140,6 +141,7 @@ static int ehci_hcd_grlib_probe(struct platform_device *op)  	if (rv)  		goto err_ioremap; +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_ioremap: diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5d6022f30eb..81cda09b47e 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -71,7 +71,6 @@  static const char	hcd_name [] = "ehci_hcd"; -#undef VERBOSE_DEBUG  #undef EHCI_URB_TRACE  /* magic numbers that can affect system performance */ @@ -110,6 +109,9 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");  #include "ehci.h"  #include "pci-quirks.h" +static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE], +		struct ehci_tt *tt); +  /*   * The MosChip MCS9990 controller updates its microframe counter   * a little before the frame counter, and occasionally we will read @@ -484,6 +486,7 @@ static int ehci_init(struct usb_hcd *hcd)  	INIT_LIST_HEAD(&ehci->intr_qh_list);  	INIT_LIST_HEAD(&ehci->cached_itd_list);  	INIT_LIST_HEAD(&ehci->cached_sitd_list); +	INIT_LIST_HEAD(&ehci->tt_list);  	if (HCC_PGM_FRAMELISTLEN(hcc_params)) {  		/* periodic schedule size can be smaller than default */ @@ -682,8 +685,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);  	u32			status, masked_status, pcd_status = 0, cmd;  	int			bh; +	unsigned long		flags; -	spin_lock (&ehci->lock); +	/* +	 * For threadirqs option we use spin_lock_irqsave() variant to prevent +	 * deadlock with ehci hrtimer callback, because hrtimer callbacks run +	 * in interrupt context even when threadirqs is specified. We can go +	 * back to spin_lock() variant when hrtimer callbacks become threaded. +	 */ +	spin_lock_irqsave(&ehci->lock, flags);  	status = ehci_readl(ehci, &ehci->regs->status); @@ -701,7 +711,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  	/* Shared IRQ? */  	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { -		spin_unlock(&ehci->lock); +		spin_unlock_irqrestore(&ehci->lock, flags);  		return IRQ_NONE;  	} @@ -710,13 +720,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)  	cmd = ehci_readl(ehci, &ehci->regs->command);  	bh = 0; -#ifdef	VERBOSE_DEBUG -	/* unrequested/ignored: Frame List Rollover */ -	dbg_status (ehci, "irq", status); -#endif - -	/* INT, ERR, and IAA interrupt rates can be throttled */ -  	/* normal [4.15.1.2] or error [4.15.1.1] completion */  	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {  		if (likely ((status & STS_ERR) == 0)) @@ -819,7 +822,7 @@ dead:  	if (bh)  		ehci_work (ehci); -	spin_unlock (&ehci->lock); +	spin_unlock_irqrestore(&ehci->lock, flags);  	if (pcd_status)  		usb_hcd_poll_rh_status(hcd);  	return IRQ_HANDLED; @@ -956,6 +959,7 @@ rescan:  			goto idle_timeout;  		/* BUG_ON(!list_empty(&stream->free_list)); */ +		reserve_release_iso_bandwidth(ehci, stream, -1);  		kfree(stream);  		goto done;  	} @@ -982,6 +986,8 @@ idle_timeout:  		if (qh->clearing_tt)  			goto idle_timeout;  		if (list_empty (&qh->qtd_list)) { +			if (qh->ps.bw_uperiod) +				reserve_release_intr_bandwidth(ehci, qh, -1);  			qh_destroy(ehci, qh);  			break;  		} @@ -1022,7 +1028,6 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)  	 * the toggle bit in the QH.  	 */  	if (qh) { -		usb_settoggle(qh->dev, epnum, is_out, 0);  		if (!list_empty(&qh->qtd_list)) {  			WARN_ONCE(1, "clear_halt for a busy endpoint\n");  		} else { @@ -1030,6 +1035,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)  			 * while the QH is active.  Unlink it now;  			 * re-linking will call qh_refresh().  			 */ +			usb_settoggle(qh->ps.udev, epnum, is_out, 0);  			qh->exception = 1;  			if (eptype == USB_ENDPOINT_XFER_BULK)  				start_unlink_async(ehci, qh); @@ -1048,6 +1054,19 @@ static int ehci_get_frame (struct usb_hcd *hcd)  /*-------------------------------------------------------------------------*/ +/* Device addition and removal */ + +static void ehci_remove_device(struct usb_hcd *hcd, struct usb_device *udev) +{ +	struct ehci_hcd		*ehci = hcd_to_ehci(hcd); + +	spin_lock_irq(&ehci->lock); +	drop_tt(udev); +	spin_unlock_irq(&ehci->lock); +} + +/*-------------------------------------------------------------------------*/ +  #ifdef	CONFIG_PM  /* suspend/resume, section 4.3 */ @@ -1075,6 +1094,14 @@ int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup)  	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);  	spin_unlock_irq(&ehci->lock); +	synchronize_irq(hcd->irq); + +	/* Check for race with a wakeup request */ +	if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { +		ehci_resume(hcd, false); +		return -EBUSY; +	} +  	return 0;  }  EXPORT_SYMBOL_GPL(ehci_suspend); @@ -1191,6 +1218,11 @@ static const struct hc_driver ehci_hc_driver = {  	.bus_resume =		ehci_bus_resume,  	.relinquish_port =	ehci_relinquish_port,  	.port_handed_over =	ehci_port_handed_over, + +	/* +	 * device support +	 */ +	.free_dev =		ehci_remove_device,  };  void ehci_init_driver(struct hc_driver *drv, @@ -1238,11 +1270,6 @@ MODULE_LICENSE ("GPL");  #define XILINX_OF_PLATFORM_DRIVER	ehci_hcd_xilinx_of_driver  #endif -#ifdef CONFIG_USB_W90X900_EHCI -#include "ehci-w90x900.c" -#define	PLATFORM_DRIVER		ehci_hcd_w90x900_driver -#endif -  #ifdef CONFIG_USB_OCTEON_EHCI  #include "ehci-octeon.c"  #define PLATFORM_DRIVER		ehci_octeon_driver @@ -1292,7 +1319,7 @@ static int __init ehci_hcd_init(void)  		 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),  		 sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  	ehci_debug_root = debugfs_create_dir("ehci", usb_debug_root);  	if (!ehci_debug_root) {  		retval = -ENOENT; @@ -1341,7 +1368,7 @@ clean2:  	platform_driver_unregister(&PLATFORM_DRIVER);  clean0:  #endif -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  	debugfs_remove(ehci_debug_root);  	ehci_debug_root = NULL;  err_debug: @@ -1365,7 +1392,7 @@ static void __exit ehci_hcd_cleanup(void)  #ifdef PS3_SYSTEM_BUS_DRIVER  	ps3_ehci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);  #endif -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  	debugfs_remove(ehci_debug_root);  #endif  	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 835fc0844a6..cc305c71ac3 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -33,15 +33,6 @@  #ifdef	CONFIG_PM -static int ehci_hub_control( -	struct usb_hcd	*hcd, -	u16		typeReq, -	u16		wValue, -	u16		wIndex, -	char		*buf, -	u16		wLength -); -  static int persist_enabled_on_companion(struct usb_device *udev, void *unused)  {  	return !udev->maxchild && udev->persist_enabled && @@ -238,6 +229,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)  	int			port;  	int			mask;  	int			changed; +	bool			fs_idle_delay;  	ehci_dbg(ehci, "suspend root hub\n"); @@ -272,6 +264,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)  	ehci->bus_suspended = 0;  	ehci->owned_ports = 0;  	changed = 0; +	fs_idle_delay = false;  	port = HCS_N_PORTS(ehci->hcs_params);  	while (port--) {  		u32 __iomem	*reg = &ehci->regs->port_status [port]; @@ -300,16 +293,32 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)  		}  		if (t1 != t2) { +			/* +			 * On some controllers, Wake-On-Disconnect will +			 * generate false wakeup signals until the bus +			 * switches over to full-speed idle.  For their +			 * sake, add a delay if we need one. +			 */ +			if ((t2 & PORT_WKDISC_E) && +					ehci_port_speed(ehci, t2) == +						USB_PORT_STAT_HIGH_SPEED) +				fs_idle_delay = true;  			ehci_writel(ehci, t2, reg);  			changed = 1;  		}  	} +	spin_unlock_irq(&ehci->lock); + +	if ((changed && ehci->has_tdi_phy_lpm) || fs_idle_delay) { +		/* +		 * Wait for HCD to enter low-power mode or for the bus +		 * to switch to full-speed idle. +		 */ +		usleep_range(5000, 5500); +	}  	if (changed && ehci->has_tdi_phy_lpm) { -		spin_unlock_irq(&ehci->lock); -		msleep(5);	/* 5 ms for HCD to enter low-power mode */  		spin_lock_irq(&ehci->lock); -  		port = HCS_N_PORTS(ehci->hcs_params);  		while (port--) {  			u32 __iomem	*hostpc_reg = &ehci->regs->hostpc[port]; @@ -322,8 +331,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)  					port, (t3 & HOSTPC_PHCD) ?  					"succeeded" : "failed");  		} +		spin_unlock_irq(&ehci->lock);  	} -	spin_unlock_irq(&ehci->lock);  	/* Apparently some devices need a >= 1-uframe delay here */  	if (ehci->bus_suspended) @@ -847,7 +856,7 @@ cleanup:  #endif /* CONFIG_USB_HCD_TEST_MODE */  /*-------------------------------------------------------------------------*/ -static int ehci_hub_control ( +int ehci_hub_control(  	struct usb_hcd	*hcd,  	u16		typeReq,  	u16		wValue, @@ -1114,10 +1123,8 @@ static int ehci_hub_control (  		if (test_bit(wIndex, &ehci->port_c_suspend))  			status |= USB_PORT_STAT_C_SUSPEND << 16; -#ifndef	VERBOSE_DEBUG -	if (status & ~0xffff)	/* only if wPortChange is interesting */ -#endif -		dbg_port (ehci, "GetStatus", wIndex + 1, temp); +		if (status & ~0xffff)	/* only if wPortChange is interesting */ +			dbg_port(ehci, "GetStatus", wIndex + 1, temp);  		put_unaligned_le32(status, buf);  		break;  	case SetHubFeature: @@ -1269,6 +1276,7 @@ error_exit:  	spin_unlock_irqrestore (&ehci->lock, flags);  	return retval;  } +EXPORT_SYMBOL_GPL(ehci_hub_control);  static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)  { diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 52a77734a22..c0fb6a8ae6a 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -224,11 +224,11 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)  		hw->hw_next = EHCI_LIST_END(ehci);  		hw->hw_qtd_next = EHCI_LIST_END(ehci);  		hw->hw_alt_next = EHCI_LIST_END(ehci); -		hw->hw_token &= ~QTD_STS_ACTIVE;  		ehci->dummy->hw = hw;  		for (i = 0; i < ehci->periodic_size; i++) -			ehci->periodic[i] = ehci->dummy->qh_dma; +			ehci->periodic[i] = cpu_to_hc32(ehci, +					ehci->dummy->qh_dma);  	} else {  		for (i = 0; i < ehci->periodic_size; i++)  			ehci->periodic[i] = EHCI_LIST_END(ehci); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index 0f717dc688b..982c09bebe0 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -42,7 +42,6 @@  static const char hcd_name[] = "ehci-msm";  static struct hc_driver __read_mostly msm_hc_driver; -static struct usb_phy *phy;  static int ehci_msm_reset(struct usb_hcd *hcd)  { @@ -70,6 +69,7 @@ static int ehci_msm_probe(struct platform_device *pdev)  {  	struct usb_hcd *hcd;  	struct resource *res; +	struct usb_phy *phy;  	int ret;  	dev_dbg(&pdev->dev, "ehci_msm proble\n"); @@ -96,10 +96,9 @@ static int ehci_msm_probe(struct platform_device *pdev)  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "ioremap failed\n"); -		ret = -ENOMEM; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		ret = PTR_ERR(hcd->regs);  		goto put_hcd;  	} @@ -108,10 +107,14 @@ static int ehci_msm_probe(struct platform_device *pdev)  	 * powering up VBUS, mapping of registers address space and power  	 * management.  	 */ -	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); +	if (pdev->dev.of_node) +		phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); +	else +		phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); +  	if (IS_ERR(phy)) {  		dev_err(&pdev->dev, "unable to find transceiver\n"); -		ret = -ENODEV; +		ret = -EPROBE_DEFER;  		goto put_hcd;  	} @@ -121,6 +124,7 @@ static int ehci_msm_probe(struct platform_device *pdev)  		goto put_hcd;  	} +	hcd->phy = phy;  	device_init_wakeup(&pdev->dev, 1);  	/*  	 * OTG device parent of HCD takes care of putting @@ -147,7 +151,7 @@ static int ehci_msm_remove(struct platform_device *pdev)  	pm_runtime_disable(&pdev->dev);  	pm_runtime_set_suspended(&pdev->dev); -	otg_set_host(phy->otg, NULL); +	otg_set_host(hcd->phy->otg, NULL);  	/* FIXME: need to call usb_remove_hcd() here? */ @@ -186,12 +190,19 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = {  	.resume          = ehci_msm_pm_resume,  }; +static struct of_device_id msm_ehci_dt_match[] = { +	{ .compatible = "qcom,ehci-host", }, +	{} +}; +MODULE_DEVICE_TABLE(of, msm_ehci_dt_match); +  static struct platform_driver ehci_msm_driver = {  	.probe	= ehci_msm_probe,  	.remove	= ehci_msm_remove,  	.driver = {  		   .name = "msm_hsusb_host",  		   .pm = &ehci_msm_dev_pm_ops, +		   .of_match_table = msm_ehci_dt_match,  	},  }; diff --git a/drivers/usb/host/ehci-mv.c b/drivers/usb/host/ehci-mv.c index 417c10da945..08147c35f83 100644 --- a/drivers/usb/host/ehci-mv.c +++ b/drivers/usb/host/ehci-mv.c @@ -176,11 +176,9 @@ static int mv_ehci_probe(struct platform_device *pdev)  		goto err_put_hcd;  	} -	ehci_mv->phy_regs = devm_ioremap(&pdev->dev, r->start, -					 resource_size(r)); -	if (ehci_mv->phy_regs == 0) { -		dev_err(&pdev->dev, "failed to map phy I/O memory\n"); -		retval = -EFAULT; +	ehci_mv->phy_regs = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(ehci_mv->phy_regs)) { +		retval = PTR_ERR(ehci_mv->phy_regs);  		goto err_put_hcd;  	} @@ -191,11 +189,9 @@ static int mv_ehci_probe(struct platform_device *pdev)  		goto err_put_hcd;  	} -	ehci_mv->cap_regs = devm_ioremap(&pdev->dev, r->start, -					 resource_size(r)); -	if (ehci_mv->cap_regs == NULL) { -		dev_err(&pdev->dev, "failed to map I/O memory\n"); -		retval = -EFAULT; +	ehci_mv->cap_regs = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(ehci_mv->cap_regs)) { +		retval = PTR_ERR(ehci_mv->cap_regs);  		goto err_put_hcd;  	} @@ -257,6 +253,7 @@ static int mv_ehci_probe(struct platform_device *pdev)  				"failed to add hcd with err %d\n", retval);  			goto err_set_vbus;  		} +		device_wakeup_enable(hcd->self.controller);  	}  	if (pdata->private_init) diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 0528dc4526c..dbe5e4eea08 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -155,6 +155,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)  	if (ret)  		goto err_add; +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_add: diff --git a/drivers/usb/host/ehci-octeon.c b/drivers/usb/host/ehci-octeon.c index ab0397e4d8f..9051439039a 100644 --- a/drivers/usb/host/ehci-octeon.c +++ b/drivers/usb/host/ehci-octeon.c @@ -116,8 +116,10 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)  	 * We can DMA from anywhere. But the descriptors must be in  	 * the lower 4GB.  	 */ -	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);  	pdev->dev.dma_mask = &ehci_octeon_dma_mask; +	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret;  	hcd = usb_create_hcd(&ehci_octeon_hc_driver, &pdev->dev, "octeon");  	if (!hcd) @@ -126,20 +128,12 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)  	hcd->rsrc_start = res_mem->start;  	hcd->rsrc_len = resource_size(res_mem); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, -				OCTEON_EHCI_HCD_NAME)) { -		dev_err(&pdev->dev, "request_mem_region failed\n"); -		ret = -EBUSY; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res_mem); +	if (IS_ERR(hcd->regs)) { +		ret = PTR_ERR(hcd->regs);  		goto err1;  	} -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "ioremap failed\n"); -		ret = -ENOMEM; -		goto err2; -	} -  	ehci_octeon_start();  	ehci = hcd_to_ehci(hcd); @@ -154,18 +148,16 @@ static int ehci_octeon_drv_probe(struct platform_device *pdev)  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret) {  		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); -		goto err3; +		goto err2;  	} +	device_wakeup_enable(hcd->self.controller);  	platform_set_drvdata(pdev, hcd);  	return 0; -err3: +err2:  	ehci_octeon_stop(); -	iounmap(hcd->regs); -err2: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  err1:  	usb_put_hcd(hcd);  	return ret; @@ -178,8 +170,6 @@ static int ehci_octeon_drv_remove(struct platform_device *pdev)  	usb_remove_hcd(hcd);  	ehci_octeon_stop(); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd);  	return 0; diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 78b01fa475b..a24720beb39 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -104,7 +104,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	struct resource	*res;  	struct usb_hcd	*hcd;  	void __iomem *regs; -	int ret = -ENODEV; +	int ret;  	int irq;  	int i;  	struct omap_hcd	*omap; @@ -144,11 +144,11 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!dev->dma_mask) -		dev->dma_mask = &dev->coherent_dma_mask; -	if (!dev->coherent_dma_mask) -		dev->coherent_dma_mask = DMA_BIT_MASK(32); +	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret; +	ret = -ENODEV;  	hcd = usb_create_hcd(&ehci_omap_hc_driver, dev,  			dev_name(dev));  	if (!hcd) { @@ -215,6 +215,7 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)  		dev_err(dev, "failed to add hcd with err %d\n", ret);  		goto err_pm_runtime;  	} +	device_wakeup_enable(hcd->self.controller);  	/*  	 * Bring PHYs out of reset for non PHY modes. diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index d1dfb9db5b4..22e15cab8ea 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -15,6 +15,7 @@  #include <linux/clk.h>  #include <linux/platform_data/usb-ehci-orion.h>  #include <linux/of.h> +#include <linux/phy/phy.h>  #include <linux/of_device.h>  #include <linux/of_irq.h>  #include <linux/usb.h> @@ -42,6 +43,13 @@  #define DRIVER_DESC "EHCI orion driver" +#define hcd_to_orion_priv(h) ((struct orion_ehci_hcd *)hcd_to_ehci(h)->priv) + +struct orion_ehci_hcd { +	struct clk *clk; +	struct phy *phy; +}; +  static const char hcd_name[] = "ehci-orion";  static struct hc_driver __read_mostly ehci_orion_hc_driver; @@ -137,6 +145,10 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,  	}  } +static const struct ehci_driver_overrides orion_overrides __initconst = { +	.extra_priv_size =	sizeof(struct orion_ehci_hcd), +}; +  static int ehci_orion_drv_probe(struct platform_device *pdev)  {  	struct orion_ehci_data *pd = dev_get_platdata(&pdev->dev); @@ -144,26 +156,23 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)  	struct resource *res;  	struct usb_hcd *hcd;  	struct ehci_hcd *ehci; -	struct clk *clk;  	void __iomem *regs;  	int irq, err;  	enum orion_ehci_phy_ver phy_version; +	struct orion_ehci_hcd *priv;  	if (usb_disabled())  		return -ENODEV;  	pr_debug("Initializing Orion-SoC USB Host Controller\n"); -	if (pdev->dev.of_node) -		irq = irq_of_parse_and_map(pdev->dev.of_node, 0); -	else -		irq = platform_get_irq(pdev, 0); +	irq = platform_get_irq(pdev, 0);  	if (irq <= 0) {  		dev_err(&pdev->dev,  			"Found HC with no IRQ. Check %s setup!\n",  			dev_name(&pdev->dev));  		err = -ENODEV; -		goto err1; +		goto err;  	}  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -172,7 +181,7 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)  			"Found HC with no register addr. Check %s setup!\n",  			dev_name(&pdev->dev));  		err = -ENODEV; -		goto err1; +		goto err;  	}  	/* @@ -180,38 +189,21 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)  	 * set. Since shared usb code relies on it, set it here for  	 * now. Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - -	if (!request_mem_region(res->start, resource_size(res), -				ehci_orion_hc_driver.description)) { -		dev_dbg(&pdev->dev, "controller already in use\n"); -		err = -EBUSY; -		goto err1; -	} - -	regs = ioremap(res->start, resource_size(res)); -	if (regs == NULL) { -		dev_dbg(&pdev->dev, "error mapping memory\n"); -		err = -EFAULT; -		goto err2; -	} +	err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (err) +		goto err; -	/* Not all platforms can gate the clock, so it is not -	   an error if the clock does not exists. */ -	clk = clk_get(&pdev->dev, NULL); -	if (!IS_ERR(clk)) { -		clk_prepare_enable(clk); -		clk_put(clk); +	regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(regs)) { +		err = PTR_ERR(regs); +		goto err;  	}  	hcd = usb_create_hcd(&ehci_orion_hc_driver,  			&pdev->dev, dev_name(&pdev->dev));  	if (!hcd) {  		err = -ENOMEM; -		goto err3; +		goto err;  	}  	hcd->rsrc_start = res->start; @@ -222,6 +214,29 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)  	ehci->caps = hcd->regs + 0x100;  	hcd->has_tt = 1; +	priv = hcd_to_orion_priv(hcd); +	/* +	 * Not all platforms can gate the clock, so it is not an error if +	 * the clock does not exists. +	 */ +	priv->clk = devm_clk_get(&pdev->dev, NULL); +	if (!IS_ERR(priv->clk)) +		clk_prepare_enable(priv->clk); + +	priv->phy = devm_phy_optional_get(&pdev->dev, "usb"); +	if (IS_ERR(priv->phy)) { +		err = PTR_ERR(priv->phy); +		goto err_phy_get; +	} else { +		err = phy_init(priv->phy); +		if (err) +			goto err_phy_init; + +		err = phy_power_on(priv->phy); +		if (err) +			goto err_phy_power_on; +	} +  	/*  	 * (Re-)program MBUS remapping windows if we are asked to.  	 */ @@ -246,26 +261,28 @@ static int ehci_orion_drv_probe(struct platform_device *pdev)  	case EHCI_PHY_DD:  	case EHCI_PHY_KW:  	default: -		printk(KERN_WARNING "Orion ehci -USB phy version isn't supported.\n"); +		dev_warn(&pdev->dev, "USB phy version isn't supported.\n");  	}  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (err) -		goto err4; +		goto err_add_hcd; +	device_wakeup_enable(hcd->self.controller);  	return 0; -err4: +err_add_hcd: +	if (!IS_ERR(priv->phy)) +		phy_power_off(priv->phy); +err_phy_power_on: +	if (!IS_ERR(priv->phy)) +		phy_exit(priv->phy); +err_phy_init: +err_phy_get: +	if (!IS_ERR(priv->clk)) +		clk_disable_unprepare(priv->clk);  	usb_put_hcd(hcd); -err3: -	if (!IS_ERR(clk)) { -		clk_disable_unprepare(clk); -		clk_put(clk); -	} -	iounmap(regs); -err2: -	release_mem_region(res->start, resource_size(res)); -err1: +err:  	dev_err(&pdev->dev, "init %s fail, %d\n",  		dev_name(&pdev->dev), err); @@ -275,18 +292,20 @@ err1:  static int ehci_orion_drv_remove(struct platform_device *pdev)  {  	struct usb_hcd *hcd = platform_get_drvdata(pdev); -	struct clk *clk; +	struct orion_ehci_hcd *priv = hcd_to_orion_priv(hcd);  	usb_remove_hcd(hcd); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -	usb_put_hcd(hcd); -	clk = clk_get(&pdev->dev, NULL); -	if (!IS_ERR(clk)) { -		clk_disable_unprepare(clk); -		clk_put(clk); +	if (!IS_ERR(priv->phy)) { +		phy_power_off(priv->phy); +		phy_exit(priv->phy);  	} + +	if (!IS_ERR(priv->clk)) +		clk_disable_unprepare(priv->clk); + +	usb_put_hcd(hcd); +  	return 0;  } @@ -314,7 +333,7 @@ static int __init ehci_orion_init(void)  	pr_info("%s: " DRIVER_DESC "\n", hcd_name); -	ehci_init_driver(&ehci_orion_hc_driver, NULL); +	ehci_init_driver(&ehci_orion_hc_driver, &orion_overrides);  	return platform_driver_register(&ehci_orion_driver);  }  module_init(ehci_orion_init); diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 6bd299e61f5..3e86bf4371b 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -58,8 +58,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  {  	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);  	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller); -	struct pci_dev		*p_smbus; -	u8			rev;  	u32			temp;  	int			retval; @@ -175,22 +173,12 @@ static int ehci_pci_setup(struct usb_hcd *hcd)  		/* SB600 and old version of SB700 have a bug in EHCI controller,  		 * which causes usb devices lose response in some cases.  		 */ -		if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) { -			p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, -						 PCI_DEVICE_ID_ATI_SBX00_SMBUS, -						 NULL); -			if (!p_smbus) -				break; -			rev = p_smbus->revision; -			if ((pdev->device == 0x4386) || (rev == 0x3a) -			    || (rev == 0x3b)) { -				u8 tmp; -				ehci_info(ehci, "applying AMD SB600/SB700 USB " -					"freeze workaround\n"); -				pci_read_config_byte(pdev, 0x53, &tmp); -				pci_write_config_byte(pdev, 0x53, tmp | (1<<3)); -			} -			pci_dev_put(p_smbus); +		if ((pdev->device == 0x4386 || pdev->device == 0x4396) && +				usb_amd_hang_symptom_quirk()) { +			u8 tmp; +			ehci_info(ehci, "applying AMD SB600/SB700 USB freeze workaround\n"); +			pci_read_config_byte(pdev, 0x53, &tmp); +			pci_write_config_byte(pdev, 0x53, tmp | (1<<3));  		}  		break;  	case PCI_VENDOR_ID_NETMOS: @@ -361,7 +349,7 @@ static struct pci_driver ehci_pci_driver = {  	.remove =	usb_hcd_pci_remove,  	.shutdown = 	usb_hcd_pci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM  	.driver =	{  		.pm =	&usb_hcd_pci_pm_ops  	}, diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index f6b790ca8cf..2f5b9ce3e04 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -3,6 +3,7 @@   *   * Copyright 2007 Steven Brown <sbrown@cortland.com>   * Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> + * Copyright 2014 Hans de Goede <hdegoede@redhat.com>   *   * Derived from the ohci-ssb driver   * Copyright 2007 Michael Buesch <m@bues.ch> @@ -18,6 +19,7 @@   *   * Licensed under the GNU/GPL. See COPYING for details.   */ +#include <linux/clk.h>  #include <linux/dma-mapping.h>  #include <linux/err.h>  #include <linux/kernel.h> @@ -25,7 +27,9 @@  #include <linux/io.h>  #include <linux/module.h>  #include <linux/of.h> +#include <linux/phy/phy.h>  #include <linux/platform_device.h> +#include <linux/reset.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h>  #include <linux/usb/ehci_pdriver.h> @@ -33,6 +37,14 @@  #include "ehci.h"  #define DRIVER_DESC "EHCI generic platform driver" +#define EHCI_MAX_CLKS 3 +#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) + +struct ehci_platform_priv { +	struct clk *clks[EHCI_MAX_CLKS]; +	struct reset_control *rst; +	struct phy *phy; +};  static const char hcd_name[] = "ehci-platform"; @@ -45,8 +57,6 @@ static int ehci_platform_reset(struct usb_hcd *hcd)  	hcd->has_tt = pdata->has_tt;  	ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug; -	ehci->big_endian_desc = pdata->big_endian_desc; -	ehci->big_endian_mmio = pdata->big_endian_mmio;  	if (pdata->pre_setup) {  		retval = pdata->pre_setup(hcd); @@ -64,37 +74,90 @@ static int ehci_platform_reset(struct usb_hcd *hcd)  	return 0;  } +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; + +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) { +		ret = clk_prepare_enable(priv->clks[clk]); +		if (ret) +			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; +	} + +	return 0; + +err_exit_phy: +	phy_exit(priv->phy); +err_disable_clks: +	while (--clk >= 0) +		clk_disable_unprepare(priv->clks[clk]); + +	return ret; +} + +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; + +	if (priv->phy) { +		phy_power_off(priv->phy); +		phy_exit(priv->phy); +	} + +	for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--) +		if (priv->clks[clk]) +			clk_disable_unprepare(priv->clks[clk]); +} +  static struct hc_driver __read_mostly ehci_platform_hc_driver;  static const struct ehci_driver_overrides platform_overrides __initconst = { -	.reset =	ehci_platform_reset, +	.reset =		ehci_platform_reset, +	.extra_priv_size =	sizeof(struct ehci_platform_priv),  }; -static struct usb_ehci_pdata ehci_platform_defaults; +static struct usb_ehci_pdata ehci_platform_defaults = { +	.power_on =		ehci_platform_power_on, +	.power_suspend =	ehci_platform_power_off, +	.power_off =		ehci_platform_power_off, +};  static int ehci_platform_probe(struct platform_device *dev)  {  	struct usb_hcd *hcd;  	struct resource *res_mem; -	struct usb_ehci_pdata *pdata; -	int irq; -	int err = -ENOMEM; +	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); +	struct ehci_platform_priv *priv; +	struct ehci_hcd *ehci; +	int err, irq, clk = 0;  	if (usb_disabled())  		return -ENODEV;  	/* -	 * use reasonable defaults so platforms don't have to provide these. -	 * with DT probing on ARM, none of these are set. +	 * Use reasonable defaults so platforms don't have to provide these +	 * with DT probing on ARM.  	 */ -	if (!dev_get_platdata(&dev->dev)) -		dev->dev.platform_data = &ehci_platform_defaults; -	if (!dev->dev.dma_mask) -		dev->dev.dma_mask = &dev->dev.coherent_dma_mask; -	if (!dev->dev.coherent_dma_mask) -		dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	if (!pdata) +		pdata = &ehci_platform_defaults; -	pdata = dev_get_platdata(&dev->dev); +	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); +	if (err) +		return err;  	irq = platform_get_irq(dev, 0);  	if (irq < 0) { @@ -107,17 +170,84 @@ static int ehci_platform_probe(struct platform_device *dev)  		return -ENXIO;  	} +	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, +			     dev_name(&dev->dev)); +	if (!hcd) +		return -ENOMEM; + +	platform_set_drvdata(dev, hcd); +	dev->dev.platform_data = pdata; +	priv = hcd_to_ehci_priv(hcd); +	ehci = hcd_to_ehci(hcd); + +	if (pdata == &ehci_platform_defaults && dev->dev.of_node) { +		if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) +			ehci->big_endian_mmio = 1; + +		if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) +			ehci->big_endian_desc = 1; + +		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; +		} + +		for (clk = 0; clk < EHCI_MAX_CLKS; clk++) { +			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); +			if (IS_ERR(priv->clks[clk])) { +				err = PTR_ERR(priv->clks[clk]); +				if (err == -EPROBE_DEFER) +					goto err_put_clks; +				priv->clks[clk] = NULL; +				break; +			} +		} +	} + +	priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); +	if (IS_ERR(priv->rst)) { +		err = PTR_ERR(priv->rst); +		if (err == -EPROBE_DEFER) +			goto err_put_clks; +		priv->rst = NULL; +	} else { +		err = reset_control_deassert(priv->rst); +		if (err) +			goto err_put_clks; +	} + +	if (pdata->big_endian_desc) +		ehci->big_endian_desc = 1; +	if (pdata->big_endian_mmio) +		ehci->big_endian_mmio = 1; + +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO +	if (ehci->big_endian_mmio) { +		dev_err(&dev->dev, +			"Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n"); +		err = -EINVAL; +		goto err_reset; +	} +#endif +#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC +	if (ehci->big_endian_desc) { +		dev_err(&dev->dev, +			"Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n"); +		err = -EINVAL; +		goto err_reset; +	} +#endif +  	if (pdata->power_on) {  		err = pdata->power_on(dev);  		if (err < 0) -			return err; -	} - -	hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev, -			     dev_name(&dev->dev)); -	if (!hcd) { -		err = -ENOMEM; -		goto err_power; +			goto err_reset;  	}  	hcd->rsrc_start = res_mem->start; @@ -126,21 +256,31 @@ static int ehci_platform_probe(struct platform_device *dev)  	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);  	if (IS_ERR(hcd->regs)) {  		err = PTR_ERR(hcd->regs); -		goto err_put_hcd; +		goto err_power;  	}  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (err) -		goto err_put_hcd; +		goto err_power; +	device_wakeup_enable(hcd->self.controller);  	platform_set_drvdata(dev, hcd);  	return err; -err_put_hcd: -	usb_put_hcd(hcd);  err_power:  	if (pdata->power_off)  		pdata->power_off(dev); +err_reset: +	if (priv->rst) +		reset_control_assert(priv->rst); +err_put_clks: +	while (--clk >= 0) +		clk_put(priv->clks[clk]); +err_put_hcd: +	if (pdata == &ehci_platform_defaults) +		dev->dev.platform_data = NULL; + +	usb_put_hcd(hcd);  	return err;  } @@ -149,13 +289,22 @@ static int ehci_platform_remove(struct platform_device *dev)  {  	struct usb_hcd *hcd = platform_get_drvdata(dev);  	struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev); +	struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); +	int clk;  	usb_remove_hcd(hcd); -	usb_put_hcd(hcd);  	if (pdata->power_off)  		pdata->power_off(dev); +	if (priv->rst) +		reset_control_assert(priv->rst); + +	for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) +		clk_put(priv->clks[clk]); + +	usb_put_hcd(hcd); +  	if (pdata == &ehci_platform_defaults)  		dev->dev.platform_data = NULL; @@ -174,6 +323,8 @@ static int ehci_platform_suspend(struct device *dev)  	int ret;  	ret = ehci_suspend(hcd, do_wakeup); +	if (ret) +		return ret;  	if (pdata->power_suspend)  		pdata->power_suspend(pdev); @@ -206,8 +357,10 @@ static int ehci_platform_resume(struct device *dev)  static const struct of_device_id vt8500_ehci_ids[] = {  	{ .compatible = "via,vt8500-ehci", },  	{ .compatible = "wm,prizm-ehci", }, +	{ .compatible = "generic-ehci", },  	{}  }; +MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);  static const struct platform_device_id ehci_platform_table[] = {  	{ "ehci-platform", 0 }, diff --git a/drivers/usb/host/ehci-pmcmsp.c b/drivers/usb/host/ehci-pmcmsp.c index 893b707f000..7d75465d97c 100644 --- a/drivers/usb/host/ehci-pmcmsp.c +++ b/drivers/usb/host/ehci-pmcmsp.c @@ -68,9 +68,6 @@ static void usb_hcd_tdi_set_mode(struct ehci_hcd *ehci)  	/* set TWI GPIO USB_HOST_DEV pin high */  	gpio_direction_output(MSP_PIN_USB0_HOST_DEV, 1); -#ifdef CONFIG_MSP_HAS_DUAL_USB -	gpio_direction_output(MSP_PIN_USB1_HOST_DEV, 1); -#endif  }  /* called during probe() after chip reset completes */ @@ -210,8 +207,10 @@ int usb_hcd_msp_probe(const struct hc_driver *driver,  	retval = usb_add_hcd(hcd, res->start, IRQF_SHARED); -	if (retval == 0) +	if (retval == 0) { +		device_wakeup_enable(hcd->self.controller);  		return 0; +	}  	usb_remove_hcd(hcd);  err3: @@ -246,33 +245,6 @@ void usb_hcd_msp_remove(struct usb_hcd *hcd, struct platform_device *dev)  	usb_put_hcd(hcd);  } -#ifdef CONFIG_MSP_HAS_DUAL_USB -/* - * Wrapper around the main ehci_irq.  Since both USB host controllers are - * sharing the same IRQ, need to first determine whether we're the intended - * recipient of this interrupt. - */ -static irqreturn_t ehci_msp_irq(struct usb_hcd *hcd) -{ -	u32 int_src; -	struct device *dev = hcd->self.controller; -	struct platform_device *pdev; -	struct mspusb_device *mdev; -	struct ehci_hcd	*ehci = hcd_to_ehci(hcd); -	/* need to reverse-map a couple of containers to get our device */ -	pdev = to_platform_device(dev); -	mdev = to_mspusb_device(pdev); - -	/* Check to see if this interrupt is for this host controller */ -	int_src = ehci_readl(ehci, &mdev->mab_regs->int_stat); -	if (int_src & (1 << pdev->id)) -		return ehci_irq(hcd); - -	/* Not for this device */ -	return IRQ_NONE; -} -#endif /* DUAL_USB */ -  static const struct hc_driver ehci_msp_hc_driver = {  	.description =		hcd_name,  	.product_desc =		"PMC MSP EHCI", @@ -281,11 +253,7 @@ static const struct hc_driver ehci_msp_hc_driver = {  	/*  	 * generic hardware linkage  	 */ -#ifdef CONFIG_MSP_HAS_DUAL_USB -	.irq =			ehci_msp_irq, -#else  	.irq =			ehci_irq, -#endif  	.flags =		HCD_MEMORY | HCD_USB2 | HCD_BH,  	/* @@ -332,9 +300,6 @@ static int ehci_hcd_msp_drv_probe(struct platform_device *pdev)  		return -ENODEV;  	gpio_request(MSP_PIN_USB0_HOST_DEV, "USB0_HOST_DEV_GPIO"); -#ifdef CONFIG_MSP_HAS_DUAL_USB -	gpio_request(MSP_PIN_USB1_HOST_DEV, "USB1_HOST_DEV_GPIO"); -#endif  	ret = usb_hcd_msp_probe(&ehci_msp_hc_driver, pdev); @@ -349,9 +314,6 @@ static int ehci_hcd_msp_drv_remove(struct platform_device *pdev)  	/* free TWI GPIO USB_HOST_DEV pin */  	gpio_free(MSP_PIN_USB0_HOST_DEV); -#ifdef CONFIG_MSP_HAS_DUAL_USB -	gpio_free(MSP_PIN_USB1_HOST_DEV); -#endif  	return 0;  } diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c index 6cc5567bf9c..547924796d2 100644 --- a/drivers/usb/host/ehci-ppc-of.c +++ b/drivers/usb/host/ehci-ppc-of.c @@ -16,6 +16,8 @@  #include <linux/signal.h>  #include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h> @@ -117,7 +119,8 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op)  	irq = irq_of_parse_and_map(dn, 0);  	if (irq == NO_IRQ) { -		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); +		dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", +			__FILE__);  		rv = -EBUSY;  		goto err_irq;  	} @@ -167,6 +170,7 @@ static int ehci_hcd_ppc_of_probe(struct platform_device *op)  	if (rv)  		goto err_ioremap; +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_ioremap: diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 8188542ba17..7934ff9b35e 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c @@ -189,6 +189,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)  		goto fail_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return result;  fail_add_hcd: diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index e321804c347..54f5332f814 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -105,9 +105,9 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)  		is_out = qh->is_out;  		epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f; -		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) { +		if (unlikely(!usb_gettoggle(qh->ps.udev, epnum, is_out))) {  			hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); -			usb_settoggle (qh->dev, epnum, is_out, 1); +			usb_settoggle(qh->ps.udev, epnum, is_out, 1);  		}  	} @@ -168,13 +168,13 @@ static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,  	 * Note: this routine is never called for Isochronous transfers.  	 */  	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  		struct usb_device *tt = urb->dev->tt->hub;  		dev_dbg(&tt->dev,  			"clear tt buffer port %d, a%d ep%d t%08x\n",  			urb->dev->ttport, urb->dev->devnum,  			usb_pipeendpoint(urb->pipe), token); -#endif /* DEBUG || CONFIG_DYNAMIC_DEBUG */ +#endif /* CONFIG_DYNAMIC_DEBUG */  		if (!ehci_is_TDI(ehci)  				|| urb->dev->tt->hub !=  				   ehci_to_hcd(ehci)->self.root_hub) { @@ -797,26 +797,35 @@ qh_make (  	 * For control/bulk requests, the HC or TT handles these.  	 */  	if (type == PIPE_INTERRUPT) { -		qh->usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH, +		unsigned	tmp; + +		qh->ps.usecs = NS_TO_US(usb_calc_bus_time(USB_SPEED_HIGH,  				is_input, 0,  				hb_mult(maxp) * max_packet(maxp))); -		qh->start = NO_FRAME; +		qh->ps.phase = NO_FRAME;  		if (urb->dev->speed == USB_SPEED_HIGH) { -			qh->c_usecs = 0; +			qh->ps.c_usecs = 0;  			qh->gap_uf = 0; -			qh->period = urb->interval >> 3; -			if (qh->period == 0 && urb->interval != 1) { +			if (urb->interval > 1 && urb->interval < 8) {  				/* NOTE interval 2 or 4 uframes could work.  				 * But interval 1 scheduling is simpler, and  				 * includes high bandwidth.  				 */  				urb->interval = 1; -			} else if (qh->period > ehci->periodic_size) { -				qh->period = ehci->periodic_size; -				urb->interval = qh->period << 3; +			} else if (urb->interval > ehci->periodic_size << 3) { +				urb->interval = ehci->periodic_size << 3;  			} +			qh->ps.period = urb->interval >> 3; + +			/* period for bandwidth allocation */ +			tmp = min_t(unsigned, EHCI_BANDWIDTH_SIZE, +					1 << (urb->ep->desc.bInterval - 1)); + +			/* Allow urb->interval to override */ +			qh->ps.bw_uperiod = min_t(unsigned, tmp, urb->interval); +			qh->ps.bw_period = qh->ps.bw_uperiod >> 3;  		} else {  			int		think_time; @@ -826,27 +835,35 @@ qh_make (  			/* FIXME this just approximates SPLIT/CSPLIT times */  			if (is_input) {		// SPLIT, gap, CSPLIT+DATA -				qh->c_usecs = qh->usecs + HS_USECS (0); -				qh->usecs = HS_USECS (1); +				qh->ps.c_usecs = qh->ps.usecs + HS_USECS(0); +				qh->ps.usecs = HS_USECS(1);  			} else {		// SPLIT+DATA, gap, CSPLIT -				qh->usecs += HS_USECS (1); -				qh->c_usecs = HS_USECS (0); +				qh->ps.usecs += HS_USECS(1); +				qh->ps.c_usecs = HS_USECS(0);  			}  			think_time = tt ? tt->think_time : 0; -			qh->tt_usecs = NS_TO_US (think_time + +			qh->ps.tt_usecs = NS_TO_US(think_time +  					usb_calc_bus_time (urb->dev->speed,  					is_input, 0, max_packet (maxp))); -			qh->period = urb->interval; -			if (qh->period > ehci->periodic_size) { -				qh->period = ehci->periodic_size; -				urb->interval = qh->period; -			} +			if (urb->interval > ehci->periodic_size) +				urb->interval = ehci->periodic_size; +			qh->ps.period = urb->interval; + +			/* period for bandwidth allocation */ +			tmp = min_t(unsigned, EHCI_BANDWIDTH_FRAMES, +					urb->ep->desc.bInterval); +			tmp = rounddown_pow_of_two(tmp); + +			/* Allow urb->interval to override */ +			qh->ps.bw_period = min_t(unsigned, tmp, urb->interval); +			qh->ps.bw_uperiod = qh->ps.bw_period << 3;  		}  	}  	/* support for tt scheduling, and access to toggles */ -	qh->dev = urb->dev; +	qh->ps.udev = urb->dev; +	qh->ps.ep = urb->ep;  	/* using TT? */  	switch (urb->dev->speed) { diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c deleted file mode 100644 index 7c3de95c705..00000000000 --- a/drivers/usb/host/ehci-s5p.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * SAMSUNG S5P USB HOST EHCI Controller - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * Author: Jingoo Han <jg1.han@samsung.com> - * Author: Joonyoung Shim <jy0922.shim@samsung.com> - * - * This program is free software; you can redistribute  it and/or modify it - * under  the terms of  the GNU General  Public License as published by the - * Free Software Foundation;  either version 2 of the  License, or (at your - * option) any later version. - * - */ - -#include <linux/clk.h> -#include <linux/dma-mapping.h> -#include <linux/io.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/of_gpio.h> -#include <linux/platform_device.h> -#include <linux/platform_data/usb-ehci-s5p.h> -#include <linux/usb/phy.h> -#include <linux/usb/samsung_usb_phy.h> -#include <linux/usb.h> -#include <linux/usb/hcd.h> -#include <linux/usb/otg.h> - -#include "ehci.h" - -#define DRIVER_DESC "EHCI s5p driver" - -#define EHCI_INSNREG00(base)			(base + 0x90) -#define EHCI_INSNREG00_ENA_INCR16		(0x1 << 25) -#define EHCI_INSNREG00_ENA_INCR8		(0x1 << 24) -#define EHCI_INSNREG00_ENA_INCR4		(0x1 << 23) -#define EHCI_INSNREG00_ENA_INCRX_ALIGN		(0x1 << 22) -#define EHCI_INSNREG00_ENABLE_DMA_BURST	\ -	(EHCI_INSNREG00_ENA_INCR16 | EHCI_INSNREG00_ENA_INCR8 |	\ -	 EHCI_INSNREG00_ENA_INCR4 | EHCI_INSNREG00_ENA_INCRX_ALIGN) - -static const char hcd_name[] = "ehci-s5p"; -static struct hc_driver __read_mostly s5p_ehci_hc_driver; - -struct s5p_ehci_hcd { -	struct clk *clk; -	struct usb_phy *phy; -	struct usb_otg *otg; -	struct s5p_ehci_platdata *pdata; -}; - -static struct s5p_ehci_platdata empty_platdata; - -#define to_s5p_ehci(hcd)      (struct s5p_ehci_hcd *)(hcd_to_ehci(hcd)->priv) - -static void s5p_setup_vbus_gpio(struct platform_device *pdev) -{ -	struct device *dev = &pdev->dev; -	int err; -	int gpio; - -	if (!dev->of_node) -		return; - -	gpio = of_get_named_gpio(dev->of_node, "samsung,vbus-gpio", 0); -	if (!gpio_is_valid(gpio)) -		return; - -	err = devm_gpio_request_one(dev, gpio, GPIOF_OUT_INIT_HIGH, -				    "ehci_vbus_gpio"); -	if (err) -		dev_err(dev, "can't request ehci vbus gpio %d", gpio); -} - -static int s5p_ehci_probe(struct platform_device *pdev) -{ -	struct s5p_ehci_platdata *pdata = dev_get_platdata(&pdev->dev); -	struct s5p_ehci_hcd *s5p_ehci; -	struct usb_hcd *hcd; -	struct ehci_hcd *ehci; -	struct resource *res; -	struct usb_phy *phy; -	int irq; -	int err; - -	/* -	 * Right now device-tree probed devices don't get dma_mask set. -	 * Since shared usb code relies on it, set it here for now. -	 * Once we move to full device tree support this will vanish off. -	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - -	s5p_setup_vbus_gpio(pdev); - -	hcd = usb_create_hcd(&s5p_ehci_hc_driver, -			     &pdev->dev, dev_name(&pdev->dev)); -	if (!hcd) { -		dev_err(&pdev->dev, "Unable to create HCD\n"); -		return -ENOMEM; -	} -	s5p_ehci = to_s5p_ehci(hcd); - -	if (of_device_is_compatible(pdev->dev.of_node, -					"samsung,exynos5440-ehci")) { -		s5p_ehci->pdata = &empty_platdata; -		goto skip_phy; -	} - -	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); -	if (IS_ERR(phy)) { -		/* Fallback to pdata */ -		if (!pdata) { -			usb_put_hcd(hcd); -			dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); -			return -EPROBE_DEFER; -		} else { -			s5p_ehci->pdata = pdata; -		} -	} else { -		s5p_ehci->phy = phy; -		s5p_ehci->otg = phy->otg; -	} - -skip_phy: - -	s5p_ehci->clk = devm_clk_get(&pdev->dev, "usbhost"); - -	if (IS_ERR(s5p_ehci->clk)) { -		dev_err(&pdev->dev, "Failed to get usbhost clock\n"); -		err = PTR_ERR(s5p_ehci->clk); -		goto fail_clk; -	} - -	err = clk_prepare_enable(s5p_ehci->clk); -	if (err) -		goto fail_clk; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) { -		dev_err(&pdev->dev, "Failed to get I/O memory\n"); -		err = -ENXIO; -		goto fail_io; -	} - -	hcd->rsrc_start = res->start; -	hcd->rsrc_len = resource_size(res); -	hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "Failed to remap I/O memory\n"); -		err = -ENOMEM; -		goto fail_io; -	} - -	irq = platform_get_irq(pdev, 0); -	if (!irq) { -		dev_err(&pdev->dev, "Failed to get IRQ\n"); -		err = -ENODEV; -		goto fail_io; -	} - -	if (s5p_ehci->otg) -		s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self); - -	if (s5p_ehci->phy) -		usb_phy_init(s5p_ehci->phy); -	else if (s5p_ehci->pdata->phy_init) -		s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); - -	ehci = hcd_to_ehci(hcd); -	ehci->caps = hcd->regs; - -	/* DMA burst Enable */ -	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); - -	err = usb_add_hcd(hcd, irq, IRQF_SHARED); -	if (err) { -		dev_err(&pdev->dev, "Failed to add USB HCD\n"); -		goto fail_add_hcd; -	} - -	platform_set_drvdata(pdev, hcd); - -	return 0; - -fail_add_hcd: -	if (s5p_ehci->phy) -		usb_phy_shutdown(s5p_ehci->phy); -	else if (s5p_ehci->pdata->phy_exit) -		s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); -fail_io: -	clk_disable_unprepare(s5p_ehci->clk); -fail_clk: -	usb_put_hcd(hcd); -	return err; -} - -static int s5p_ehci_remove(struct platform_device *pdev) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); -	struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd); - -	usb_remove_hcd(hcd); - -	if (s5p_ehci->otg) -		s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self); - -	if (s5p_ehci->phy) -		usb_phy_shutdown(s5p_ehci->phy); -	else if (s5p_ehci->pdata->phy_exit) -		s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); - -	clk_disable_unprepare(s5p_ehci->clk); - -	usb_put_hcd(hcd); - -	return 0; -} - -#ifdef CONFIG_PM -static int s5p_ehci_suspend(struct device *dev) -{ -	struct usb_hcd *hcd = dev_get_drvdata(dev); -	struct s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd); -	struct platform_device *pdev = to_platform_device(dev); - -	bool do_wakeup = device_may_wakeup(dev); -	int rc; - -	rc = ehci_suspend(hcd, do_wakeup); - -	if (s5p_ehci->otg) -		s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self); - -	if (s5p_ehci->phy) -		usb_phy_shutdown(s5p_ehci->phy); -	else if (s5p_ehci->pdata->phy_exit) -		s5p_ehci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); - -	clk_disable_unprepare(s5p_ehci->clk); - -	return rc; -} - -static int s5p_ehci_resume(struct device *dev) -{ -	struct usb_hcd *hcd = dev_get_drvdata(dev); -	struct  s5p_ehci_hcd *s5p_ehci = to_s5p_ehci(hcd); -	struct platform_device *pdev = to_platform_device(dev); - -	clk_prepare_enable(s5p_ehci->clk); - -	if (s5p_ehci->otg) -		s5p_ehci->otg->set_host(s5p_ehci->otg, &hcd->self); - -	if (s5p_ehci->phy) -		usb_phy_init(s5p_ehci->phy); -	else if (s5p_ehci->pdata->phy_init) -		s5p_ehci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); - -	/* DMA burst Enable */ -	writel(EHCI_INSNREG00_ENABLE_DMA_BURST, EHCI_INSNREG00(hcd->regs)); - -	ehci_resume(hcd, false); -	return 0; -} -#else -#define s5p_ehci_suspend	NULL -#define s5p_ehci_resume		NULL -#endif - -static const struct dev_pm_ops s5p_ehci_pm_ops = { -	.suspend	= s5p_ehci_suspend, -	.resume		= s5p_ehci_resume, -}; - -#ifdef CONFIG_OF -static const struct of_device_id exynos_ehci_match[] = { -	{ .compatible = "samsung,exynos4210-ehci" }, -	{ .compatible = "samsung,exynos5440-ehci" }, -	{}, -}; -MODULE_DEVICE_TABLE(of, exynos_ehci_match); -#endif - -static struct platform_driver s5p_ehci_driver = { -	.probe		= s5p_ehci_probe, -	.remove		= s5p_ehci_remove, -	.shutdown	= usb_hcd_platform_shutdown, -	.driver = { -		.name	= "s5p-ehci", -		.owner	= THIS_MODULE, -		.pm	= &s5p_ehci_pm_ops, -		.of_match_table = of_match_ptr(exynos_ehci_match), -	} -}; -static const struct ehci_driver_overrides s5p_overrides __initdata = { -	.extra_priv_size = sizeof(struct s5p_ehci_hcd), -}; - -static int __init ehci_s5p_init(void) -{ -	if (usb_disabled()) -		return -ENODEV; - -	pr_info("%s: " DRIVER_DESC "\n", hcd_name); -	ehci_init_driver(&s5p_ehci_hc_driver, &s5p_overrides); -	return platform_driver_register(&s5p_ehci_driver); -} -module_init(ehci_s5p_init); - -static void __exit ehci_s5p_cleanup(void) -{ -	platform_driver_unregister(&s5p_ehci_driver); -} -module_exit(ehci_s5p_cleanup); - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_ALIAS("platform:s5p-ehci"); -MODULE_AUTHOR("Jingoo Han"); -MODULE_AUTHOR("Joonyoung Shim"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 85dd24ed97a..e113fd73aea 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -103,83 +103,210 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)  		*hw_p = *shadow_next_periodic(ehci, &here,  				Q_NEXT_TYPE(ehci, *hw_p));  	else -		*hw_p = ehci->dummy->qh_dma; +		*hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma);  } -/* how many of the uframe's 125 usecs are allocated? */ -static unsigned short -periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe) +/*-------------------------------------------------------------------------*/ + +/* Bandwidth and TT management */ + +/* Find the TT data structure for this device; create it if necessary */ +static struct ehci_tt *find_tt(struct usb_device *udev)  { -	__hc32			*hw_p = &ehci->periodic [frame]; -	union ehci_shadow	*q = &ehci->pshadow [frame]; -	unsigned		usecs = 0; -	struct ehci_qh_hw	*hw; - -	while (q->ptr) { -		switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { -		case Q_TYPE_QH: -			hw = q->qh->hw; -			/* is it in the S-mask? */ -			if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe)) -				usecs += q->qh->usecs; -			/* ... or C-mask? */ -			if (hw->hw_info2 & cpu_to_hc32(ehci, -					1 << (8 + uframe))) -				usecs += q->qh->c_usecs; -			hw_p = &hw->hw_next; -			q = &q->qh->qh_next; -			break; -		// case Q_TYPE_FSTN: -		default: -			/* for "save place" FSTNs, count the relevant INTR -			 * bandwidth from the previous frame -			 */ -			if (q->fstn->hw_prev != EHCI_LIST_END(ehci)) { -				ehci_dbg (ehci, "ignoring FSTN cost ...\n"); -			} -			hw_p = &q->fstn->hw_next; -			q = &q->fstn->fstn_next; -			break; -		case Q_TYPE_ITD: -			if (q->itd->hw_transaction[uframe]) -				usecs += q->itd->stream->usecs; -			hw_p = &q->itd->hw_next; -			q = &q->itd->itd_next; -			break; -		case Q_TYPE_SITD: -			/* is it in the S-mask?  (count SPLIT, DATA) */ -			if (q->sitd->hw_uframe & cpu_to_hc32(ehci, -					1 << uframe)) { -				if (q->sitd->hw_fullspeed_ep & -						cpu_to_hc32(ehci, 1<<31)) -					usecs += q->sitd->stream->usecs; -				else	/* worst case for OUT start-split */ -					usecs += HS_USECS_ISO (188); -			} +	struct usb_tt		*utt = udev->tt; +	struct ehci_tt		*tt, **tt_index, **ptt; +	unsigned		port; +	bool			allocated_index = false; + +	if (!utt) +		return NULL;		/* Not below a TT */ + +	/* +	 * Find/create our data structure. +	 * For hubs with a single TT, we get it directly. +	 * For hubs with multiple TTs, there's an extra level of pointers. +	 */ +	tt_index = NULL; +	if (utt->multi) { +		tt_index = utt->hcpriv; +		if (!tt_index) {		/* Create the index array */ +			tt_index = kzalloc(utt->hub->maxchild * +					sizeof(*tt_index), GFP_ATOMIC); +			if (!tt_index) +				return ERR_PTR(-ENOMEM); +			utt->hcpriv = tt_index; +			allocated_index = true; +		} +		port = udev->ttport - 1; +		ptt = &tt_index[port]; +	} else { +		port = 0; +		ptt = (struct ehci_tt **) &utt->hcpriv; +	} + +	tt = *ptt; +	if (!tt) {				/* Create the ehci_tt */ +		struct ehci_hcd		*ehci = +				hcd_to_ehci(bus_to_hcd(udev->bus)); -			/* ... C-mask?  (count CSPLIT, DATA) */ -			if (q->sitd->hw_uframe & -					cpu_to_hc32(ehci, 1 << (8 + uframe))) { -				/* worst case for IN complete-split */ -				usecs += q->sitd->stream->c_usecs; +		tt = kzalloc(sizeof(*tt), GFP_ATOMIC); +		if (!tt) { +			if (allocated_index) { +				utt->hcpriv = NULL; +				kfree(tt_index);  			} +			return ERR_PTR(-ENOMEM); +		} +		list_add_tail(&tt->tt_list, &ehci->tt_list); +		INIT_LIST_HEAD(&tt->ps_list); +		tt->usb_tt = utt; +		tt->tt_port = port; +		*ptt = tt; +	} -			hw_p = &q->sitd->hw_next; -			q = &q->sitd->sitd_next; -			break; +	return tt; +} + +/* Release the TT above udev, if it's not in use */ +static void drop_tt(struct usb_device *udev) +{ +	struct usb_tt		*utt = udev->tt; +	struct ehci_tt		*tt, **tt_index, **ptt; +	int			cnt, i; + +	if (!utt || !utt->hcpriv) +		return;		/* Not below a TT, or never allocated */ + +	cnt = 0; +	if (utt->multi) { +		tt_index = utt->hcpriv; +		ptt = &tt_index[udev->ttport - 1]; + +		/* How many entries are left in tt_index? */ +		for (i = 0; i < utt->hub->maxchild; ++i) +			cnt += !!tt_index[i]; +	} else { +		tt_index = NULL; +		ptt = (struct ehci_tt **) &utt->hcpriv; +	} + +	tt = *ptt; +	if (!tt || !list_empty(&tt->ps_list)) +		return;		/* never allocated, or still in use */ + +	list_del(&tt->tt_list); +	*ptt = NULL; +	kfree(tt); +	if (cnt == 1) { +		utt->hcpriv = NULL; +		kfree(tt_index); +	} +} + +static void bandwidth_dbg(struct ehci_hcd *ehci, int sign, char *type, +		struct ehci_per_sched *ps) +{ +	dev_dbg(&ps->udev->dev, +			"ep %02x: %s %s @ %u+%u (%u.%u+%u) [%u/%u us] mask %04x\n", +			ps->ep->desc.bEndpointAddress, +			(sign >= 0 ? "reserve" : "release"), type, +			(ps->bw_phase << 3) + ps->phase_uf, ps->bw_uperiod, +			ps->phase, ps->phase_uf, ps->period, +			ps->usecs, ps->c_usecs, ps->cs_mask); +} + +static void reserve_release_intr_bandwidth(struct ehci_hcd *ehci, +		struct ehci_qh *qh, int sign) +{ +	unsigned		start_uf; +	unsigned		i, j, m; +	int			usecs = qh->ps.usecs; +	int			c_usecs = qh->ps.c_usecs; +	int			tt_usecs = qh->ps.tt_usecs; +	struct ehci_tt		*tt; + +	if (qh->ps.phase == NO_FRAME)	/* Bandwidth wasn't reserved */ +		return; +	start_uf = qh->ps.bw_phase << 3; + +	bandwidth_dbg(ehci, sign, "intr", &qh->ps); + +	if (sign < 0) {		/* Release bandwidth */ +		usecs = -usecs; +		c_usecs = -c_usecs; +		tt_usecs = -tt_usecs; +	} + +	/* Entire transaction (high speed) or start-split (full/low speed) */ +	for (i = start_uf + qh->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE; +			i += qh->ps.bw_uperiod) +		ehci->bandwidth[i] += usecs; + +	/* Complete-split (full/low speed) */ +	if (qh->ps.c_usecs) { +		/* NOTE: adjustments needed for FSTN */ +		for (i = start_uf; i < EHCI_BANDWIDTH_SIZE; +				i += qh->ps.bw_uperiod) { +			for ((j = 2, m = 1 << (j+8)); j < 8; (++j, m <<= 1)) { +				if (qh->ps.cs_mask & m) +					ehci->bandwidth[i+j] += c_usecs; +			}  		}  	} -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) -	if (usecs > ehci->uframe_periodic_max) -		ehci_err (ehci, "uframe %d sched overrun: %d usecs\n", -			frame * 8 + uframe, usecs); -#endif -	return usecs; + +	/* FS/LS bus bandwidth */ +	if (tt_usecs) { +		tt = find_tt(qh->ps.udev); +		if (sign > 0) +			list_add_tail(&qh->ps.ps_list, &tt->ps_list); +		else +			list_del(&qh->ps.ps_list); + +		for (i = start_uf >> 3; i < EHCI_BANDWIDTH_FRAMES; +				i += qh->ps.bw_period) +			tt->bandwidth[i] += tt_usecs; +	}  }  /*-------------------------------------------------------------------------*/ -static int same_tt (struct usb_device *dev1, struct usb_device *dev2) +static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE], +		struct ehci_tt *tt) +{ +	struct ehci_per_sched	*ps; +	unsigned		uframe, uf, x; +	u8			*budget_line; + +	if (!tt) +		return; +	memset(budget_table, 0, EHCI_BANDWIDTH_SIZE); + +	/* Add up the contributions from all the endpoints using this TT */ +	list_for_each_entry(ps, &tt->ps_list, ps_list) { +		for (uframe = ps->bw_phase << 3; uframe < EHCI_BANDWIDTH_SIZE; +				uframe += ps->bw_uperiod) { +			budget_line = &budget_table[uframe]; +			x = ps->tt_usecs; + +			/* propagate the time forward */ +			for (uf = ps->phase_uf; uf < 8; ++uf) { +				x += budget_line[uf]; + +				/* Each microframe lasts 125 us */ +				if (x <= 125) { +					budget_line[uf] = x; +					break; +				} else { +					budget_line[uf] = 125; +					x -= 125; +				} +			} +		} +	} +} + +static int __maybe_unused same_tt(struct usb_device *dev1, +		struct usb_device *dev2)  {  	if (!dev1->tt || !dev2->tt)  		return 0; @@ -227,68 +354,6 @@ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])  	}  } -/* How many of the tt's periodic downstream 1000 usecs are allocated? - * - * While this measures the bandwidth in terms of usecs/uframe, - * the low/fullspeed bus has no notion of uframes, so any particular - * low/fullspeed transfer can "carry over" from one uframe to the next, - * since the TT just performs downstream transfers in sequence. - * - * For example two separate 100 usec transfers can start in the same uframe, - * and the second one would "carry over" 75 usecs into the next uframe. - */ -static void -periodic_tt_usecs ( -	struct ehci_hcd *ehci, -	struct usb_device *dev, -	unsigned frame, -	unsigned short tt_usecs[8] -) -{ -	__hc32			*hw_p = &ehci->periodic [frame]; -	union ehci_shadow	*q = &ehci->pshadow [frame]; -	unsigned char		uf; - -	memset(tt_usecs, 0, 16); - -	while (q->ptr) { -		switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { -		case Q_TYPE_ITD: -			hw_p = &q->itd->hw_next; -			q = &q->itd->itd_next; -			continue; -		case Q_TYPE_QH: -			if (same_tt(dev, q->qh->dev)) { -				uf = tt_start_uframe(ehci, q->qh->hw->hw_info2); -				tt_usecs[uf] += q->qh->tt_usecs; -			} -			hw_p = &q->qh->hw->hw_next; -			q = &q->qh->qh_next; -			continue; -		case Q_TYPE_SITD: -			if (same_tt(dev, q->sitd->urb->dev)) { -				uf = tt_start_uframe(ehci, q->sitd->hw_uframe); -				tt_usecs[uf] += q->sitd->stream->tt_usecs; -			} -			hw_p = &q->sitd->hw_next; -			q = &q->sitd->sitd_next; -			continue; -		// case Q_TYPE_FSTN: -		default: -			ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n", -					frame); -			hw_p = &q->fstn->hw_next; -			q = &q->fstn->fstn_next; -		} -	} - -	carryover_tt_bandwidth(tt_usecs); - -	if (max_tt_usecs[7] < tt_usecs[7]) -		ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n", -			frame, tt_usecs[7] - max_tt_usecs[7]); -} -  /*   * Return true if the device's tt's downstream bus is available for a   * periodic transfer of the specified length (usecs), starting at the @@ -312,20 +377,29 @@ periodic_tt_usecs (   */  static int tt_available (  	struct ehci_hcd		*ehci, -	unsigned		period, -	struct usb_device	*dev, +	struct ehci_per_sched	*ps, +	struct ehci_tt		*tt,  	unsigned		frame, -	unsigned		uframe, -	u16			usecs +	unsigned		uframe  )  { +	unsigned		period = ps->bw_period; +	unsigned		usecs = ps->tt_usecs; +  	if ((period == 0) || (uframe >= 7))	/* error */  		return 0; -	for (; frame < ehci->periodic_size; frame += period) { -		unsigned short tt_usecs[8]; +	for (frame &= period - 1; frame < EHCI_BANDWIDTH_FRAMES; +			frame += period) { +		unsigned	i, uf; +		unsigned short	tt_usecs[8]; -		periodic_tt_usecs (ehci, dev, frame, tt_usecs); +		if (tt->bandwidth[frame] + usecs > 900) +			return 0; + +		uf = frame << 3; +		for (i = 0; i < 8; (++i, ++uf)) +			tt_usecs[i] = ehci->tt_budget[uf];  		if (max_tt_usecs[uframe] <= tt_usecs[uframe])  			return 0; @@ -337,7 +411,7 @@ static int tt_available (  		 */  		if (125 < usecs) {  			int ufs = (usecs / 125); -			int i; +  			for (i = uframe; i < (uframe + ufs) && i < 8; i++)  				if (0 < tt_usecs[i])  					return 0; @@ -391,7 +465,7 @@ static int tt_no_collision (  				continue;  			case Q_TYPE_QH:  				hw = here.qh->hw; -				if (same_tt (dev, here.qh->dev)) { +				if (same_tt(dev, here.qh->ps.udev)) {  					u32		mask;  					mask = hc32_to_cpu(ehci, @@ -471,19 +545,19 @@ static void disable_periodic(struct ehci_hcd *ehci)  static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)  {  	unsigned	i; -	unsigned	period = qh->period; +	unsigned	period = qh->ps.period; -	dev_dbg (&qh->dev->dev, +	dev_dbg(&qh->ps.udev->dev,  		"link qh%d-%04x/%p start %d [%d/%d us]\n",  		period, hc32_to_cpup(ehci, &qh->hw->hw_info2)  			& (QH_CMASK | QH_SMASK), -		qh, qh->start, qh->usecs, qh->c_usecs); +		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);  	/* high bandwidth, or otherwise every microframe */  	if (period == 0)  		period = 1; -	for (i = qh->start; i < ehci->periodic_size; i += period) { +	for (i = qh->ps.phase; i < ehci->periodic_size; i += period) {  		union ehci_shadow	*prev = &ehci->pshadow[i];  		__hc32			*hw_p = &ehci->periodic[i];  		union ehci_shadow	here = *prev; @@ -503,7 +577,7 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)  		 * enables sharing interior tree nodes  		 */  		while (here.ptr && qh != here.qh) { -			if (qh->period > here.qh->period) +			if (qh->ps.period > here.qh->ps.period)  				break;  			prev = &here.qh->qh_next;  			hw_p = &here.qh->hw->hw_next; @@ -523,10 +597,10 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)  	qh->xacterrs = 0;  	qh->exception = 0; -	/* update per-qh bandwidth for usbfs */ -	ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->period -		? ((qh->usecs + qh->c_usecs) / qh->period) -		: (qh->usecs * 8); +	/* update per-qh bandwidth for debugfs */ +	ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->ps.bw_period +		? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period) +		: (qh->ps.usecs * 8);  	list_add(&qh->intr_node, &ehci->intr_qh_list); @@ -556,22 +630,21 @@ static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)  	 */  	/* high bandwidth, or otherwise part of every microframe */ -	if ((period = qh->period) == 0) -		period = 1; +	period = qh->ps.period ? : 1; -	for (i = qh->start; i < ehci->periodic_size; i += period) +	for (i = qh->ps.phase; i < ehci->periodic_size; i += period)  		periodic_unlink (ehci, i, qh); -	/* update per-qh bandwidth for usbfs */ -	ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->period -		? ((qh->usecs + qh->c_usecs) / qh->period) -		: (qh->usecs * 8); +	/* update per-qh bandwidth for debugfs */ +	ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->ps.bw_period +		? ((qh->ps.usecs + qh->ps.c_usecs) / qh->ps.bw_period) +		: (qh->ps.usecs * 8); -	dev_dbg (&qh->dev->dev, +	dev_dbg(&qh->ps.udev->dev,  		"unlink qh%d-%04x/%p start %d [%d/%d us]\n", -		qh->period, +		qh->ps.period,  		hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK), -		qh, qh->start, qh->usecs, qh->c_usecs); +		qh, qh->ps.phase, qh->ps.usecs, qh->ps.c_usecs);  	/* qh->qh_next still "live" to HC */  	qh->qh_state = QH_STATE_UNLINK; @@ -694,11 +767,9 @@ static int check_period (  	struct ehci_hcd *ehci,  	unsigned	frame,  	unsigned	uframe, -	unsigned	period, +	unsigned	uperiod,  	unsigned	usecs  ) { -	int		claimed; -  	/* complete split running into next frame?  	 * given FSTN support, we could sometimes check...  	 */ @@ -708,25 +779,10 @@ static int check_period (  	/* convert "usecs we need" to "max already claimed" */  	usecs = ehci->uframe_periodic_max - usecs; -	/* we "know" 2 and 4 uframe intervals were rejected; so -	 * for period 0, check _every_ microframe in the schedule. -	 */ -	if (unlikely (period == 0)) { -		do { -			for (uframe = 0; uframe < 7; uframe++) { -				claimed = periodic_usecs (ehci, frame, uframe); -				if (claimed > usecs) -					return 0; -			} -		} while ((frame += 1) < ehci->periodic_size); - -	/* just check the specified uframe, at that period */ -	} else { -		do { -			claimed = periodic_usecs (ehci, frame, uframe); -			if (claimed > usecs) -				return 0; -		} while ((frame += period) < ehci->periodic_size); +	for (uframe += frame << 3; uframe < EHCI_BANDWIDTH_SIZE; +			uframe += uperiod) { +		if (ehci->bandwidth[uframe] > usecs) +			return 0;  	}  	// success! @@ -737,40 +793,40 @@ static int check_intr_schedule (  	struct ehci_hcd		*ehci,  	unsigned		frame,  	unsigned		uframe, -	const struct ehci_qh	*qh, -	__hc32			*c_maskp +	struct ehci_qh		*qh, +	unsigned		*c_maskp, +	struct ehci_tt		*tt  )  {  	int		retval = -ENOSPC;  	u8		mask = 0; -	if (qh->c_usecs && uframe >= 6)		/* FSTN territory? */ +	if (qh->ps.c_usecs && uframe >= 6)	/* FSTN territory? */  		goto done; -	if (!check_period (ehci, frame, uframe, qh->period, qh->usecs)) +	if (!check_period(ehci, frame, uframe, qh->ps.bw_uperiod, qh->ps.usecs))  		goto done; -	if (!qh->c_usecs) { +	if (!qh->ps.c_usecs) {  		retval = 0;  		*c_maskp = 0;  		goto done;  	}  #ifdef CONFIG_USB_EHCI_TT_NEWSCHED -	if (tt_available (ehci, qh->period, qh->dev, frame, uframe, -				qh->tt_usecs)) { +	if (tt_available(ehci, &qh->ps, tt, frame, uframe)) {  		unsigned i;  		/* TODO : this may need FSTN for SSPLIT in uframe 5. */ -		for (i=uframe+1; i<8 && i<uframe+4; i++) -			if (!check_period (ehci, frame, i, -						qh->period, qh->c_usecs)) +		for (i = uframe+2; i < 8 && i <= uframe+4; i++) +			if (!check_period(ehci, frame, i, +					qh->ps.bw_uperiod, qh->ps.c_usecs))  				goto done;  			else  				mask |= 1 << i;  		retval = 0; -		*c_maskp = cpu_to_hc32(ehci, mask << 8); +		*c_maskp = mask;  	}  #else  	/* Make sure this tt's buffer is also available for CSPLITs. @@ -781,15 +837,15 @@ static int check_intr_schedule (  	 * one smart pass...  	 */  	mask = 0x03 << (uframe + qh->gap_uf); -	*c_maskp = cpu_to_hc32(ehci, mask << 8); +	*c_maskp = mask;  	mask |= 1 << uframe; -	if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) { -		if (!check_period (ehci, frame, uframe + qh->gap_uf + 1, -					qh->period, qh->c_usecs)) +	if (tt_no_collision(ehci, qh->ps.bw_period, qh->ps.udev, frame, mask)) { +		if (!check_period(ehci, frame, uframe + qh->gap_uf + 1, +				qh->ps.bw_uperiod, qh->ps.c_usecs))  			goto done; -		if (!check_period (ehci, frame, uframe + qh->gap_uf, -					qh->period, qh->c_usecs)) +		if (!check_period(ehci, frame, uframe + qh->gap_uf, +				qh->ps.bw_uperiod, qh->ps.c_usecs))  			goto done;  		retval = 0;  	} @@ -803,62 +859,67 @@ done:   */  static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)  { -	int		status; +	int		status = 0;  	unsigned	uframe; -	__hc32		c_mask; -	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */ +	unsigned	c_mask;  	struct ehci_qh_hw	*hw = qh->hw; +	struct ehci_tt		*tt;  	hw->hw_next = EHCI_LIST_END(ehci); -	frame = qh->start;  	/* reuse the previous schedule slots, if we can */ -	if (frame < qh->period) { -		uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK); -		status = check_intr_schedule (ehci, frame, --uframe, -				qh, &c_mask); -	} else { -		uframe = 0; -		c_mask = 0; -		status = -ENOSPC; +	if (qh->ps.phase != NO_FRAME) { +		ehci_dbg(ehci, "reused qh %p schedule\n", qh); +		return 0; +	} + +	uframe = 0; +	c_mask = 0; +	tt = find_tt(qh->ps.udev); +	if (IS_ERR(tt)) { +		status = PTR_ERR(tt); +		goto done;  	} +	compute_tt_budget(ehci->tt_budget, tt);  	/* else scan the schedule to find a group of slots such that all  	 * uframes have enough periodic bandwidth available.  	 */ -	if (status) { -		/* "normal" case, uframing flexible except with splits */ -		if (qh->period) { -			int		i; - -			for (i = qh->period; status && i > 0; --i) { -				frame = ++ehci->random_frame % qh->period; -				for (uframe = 0; uframe < 8; uframe++) { -					status = check_intr_schedule (ehci, -							frame, uframe, qh, -							&c_mask); -					if (status == 0) -						break; -				} +	/* "normal" case, uframing flexible except with splits */ +	if (qh->ps.bw_period) { +		int		i; +		unsigned	frame; + +		for (i = qh->ps.bw_period; i > 0; --i) { +			frame = ++ehci->random_frame & (qh->ps.bw_period - 1); +			for (uframe = 0; uframe < 8; uframe++) { +				status = check_intr_schedule(ehci, +						frame, uframe, qh, &c_mask, tt); +				if (status == 0) +					goto got_it;  			} - -		/* qh->period == 0 means every uframe */ -		} else { -			frame = 0; -			status = check_intr_schedule (ehci, 0, 0, qh, &c_mask);  		} -		if (status) -			goto done; -		qh->start = frame; -		/* reset S-frame and (maybe) C-frame masks */ -		hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); -		hw->hw_info2 |= qh->period -			? cpu_to_hc32(ehci, 1 << uframe) -			: cpu_to_hc32(ehci, QH_SMASK); -		hw->hw_info2 |= c_mask; -	} else -		ehci_dbg (ehci, "reused qh %p schedule\n", qh); +	/* qh->ps.bw_period == 0 means every uframe */ +	} else { +		status = check_intr_schedule(ehci, 0, 0, qh, &c_mask, tt); +	} +	if (status) +		goto done; + + got_it: +	qh->ps.phase = (qh->ps.period ? ehci->random_frame & +			(qh->ps.period - 1) : 0); +	qh->ps.bw_phase = qh->ps.phase & (qh->ps.bw_period - 1); +	qh->ps.phase_uf = uframe; +	qh->ps.cs_mask = qh->ps.period ? +			(c_mask << 8) | (1 << uframe) : +			QH_SMASK; + +	/* reset S-frame and (maybe) C-frame masks */ +	hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); +	hw->hw_info2 |= cpu_to_hc32(ehci, qh->ps.cs_mask); +	reserve_release_intr_bandwidth(ehci, qh, 1);  done:  	return status; @@ -969,7 +1030,8 @@ iso_stream_alloc (gfp_t mem_flags)  	if (likely (stream != NULL)) {  		INIT_LIST_HEAD(&stream->td_list);  		INIT_LIST_HEAD(&stream->free_list); -		stream->next_uframe = -1; +		stream->next_uframe = NO_FRAME; +		stream->ps.phase = NO_FRAME;  	}  	return stream;  } @@ -978,25 +1040,24 @@ static void  iso_stream_init (  	struct ehci_hcd		*ehci,  	struct ehci_iso_stream	*stream, -	struct usb_device	*dev, -	int			pipe, -	unsigned		interval +	struct urb		*urb  )  {  	static const u8 smask_out [] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f }; +	struct usb_device	*dev = urb->dev;  	u32			buf1;  	unsigned		epnum, maxp;  	int			is_input; -	long			bandwidth; +	unsigned		tmp;  	/*  	 * this might be a "high bandwidth" highspeed endpoint,  	 * as encoded in the ep descriptor's wMaxPacket field  	 */ -	epnum = usb_pipeendpoint (pipe); -	is_input = usb_pipein (pipe) ? USB_DIR_IN : 0; -	maxp = usb_maxpacket(dev, pipe, !is_input); +	epnum = usb_pipeendpoint(urb->pipe); +	is_input = usb_pipein(urb->pipe) ? USB_DIR_IN : 0; +	maxp = usb_endpoint_maxp(&urb->ep->desc);  	if (is_input) {  		buf1 = (1 << 11);  	} else { @@ -1020,9 +1081,19 @@ iso_stream_init (  		/* usbfs wants to report the average usecs per frame tied up  		 * when transfers on this endpoint are scheduled ...  		 */ -		stream->usecs = HS_USECS_ISO (maxp); -		bandwidth = stream->usecs * 8; -		bandwidth /= interval; +		stream->ps.usecs = HS_USECS_ISO(maxp); + +		/* period for bandwidth allocation */ +		tmp = min_t(unsigned, EHCI_BANDWIDTH_SIZE, +				1 << (urb->ep->desc.bInterval - 1)); + +		/* Allow urb->interval to override */ +		stream->ps.bw_uperiod = min_t(unsigned, tmp, urb->interval); + +		stream->uperiod = urb->interval; +		stream->ps.period = urb->interval >> 3; +		stream->bandwidth = stream->ps.usecs * 8 / +				stream->ps.bw_uperiod;  	} else {  		u32		addr; @@ -1036,36 +1107,46 @@ iso_stream_init (  			addr |= dev->tt->hub->devnum << 16;  		addr |= epnum << 8;  		addr |= dev->devnum; -		stream->usecs = HS_USECS_ISO (maxp); +		stream->ps.usecs = HS_USECS_ISO(maxp);  		think_time = dev->tt ? dev->tt->think_time : 0; -		stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time ( +		stream->ps.tt_usecs = NS_TO_US(think_time + usb_calc_bus_time(  				dev->speed, is_input, 1, maxp));  		hs_transfers = max (1u, (maxp + 187) / 188);  		if (is_input) {  			u32	tmp;  			addr |= 1 << 31; -			stream->c_usecs = stream->usecs; -			stream->usecs = HS_USECS_ISO (1); -			stream->raw_mask = 1; +			stream->ps.c_usecs = stream->ps.usecs; +			stream->ps.usecs = HS_USECS_ISO(1); +			stream->ps.cs_mask = 1;  			/* c-mask as specified in USB 2.0 11.18.4 3.c */  			tmp = (1 << (hs_transfers + 2)) - 1; -			stream->raw_mask |= tmp << (8 + 2); +			stream->ps.cs_mask |= tmp << (8 + 2);  		} else -			stream->raw_mask = smask_out [hs_transfers - 1]; -		bandwidth = stream->usecs + stream->c_usecs; -		bandwidth /= interval << 3; +			stream->ps.cs_mask = smask_out[hs_transfers - 1]; + +		/* period for bandwidth allocation */ +		tmp = min_t(unsigned, EHCI_BANDWIDTH_FRAMES, +				1 << (urb->ep->desc.bInterval - 1)); + +		/* Allow urb->interval to override */ +		stream->ps.bw_period = min_t(unsigned, tmp, urb->interval); +		stream->ps.bw_uperiod = stream->ps.bw_period << 3; -		/* stream->splits gets created from raw_mask later */ +		stream->ps.period = urb->interval; +		stream->uperiod = urb->interval << 3; +		stream->bandwidth = (stream->ps.usecs + stream->ps.c_usecs) / +				stream->ps.bw_period; + +		/* stream->splits gets created from cs_mask later */  		stream->address = cpu_to_hc32(ehci, addr);  	} -	stream->bandwidth = bandwidth; -	stream->udev = dev; +	stream->ps.udev = dev; +	stream->ps.ep = urb->ep;  	stream->bEndpointAddress = is_input | epnum; -	stream->interval = interval;  	stream->maxp = maxp;  } @@ -1090,9 +1171,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb)  		stream = iso_stream_alloc(GFP_ATOMIC);  		if (likely (stream != NULL)) {  			ep->hcpriv = stream; -			stream->ep = ep; -			iso_stream_init(ehci, stream, urb->dev, urb->pipe, -					urb->interval); +			iso_stream_init(ehci, stream, urb);  		}  	/* if dev->ep [epnum] is a QH, hw is set */ @@ -1137,7 +1216,7 @@ itd_sched_init(  	dma_addr_t	dma = urb->transfer_dma;  	/* how many uframes are needed for these transfers */ -	iso_sched->span = urb->number_of_packets * stream->interval; +	iso_sched->span = urb->number_of_packets * stream->uperiod;  	/* figure out per-uframe itd fields that we'll need later  	 * when we fit new itds into the schedule. @@ -1236,7 +1315,7 @@ itd_urb_transaction (  		memset (itd, 0, sizeof *itd);  		itd->itd_dma = itd_dma; -		itd->frame = 9999;		/* an invalid value */ +		itd->frame = NO_FRAME;  		list_add (&itd->itd_list, &sched->td_list);  	}  	spin_unlock_irqrestore (&ehci->lock, flags); @@ -1249,49 +1328,106 @@ itd_urb_transaction (  /*-------------------------------------------------------------------------*/ +static void reserve_release_iso_bandwidth(struct ehci_hcd *ehci, +		struct ehci_iso_stream *stream, int sign) +{ +	unsigned		uframe; +	unsigned		i, j; +	unsigned		s_mask, c_mask, m; +	int			usecs = stream->ps.usecs; +	int			c_usecs = stream->ps.c_usecs; +	int			tt_usecs = stream->ps.tt_usecs; +	struct ehci_tt		*tt; + +	if (stream->ps.phase == NO_FRAME)	/* Bandwidth wasn't reserved */ +		return; +	uframe = stream->ps.bw_phase << 3; + +	bandwidth_dbg(ehci, sign, "iso", &stream->ps); + +	if (sign < 0) {		/* Release bandwidth */ +		usecs = -usecs; +		c_usecs = -c_usecs; +		tt_usecs = -tt_usecs; +	} + +	if (!stream->splits) {		/* High speed */ +		for (i = uframe + stream->ps.phase_uf; i < EHCI_BANDWIDTH_SIZE; +				i += stream->ps.bw_uperiod) +			ehci->bandwidth[i] += usecs; + +	} else {			/* Full speed */ +		s_mask = stream->ps.cs_mask; +		c_mask = s_mask >> 8; + +		/* NOTE: adjustment needed for frame overflow */ +		for (i = uframe; i < EHCI_BANDWIDTH_SIZE; +				i += stream->ps.bw_uperiod) { +			for ((j = stream->ps.phase_uf, m = 1 << j); j < 8; +					(++j, m <<= 1)) { +				if (s_mask & m) +					ehci->bandwidth[i+j] += usecs; +				else if (c_mask & m) +					ehci->bandwidth[i+j] += c_usecs; +			} +		} + +		tt = find_tt(stream->ps.udev); +		if (sign > 0) +			list_add_tail(&stream->ps.ps_list, &tt->ps_list); +		else +			list_del(&stream->ps.ps_list); + +		for (i = uframe >> 3; i < EHCI_BANDWIDTH_FRAMES; +				i += stream->ps.bw_period) +			tt->bandwidth[i] += tt_usecs; +	} +} +  static inline int  itd_slot_ok (  	struct ehci_hcd		*ehci, -	u32			mod, -	u32			uframe, -	u8			usecs, -	u32			period +	struct ehci_iso_stream	*stream, +	unsigned		uframe  )  { -	uframe %= period; -	do { -		/* can't commit more than uframe_periodic_max usec */ -		if (periodic_usecs (ehci, uframe >> 3, uframe & 0x7) -				> (ehci->uframe_periodic_max - usecs)) -			return 0; +	unsigned		usecs; + +	/* convert "usecs we need" to "max already claimed" */ +	usecs = ehci->uframe_periodic_max - stream->ps.usecs; -		/* we know urb->interval is 2^N uframes */ -		uframe += period; -	} while (uframe < mod); +	for (uframe &= stream->ps.bw_uperiod - 1; uframe < EHCI_BANDWIDTH_SIZE; +			uframe += stream->ps.bw_uperiod) { +		if (ehci->bandwidth[uframe] > usecs) +			return 0; +	}  	return 1;  }  static inline int  sitd_slot_ok (  	struct ehci_hcd		*ehci, -	u32			mod,  	struct ehci_iso_stream	*stream, -	u32			uframe, +	unsigned		uframe,  	struct ehci_iso_sched	*sched, -	u32			period_uframes +	struct ehci_tt		*tt  )  { -	u32			mask, tmp; -	u32			frame, uf; +	unsigned		mask, tmp; +	unsigned		frame, uf; + +	mask = stream->ps.cs_mask << (uframe & 7); -	mask = stream->raw_mask << (uframe & 7); +	/* for OUT, don't wrap SSPLIT into H-microframe 7 */ +	if (((stream->ps.cs_mask & 0xff) << (uframe & 7)) >= (1 << 7)) +		return 0;  	/* for IN, don't wrap CSPLIT into the next frame */  	if (mask & ~0xffff)  		return 0;  	/* check bandwidth */ -	uframe %= period_uframes; +	uframe &= stream->ps.bw_uperiod - 1;  	frame = uframe >> 3;  #ifdef CONFIG_USB_EHCI_TT_NEWSCHED @@ -1299,54 +1435,48 @@ sitd_slot_ok (  	 * tt_available scheduling guarantees 10+% for control/bulk.  	 */  	uf = uframe & 7; -	if (!tt_available(ehci, period_uframes >> 3, -			stream->udev, frame, uf, stream->tt_usecs)) +	if (!tt_available(ehci, &stream->ps, tt, frame, uf))  		return 0;  #else  	/* tt must be idle for start(s), any gap, and csplit.  	 * assume scheduling slop leaves 10+% for control/bulk.  	 */ -	if (!tt_no_collision(ehci, period_uframes >> 3, -			stream->udev, frame, mask)) +	if (!tt_no_collision(ehci, stream->ps.bw_period, +			stream->ps.udev, frame, mask))  		return 0;  #endif -	/* this multi-pass logic is simple, but performance may -	 * suffer when the schedule data isn't cached. -	 */  	do { -		u32		max_used; - -		frame = uframe >> 3; -		uf = uframe & 7; +		unsigned	max_used; +		unsigned	i;  		/* check starts (OUT uses more than one) */ -		max_used = ehci->uframe_periodic_max - stream->usecs; -		for (tmp = stream->raw_mask & 0xff; tmp; tmp >>= 1, uf++) { -			if (periodic_usecs (ehci, frame, uf) > max_used) +		uf = uframe; +		max_used = ehci->uframe_periodic_max - stream->ps.usecs; +		for (tmp = stream->ps.cs_mask & 0xff; tmp; tmp >>= 1, uf++) { +			if (ehci->bandwidth[uf] > max_used)  				return 0;  		}  		/* for IN, check CSPLIT */ -		if (stream->c_usecs) { -			uf = uframe & 7; -			max_used = ehci->uframe_periodic_max - stream->c_usecs; -			do { -				tmp = 1 << uf; -				tmp <<= 8; -				if ((stream->raw_mask & tmp) == 0) +		if (stream->ps.c_usecs) { +			max_used = ehci->uframe_periodic_max - +					stream->ps.c_usecs; +			uf = uframe & ~7; +			tmp = 1 << (2+8); +			for (i = (uframe & 7) + 2; i < 8; (++i, tmp <<= 1)) { +				if ((stream->ps.cs_mask & tmp) == 0)  					continue; -				if (periodic_usecs (ehci, frame, uf) -						> max_used) +				if (ehci->bandwidth[uf+i] > max_used)  					return 0; -			} while (++uf < 8); +			}  		} -		/* we know urb->interval is 2^N uframes */ -		uframe += period_uframes; -	} while (uframe < mod); +		uframe += stream->ps.bw_uperiod; +	} while (uframe < EHCI_BANDWIDTH_SIZE); -	stream->splits = cpu_to_hc32(ehci, stream->raw_mask << (uframe & 7)); +	stream->ps.cs_mask <<= uframe & 7; +	stream->splits = cpu_to_hc32(ehci, stream->ps.cs_mask);  	return 1;  } @@ -1361,8 +1491,6 @@ sitd_slot_ok (   * given EHCI_TUNE_FLS and the slop).  Or, write a smarter scheduler!   */ -#define SCHEDULING_DELAY	40	/* microframes */ -  static int  iso_stream_schedule (  	struct ehci_hcd		*ehci, @@ -1370,134 +1498,184 @@ iso_stream_schedule (  	struct ehci_iso_stream	*stream  )  { -	u32			now, base, next, start, period, span; -	int			status; +	u32			now, base, next, start, period, span, now2; +	u32			wrap = 0, skip = 0; +	int			status = 0;  	unsigned		mod = ehci->periodic_size << 3;  	struct ehci_iso_sched	*sched = urb->hcpriv; +	bool			empty = list_empty(&stream->td_list); +	bool			new_stream = false; -	period = urb->interval; +	period = stream->uperiod;  	span = sched->span; -	if (!stream->highspeed) { -		period <<= 3; +	if (!stream->highspeed)  		span <<= 3; -	} -	now = ehci_read_frame_index(ehci) & (mod - 1); +	/* Start a new isochronous stream? */ +	if (unlikely(empty && !hcd_periodic_completion_in_progress( +			ehci_to_hcd(ehci), urb->ep))) { -	/* Typical case: reuse current schedule, stream is still active. -	 * Hopefully there are no gaps from the host falling behind -	 * (irq delays etc).  If there are, the behavior depends on -	 * whether URB_ISO_ASAP is set. -	 */ -	if (likely (!list_empty (&stream->td_list))) { +		/* Schedule the endpoint */ +		if (stream->ps.phase == NO_FRAME) { +			int		done = 0; +			struct ehci_tt	*tt = find_tt(stream->ps.udev); -		/* Take the isochronous scheduling threshold into account */ -		if (ehci->i_thresh) -			next = now + ehci->i_thresh;	/* uframe cache */ -		else -			next = (now + 2 + 7) & ~0x07;	/* full frame cache */ - -		/* -		 * Use ehci->last_iso_frame as the base.  There can't be any -		 * TDs scheduled for earlier than that. -		 */ -		base = ehci->last_iso_frame << 3; -		next = (next - base) & (mod - 1); -		start = (stream->next_uframe - base) & (mod - 1); - -		/* Is the schedule already full? */ -		if (unlikely(start < period)) { -			ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", -					urb, stream->next_uframe, base, -					period, mod); -			status = -ENOSPC; -			goto fail; -		} - -		/* Behind the scheduling threshold? */ -		if (unlikely(start < next)) { -			unsigned now2 = (now - base) & (mod - 1); +			if (IS_ERR(tt)) { +				status = PTR_ERR(tt); +				goto fail; +			} +			compute_tt_budget(ehci->tt_budget, tt); -			/* USB_ISO_ASAP: Round up to the first available slot */ -			if (urb->transfer_flags & URB_ISO_ASAP) -				start += (next - start + period - 1) & -period; +			start = ((-(++ehci->random_frame)) << 3) & (period - 1); -			/* -			 * Not ASAP: Use the next slot in the stream, -			 * no matter what. +			/* find a uframe slot with enough bandwidth. +			 * Early uframes are more precious because full-speed +			 * iso IN transfers can't use late uframes, +			 * and therefore they should be allocated last.  			 */ -			else if (start + span - period < now2) { -				ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n", -						urb, start + base, -						span - period, now2 + base); +			next = start; +			start += period; +			do { +				start--; +				/* check schedule: enough space? */ +				if (stream->highspeed) { +					if (itd_slot_ok(ehci, stream, start)) +						done = 1; +				} else { +					if ((start % 8) >= 6) +						continue; +					if (sitd_slot_ok(ehci, stream, start, +							sched, tt)) +						done = 1; +				} +			} while (start > next && !done); + +			/* no room in the schedule */ +			if (!done) { +				ehci_dbg(ehci, "iso sched full %p", urb); +				status = -ENOSPC; +				goto fail;  			} +			stream->ps.phase = (start >> 3) & +					(stream->ps.period - 1); +			stream->ps.bw_phase = stream->ps.phase & +					(stream->ps.bw_period - 1); +			stream->ps.phase_uf = start & 7; +			reserve_release_iso_bandwidth(ehci, stream, 1); +		} + +		/* New stream is already scheduled; use the upcoming slot */ +		else { +			start = (stream->ps.phase << 3) + stream->ps.phase_uf;  		} -		start += base; +		stream->next_uframe = start; +		new_stream = true;  	} -	/* need to schedule; when's the next (u)frame we could start? -	 * this is bigger than ehci->i_thresh allows; scheduling itself -	 * isn't free, the delay should handle reasonably slow cpus.  it -	 * can also help high bandwidth if the dma and irq loads don't -	 * jump until after the queue is primed. +	now = ehci_read_frame_index(ehci) & (mod - 1); + +	/* Take the isochronous scheduling threshold into account */ +	if (ehci->i_thresh) +		next = now + ehci->i_thresh;	/* uframe cache */ +	else +		next = (now + 2 + 7) & ~0x07;	/* full frame cache */ + +	/* +	 * Use ehci->last_iso_frame as the base.  There can't be any +	 * TDs scheduled for earlier than that.  	 */ -	else { -		int done = 0; +	base = ehci->last_iso_frame << 3; +	next = (next - base) & (mod - 1); +	start = (stream->next_uframe - base) & (mod - 1); -		base = now & ~0x07; -		start = base + SCHEDULING_DELAY; +	if (unlikely(new_stream)) +		goto do_ASAP; -		/* find a uframe slot with enough bandwidth. -		 * Early uframes are more precious because full-speed -		 * iso IN transfers can't use late uframes, -		 * and therefore they should be allocated last. -		 */ -		next = start; -		start += period; -		do { -			start--; -			/* check schedule: enough space? */ -			if (stream->highspeed) { -				if (itd_slot_ok(ehci, mod, start, -						stream->usecs, period)) -					done = 1; -			} else { -				if ((start % 8) >= 6) -					continue; -				if (sitd_slot_ok(ehci, mod, stream, -						start, sched, period)) -					done = 1; -			} -		} while (start > next && !done); +	/* +	 * Typical case: reuse current schedule, stream may still be active. +	 * Hopefully there are no gaps from the host falling behind +	 * (irq delays etc).  If there are, the behavior depends on +	 * whether URB_ISO_ASAP is set. +	 */ +	now2 = (now - base) & (mod - 1); + +	/* Is the schedule already full? */ +	if (unlikely(!empty && start < period)) { +		ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", +				urb, stream->next_uframe, base, period, mod); +		status = -ENOSPC; +		goto fail; +	} + +	/* Is the next packet scheduled after the base time? */ +	if (likely(!empty || start <= now2 + period)) { + +		/* URB_ISO_ASAP: make sure that start >= next */ +		if (unlikely(start < next && +				(urb->transfer_flags & URB_ISO_ASAP))) +			goto do_ASAP; + +		/* Otherwise use start, if it's not in the past */ +		if (likely(start >= now2)) +			goto use_start; -		/* no room in the schedule */ -		if (!done) { -			ehci_dbg(ehci, "iso sched full %p", urb); -			status = -ENOSPC; -			goto fail; +	/* Otherwise we got an underrun while the queue was empty */ +	} else { +		if (urb->transfer_flags & URB_ISO_ASAP) +			goto do_ASAP; +		wrap = mod; +		now2 += mod; +	} + +	/* How many uframes and packets do we need to skip? */ +	skip = (now2 - start + period - 1) & -period; +	if (skip >= span) {		/* Entirely in the past? */ +		ehci_dbg(ehci, "iso underrun %p (%u+%u < %u) [%u]\n", +				urb, start + base, span - period, now2 + base, +				base); + +		/* Try to keep the last TD intact for scanning later */ +		skip = span - period; + +		/* Will it come before the current scan position? */ +		if (empty) { +			skip = span;	/* Skip the entire URB */ +			status = 1;	/* and give it back immediately */ +			iso_sched_free(stream, sched); +			sched = NULL;  		}  	} +	urb->error_count = skip / period; +	if (sched) +		sched->first_packet = urb->error_count; +	goto use_start; + do_ASAP: +	/* Use the first slot after "next" */ +	start = next + ((start - next) & (period - 1)); + + use_start:  	/* Tried to schedule too far into the future? */ -	if (unlikely(start - base + span - period >= mod)) { +	if (unlikely(start + span - period >= mod + wrap)) {  		ehci_dbg(ehci, "request %p would overflow (%u+%u >= %u)\n", -				urb, start - base, span - period, mod); +				urb, start, span - period, mod + wrap);  		status = -EFBIG;  		goto fail;  	} -	stream->next_uframe = start & (mod - 1); +	start += base; +	stream->next_uframe = (start + skip) & (mod - 1);  	/* report high speed start in uframes; full speed, in frames */ -	urb->start_frame = stream->next_uframe; +	urb->start_frame = start & (mod - 1);  	if (!stream->highspeed)  		urb->start_frame >>= 3;  	/* Make sure scan_isoc() sees these */  	if (ehci->isoc_count == 0)  		ehci->last_iso_frame = now >> 3; -	return 0; +	return status;   fail:  	iso_sched_free(stream, sched); @@ -1610,7 +1788,8 @@ static void itd_link_urb(  	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;  	/* fill iTDs uframe by uframe */ -	for (packet = 0, itd = NULL; packet < urb->number_of_packets; ) { +	for (packet = iso_sched->first_packet, itd = NULL; +			packet < urb->number_of_packets;) {  		if (itd == NULL) {  			/* ASSERT:  we have all necessary itds */  			// BUG_ON (list_empty (&iso_sched->td_list)); @@ -1630,7 +1809,7 @@ static void itd_link_urb(  		itd_patch(ehci, itd, iso_sched, packet, uframe); -		next_uframe += stream->interval; +		next_uframe += stream->uperiod;  		next_uframe &= mod - 1;  		packet++; @@ -1770,9 +1949,9 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,  		ehci_dbg (ehci, "can't get iso stream\n");  		return -ENOMEM;  	} -	if (unlikely (urb->interval != stream->interval)) { +	if (unlikely(urb->interval != stream->uperiod)) {  		ehci_dbg (ehci, "can't change iso interval %d --> %d\n", -			stream->interval, urb->interval); +			stream->uperiod, urb->interval);  		goto done;  	} @@ -1804,10 +1983,14 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,  	if (unlikely(status))  		goto done_not_linked;  	status = iso_stream_schedule(ehci, urb, stream); -	if (likely (status == 0)) +	if (likely(status == 0)) {  		itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); -	else +	} else if (status > 0) { +		status = 0; +		ehci_urb_done(ehci, urb, 0); +	} else {  		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); +	}   done_not_linked:  	spin_unlock_irqrestore (&ehci->lock, flags);   done: @@ -1833,7 +2016,7 @@ sitd_sched_init(  	dma_addr_t	dma = urb->transfer_dma;  	/* how many frames are needed for these transfers */ -	iso_sched->span = urb->number_of_packets * stream->interval; +	iso_sched->span = urb->number_of_packets * stream->ps.period;  	/* figure out per-frame sitd fields that we'll need later  	 * when we fit new sitds into the schedule. @@ -1925,7 +2108,7 @@ sitd_urb_transaction (  		memset (sitd, 0, sizeof *sitd);  		sitd->sitd_dma = sitd_dma; -		sitd->frame = 9999;		/* an invalid value */ +		sitd->frame = NO_FRAME;  		list_add (&sitd->sitd_list, &iso_sched->td_list);  	} @@ -2008,7 +2191,7 @@ static void sitd_link_urb(  	ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;  	/* fill sITDs frame by frame */ -	for (packet = 0, sitd = NULL; +	for (packet = sched->first_packet, sitd = NULL;  			packet < urb->number_of_packets;  			packet++) { @@ -2027,7 +2210,7 @@ static void sitd_link_urb(  		sitd_link(ehci, (next_uframe >> 3) & (ehci->periodic_size - 1),  				sitd); -		next_uframe += stream->interval << 3; +		next_uframe += stream->uperiod;  	}  	stream->next_uframe = next_uframe & (mod - 1); @@ -2146,9 +2329,9 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,  		ehci_dbg (ehci, "can't get iso stream\n");  		return -ENOMEM;  	} -	if (urb->interval != stream->interval) { +	if (urb->interval != stream->ps.period) {  		ehci_dbg (ehci, "can't change iso interval %d --> %d\n", -			stream->interval, urb->interval); +			stream->ps.period, urb->interval);  		goto done;  	} @@ -2178,10 +2361,14 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,  	if (unlikely(status))  		goto done_not_linked;  	status = iso_stream_schedule(ehci, urb, stream); -	if (status == 0) +	if (likely(status == 0)) {  		sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); -	else +	} else if (status > 0) { +		status = 0; +		ehci_urb_done(ehci, urb, 0); +	} else {  		usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); +	}   done_not_linked:  	spin_unlock_irqrestore (&ehci->lock, flags);   done: @@ -2259,7 +2446,8 @@ restart:  				    q.itd->hw_next != EHCI_LIST_END(ehci))  					*hw_p = q.itd->hw_next;  				else -					*hw_p = ehci->dummy->qh_dma; +					*hw_p = cpu_to_hc32(ehci, +							ehci->dummy->qh_dma);  				type = Q_NEXT_TYPE(ehci, q.itd->hw_next);  				wmb();  				modified = itd_complete (ehci, q.itd); @@ -2294,7 +2482,8 @@ restart:  				    q.sitd->hw_next != EHCI_LIST_END(ehci))  					*hw_p = q.sitd->hw_next;  				else -					*hw_p = ehci->dummy->qh_dma; +					*hw_p = cpu_to_hc32(ehci, +							ehci->dummy->qh_dma);  				type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);  				wmb();  				modified = sitd_complete (ehci, q.sitd); diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 8a734498079..cf126767386 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c @@ -126,6 +126,7 @@ static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev)  			  IRQF_SHARED);  	if (ret == 0) {  		platform_set_drvdata(pdev, hcd); +		device_wakeup_enable(hcd->self.controller);  		return ret;  	} diff --git a/drivers/usb/host/ehci-sh.c b/drivers/usb/host/ehci-sh.c index dc899eb2b86..9b9b9f5b016 100644 --- a/drivers/usb/host/ehci-sh.c +++ b/drivers/usb/host/ehci-sh.c @@ -151,6 +151,7 @@ static int ehci_hcd_sh_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "Failed to add hcd");  		goto fail_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	priv->hcd = hcd;  	platform_set_drvdata(pdev, priv); diff --git a/drivers/usb/host/ehci-spear.c b/drivers/usb/host/ehci-spear.c index 1cf0adba3fc..1d59958ad0c 100644 --- a/drivers/usb/host/ehci-spear.c +++ b/drivers/usb/host/ehci-spear.c @@ -81,10 +81,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (retval) +		goto fail;  	usbh_clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(usbh_clk)) { @@ -107,16 +106,9 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len, -				driver->description)) { -		retval = -EBUSY; -		goto err_put_hcd; -	} - -	hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); -	if (hcd->regs == NULL) { -		dev_dbg(&pdev->dev, "error mapping memory\n"); -		retval = -ENOMEM; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs);  		goto err_put_hcd;  	} @@ -131,6 +123,7 @@ static int spear_ehci_hcd_drv_probe(struct platform_device *pdev)  	if (retval)  		goto err_stop_ehci; +	device_wakeup_enable(hcd->self.controller);  	return retval;  err_stop_ehci: diff --git a/drivers/usb/host/ehci-sysfs.c b/drivers/usb/host/ehci-sysfs.c index 14ced00ba22..f6459dfb6f5 100644 --- a/drivers/usb/host/ehci-sysfs.c +++ b/drivers/usb/host/ehci-sysfs.c @@ -97,8 +97,7 @@ static ssize_t store_uframe_periodic_max(struct device *dev,  {  	struct ehci_hcd		*ehci;  	unsigned		uframe_periodic_max; -	unsigned		frame, uframe; -	unsigned short		allocated_max; +	unsigned		uframe;  	unsigned long		flags;  	ssize_t			ret; @@ -122,16 +121,14 @@ static ssize_t store_uframe_periodic_max(struct device *dev,  	/*  	 * for request to decrease max periodic bandwidth, we have to check -	 * every microframe in the schedule to see whether the decrease is -	 * possible. +	 * to see whether the decrease is possible.  	 */  	if (uframe_periodic_max < ehci->uframe_periodic_max) { -		allocated_max = 0; +		u8		allocated_max = 0; -		for (frame = 0; frame < ehci->periodic_size; ++frame) -			for (uframe = 0; uframe < 7; ++uframe) -				allocated_max = max(allocated_max, -						    periodic_usecs (ehci, frame, uframe)); +		for (uframe = 0; uframe < EHCI_BANDWIDTH_SIZE; ++uframe) +			allocated_max = max(allocated_max, +					ehci->bandwidth[uframe]);  		if (allocated_max > uframe_periodic_max) {  			ehci_info(ehci, diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 78fa76da332..6fdcb8ad229 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -17,7 +17,6 @@   */  #include <linux/clk.h> -#include <linux/clk/tegra.h>  #include <linux/dma-mapping.h>  #include <linux/err.h>  #include <linux/gpio.h> @@ -29,6 +28,7 @@  #include <linux/of_gpio.h>  #include <linux/platform_device.h>  #include <linux/pm_runtime.h> +#include <linux/reset.h>  #include <linux/slab.h>  #include <linux/usb/ehci_def.h>  #include <linux/usb/tegra_usb_phy.h> @@ -38,10 +38,6 @@  #include "ehci.h" -#define TEGRA_USB_BASE			0xC5000000 -#define TEGRA_USB2_BASE			0xC5004000 -#define TEGRA_USB3_BASE			0xC5008000 -  #define PORT_WAKE_BITS (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)  #define TEGRA_USB_DMA_ALIGN 32 @@ -55,13 +51,10 @@ struct tegra_ehci_soc_config {  	bool has_hostpc;  }; -static int (*orig_hub_control)(struct usb_hcd *hcd, -				u16 typeReq, u16 wValue, u16 wIndex, -				char *buf, u16 wLength); -  struct tegra_ehci_hcd {  	struct tegra_usb_phy *phy;  	struct clk *clk; +	struct reset_control *rst;  	int port_resuming;  	bool needs_double_reset;  	enum tegra_usb_phy_port_speed port_speed; @@ -239,7 +232,7 @@ static int tegra_ehci_hub_control(  	spin_unlock_irqrestore(&ehci->lock, flags);  	/* Handle the hub control events here */ -	return orig_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +	return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);  done:  	spin_unlock_irqrestore(&ehci->lock, flags); @@ -362,10 +355,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (err) +		return err;  	hcd = usb_create_hcd(&tegra_ehci_hc_driver, &pdev->dev,  					dev_name(&pdev->dev)); @@ -386,13 +378,20 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		goto cleanup_hcd_create;  	} +	tegra->rst = devm_reset_control_get(&pdev->dev, "usb"); +	if (IS_ERR(tegra->rst)) { +		dev_err(&pdev->dev, "Can't get ehci reset\n"); +		err = PTR_ERR(tegra->rst); +		goto cleanup_hcd_create; +	} +  	err = clk_prepare_enable(tegra->clk);  	if (err) -		goto cleanup_clk_get; +		goto cleanup_hcd_create; -	tegra_periph_reset_assert(tegra->clk); +	reset_control_assert(tegra->rst);  	udelay(1); -	tegra_periph_reset_deassert(tegra->clk); +	reset_control_deassert(tegra->rst);  	u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0);  	if (IS_ERR(u_phy)) { @@ -412,10 +411,9 @@ static int tegra_ehci_probe(struct platform_device *pdev)  	}  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	hcd->regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "Failed to remap I/O memory\n"); -		err = -ENOMEM; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		err = PTR_ERR(hcd->regs);  		goto cleanup_clk_en;  	}  	ehci->caps = hcd->regs + 0x100; @@ -456,6 +454,7 @@ static int tegra_ehci_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "Failed to add USB HCD\n");  		goto cleanup_otg_set_host;  	} +	device_wakeup_enable(hcd->self.controller);  	return err; @@ -465,8 +464,6 @@ cleanup_phy:  	usb_phy_shutdown(hcd->phy);  cleanup_clk_en:  	clk_disable_unprepare(tegra->clk); -cleanup_clk_get: -	clk_put(tegra->clk);  cleanup_hcd_create:  	usb_put_hcd(hcd);  	return err; @@ -507,8 +504,31 @@ static struct platform_driver tegra_ehci_driver = {  	}  }; +static int tegra_ehci_reset(struct usb_hcd *hcd) +{ +	struct ehci_hcd *ehci = hcd_to_ehci(hcd); +	int retval; +	int txfifothresh; + +	retval = ehci_setup(hcd); +	if (retval) +		return retval; + +	/* +	 * We should really pull this value out of tegra_ehci_soc_config, but +	 * to avoid needing access to it, make use of the fact that Tegra20 is +	 * the only one so far that needs a value of 10, and Tegra20 is the +	 * only one which doesn't set has_hostpc. +	 */ +	txfifothresh = ehci->has_hostpc ? 0x10 : 10; +	ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning); + +	return 0; +} +  static const struct ehci_driver_overrides tegra_overrides __initconst = {  	.extra_priv_size	= sizeof(struct tegra_ehci_hcd), +	.reset			= tegra_ehci_reset,  };  static int __init ehci_tegra_init(void) @@ -529,8 +549,6 @@ static int __init ehci_tegra_init(void)  	 * too easy.  	 */ -	orig_hub_control = tegra_ehci_hc_driver.hub_control; -  	tegra_ehci_hc_driver.map_urb_for_dma = tegra_ehci_map_urb_for_dma;  	tegra_ehci_hc_driver.unmap_urb_for_dma = tegra_ehci_unmap_urb_for_dma;  	tegra_ehci_hc_driver.hub_control = tegra_ehci_hub_control; diff --git a/drivers/usb/host/ehci-tilegx.c b/drivers/usb/host/ehci-tilegx.c index 67026ffbf9a..0d247673c3c 100644 --- a/drivers/usb/host/ehci-tilegx.c +++ b/drivers/usb/host/ehci-tilegx.c @@ -142,8 +142,8 @@ static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)  	ehci->hcs_params = readl(&ehci->caps->hcs_params);  	/* Create our IRQs and register them. */ -	pdata->irq = create_irq(); -	if (pdata->irq < 0) { +	pdata->irq = irq_alloc_hwirq(-1); +	if (!pdata->irq) {  		ret = -ENXIO;  		goto err_no_irq;  	} @@ -170,11 +170,12 @@ static int ehci_hcd_tilegx_drv_probe(struct platform_device *pdev)  	ret = usb_add_hcd(hcd, pdata->irq, IRQF_SHARED);  	if (ret == 0) {  		platform_set_drvdata(pdev, hcd); +		device_wakeup_enable(hcd->self.controller);  		return ret;  	}  err_have_irq: -	destroy_irq(pdata->irq); +	irq_free_hwirq(pdata->irq);  err_no_irq:  	tilegx_stop_ehc();  	usb_put_hcd(hcd); @@ -192,7 +193,7 @@ static int ehci_hcd_tilegx_drv_remove(struct platform_device *pdev)  	usb_put_hcd(hcd);  	tilegx_stop_ehc();  	gxio_usb_host_destroy(&pdata->usb_ctx); -	destroy_irq(pdata->irq); +	irq_free_hwirq(pdata->irq);  	return 0;  } diff --git a/drivers/usb/host/ehci-w90x900.c b/drivers/usb/host/ehci-w90x900.c index 1c370dfbee0..a9303aff125 100644 --- a/drivers/usb/host/ehci-w90x900.c +++ b/drivers/usb/host/ehci-w90x900.c @@ -11,13 +11,28 @@   *   */ +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h>  #include <linux/platform_device.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include "ehci.h"  /* enable phy0 and phy1 for w90p910 */  #define	ENPHY		(0x01<<8)  #define PHY0_CTR	(0xA4)  #define PHY1_CTR	(0xA8) +#define DRIVER_DESC "EHCI w90x900 driver" + +static const char hcd_name[] = "ehci-w90x900 "; + +static struct hc_driver __read_mostly ehci_w90x900_hc_driver; +  static int usb_w90x900_probe(const struct hc_driver *driver,  		      struct platform_device *pdev)  { @@ -43,17 +58,12 @@ static int usb_w90x900_probe(const struct hc_driver *driver,  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		retval = -EBUSY; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs);  		goto err2;  	} -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (hcd->regs == NULL) { -		retval = -EFAULT; -		goto err3; -	} -  	ehci = hcd_to_ehci(hcd);  	ehci->caps = hcd->regs;  	ehci->regs = hcd->regs + @@ -73,80 +83,27 @@ static int usb_w90x900_probe(const struct hc_driver *driver,  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) -		goto err4; +		goto err2;  	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (retval != 0) -		goto err4; +		goto err2; +	device_wakeup_enable(hcd->self.controller);  	return retval; -err4: -	iounmap(hcd->regs); -err3: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  err2:  	usb_put_hcd(hcd);  err1:  	return retval;  } -static -void usb_w90x900_remove(struct usb_hcd *hcd, struct platform_device *pdev) +static void usb_w90x900_remove(struct usb_hcd *hcd, +			struct platform_device *pdev)  {  	usb_remove_hcd(hcd); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd);  } -static const struct hc_driver ehci_w90x900_hc_driver = { -	.description = hcd_name, -	.product_desc = "Nuvoton w90x900 EHCI Host Controller", -	.hcd_priv_size = sizeof(struct ehci_hcd), - -	/* -	 * generic hardware linkage -	 */ -	.irq = ehci_irq, -	.flags = HCD_USB2|HCD_MEMORY|HCD_BH, - -	/* -	 * basic lifecycle operations -	 */ -	.reset = ehci_setup, -	.start = ehci_run, - -	.stop = ehci_stop, -	.shutdown = ehci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue = ehci_urb_enqueue, -	.urb_dequeue = ehci_urb_dequeue, -	.endpoint_disable = ehci_endpoint_disable, -	.endpoint_reset = ehci_endpoint_reset, - -	/* -	 * scheduling support -	 */ -	.get_frame_number = ehci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data = ehci_hub_status_data, -	.hub_control = ehci_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend = ehci_bus_suspend, -	.bus_resume = ehci_bus_resume, -#endif -	.relinquish_port	= ehci_relinquish_port, -	.port_handed_over	= ehci_port_handed_over, - -	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; -  static int ehci_w90x900_probe(struct platform_device *pdev)  {  	if (usb_disabled()) @@ -173,7 +130,25 @@ static struct platform_driver ehci_hcd_w90x900_driver = {  	},  }; +static int __init ehci_w90X900_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ehci_init_driver(&ehci_w90x900_hc_driver, NULL); +	return platform_driver_register(&ehci_hcd_w90x900_driver); +} +module_init(ehci_w90X900_init); + +static void __exit ehci_w90X900_cleanup(void) +{ +	platform_driver_unregister(&ehci_hcd_w90x900_driver); +} +module_exit(ehci_w90X900_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); -MODULE_DESCRIPTION("w90p910 usb ehci driver!"); -MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:w90p910-ehci"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/ehci-xilinx-of.c b/drivers/usb/host/ehci-xilinx-of.c index 95979f9f438..fe57710753e 100644 --- a/drivers/usb/host/ehci-xilinx-of.c +++ b/drivers/usb/host/ehci-xilinx-of.c @@ -155,7 +155,8 @@ static int ehci_hcd_xilinx_of_probe(struct platform_device *op)  	irq = irq_of_parse_and_map(dn, 0);  	if (!irq) { -		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); +		dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", +			__FILE__);  		rv = -EBUSY;  		goto err_irq;  	} @@ -191,8 +192,10 @@ static int ehci_hcd_xilinx_of_probe(struct platform_device *op)  	ehci->caps = hcd->regs + 0x100;  	rv = usb_add_hcd(hcd, irq, 0); -	if (rv == 0) +	if (rv == 0) { +		device_wakeup_enable(hcd->self.controller);  		return 0; +	}  err_irq:  	usb_put_hcd(hcd); diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 291db7d09f2..eee228a26a0 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -38,7 +38,7 @@ typedef __u16 __bitwise __hc16;  #endif  /* statistics can be kept for tuning/monitoring */ -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  #define EHCI_STATS  #endif @@ -54,6 +54,28 @@ struct ehci_stats {  	unsigned long		unlink;  }; +/* + * Scheduling and budgeting information for periodic transfers, for both + * high-speed devices and full/low-speed devices lying behind a TT. + */ +struct ehci_per_sched { +	struct usb_device	*udev;		/* access to the TT */ +	struct usb_host_endpoint *ep; +	struct list_head	ps_list;	/* node on ehci_tt's ps_list */ +	u16			tt_usecs;	/* time on the FS/LS bus */ +	u16			cs_mask;	/* C-mask and S-mask bytes */ +	u16			period;		/* actual period in frames */ +	u16			phase;		/* actual phase, frame part */ +	u8			bw_phase;	/* same, for bandwidth +						   reservation */ +	u8			phase_uf;	/* uframe part of the phase */ +	u8			usecs, c_usecs;	/* times on the HS bus */ +	u8			bw_uperiod;	/* period in microframes, for +						   bandwidth reservation */ +	u8			bw_period;	/* same, in frames */ +}; +#define NO_FRAME	29999			/* frame not assigned yet */ +  /* ehci_hcd->lock guards shared data against other CPUs:   *   ehci_hcd:	async, unlink, periodic (and shadow), ...   *   usb_host_endpoint: hcpriv @@ -203,6 +225,7 @@ struct ehci_hcd {			/* one per controller */  	unsigned		has_synopsys_hc_bug:1; /* Synopsys HC */  	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */  	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */ +	unsigned		imx28_write_fix:1; /* For Freescale i.MX28 */  	/* required for usb32 quirk */  	#define OHCI_CTRL_HCFS          (3 << 6) @@ -226,10 +249,19 @@ struct ehci_hcd {			/* one per controller */  #endif  	/* debug files */ -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) +#ifdef CONFIG_DYNAMIC_DEBUG  	struct dentry		*debug_dir;  #endif +	/* bandwidth usage */ +#define EHCI_BANDWIDTH_SIZE	64 +#define EHCI_BANDWIDTH_FRAMES	(EHCI_BANDWIDTH_SIZE >> 3) +	u8			bandwidth[EHCI_BANDWIDTH_SIZE]; +						/* us allocated per uframe */ +	u8			tt_budget[EHCI_BANDWIDTH_SIZE]; +						/* us budgeted per uframe */ +	struct list_head	tt_list; +  	/* platform-specific data -- must come last */  	unsigned long		priv[0] __aligned(sizeof(s64));  }; @@ -385,6 +417,7 @@ struct ehci_qh {  	struct list_head	intr_node;	/* list of intr QHs */  	struct ehci_qtd		*dummy;  	struct list_head	unlink_node; +	struct ehci_per_sched	ps;		/* scheduling info */  	unsigned		unlink_cycle; @@ -398,16 +431,8 @@ struct ehci_qh {  	u8			xacterrs;	/* XactErr retry counter */  #define	QH_XACTERR_MAX		32		/* XactErr retry limit */ -	/* periodic schedule info */ -	u8			usecs;		/* intr bandwidth */  	u8			gap_uf;		/* uframes split/csplit gap */ -	u8			c_usecs;	/* ... split completion bw */ -	u16			tt_usecs;	/* tt downstream bandwidth */ -	unsigned short		period;		/* polling interval */ -	unsigned short		start;		/* where polling starts */ -#define NO_FRAME ((unsigned short)~0)			/* pick new start */ -	struct usb_device	*dev;		/* access to TT */  	unsigned		is_out:1;	/* bulk or intr OUT */  	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */  	unsigned		dequeue_during_giveback:1; @@ -434,6 +459,7 @@ struct ehci_iso_packet {  struct ehci_iso_sched {  	struct list_head	td_list;  	unsigned		span; +	unsigned		first_packet;  	struct ehci_iso_packet	packet [0];  }; @@ -449,22 +475,17 @@ struct ehci_iso_stream {  	u8			highspeed;  	struct list_head	td_list;	/* queued itds/sitds */  	struct list_head	free_list;	/* list of unused itds/sitds */ -	struct usb_device	*udev; -	struct usb_host_endpoint *ep;  	/* output of (re)scheduling */ -	int			next_uframe; +	struct ehci_per_sched	ps;		/* scheduling info */ +	unsigned		next_uframe;  	__hc32			splits;  	/* the rest is derived from the endpoint descriptor, -	 * trusting urb->interval == f(epdesc->bInterval) and  	 * including the extra info for hw_bufp[0..2]  	 */ -	u8			usecs, c_usecs; -	u16			interval; -	u16			tt_usecs; +	u16			uperiod;	/* period in uframes */  	u16			maxp; -	u16			raw_mask;  	unsigned		bandwidth;  	/* This is used to initialize iTD's hw_bufp fields */ @@ -579,6 +600,35 @@ struct ehci_fstn {  /*-------------------------------------------------------------------------*/ +/* + * USB-2.0 Specification Sections 11.14 and 11.18 + * Scheduling and budgeting split transactions using TTs + * + * A hub can have a single TT for all its ports, or multiple TTs (one for each + * port).  The bandwidth and budgeting information for the full/low-speed bus + * below each TT is self-contained and independent of the other TTs or the + * high-speed bus. + * + * "Bandwidth" refers to the number of microseconds on the FS/LS bus allocated + * to an interrupt or isochronous endpoint for each frame.  "Budget" refers to + * the best-case estimate of the number of full-speed bytes allocated to an + * endpoint for each microframe within an allocated frame. + * + * Removal of an endpoint invalidates a TT's budget.  Instead of trying to + * keep an up-to-date record, we recompute the budget when it is needed. + */ + +struct ehci_tt { +	u16			bandwidth[EHCI_BANDWIDTH_FRAMES]; + +	struct list_head	tt_list;	/* List of all ehci_tt's */ +	struct list_head	ps_list;	/* Items using this TT */ +	struct usb_tt		*usb_tt; +	int			tt_port;	/* TT port number */ +}; + +/*-------------------------------------------------------------------------*/ +  /* Prepare the PORTSC wakeup flags during controller suspend/resume */  #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup)	\ @@ -679,6 +729,18 @@ static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,  #endif  } +#ifdef CONFIG_SOC_IMX28 +static inline void imx28_ehci_writel(const unsigned int val, +		volatile __u32 __iomem *addr) +{ +	__asm__ ("swp %0, %0, [%1]" : : "r"(val), "r"(addr)); +} +#else +static inline void imx28_ehci_writel(const unsigned int val, +		volatile __u32 __iomem *addr) +{ +} +#endif  static inline void ehci_writel(const struct ehci_hcd *ehci,  		const unsigned int val, __u32 __iomem *regs)  { @@ -687,7 +749,10 @@ static inline void ehci_writel(const struct ehci_hcd *ehci,  		writel_be(val, regs) :  		writel(val, regs);  #else -	writel(val, regs); +	if (ehci->imx28_write_fix) +		imx28_ehci_writel(val, regs); +	else +		writel(val, regs);  #endif  } @@ -783,9 +848,9 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)  	dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args) -#if !defined(DEBUG) && !defined(CONFIG_DYNAMIC_DEBUG) +#ifndef CONFIG_DYNAMIC_DEBUG  #define STUB_DEBUG_FILES -#endif	/* !DEBUG && !CONFIG_DYNAMIC_DEBUG */ +#endif  /*-------------------------------------------------------------------------*/ @@ -807,4 +872,7 @@ extern int	ehci_suspend(struct usb_hcd *hcd, bool do_wakeup);  extern int	ehci_resume(struct usb_hcd *hcd, bool hibernated);  #endif	/* CONFIG_PM */ +extern int	ehci_hub_control(struct usb_hcd	*hcd, u16 typeReq, u16 wValue, +				 u16 wIndex, char *buf, u16 wLength); +  #endif /* __LINUX_EHCI_HCD_H */ diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 0b46542591f..1cf68eaf2ed 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -26,6 +26,8 @@  #include <linux/io.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <linux/of_gpio.h>  #include <linux/slab.h> @@ -752,6 +754,8 @@ static int of_fhci_probe(struct platform_device *ofdev)  	if (ret < 0)  		goto err_add_hcd; +	device_wakeup_enable(hcd->self.controller); +  	fhci_dfs_create(fhci);  	return 0; diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index fce13bcc4a3..98a89d16cc3 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -56,12 +56,9 @@  static const char	hcd_name[] = "fotg210_hcd"; -#undef VERBOSE_DEBUG  #undef FOTG210_URB_TRACE -#ifdef DEBUG  #define FOTG210_STATS -#endif  /* magic numbers that can affect system performance */  #define	FOTG210_TUNE_CERR		3 /* 0-3 qtd retries; 0 == don't stop */ @@ -107,14 +104,6 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");  #define fotg210_warn(fotg210, fmt, args...) \  	dev_warn(fotg210_to_hcd(fotg210)->self.controller , fmt , ## args) -#ifdef VERBOSE_DEBUG -#	define fotg210_vdbg fotg210_dbg -#else -	static inline void fotg210_vdbg(struct fotg210_hcd *fotg210, ...) {} -#endif - -#ifdef	DEBUG -  /* check the values in the HCSPARAMS register   * (host controller _Structural_ parameters)   * see EHCI spec, Table 2-4 for each value @@ -129,13 +118,6 @@ static void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label)  		HCS_N_PORTS(params)  		);  } -#else - -static inline void dbg_hcs_params(struct fotg210_hcd *fotg210, char *label) {} - -#endif - -#ifdef	DEBUG  /* check the values in the HCCPARAMS register   * (host controller _Capability_ parameters) @@ -152,13 +134,6 @@ static void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label)  		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",  		HCC_CANPARK(params) ? " park" : "");  } -#else - -static inline void dbg_hcc_params(struct fotg210_hcd *fotg210, char *label) {} - -#endif - -#ifdef	DEBUG  static void __maybe_unused  dbg_qtd(const char *label, struct fotg210_hcd *fotg210, struct fotg210_qtd *qtd) @@ -272,8 +247,8 @@ dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)  		);  } -static int -dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status) +static char +*dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)  {  	char	*sig; @@ -293,7 +268,7 @@ dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)  		break;  	} -	return scnprintf(buf, len, +	scnprintf(buf, len,  		"%s%sport:%d status %06x %d "  		"sig=%s%s%s%s%s%s%s%s",  		label, label[0] ? " " : "", port, status, @@ -306,31 +281,9 @@ dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)  		(status & PORT_PE) ? " PE" : "",  		(status & PORT_CSC) ? " CSC" : "",  		(status & PORT_CONNECT) ? " CONNECT" : ""); +	return buf;  } -#else -static inline void __maybe_unused -dbg_qh(char *label, struct fotg210_hcd *fotg210, struct fotg210_qh *qh) -{} - -static inline int __maybe_unused -dbg_status_buf(char *buf, unsigned len, const char *label, u32 status) -{ return 0; } - -static inline int __maybe_unused -dbg_command_buf(char *buf, unsigned len, const char *label, u32 command) -{ return 0; } - -static inline int __maybe_unused -dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable) -{ return 0; } - -static inline int __maybe_unused -dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status) -{ return 0; } - -#endif	/* DEBUG */ -  /* functions have the "wrong" filename when they're output... */  #define dbg_status(fotg210, label, status) { \  	char _buf[80]; \ @@ -346,19 +299,11 @@ dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)  #define dbg_port(fotg210, label, port, status) { \  	char _buf[80]; \ -	dbg_port_buf(_buf, sizeof(_buf), label, port, status); \ -	fotg210_dbg(fotg210, "%s\n", _buf); \ +	fotg210_dbg(fotg210, "%s\n", dbg_port_buf(_buf, sizeof(_buf), label, port, status) ); \  }  /*-------------------------------------------------------------------------*/ -#ifdef STUB_DEBUG_FILES - -static inline void create_debug_files(struct fotg210_hcd *bus) { } -static inline void remove_debug_files(struct fotg210_hcd *bus) { } - -#else -  /* troubleshooting help: expose state in debugfs */  static int debug_async_open(struct inode *, struct file *); @@ -412,7 +357,7 @@ struct debug_buffer {  			tmp = 'h'; break; \  		default:		\  			tmp = '?'; break; \ -		}; tmp; }) +		} tmp; })  static inline char token_mark(struct fotg210_hcd *fotg210, __hc32 token)  { @@ -954,7 +899,6 @@ static inline void remove_debug_files(struct fotg210_hcd *fotg210)  	debugfs_remove_recursive(fotg210->debug_dir);  } -#endif /* STUB_DEBUG_FILES */  /*-------------------------------------------------------------------------*/  /* @@ -1398,7 +1342,7 @@ static void fotg210_iaa_watchdog(struct fotg210_hcd *fotg210)  				       &fotg210->regs->status);  		} -		fotg210_vdbg(fotg210, "IAA watchdog: status %x cmd %x\n", +		fotg210_dbg(fotg210, "IAA watchdog: status %x cmd %x\n",  				status, cmd);  		end_unlink_async(fotg210);  	} @@ -1810,10 +1754,8 @@ static int fotg210_hub_control(  		if (test_bit(wIndex, &fotg210->port_c_suspend))  			status |= USB_PORT_STAT_C_SUSPEND << 16; -#ifndef	VERBOSE_DEBUG -	if (status & ~0xffff)	/* only if wPortChange is interesting */ -#endif -		dbg_port(fotg210, "GetStatus", wIndex + 1, temp); +		if (status & ~0xffff)	/* only if wPortChange is interesting */ +			dbg_port(fotg210, "GetStatus", wIndex + 1, temp);  		put_unaligned_le32(status, buf);  		break;  	case SetHubFeature: @@ -1856,7 +1798,7 @@ static int fotg210_hub_control(  			 * which can be fine if this root hub has a  			 * transaction translator built in.  			 */ -			fotg210_vdbg(fotg210, "port %d reset\n", wIndex + 1); +			fotg210_dbg(fotg210, "port %d reset\n", wIndex + 1);  			temp |= PORT_RESET;  			temp &= ~PORT_PE; @@ -2274,13 +2216,12 @@ static void fotg210_clear_tt_buffer(struct fotg210_hcd *fotg210,  	 * Note: this routine is never called for Isochronous transfers.  	 */  	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { -#ifdef DEBUG  		struct usb_device *tt = urb->dev->tt->hub;  		dev_dbg(&tt->dev,  			"clear tt buffer port %d, a%d ep%d t%08x\n",  			urb->dev->ttport, urb->dev->devnum,  			usb_pipeendpoint(urb->pipe), token); -#endif /* DEBUG */ +  		if (urb->dev->tt->hub !=  		    fotg210_to_hcd(fotg210)->self.root_hub) {  			if (usb_hub_clear_tt_buffer(urb) == 0) @@ -2341,7 +2282,7 @@ static int qtd_copy_status(  			status = -EPROTO;  		} -		fotg210_vdbg(fotg210, +		fotg210_dbg(fotg210,  			"dev%d ep%d%s qtd token %08x --> status %d\n",  			usb_pipedevice(urb->pipe),  			usb_pipeendpoint(urb->pipe), @@ -3583,11 +3524,9 @@ periodic_usecs(struct fotg210_hcd *fotg210, unsigned frame, unsigned uframe)  			break;  		}  	} -#ifdef	DEBUG  	if (usecs > fotg210->uframe_periodic_max)  		fotg210_err(fotg210, "uframe %d sched overrun: %d usecs\n",  			frame * 8 + uframe, usecs); -#endif  	return usecs;  } @@ -4646,7 +4585,7 @@ static void itd_link_urb(  	if (unlikely(list_empty(&stream->td_list))) {  		fotg210_to_hcd(fotg210)->self.bandwidth_allocated  				+= stream->bandwidth; -		fotg210_vdbg(fotg210, +		fotg210_dbg(fotg210,  			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",  			urb->dev->devpath, stream->bEndpointAddress & 0x0f,  			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", @@ -4779,7 +4718,7 @@ static bool itd_complete(struct fotg210_hcd *fotg210, struct fotg210_itd *itd)  	if (unlikely(list_is_singular(&stream->td_list))) {  		fotg210_to_hcd(fotg210)->self.bandwidth_allocated  				-= stream->bandwidth; -		fotg210_vdbg(fotg210, +		fotg210_dbg(fotg210,  			"deschedule devp %s ep%d%s-iso\n",  			dev->devpath, stream->bEndpointAddress & 0x0f,  			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); @@ -5444,10 +5383,8 @@ static irqreturn_t fotg210_irq(struct usb_hcd *hcd)  	cmd = fotg210_readl(fotg210, &fotg210->regs->command);  	bh = 0; -#ifdef	VERBOSE_DEBUG  	/* unrequested/ignored: Frame List Rollover */  	dbg_status(fotg210, "irq", status); -#endif  	/* INT, ERR, and IAA interrupt rates can be throttled */ @@ -5952,6 +5889,7 @@ static int fotg210_hcd_probe(struct platform_device *pdev)  		dev_err(dev, "failed to add hcd with err %d\n", retval);  		goto fail_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return retval; @@ -6013,13 +5951,11 @@ static int __init fotg210_hcd_init(void)  		 sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd),  		 sizeof(struct fotg210_itd)); -#ifdef DEBUG  	fotg210_debug_root = debugfs_create_dir("fotg210", usb_debug_root);  	if (!fotg210_debug_root) {  		retval = -ENOENT;  		goto err_debug;  	} -#endif  	retval = platform_driver_register(&fotg210_hcd_driver);  	if (retval < 0) @@ -6028,11 +5964,9 @@ static int __init fotg210_hcd_init(void)  	platform_driver_unregister(&fotg210_hcd_driver);  clean: -#ifdef DEBUG  	debugfs_remove(fotg210_debug_root);  	fotg210_debug_root = NULL;  err_debug: -#endif  	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);  	return retval;  } @@ -6041,9 +5975,7 @@ module_init(fotg210_hcd_init);  static void __exit fotg210_hcd_cleanup(void)  {  	platform_driver_unregister(&fotg210_hcd_driver); -#ifdef DEBUG  	debugfs_remove(fotg210_debug_root); -#endif  	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);  }  module_exit(fotg210_hcd_cleanup); diff --git a/drivers/usb/host/fotg210.h b/drivers/usb/host/fotg210.h index 8920f9d3256..ac6cd1bfd20 100644 --- a/drivers/usb/host/fotg210.h +++ b/drivers/usb/host/fotg210.h @@ -174,9 +174,7 @@ struct fotg210_hcd {			/* one per controller */  #endif  	/* debug files */ -#ifdef DEBUG  	struct dentry		*debug_dir; -#endif  };  /* convert between an HCD pointer and the corresponding FOTG210_HCD */ @@ -741,10 +739,4 @@ static inline unsigned fotg210_read_frame_index(struct fotg210_hcd *fotg210)  })  /*-------------------------------------------------------------------------*/ -#ifndef DEBUG -#define STUB_DEBUG_FILES -#endif	/* DEBUG */ - -/*-------------------------------------------------------------------------*/ -  #endif /* __LINUX_FOTG210_H */ diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 9e0020d9e4c..9162d1b6c0a 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -24,7 +24,7 @@ struct fsl_usb2_dev_data {  	enum fsl_usb2_operating_modes op_mode;	/* operating mode */  }; -struct fsl_usb2_dev_data dr_mode_data[] = { +static struct fsl_usb2_dev_data dr_mode_data[] = {  	{  		.dr_mode = "host",  		.drivers = { "fsl-ehci", NULL, NULL, }, @@ -42,7 +42,7 @@ struct fsl_usb2_dev_data dr_mode_data[] = {  	},  }; -struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np) +static struct fsl_usb2_dev_data *get_dr_mode_data(struct device_node *np)  {  	const unsigned char *prop;  	int i; @@ -75,7 +75,7 @@ static enum fsl_usb2_phy_modes determine_usb_phy(const char *phy_type)  	return FSL_USB2_PHY_NONE;  } -struct platform_device *fsl_usb2_device_register( +static struct platform_device *fsl_usb2_device_register(  					struct platform_device *ofdev,  					struct fsl_usb2_platform_data *pdata,  					const char *name, int id) @@ -261,19 +261,8 @@ int fsl_usb2_mpc5121_init(struct platform_device *pdev)  	struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);  	struct clk *clk;  	int err; -	char clk_name[10]; -	int base, clk_num; - -	base = pdev->resource->start & 0xf000; -	if (base == 0x3000) -		clk_num = 1; -	else if (base == 0x4000) -		clk_num = 2; -	else -		return -ENODEV; -	snprintf(clk_name, sizeof(clk_name), "usb%d_clk", clk_num); -	clk = devm_clk_get(pdev->dev.parent, clk_name); +	clk = devm_clk_get(pdev->dev.parent, "ipg");  	if (IS_ERR(clk)) {  		dev_err(&pdev->dev, "failed to get clk\n");  		return PTR_ERR(clk); diff --git a/drivers/usb/host/fusbh200-hcd.c b/drivers/usb/host/fusbh200-hcd.c index 299253c826c..ba9499060f6 100644 --- a/drivers/usb/host/fusbh200-hcd.c +++ b/drivers/usb/host/fusbh200-hcd.c @@ -57,13 +57,8 @@  static const char	hcd_name [] = "fusbh200_hcd"; -#undef VERBOSE_DEBUG  #undef FUSBH200_URB_TRACE -#ifdef DEBUG -#define FUSBH200_STATS -#endif -  /* magic numbers that can affect system performance */  #define	FUSBH200_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */  #define	FUSBH200_TUNE_RL_HS		4	/* nak throttle; see 4.9 */ @@ -108,14 +103,6 @@ MODULE_PARM_DESC(hird, "host initiated resume duration, +1 for each 75us");  #define fusbh200_warn(fusbh200, fmt, args...) \  	dev_warn (fusbh200_to_hcd(fusbh200)->self.controller , fmt , ## args ) -#ifdef VERBOSE_DEBUG -#	define fusbh200_vdbg fusbh200_dbg -#else -	static inline void fusbh200_vdbg(struct fusbh200_hcd *fusbh200, ...) {} -#endif - -#ifdef	DEBUG -  /* check the values in the HCSPARAMS register   * (host controller _Structural_ parameters)   * see EHCI spec, Table 2-4 for each value @@ -130,13 +117,6 @@ static void dbg_hcs_params (struct fusbh200_hcd *fusbh200, char *label)  		HCS_N_PORTS (params)  		);  } -#else - -static inline void dbg_hcs_params (struct fusbh200_hcd *fusbh200, char *label) {} - -#endif - -#ifdef	DEBUG  /* check the values in the HCCPARAMS register   * (host controller _Capability_ parameters) @@ -153,13 +133,6 @@ static void dbg_hcc_params (struct fusbh200_hcd *fusbh200, char *label)  		HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",  		HCC_CANPARK(params) ? " park" : "");  } -#else - -static inline void dbg_hcc_params (struct fusbh200_hcd *fusbh200, char *label) {} - -#endif - -#ifdef	DEBUG  static void __maybe_unused  dbg_qtd (const char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qtd *qtd) @@ -302,29 +275,6 @@ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)  		(status & PORT_CONNECT) ? " CONNECT" : "");  } -#else -static inline void __maybe_unused -dbg_qh (char *label, struct fusbh200_hcd *fusbh200, struct fusbh200_qh *qh) -{} - -static inline int __maybe_unused -dbg_status_buf (char *buf, unsigned len, const char *label, u32 status) -{ return 0; } - -static inline int __maybe_unused -dbg_command_buf (char *buf, unsigned len, const char *label, u32 command) -{ return 0; } - -static inline int __maybe_unused -dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable) -{ return 0; } - -static inline int __maybe_unused -dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status) -{ return 0; } - -#endif	/* DEBUG */ -  /* functions have the "wrong" filename when they're output... */  #define dbg_status(fusbh200, label, status) { \  	char _buf [80]; \ @@ -346,13 +296,6 @@ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)  /*-------------------------------------------------------------------------*/ -#ifdef STUB_DEBUG_FILES - -static inline void create_debug_files (struct fusbh200_hcd *bus) { } -static inline void remove_debug_files (struct fusbh200_hcd *bus) { } - -#else -  /* troubleshooting help: expose state in debugfs */  static int debug_async_open(struct inode *, struct file *); @@ -402,7 +345,7 @@ struct debug_buffer {  		case QH_LOW_SPEED:  tmp = 'l'; break; \  		case QH_HIGH_SPEED: tmp = 'h'; break; \  		default: tmp = '?'; break; \ -		}; tmp; }) +		} tmp; })  static inline char token_mark(struct fusbh200_hcd *fusbh200, __hc32 token)  { @@ -775,7 +718,6 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)  		next += temp;  	} -#ifdef FUSBH200_STATS  	temp = scnprintf (next, size,  		"irq normal %ld err %ld iaa %ld (lost %ld)\n",  		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa, @@ -787,7 +729,6 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)  		fusbh200->stats.complete, fusbh200->stats.unlink);  	size -= temp;  	next += temp; -#endif  done:  	spin_unlock_irqrestore (&fusbh200->lock, flags); @@ -928,7 +869,6 @@ static inline void remove_debug_files (struct fusbh200_hcd *fusbh200)  	debugfs_remove_recursive(fusbh200->debug_dir);  } -#endif /* STUB_DEBUG_FILES */  /*-------------------------------------------------------------------------*/  /* @@ -1362,7 +1302,7 @@ static void fusbh200_iaa_watchdog(struct fusbh200_hcd *fusbh200)  			fusbh200_writel(fusbh200, STS_IAA, &fusbh200->regs->status);  		} -		fusbh200_vdbg(fusbh200, "IAA watchdog: status %x cmd %x\n", +		fusbh200_dbg(fusbh200, "IAA watchdog: status %x cmd %x\n",  				status, cmd);  		end_unlink_async(fusbh200);  	} @@ -1769,10 +1709,8 @@ static int fusbh200_hub_control (  		if (test_bit(wIndex, &fusbh200->port_c_suspend))  			status |= USB_PORT_STAT_C_SUSPEND << 16; -#ifndef	VERBOSE_DEBUG -	if (status & ~0xffff)	/* only if wPortChange is interesting */ -#endif -		dbg_port (fusbh200, "GetStatus", wIndex + 1, temp); +		if (status & ~0xffff)	/* only if wPortChange is interesting */ +			dbg_port(fusbh200, "GetStatus", wIndex + 1, temp);  		put_unaligned_le32(status, buf);  		break;  	case SetHubFeature: @@ -1814,7 +1752,7 @@ static int fusbh200_hub_control (  			 * which can be fine if this root hub has a  			 * transaction translator built in.  			 */ -			fusbh200_vdbg (fusbh200, "port %d reset\n", wIndex + 1); +			fusbh200_dbg(fusbh200, "port %d reset\n", wIndex + 1);  			temp |= PORT_RESET;  			temp &= ~PORT_PE; @@ -2230,13 +2168,13 @@ static void fusbh200_clear_tt_buffer(struct fusbh200_hcd *fusbh200, struct fusbh  	 * Note: this routine is never called for Isochronous transfers.  	 */  	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) { -#ifdef DEBUG  		struct usb_device *tt = urb->dev->tt->hub; +  		dev_dbg(&tt->dev,  			"clear tt buffer port %d, a%d ep%d t%08x\n",  			urb->dev->ttport, urb->dev->devnum,  			usb_pipeendpoint(urb->pipe), token); -#endif /* DEBUG */ +  		if (urb->dev->tt->hub !=  		    fusbh200_to_hcd(fusbh200)->self.root_hub) {  			if (usb_hub_clear_tt_buffer(urb) == 0) @@ -2297,7 +2235,7 @@ static int qtd_copy_status (  			status = -EPROTO;  		} -		fusbh200_vdbg (fusbh200, +		fusbh200_dbg(fusbh200,  			"dev%d ep%d%s qtd token %08x --> status %d\n",  			usb_pipedevice (urb->pipe),  			usb_pipeendpoint (urb->pipe), @@ -3529,11 +3467,9 @@ periodic_usecs (struct fusbh200_hcd *fusbh200, unsigned frame, unsigned uframe)  			break;  		}  	} -#ifdef	DEBUG  	if (usecs > fusbh200->uframe_periodic_max)  		fusbh200_err (fusbh200, "uframe %d sched overrun: %d usecs\n",  			frame * 8 + uframe, usecs); -#endif  	return usecs;  } @@ -4586,7 +4522,7 @@ static void itd_link_urb(  	if (unlikely (list_empty(&stream->td_list))) {  		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated  				+= stream->bandwidth; -		fusbh200_vdbg (fusbh200, +		fusbh200_dbg(fusbh200,  			"schedule devp %s ep%d%s-iso period %d start %d.%d\n",  			urb->dev->devpath, stream->bEndpointAddress & 0x0f,  			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out", @@ -4717,7 +4653,7 @@ static bool itd_complete(struct fusbh200_hcd *fusbh200, struct fusbh200_itd *itd  	if (unlikely(list_is_singular(&stream->td_list))) {  		fusbh200_to_hcd(fusbh200)->self.bandwidth_allocated  				-= stream->bandwidth; -		fusbh200_vdbg (fusbh200, +		fusbh200_dbg(fusbh200,  			"deschedule devp %s ep%d%s-iso\n",  			dev->devpath, stream->bEndpointAddress & 0x0f,  			(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); @@ -5115,13 +5051,11 @@ static void fusbh200_stop (struct usb_hcd *hcd)  	spin_unlock_irq (&fusbh200->lock);  	fusbh200_mem_cleanup (fusbh200); -#ifdef	FUSBH200_STATS  	fusbh200_dbg(fusbh200, "irq normal %ld err %ld iaa %ld (lost %ld)\n",  		fusbh200->stats.normal, fusbh200->stats.error, fusbh200->stats.iaa,  		fusbh200->stats.lost_iaa);  	fusbh200_dbg (fusbh200, "complete %ld unlink %ld\n",  		fusbh200->stats.complete, fusbh200->stats.unlink); -#endif  	dbg_status (fusbh200, "fusbh200_stop completed",  		    fusbh200_readl(fusbh200, &fusbh200->regs->status)); @@ -5365,13 +5299,6 @@ static irqreturn_t fusbh200_irq (struct usb_hcd *hcd)  	cmd = fusbh200_readl(fusbh200, &fusbh200->regs->command);  	bh = 0; -#ifdef	VERBOSE_DEBUG -	/* unrequested/ignored: Frame List Rollover */ -	dbg_status (fusbh200, "irq", status); -#endif - -	/* INT, ERR, and IAA interrupt rates can be throttled */ -  	/* normal [4.15.1.2] or error [4.15.1.1] completion */  	if (likely ((status & (STS_INT|STS_ERR)) != 0)) {  		if (likely ((status & STS_ERR) == 0)) @@ -5871,6 +5798,7 @@ static int fusbh200_hcd_probe(struct platform_device *pdev)  		dev_err(dev, "failed to add hcd with err %d\n", retval);  		goto fail_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return retval; @@ -5936,13 +5864,11 @@ static int __init fusbh200_hcd_init(void)  		 sizeof(struct fusbh200_qh), sizeof(struct fusbh200_qtd),  		 sizeof(struct fusbh200_itd)); -#ifdef DEBUG  	fusbh200_debug_root = debugfs_create_dir("fusbh200", usb_debug_root);  	if (!fusbh200_debug_root) {  		retval = -ENOENT;  		goto err_debug;  	} -#endif  	retval = platform_driver_register(&fusbh200_hcd_fusbh200_driver);  	if (retval < 0) @@ -5951,11 +5877,9 @@ static int __init fusbh200_hcd_init(void)  	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver);  clean: -#ifdef DEBUG  	debugfs_remove(fusbh200_debug_root);  	fusbh200_debug_root = NULL;  err_debug: -#endif  	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);  	return retval;  } @@ -5964,9 +5888,7 @@ module_init(fusbh200_hcd_init);  static void __exit fusbh200_hcd_cleanup(void)  {  	platform_driver_unregister(&fusbh200_hcd_fusbh200_driver); -#ifdef DEBUG  	debugfs_remove(fusbh200_debug_root); -#endif  	clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);  }  module_exit(fusbh200_hcd_cleanup); diff --git a/drivers/usb/host/fusbh200.h b/drivers/usb/host/fusbh200.h index 797c9e85527..6b719e066c3 100644 --- a/drivers/usb/host/fusbh200.h +++ b/drivers/usb/host/fusbh200.h @@ -165,17 +165,11 @@ struct fusbh200_hcd {			/* one per controller */  	u8			sbrn;		/* packed release number */  	/* irq statistics */ -#ifdef FUSBH200_STATS  	struct fusbh200_stats	stats;  #	define COUNT(x) do { (x)++; } while (0) -#else -#	define COUNT(x) do {} while (0) -#endif  	/* debug files */ -#ifdef DEBUG  	struct dentry		*debug_dir; -#endif  };  /* convert between an HCD pointer and the corresponding FUSBH200_HCD */ @@ -734,10 +728,4 @@ static inline unsigned fusbh200_read_frame_index(struct fusbh200_hcd *fusbh200)  })  /*-------------------------------------------------------------------------*/ -#ifndef DEBUG -#define STUB_DEBUG_FILES -#endif	/* DEBUG */ - -/*-------------------------------------------------------------------------*/ -  #endif /* __LINUX_FUSBH200_H */ diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 5b86ffb88f1..d0d8fadf706 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -54,7 +54,6 @@   *                      DWA).   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/workqueue.h> @@ -86,7 +85,7 @@ static int __hwahc_set_cluster_id(struct hwahc *hwahc, u8 cluster_id)  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			cluster_id,  			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, -			NULL, 0, 1000 /* FIXME: arbitrary */); +			NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (result < 0)  		dev_err(dev, "Cannot set WUSB Cluster ID to 0x%02x: %d\n",  			cluster_id, result); @@ -106,7 +105,7 @@ static int __hwahc_op_set_num_dnts(struct wusbhc *wusbhc, u8 interval, u8 slots)  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			interval << 8 | slots,  			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, -			NULL, 0, 1000 /* FIXME: arbitrary */); +			NULL, 0, USB_CTRL_SET_TIMEOUT);  }  /* @@ -199,10 +198,14 @@ static int hwahc_op_get_frame_number(struct usb_hcd *usb_hcd)  {  	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);  	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); +	struct wahc *wa = &hwahc->wa; -	dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__, -		usb_hcd, hwahc); -	return -ENOSYS; +	/* +	 * We cannot query the HWA for the WUSB time since that requires sending +	 * a synchronous URB and this function can be called in_interrupt. +	 * Instead, query the USB frame number for our parent and use that. +	 */ +	return usb_get_current_frame_number(wa->usb_dev);  }  static int hwahc_op_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb, @@ -220,7 +223,7 @@ static int hwahc_op_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb,  	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);  	struct hwahc *hwahc = container_of(wusbhc, struct hwahc, wusbhc); -	return wa_urb_dequeue(&hwahc->wa, urb); +	return wa_urb_dequeue(&hwahc->wa, urb, status);  }  /* @@ -258,8 +261,44 @@ static int __hwahc_op_wusbhc_start(struct wusbhc *wusbhc)  		dev_err(dev, "cannot listen to notifications: %d\n", result);  		goto error_stop;  	} +	/* +	 * If WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS is set, +	 *  disable transfer notifications. +	 */ +	if (hwahc->wa.quirks & +		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS) { +		struct usb_host_interface *cur_altsetting = +			hwahc->wa.usb_iface->cur_altsetting; + +		result = usb_control_msg(hwahc->wa.usb_dev, +				usb_sndctrlpipe(hwahc->wa.usb_dev, 0), +				WA_REQ_ALEREON_DISABLE_XFER_NOTIFICATIONS, +				USB_DIR_OUT | USB_TYPE_VENDOR | +					USB_RECIP_INTERFACE, +				WA_REQ_ALEREON_FEATURE_SET, +				cur_altsetting->desc.bInterfaceNumber, +				NULL, 0, +				USB_CTRL_SET_TIMEOUT); +		/* +		 * If we successfully sent the control message, start DTI here +		 * because no transfer notifications will be received which is +		 * where DTI is normally started. +		 */ +		if (result == 0) +			result = wa_dti_start(&hwahc->wa); +		else +			result = 0;	/* OK.  Continue normally. */ + +		if (result < 0) { +			dev_err(dev, "cannot start DTI: %d\n", result); +			goto error_dti_start; +		} +	} +  	return result; +error_dti_start: +	wa_nep_disarm(&hwahc->wa);  error_stop:  	__wa_clear_feature(&hwahc->wa, WA_ENABLE);  	return result; @@ -277,7 +316,7 @@ static void __hwahc_op_wusbhc_stop(struct wusbhc *wusbhc, int delay)  			      USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			      delay * 1000,  			      iface_no, -			      NULL, 0, 1000 /* FIXME: arbitrary */); +			      NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (ret == 0)  		msleep(delay); @@ -306,7 +345,7 @@ static int __hwahc_op_bwa_set(struct wusbhc *wusbhc, s8 stream_index,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			stream_index,  			wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, -			NULL, 0, 1000 /* FIXME: arbitrary */); +			NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (result < 0) {  		dev_err(dev, "Cannot set WUSB stream index: %d\n", result);  		goto out; @@ -317,7 +356,7 @@ static int __hwahc_op_bwa_set(struct wusbhc *wusbhc, s8 stream_index,  			WUSB_REQ_SET_WUSB_MAS,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, -			mas_le, 32, 1000 /* FIXME: arbitrary */); +			mas_le, 32, USB_CTRL_SET_TIMEOUT);  	if (result < 0)  		dev_err(dev, "Cannot set WUSB MAS allocation: %d\n", result);  out: @@ -351,7 +390,7 @@ static int __hwahc_op_mmcie_add(struct wusbhc *wusbhc, u8 interval,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			interval << 8 | repeat_cnt,  			handle << 8 | iface_no, -			wuie, wuie->bLength, 1000 /* FIXME: arbitrary */); +			wuie, wuie->bLength, USB_CTRL_SET_TIMEOUT);  }  /* @@ -368,7 +407,7 @@ static int __hwahc_op_mmcie_rm(struct wusbhc *wusbhc, u8 handle)  			WUSB_REQ_REMOVE_MMC_IE,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			0, handle << 8 | iface_no, -			NULL, 0, 1000 /* FIXME: arbitrary */); +			NULL, 0, USB_CTRL_SET_TIMEOUT);  }  /* @@ -411,7 +450,7 @@ static int __hwahc_op_dev_info_set(struct wusbhc *wusbhc,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			0, wusb_dev->port_idx << 8 | iface_no,  			dev_info, sizeof(struct hwa_dev_info), -			1000 /* FIXME: arbitrary */); +			USB_CTRL_SET_TIMEOUT);  	kfree(dev_info);  	return ret;  } @@ -451,7 +490,7 @@ static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			USB_DT_KEY << 8 | key_idx,  			port_idx << 8 | iface_no, -			keyd, keyd_len, 1000 /* FIXME: arbitrary */); +			keyd, keyd_len, USB_CTRL_SET_TIMEOUT);  	kzfree(keyd); /* clear keys etc. */  	return result; @@ -493,7 +532,7 @@ static int __hwahc_op_set_ptk(struct wusbhc *wusbhc, u8 port_idx, u32 tkid,  			USB_REQ_SET_ENCRYPTION,  			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,  			encryption_value, port_idx << 8 | iface_no, -			NULL, 0, 1000 /* FIXME: arbitrary */); +			NULL, 0, USB_CTRL_SET_TIMEOUT);  	if (result < 0)  		dev_err(wusbhc->dev, "Can't set host's WUSB encryption for "  			"port index %u to %s (value %d): %d\n", port_idx, @@ -566,14 +605,10 @@ found:  		goto error;  	}  	wa->wa_descr = wa_descr = (struct usb_wa_descriptor *) hdr; -	/* Make LE fields CPU order */ -	wa_descr->bcdWAVersion = le16_to_cpu(wa_descr->bcdWAVersion); -	wa_descr->wNumRPipes = le16_to_cpu(wa_descr->wNumRPipes); -	wa_descr->wRPipeMaxBlock = le16_to_cpu(wa_descr->wRPipeMaxBlock); -	if (wa_descr->bcdWAVersion > 0x0100) +	if (le16_to_cpu(wa_descr->bcdWAVersion) > 0x0100)  		dev_warn(dev, "Wire Adapter v%d.%d newer than groked v1.0\n", -			 wa_descr->bcdWAVersion & 0xff00 >> 8, -			 wa_descr->bcdWAVersion & 0x00ff); +			 le16_to_cpu(wa_descr->bcdWAVersion) & 0xff00 >> 8, +			 le16_to_cpu(wa_descr->bcdWAVersion) & 0x00ff);  	result = 0;  error:  	return result; @@ -679,7 +714,8 @@ static void hwahc_security_release(struct hwahc *hwahc)  	/* nothing to do here so far... */  } -static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface) +static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface, +	kernel_ulong_t quirks)  {  	int result;  	struct device *dev = &iface->dev; @@ -724,7 +760,7 @@ static int hwahc_create(struct hwahc *hwahc, struct usb_interface *iface)  		dev_err(dev, "Can't create WUSB HC structures: %d\n", result);  		goto error_wusbhc_create;  	} -	result = wa_create(&hwahc->wa, iface); +	result = wa_create(&hwahc->wa, iface, quirks);  	if (result < 0)  		goto error_wa_create;  	return 0; @@ -780,7 +816,7 @@ static int hwahc_probe(struct usb_interface *usb_iface,  	wusbhc = usb_hcd_to_wusbhc(usb_hcd);  	hwahc = container_of(wusbhc, struct hwahc, wusbhc);  	hwahc_init(hwahc); -	result = hwahc_create(hwahc, usb_iface); +	result = hwahc_create(hwahc, usb_iface, id->driver_info);  	if (result < 0) {  		dev_err(dev, "Cannot initialize internals: %d\n", result);  		goto error_hwahc_create; @@ -790,6 +826,7 @@ static int hwahc_probe(struct usb_interface *usb_iface,  		dev_err(dev, "Cannot add HCD: %d\n", result);  		goto error_add_hcd;  	} +	device_wakeup_enable(usb_hcd->self.controller);  	result = wusbhc_b_create(&hwahc->wusbhc);  	if (result < 0) {  		dev_err(dev, "Cannot setup phase B of WUSBHC: %d\n", result); @@ -824,6 +861,14 @@ static void hwahc_disconnect(struct usb_interface *usb_iface)  }  static struct usb_device_id hwahc_id_table[] = { +	/* Alereon 5310 */ +	{ USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5310, 0xe0, 0x02, 0x01), +	  .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | +		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS }, +	/* Alereon 5611 */ +	{ USB_DEVICE_AND_INTERFACE_INFO(0x13dc, 0x5611, 0xe0, 0x02, 0x01), +	  .driver_info = WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC | +		WUSB_QUIRK_ALEREON_HWA_DISABLE_XFER_NOTIFICATIONS },  	/* FIXME: use class labels for this */  	{ USB_INTERFACE_INFO(0xe0, 0x02, 0x01), },  	{}, diff --git a/drivers/usb/host/imx21-dbg.c b/drivers/usb/host/imx21-dbg.c index ec98ecee351..4f320d050da 100644 --- a/drivers/usb/host/imx21-dbg.c +++ b/drivers/usb/host/imx21-dbg.c @@ -18,6 +18,10 @@  /* this file is part of imx21-hcd.c */ +#ifdef CONFIG_DYNAMIC_DEBUG +#define DEBUG +#endif +  #ifndef DEBUG  static inline void create_debug_files(struct imx21 *imx21) { } diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index 60a5de505ca..207bad99301 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -62,6 +62,10 @@  #include "imx21-hcd.h" +#ifdef CONFIG_DYNAMIC_DEBUG +#define DEBUG +#endif +  #ifdef DEBUG  #define DEBUG_LOG_FRAME(imx21, etd, event) \  	(etd)->event##_frame = readl((imx21)->regs + USBH_FRMNUB) @@ -824,13 +828,13 @@ static int imx21_hc_urb_enqueue_isoc(struct usb_hcd *hcd,  			i = DIV_ROUND_UP(wrap_frame(  					cur_frame - urb->start_frame),  					urb->interval); -			if (urb->transfer_flags & URB_ISO_ASAP) { + +			/* Treat underruns as if URB_ISO_ASAP was set */ +			if ((urb->transfer_flags & URB_ISO_ASAP) || +					i >= urb->number_of_packets) {  				urb->start_frame = wrap_frame(urb->start_frame  						+ i * urb->interval);  				i = 0; -			} else if (i >= urb->number_of_packets) { -				ret = -EXDEV; -				goto alloc_dmem_failed;  			}  		}  	} @@ -1906,6 +1910,7 @@ static int imx21_probe(struct platform_device *pdev)  		dev_err(imx21->dev, "usb_add_hcd() returned %d\n", ret);  		goto failed_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return 0; @@ -1926,7 +1931,7 @@ failed_request_mem:  static struct platform_driver imx21_hcd_driver = {  	.driver = { -		   .name = (char *)hcd_name, +		   .name = hcd_name,  		   },  	.probe = imx21_probe,  	.remove = imx21_remove, diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h index c005770a73e..05122f8a698 100644 --- a/drivers/usb/host/imx21-hcd.h +++ b/drivers/usb/host/imx21-hcd.h @@ -24,6 +24,10 @@  #ifndef __LINUX_IMX21_HCD_H__  #define __LINUX_IMX21_HCD_H__ +#ifdef CONFIG_DYNAMIC_DEBUG +#define DEBUG +#endif +  #include <linux/platform_data/usb-mx2.h>  #define NUM_ISO_ETDS 	2 diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index c7d0f8f231b..240e792c81a 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -60,7 +60,6 @@  #include <linux/debugfs.h>  #include <linux/seq_file.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/list.h>  #include <linux/slab.h>  #include <linux/usb.h> @@ -1645,6 +1644,8 @@ static int isp116x_probe(struct platform_device *pdev)  	if (ret)  		goto err6; +	device_wakeup_enable(hcd->self.controller); +  	ret = create_debug_file(isp116x);  	if (ret) {  		ERR("Couldn't create debugfs entry\n"); @@ -1705,7 +1706,7 @@ static struct platform_driver isp116x_driver = {  	.suspend = isp116x_suspend,  	.resume = isp116x_resume,  	.driver = { -		.name = (char *)hcd_name, +		.name = hcd_name,  		.owner	= THIS_MODULE,  	},  }; diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 6f29abad681..875bcfd3ec1 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c @@ -67,7 +67,6 @@  #include <linux/sched.h>  #include <linux/slab.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/list.h>  #include <linux/interrupt.h>  #include <linux/usb.h> @@ -2108,7 +2107,7 @@ static int isp1362_show(struct seq_file *s, void *unused)  				   default:  					   s = "?";  					   break; -				   }; +				   }  				   s;}), ep->maxpacket) ;  		list_for_each_entry(urb, &ep->hep->urb_list, urb_list) {  			seq_printf(s, "  urb%p, %d/%d\n", urb, @@ -2746,6 +2745,8 @@ static int isp1362_probe(struct platform_device *pdev)  	retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_SHARED);  	if (retval != 0)  		goto err6; +	device_wakeup_enable(hcd->self.controller); +  	pr_info("%s, irq %d\n", hcd->product_desc, irq);  	create_debug_file(isp1362_hcd); @@ -2829,7 +2830,7 @@ static struct platform_driver isp1362_driver = {  	.suspend = isp1362_suspend,  	.resume = isp1362_resume,  	.driver = { -		.name = (char *)hcd_name, +		.name = hcd_name,  		.owner = THIS_MODULE,  	},  }; diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index 2facee53eab..51a0ae9cdd1 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c @@ -2250,6 +2250,7 @@ struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len,  	ret = usb_add_hcd(hcd, irq, irqflags);  	if (ret)  		goto err_unmap; +	device_wakeup_enable(hcd->self.controller);  	return hcd; diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c new file mode 100644 index 00000000000..858efcfda50 --- /dev/null +++ b/drivers/usb/host/max3421-hcd.c @@ -0,0 +1,1957 @@ +/* + * MAX3421 Host Controller driver for USB. + * + * Author: David Mosberger-Tang <davidm@egauge.net> + * + * (C) Copyright 2014 David Mosberger-Tang <davidm@egauge.net> + * + * MAX3421 is a chip implementing a USB 2.0 Full-/Low-Speed host + * controller on a SPI bus. + * + * Based on: + *	o MAX3421E datasheet + *		http://datasheets.maximintegrated.com/en/ds/MAX3421E.pdf + *	o MAX3421E Programming Guide + *		http://www.hdl.co.jp/ftpdata/utl-001/AN3785.pdf + *	o gadget/dummy_hcd.c + *		For USB HCD implementation. + *	o Arduino MAX3421 driver + *	     https://github.com/felis/USB_Host_Shield_2.0/blob/master/Usb.cpp + * + * This file is licenced under the GPL v2. + * + * Important note on worst-case (full-speed) packet size constraints + * (See USB 2.0 Section 5.6.3 and following): + * + *	- control:	  64 bytes + *	- isochronous:	1023 bytes + *	- interrupt:	  64 bytes + *	- bulk:		  64 bytes + * + * Since the MAX3421 FIFO size is 64 bytes, we do not have to work about + * multi-FIFO writes/reads for a single USB packet *except* for isochronous + * transfers.  We don't support isochronous transfers at this time, so we + * just assume that a USB packet always fits into a single FIFO buffer. + * + * NOTE: The June 2006 version of "MAX3421E Programming Guide" + * (AN3785) has conflicting info for the RCVDAVIRQ bit: + * + *	The description of RCVDAVIRQ says "The CPU *must* clear + *	this IRQ bit (by writing a 1 to it) before reading the + *	RCVFIFO data. + * + * However, the earlier section on "Programming BULK-IN + * Transfers" says * that: + * + *	After the CPU retrieves the data, it clears the + *	RCVDAVIRQ bit. + * + * The December 2006 version has been corrected and it consistently + * states the second behavior is the correct one. + * + * Synchronous SPI transactions sleep so we can't perform any such + * transactions while holding a spin-lock (and/or while interrupts are + * masked).  To achieve this, all SPI transactions are issued from a + * single thread (max3421_spi_thread). + */ + +#include <linux/module.h> +#include <linux/spi/spi.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include <linux/platform_data/max3421-hcd.h> + +#define DRIVER_DESC	"MAX3421 USB Host-Controller Driver" +#define DRIVER_VERSION	"1.0" + +/* 11-bit counter that wraps around (USB 2.0 Section 8.3.3): */ +#define USB_MAX_FRAME_NUMBER	0x7ff +#define USB_MAX_RETRIES		3 /* # of retries before error is reported */ + +/* + * Max. # of times we're willing to retransmit a request immediately in + * resposne to a NAK.  Afterwards, we fall back on trying once a frame. + */ +#define NAK_MAX_FAST_RETRANSMITS	2 + +#define POWER_BUDGET	500	/* in mA; use 8 for low-power port testing */ + +/* Port-change mask: */ +#define PORT_C_MASK	((USB_PORT_STAT_C_CONNECTION |	\ +			  USB_PORT_STAT_C_ENABLE |	\ +			  USB_PORT_STAT_C_SUSPEND |	\ +			  USB_PORT_STAT_C_OVERCURRENT | \ +			  USB_PORT_STAT_C_RESET) << 16) + +enum max3421_rh_state { +	MAX3421_RH_RESET, +	MAX3421_RH_SUSPENDED, +	MAX3421_RH_RUNNING +}; + +enum pkt_state { +	PKT_STATE_SETUP,	/* waiting to send setup packet to ctrl pipe */ +	PKT_STATE_TRANSFER,	/* waiting to xfer transfer_buffer */ +	PKT_STATE_TERMINATE	/* waiting to terminate control transfer */ +}; + +enum scheduling_pass { +	SCHED_PASS_PERIODIC, +	SCHED_PASS_NON_PERIODIC, +	SCHED_PASS_DONE +}; + +struct max3421_dma_buf { +	u8 data[2]; +}; + +struct max3421_hcd { +	spinlock_t lock; + +	struct task_struct *spi_thread; + +	struct max3421_hcd *next; + +	enum max3421_rh_state rh_state; +	/* lower 16 bits contain port status, upper 16 bits the change mask: */ +	u32 port_status; + +	unsigned active:1; + +	struct list_head ep_list;	/* list of EP's with work */ + +	/* +	 * The following are owned by spi_thread (may be accessed by +	 * SPI-thread without acquiring the HCD lock: +	 */ +	u8 rev;				/* chip revision */ +	u16 frame_number; +	/* +	 * kmalloc'd buffers guaranteed to be in separate (DMA) +	 * cache-lines: +	 */ +	struct max3421_dma_buf *tx; +	struct max3421_dma_buf *rx; +	/* +	 * URB we're currently processing.  Must not be reset to NULL +	 * unless MAX3421E chip is idle: +	 */ +	struct urb *curr_urb; +	enum scheduling_pass sched_pass; +	struct usb_device *loaded_dev;	/* dev that's loaded into the chip */ +	int loaded_epnum;		/* epnum whose toggles are loaded */ +	int urb_done;			/* > 0 -> no errors, < 0: errno */ +	size_t curr_len; +	u8 hien; +	u8 mode; +	u8 iopins[2]; +	unsigned int do_enable_irq:1; +	unsigned int do_reset_hcd:1; +	unsigned int do_reset_port:1; +	unsigned int do_check_unlink:1; +	unsigned int do_iopin_update:1; +#ifdef DEBUG +	unsigned long err_stat[16]; +#endif +}; + +struct max3421_ep { +	struct usb_host_endpoint *ep; +	struct list_head ep_list; +	u32 naks; +	u16 last_active;		/* frame # this ep was last active */ +	enum pkt_state pkt_state; +	u8 retries; +	u8 retransmit;			/* packet needs retransmission */ +}; + +static struct max3421_hcd *max3421_hcd_list; + +#define MAX3421_FIFO_SIZE	64 + +#define MAX3421_SPI_DIR_RD	0	/* read register from MAX3421 */ +#define MAX3421_SPI_DIR_WR	1	/* write register to MAX3421 */ + +/* SPI commands: */ +#define MAX3421_SPI_DIR_SHIFT	1 +#define MAX3421_SPI_REG_SHIFT	3 + +#define MAX3421_REG_RCVFIFO	1 +#define MAX3421_REG_SNDFIFO	2 +#define MAX3421_REG_SUDFIFO	4 +#define MAX3421_REG_RCVBC	6 +#define MAX3421_REG_SNDBC	7 +#define MAX3421_REG_USBIRQ	13 +#define MAX3421_REG_USBIEN	14 +#define MAX3421_REG_USBCTL	15 +#define MAX3421_REG_CPUCTL	16 +#define MAX3421_REG_PINCTL	17 +#define MAX3421_REG_REVISION	18 +#define MAX3421_REG_IOPINS1	20 +#define MAX3421_REG_IOPINS2	21 +#define MAX3421_REG_GPINIRQ	22 +#define MAX3421_REG_GPINIEN	23 +#define MAX3421_REG_GPINPOL	24 +#define MAX3421_REG_HIRQ	25 +#define MAX3421_REG_HIEN	26 +#define MAX3421_REG_MODE	27 +#define MAX3421_REG_PERADDR	28 +#define MAX3421_REG_HCTL	29 +#define MAX3421_REG_HXFR	30 +#define MAX3421_REG_HRSL	31 + +enum { +	MAX3421_USBIRQ_OSCOKIRQ_BIT = 0, +	MAX3421_USBIRQ_NOVBUSIRQ_BIT = 5, +	MAX3421_USBIRQ_VBUSIRQ_BIT +}; + +enum { +	MAX3421_CPUCTL_IE_BIT = 0, +	MAX3421_CPUCTL_PULSEWID0_BIT = 6, +	MAX3421_CPUCTL_PULSEWID1_BIT +}; + +enum { +	MAX3421_USBCTL_PWRDOWN_BIT = 4, +	MAX3421_USBCTL_CHIPRES_BIT +}; + +enum { +	MAX3421_PINCTL_GPXA_BIT	= 0, +	MAX3421_PINCTL_GPXB_BIT, +	MAX3421_PINCTL_POSINT_BIT, +	MAX3421_PINCTL_INTLEVEL_BIT, +	MAX3421_PINCTL_FDUPSPI_BIT, +	MAX3421_PINCTL_EP0INAK_BIT, +	MAX3421_PINCTL_EP2INAK_BIT, +	MAX3421_PINCTL_EP3INAK_BIT, +}; + +enum { +	MAX3421_HI_BUSEVENT_BIT = 0,	/* bus-reset/-resume */ +	MAX3421_HI_RWU_BIT,		/* remote wakeup */ +	MAX3421_HI_RCVDAV_BIT,		/* receive FIFO data available */ +	MAX3421_HI_SNDBAV_BIT,		/* send buffer available */ +	MAX3421_HI_SUSDN_BIT,		/* suspend operation done */ +	MAX3421_HI_CONDET_BIT,		/* peripheral connect/disconnect */ +	MAX3421_HI_FRAME_BIT,		/* frame generator */ +	MAX3421_HI_HXFRDN_BIT,		/* host transfer done */ +}; + +enum { +	MAX3421_HCTL_BUSRST_BIT = 0, +	MAX3421_HCTL_FRMRST_BIT, +	MAX3421_HCTL_SAMPLEBUS_BIT, +	MAX3421_HCTL_SIGRSM_BIT, +	MAX3421_HCTL_RCVTOG0_BIT, +	MAX3421_HCTL_RCVTOG1_BIT, +	MAX3421_HCTL_SNDTOG0_BIT, +	MAX3421_HCTL_SNDTOG1_BIT +}; + +enum { +	MAX3421_MODE_HOST_BIT = 0, +	MAX3421_MODE_LOWSPEED_BIT, +	MAX3421_MODE_HUBPRE_BIT, +	MAX3421_MODE_SOFKAENAB_BIT, +	MAX3421_MODE_SEPIRQ_BIT, +	MAX3421_MODE_DELAYISO_BIT, +	MAX3421_MODE_DMPULLDN_BIT, +	MAX3421_MODE_DPPULLDN_BIT +}; + +enum { +	MAX3421_HRSL_OK = 0, +	MAX3421_HRSL_BUSY, +	MAX3421_HRSL_BADREQ, +	MAX3421_HRSL_UNDEF, +	MAX3421_HRSL_NAK, +	MAX3421_HRSL_STALL, +	MAX3421_HRSL_TOGERR, +	MAX3421_HRSL_WRONGPID, +	MAX3421_HRSL_BADBC, +	MAX3421_HRSL_PIDERR, +	MAX3421_HRSL_PKTERR, +	MAX3421_HRSL_CRCERR, +	MAX3421_HRSL_KERR, +	MAX3421_HRSL_JERR, +	MAX3421_HRSL_TIMEOUT, +	MAX3421_HRSL_BABBLE, +	MAX3421_HRSL_RESULT_MASK = 0xf, +	MAX3421_HRSL_RCVTOGRD_BIT = 4, +	MAX3421_HRSL_SNDTOGRD_BIT, +	MAX3421_HRSL_KSTATUS_BIT, +	MAX3421_HRSL_JSTATUS_BIT +}; + +/* Return same error-codes as ohci.h:cc_to_error: */ +static const int hrsl_to_error[] = { +	[MAX3421_HRSL_OK] =		0, +	[MAX3421_HRSL_BUSY] =		-EINVAL, +	[MAX3421_HRSL_BADREQ] =		-EINVAL, +	[MAX3421_HRSL_UNDEF] =		-EINVAL, +	[MAX3421_HRSL_NAK] =		-EAGAIN, +	[MAX3421_HRSL_STALL] =		-EPIPE, +	[MAX3421_HRSL_TOGERR] =		-EILSEQ, +	[MAX3421_HRSL_WRONGPID] =	-EPROTO, +	[MAX3421_HRSL_BADBC] =		-EREMOTEIO, +	[MAX3421_HRSL_PIDERR] =		-EPROTO, +	[MAX3421_HRSL_PKTERR] =		-EPROTO, +	[MAX3421_HRSL_CRCERR] =		-EILSEQ, +	[MAX3421_HRSL_KERR] =		-EIO, +	[MAX3421_HRSL_JERR] =		-EIO, +	[MAX3421_HRSL_TIMEOUT] =	-ETIME, +	[MAX3421_HRSL_BABBLE] =		-EOVERFLOW +}; + +/* + * See http://www.beyondlogic.org/usbnutshell/usb4.shtml#Control for a + * reasonable overview of how control transfers use the the IN/OUT + * tokens. + */ +#define MAX3421_HXFR_BULK_IN(ep)	(0x00 | (ep))	/* bulk or interrupt */ +#define MAX3421_HXFR_SETUP		 0x10 +#define MAX3421_HXFR_BULK_OUT(ep)	(0x20 | (ep))	/* bulk or interrupt */ +#define MAX3421_HXFR_ISO_IN(ep)		(0x40 | (ep)) +#define MAX3421_HXFR_ISO_OUT(ep)	(0x60 | (ep)) +#define MAX3421_HXFR_HS_IN		 0x80		/* handshake in */ +#define MAX3421_HXFR_HS_OUT		 0xa0		/* handshake out */ + +#define field(val, bit)	((val) << (bit)) + +static inline s16 +frame_diff(u16 left, u16 right) +{ +	return ((unsigned) (left - right)) % (USB_MAX_FRAME_NUMBER + 1); +} + +static inline struct max3421_hcd * +hcd_to_max3421(struct usb_hcd *hcd) +{ +	return (struct max3421_hcd *) hcd->hcd_priv; +} + +static inline struct usb_hcd * +max3421_to_hcd(struct max3421_hcd *max3421_hcd) +{ +	return container_of((void *) max3421_hcd, struct usb_hcd, hcd_priv); +} + +static u8 +spi_rd8(struct usb_hcd *hcd, unsigned int reg) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct spi_transfer transfer; +	struct spi_message msg; + +	memset(&transfer, 0, sizeof(transfer)); + +	spi_message_init(&msg); + +	max3421_hcd->tx->data[0] = +		(field(reg, MAX3421_SPI_REG_SHIFT) | +		 field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); + +	transfer.tx_buf = max3421_hcd->tx->data; +	transfer.rx_buf = max3421_hcd->rx->data; +	transfer.len = 2; + +	spi_message_add_tail(&transfer, &msg); +	spi_sync(spi, &msg); + +	return max3421_hcd->rx->data[1]; +} + +static void +spi_wr8(struct usb_hcd *hcd, unsigned int reg, u8 val) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct spi_transfer transfer; +	struct spi_message msg; + +	memset(&transfer, 0, sizeof(transfer)); + +	spi_message_init(&msg); + +	max3421_hcd->tx->data[0] = +		(field(reg, MAX3421_SPI_REG_SHIFT) | +		 field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); +	max3421_hcd->tx->data[1] = val; + +	transfer.tx_buf = max3421_hcd->tx->data; +	transfer.len = 2; + +	spi_message_add_tail(&transfer, &msg); +	spi_sync(spi, &msg); +} + +static void +spi_rd_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct spi_transfer transfer[2]; +	struct spi_message msg; + +	memset(transfer, 0, sizeof(transfer)); + +	spi_message_init(&msg); + +	max3421_hcd->tx->data[0] = +		(field(reg, MAX3421_SPI_REG_SHIFT) | +		 field(MAX3421_SPI_DIR_RD, MAX3421_SPI_DIR_SHIFT)); +	transfer[0].tx_buf = max3421_hcd->tx->data; +	transfer[0].len = 1; + +	transfer[1].rx_buf = buf; +	transfer[1].len = len; + +	spi_message_add_tail(&transfer[0], &msg); +	spi_message_add_tail(&transfer[1], &msg); +	spi_sync(spi, &msg); +} + +static void +spi_wr_buf(struct usb_hcd *hcd, unsigned int reg, void *buf, size_t len) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct spi_transfer transfer[2]; +	struct spi_message msg; + +	memset(transfer, 0, sizeof(transfer)); + +	spi_message_init(&msg); + +	max3421_hcd->tx->data[0] = +		(field(reg, MAX3421_SPI_REG_SHIFT) | +		 field(MAX3421_SPI_DIR_WR, MAX3421_SPI_DIR_SHIFT)); + +	transfer[0].tx_buf = max3421_hcd->tx->data; +	transfer[0].len = 1; + +	transfer[1].tx_buf = buf; +	transfer[1].len = len; + +	spi_message_add_tail(&transfer[0], &msg); +	spi_message_add_tail(&transfer[1], &msg); +	spi_sync(spi, &msg); +} + +/* + * Figure out the correct setting for the LOWSPEED and HUBPRE mode + * bits.  The HUBPRE bit needs to be set when MAX3421E operates at + * full speed, but it's talking to a low-speed device (i.e., through a + * hub).  Setting that bit ensures that every low-speed packet is + * preceded by a full-speed PRE PID.  Possible configurations: + * + * Hub speed:	Device speed:	=>	LOWSPEED bit:	HUBPRE bit: + *	FULL	FULL		=>	0		0 + *	FULL	LOW		=>	1		1 + *	LOW	LOW		=>	1		0 + *	LOW	FULL		=>	1		0 + */ +static void +max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	u8 mode_lowspeed, mode_hubpre, mode = max3421_hcd->mode; + +	mode_lowspeed = BIT(MAX3421_MODE_LOWSPEED_BIT); +	mode_hubpre   = BIT(MAX3421_MODE_HUBPRE_BIT); +	if (max3421_hcd->port_status & USB_PORT_STAT_LOW_SPEED) { +		mode |=  mode_lowspeed; +		mode &= ~mode_hubpre; +	} else if (dev->speed == USB_SPEED_LOW) { +		mode |= mode_lowspeed | mode_hubpre; +	} else { +		mode &= ~(mode_lowspeed | mode_hubpre); +	} +	if (mode != max3421_hcd->mode) { +		max3421_hcd->mode = mode; +		spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); +	} + +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, +		    int force_toggles) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	int old_epnum, same_ep, rcvtog, sndtog; +	struct usb_device *old_dev; +	u8 hctl; + +	old_dev = max3421_hcd->loaded_dev; +	old_epnum = max3421_hcd->loaded_epnum; + +	same_ep = (dev == old_dev && epnum == old_epnum); +	if (same_ep && !force_toggles) +		return; + +	if (old_dev && !same_ep) { +		/* save the old end-points toggles: */ +		u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); + +		rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; +		sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; + +		/* no locking: HCD (i.e., we) own toggles, don't we? */ +		usb_settoggle(old_dev, old_epnum, 0, rcvtog); +		usb_settoggle(old_dev, old_epnum, 1, sndtog); +	} +	/* setup new endpoint's toggle bits: */ +	rcvtog = usb_gettoggle(dev, epnum, 0); +	sndtog = usb_gettoggle(dev, epnum, 1); +	hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | +		BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); + +	max3421_hcd->loaded_epnum = epnum; +	spi_wr8(hcd, MAX3421_REG_HCTL, hctl); + +	/* +	 * Note: devnum for one and the same device can change during +	 * address-assignment so it's best to just always load the +	 * address whenever the end-point changed/was forced. +	 */ +	max3421_hcd->loaded_dev = dev; +	spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum); +} + +static int +max3421_ctrl_setup(struct usb_hcd *hcd, struct urb *urb) +{ +	spi_wr_buf(hcd, MAX3421_REG_SUDFIFO, urb->setup_packet, 8); +	return MAX3421_HXFR_SETUP; +} + +static int +max3421_transfer_in(struct usb_hcd *hcd, struct urb *urb) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	int epnum = usb_pipeendpoint(urb->pipe); + +	max3421_hcd->curr_len = 0; +	max3421_hcd->hien |= BIT(MAX3421_HI_RCVDAV_BIT); +	return MAX3421_HXFR_BULK_IN(epnum); +} + +static int +max3421_transfer_out(struct usb_hcd *hcd, struct urb *urb, int fast_retransmit) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	int epnum = usb_pipeendpoint(urb->pipe); +	u32 max_packet; +	void *src; + +	src = urb->transfer_buffer + urb->actual_length; + +	if (fast_retransmit) { +		if (max3421_hcd->rev == 0x12) { +			/* work around rev 0x12 bug: */ +			spi_wr8(hcd, MAX3421_REG_SNDBC, 0); +			spi_wr8(hcd, MAX3421_REG_SNDFIFO, ((u8 *) src)[0]); +			spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len); +		} +		return MAX3421_HXFR_BULK_OUT(epnum); +	} + +	max_packet = usb_maxpacket(urb->dev, urb->pipe, 1); + +	if (max_packet > MAX3421_FIFO_SIZE) { +		/* +		 * We do not support isochronous transfers at this +		 * time. +		 */ +		dev_err(&spi->dev, +			"%s: packet-size of %u too big (limit is %u bytes)", +			__func__, max_packet, MAX3421_FIFO_SIZE); +		max3421_hcd->urb_done = -EMSGSIZE; +		return -EMSGSIZE; +	} +	max3421_hcd->curr_len = min((urb->transfer_buffer_length - +				     urb->actual_length), max_packet); + +	spi_wr_buf(hcd, MAX3421_REG_SNDFIFO, src, max3421_hcd->curr_len); +	spi_wr8(hcd, MAX3421_REG_SNDBC, max3421_hcd->curr_len); +	return MAX3421_HXFR_BULK_OUT(epnum); +} + +/* + * Issue the next host-transfer command. + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_next_transfer(struct usb_hcd *hcd, int fast_retransmit) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct urb *urb = max3421_hcd->curr_urb; +	struct max3421_ep *max3421_ep; +	int cmd = -EINVAL; + +	if (!urb) +		return;	/* nothing to do */ + +	max3421_ep = urb->ep->hcpriv; + +	switch (max3421_ep->pkt_state) { +	case PKT_STATE_SETUP: +		cmd = max3421_ctrl_setup(hcd, urb); +		break; + +	case PKT_STATE_TRANSFER: +		if (usb_urb_dir_in(urb)) +			cmd = max3421_transfer_in(hcd, urb); +		else +			cmd = max3421_transfer_out(hcd, urb, fast_retransmit); +		break; + +	case PKT_STATE_TERMINATE: +		/* +		 * IN transfers are terminated with HS_OUT token, +		 * OUT transfers with HS_IN: +		 */ +		if (usb_urb_dir_in(urb)) +			cmd = MAX3421_HXFR_HS_OUT; +		else +			cmd = MAX3421_HXFR_HS_IN; +		break; +	} + +	if (cmd < 0) +		return; + +	/* issue the command and wait for host-xfer-done interrupt: */ + +	spi_wr8(hcd, MAX3421_REG_HXFR, cmd); +	max3421_hcd->hien |= BIT(MAX3421_HI_HXFRDN_BIT); +} + +/* + * Find the next URB to process and start its execution. + * + * At this time, we do not anticipate ever connecting a USB hub to the + * MAX3421 chip, so at most USB device can be connected and we can use + * a simplistic scheduler: at the start of a frame, schedule all + * periodic transfers.  Once that is done, use the remainder of the + * frame to process non-periodic (bulk & control) transfers. + * + * Preconditions: + * o Caller must NOT hold HCD spinlock. + * o max3421_hcd->curr_urb MUST BE NULL. + * o MAX3421E chip must be idle. + */ +static int +max3421_select_and_start_urb(struct usb_hcd *hcd) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct urb *urb, *curr_urb = NULL; +	struct max3421_ep *max3421_ep; +	int epnum, force_toggles = 0; +	struct usb_host_endpoint *ep; +	struct list_head *pos; +	unsigned long flags; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	for (; +	     max3421_hcd->sched_pass < SCHED_PASS_DONE; +	     ++max3421_hcd->sched_pass) +		list_for_each(pos, &max3421_hcd->ep_list) { +			urb = NULL; +			max3421_ep = container_of(pos, struct max3421_ep, +						  ep_list); +			ep = max3421_ep->ep; + +			switch (usb_endpoint_type(&ep->desc)) { +			case USB_ENDPOINT_XFER_ISOC: +			case USB_ENDPOINT_XFER_INT: +				if (max3421_hcd->sched_pass != +				    SCHED_PASS_PERIODIC) +					continue; +				break; + +			case USB_ENDPOINT_XFER_CONTROL: +			case USB_ENDPOINT_XFER_BULK: +				if (max3421_hcd->sched_pass != +				    SCHED_PASS_NON_PERIODIC) +					continue; +				break; +			} + +			if (list_empty(&ep->urb_list)) +				continue;	/* nothing to do */ +			urb = list_first_entry(&ep->urb_list, struct urb, +					       urb_list); +			if (urb->unlinked) { +				dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", +					__func__, urb, urb->unlinked); +				max3421_hcd->curr_urb = urb; +				max3421_hcd->urb_done = 1; +				spin_unlock_irqrestore(&max3421_hcd->lock, +						       flags); +				return 1; +			} + +			switch (usb_endpoint_type(&ep->desc)) { +			case USB_ENDPOINT_XFER_CONTROL: +				/* +				 * Allow one control transaction per +				 * frame per endpoint: +				 */ +				if (frame_diff(max3421_ep->last_active, +					       max3421_hcd->frame_number) == 0) +					continue; +				break; + +			case USB_ENDPOINT_XFER_BULK: +				if (max3421_ep->retransmit +				    && (frame_diff(max3421_ep->last_active, +						   max3421_hcd->frame_number) +					== 0)) +					/* +					 * We already tried this EP +					 * during this frame and got a +					 * NAK or error; wait for next frame +					 */ +					continue; +				break; + +			case USB_ENDPOINT_XFER_ISOC: +			case USB_ENDPOINT_XFER_INT: +				if (frame_diff(max3421_hcd->frame_number, +					       max3421_ep->last_active) +				    < urb->interval) +					/* +					 * We already processed this +					 * end-point in the current +					 * frame +					 */ +					continue; +				break; +			} + +			/* move current ep to tail: */ +			list_move_tail(pos, &max3421_hcd->ep_list); +			curr_urb = urb; +			goto done; +		} +done: +	if (!curr_urb) { +		spin_unlock_irqrestore(&max3421_hcd->lock, flags); +		return 0; +	} + +	urb = max3421_hcd->curr_urb = curr_urb; +	epnum = usb_endpoint_num(&urb->ep->desc); +	if (max3421_ep->retransmit) +		/* restart (part of) a USB transaction: */ +		max3421_ep->retransmit = 0; +	else { +		/* start USB transaction: */ +		if (usb_endpoint_xfer_control(&ep->desc)) { +			/* +			 * See USB 2.0 spec section 8.6.1 +			 * Initialization via SETUP Token: +			 */ +			usb_settoggle(urb->dev, epnum, 0, 1); +			usb_settoggle(urb->dev, epnum, 1, 1); +			max3421_ep->pkt_state = PKT_STATE_SETUP; +			force_toggles = 1; +		} else +			max3421_ep->pkt_state = PKT_STATE_TRANSFER; +	} + +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); + +	max3421_ep->last_active = max3421_hcd->frame_number; +	max3421_set_address(hcd, urb->dev, epnum, force_toggles); +	max3421_set_speed(hcd, urb->dev); +	max3421_next_transfer(hcd, 0); +	return 1; +} + +/* + * Check all endpoints for URBs that got unlinked. + * + * Caller must NOT hold HCD spinlock. + */ +static int +max3421_check_unlink(struct usb_hcd *hcd) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct list_head *pos, *upos, *next_upos; +	struct max3421_ep *max3421_ep; +	struct usb_host_endpoint *ep; +	struct urb *urb; +	unsigned long flags; +	int retval = 0; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); +	list_for_each(pos, &max3421_hcd->ep_list) { +		max3421_ep = container_of(pos, struct max3421_ep, ep_list); +		ep = max3421_ep->ep; +		list_for_each_safe(upos, next_upos, &ep->urb_list) { +			urb = container_of(upos, struct urb, urb_list); +			if (urb->unlinked) { +				retval = 1; +				dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", +					__func__, urb, urb->unlinked); +				usb_hcd_unlink_urb_from_ep(hcd, urb); +				spin_unlock_irqrestore(&max3421_hcd->lock, +						       flags); +				usb_hcd_giveback_urb(hcd, urb, 0); +				spin_lock_irqsave(&max3421_hcd->lock, flags); +			} +		} +	} +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +	return retval; +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_slow_retransmit(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct urb *urb = max3421_hcd->curr_urb; +	struct max3421_ep *max3421_ep; + +	max3421_ep = urb->ep->hcpriv; +	max3421_ep->retransmit = 1; +	max3421_hcd->curr_urb = NULL; +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_recv_data_available(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct urb *urb = max3421_hcd->curr_urb; +	size_t remaining, transfer_size; +	u8 rcvbc; + +	rcvbc = spi_rd8(hcd, MAX3421_REG_RCVBC); + +	if (rcvbc > MAX3421_FIFO_SIZE) +		rcvbc = MAX3421_FIFO_SIZE; +	if (urb->actual_length >= urb->transfer_buffer_length) +		remaining = 0; +	else +		remaining = urb->transfer_buffer_length - urb->actual_length; +	transfer_size = rcvbc; +	if (transfer_size > remaining) +		transfer_size = remaining; +	if (transfer_size > 0) { +		void *dst = urb->transfer_buffer + urb->actual_length; + +		spi_rd_buf(hcd, MAX3421_REG_RCVFIFO, dst, transfer_size); +		urb->actual_length += transfer_size; +		max3421_hcd->curr_len = transfer_size; +	} + +	/* ack the RCVDAV irq now that the FIFO has been read: */ +	spi_wr8(hcd, MAX3421_REG_HIRQ, BIT(MAX3421_HI_RCVDAV_BIT)); +} + +static void +max3421_handle_error(struct usb_hcd *hcd, u8 hrsl) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	u8 result_code = hrsl & MAX3421_HRSL_RESULT_MASK; +	struct urb *urb = max3421_hcd->curr_urb; +	struct max3421_ep *max3421_ep = urb->ep->hcpriv; +	int switch_sndfifo; + +	/* +	 * If an OUT command results in any response other than OK +	 * (i.e., error or NAK), we have to perform a dummy-write to +	 * SNDBC so the FIFO gets switched back to us.  Otherwise, we +	 * get out of sync with the SNDFIFO double buffer. +	 */ +	switch_sndfifo = (max3421_ep->pkt_state == PKT_STATE_TRANSFER && +			  usb_urb_dir_out(urb)); + +	switch (result_code) { +	case MAX3421_HRSL_OK: +		return;			/* this shouldn't happen */ + +	case MAX3421_HRSL_WRONGPID:	/* received wrong PID */ +	case MAX3421_HRSL_BUSY:		/* SIE busy */ +	case MAX3421_HRSL_BADREQ:	/* bad val in HXFR */ +	case MAX3421_HRSL_UNDEF:	/* reserved */ +	case MAX3421_HRSL_KERR:		/* K-state instead of response */ +	case MAX3421_HRSL_JERR:		/* J-state instead of response */ +		/* +		 * packet experienced an error that we cannot recover +		 * from; report error +		 */ +		max3421_hcd->urb_done = hrsl_to_error[result_code]; +		dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", +			__func__, hrsl); +		break; + +	case MAX3421_HRSL_TOGERR: +		if (usb_urb_dir_in(urb)) +			; /* don't do anything (device will switch toggle) */ +		else { +			/* flip the send toggle bit: */ +			int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; + +			sndtog ^= 1; +			spi_wr8(hcd, MAX3421_REG_HCTL, +				BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); +		} +		/* FALL THROUGH */ +	case MAX3421_HRSL_BADBC:	/* bad byte count */ +	case MAX3421_HRSL_PIDERR:	/* received PID is corrupted */ +	case MAX3421_HRSL_PKTERR:	/* packet error (stuff, EOP) */ +	case MAX3421_HRSL_CRCERR:	/* CRC error */ +	case MAX3421_HRSL_BABBLE:	/* device talked too long */ +	case MAX3421_HRSL_TIMEOUT: +		if (max3421_ep->retries++ < USB_MAX_RETRIES) +			/* retry the packet again in the next frame */ +			max3421_slow_retransmit(hcd); +		else { +			/* Based on ohci.h cc_to_err[]: */ +			max3421_hcd->urb_done = hrsl_to_error[result_code]; +			dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", +				__func__, hrsl); +		} +		break; + +	case MAX3421_HRSL_STALL: +		dev_dbg(&spi->dev, "%s: unexpected error HRSL=0x%02x", +			__func__, hrsl); +		max3421_hcd->urb_done = hrsl_to_error[result_code]; +		break; + +	case MAX3421_HRSL_NAK: +		/* +		 * Device wasn't ready for data or has no data +		 * available: retry the packet again. +		 */ +		if (max3421_ep->naks++ < NAK_MAX_FAST_RETRANSMITS) { +			max3421_next_transfer(hcd, 1); +			switch_sndfifo = 0; +		} else +			max3421_slow_retransmit(hcd); +		break; +	} +	if (switch_sndfifo) +		spi_wr8(hcd, MAX3421_REG_SNDBC, 0); +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static int +max3421_transfer_in_done(struct usb_hcd *hcd, struct urb *urb) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	u32 max_packet; + +	if (urb->actual_length >= urb->transfer_buffer_length) +		return 1;	/* read is complete, so we're done */ + +	/* +	 * USB 2.0 Section 5.3.2 Pipes: packets must be full size +	 * except for last one. +	 */ +	max_packet = usb_maxpacket(urb->dev, urb->pipe, 0); +	if (max_packet > MAX3421_FIFO_SIZE) { +		/* +		 * We do not support isochronous transfers at this +		 * time... +		 */ +		dev_err(&spi->dev, +			"%s: packet-size of %u too big (limit is %u bytes)", +			__func__, max_packet, MAX3421_FIFO_SIZE); +		return -EINVAL; +	} + +	if (max3421_hcd->curr_len < max_packet) { +		if (urb->transfer_flags & URB_SHORT_NOT_OK) { +			/* +			 * remaining > 0 and received an +			 * unexpected partial packet -> +			 * error +			 */ +			return -EREMOTEIO; +		} else +			/* short read, but it's OK */ +			return 1; +	} +	return 0;	/* not done */ +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static int +max3421_transfer_out_done(struct usb_hcd *hcd, struct urb *urb) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); + +	urb->actual_length += max3421_hcd->curr_len; +	if (urb->actual_length < urb->transfer_buffer_length) +		return 0; +	if (urb->transfer_flags & URB_ZERO_PACKET) { +		/* +		 * Some hardware needs a zero-size packet at the end +		 * of a bulk-out transfer if the last transfer was a +		 * full-sized packet (i.e., such hardware use < +		 * max_packet as an indicator that the end of the +		 * packet has been reached). +		 */ +		u32 max_packet = usb_maxpacket(urb->dev, urb->pipe, 1); + +		if (max3421_hcd->curr_len == max_packet) +			return 0; +	} +	return 1; +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_host_transfer_done(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct urb *urb = max3421_hcd->curr_urb; +	struct max3421_ep *max3421_ep; +	u8 result_code, hrsl; +	int urb_done = 0; + +	max3421_hcd->hien &= ~(BIT(MAX3421_HI_HXFRDN_BIT) | +			       BIT(MAX3421_HI_RCVDAV_BIT)); + +	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); +	result_code = hrsl & MAX3421_HRSL_RESULT_MASK; + +#ifdef DEBUG +	++max3421_hcd->err_stat[result_code]; +#endif + +	max3421_ep = urb->ep->hcpriv; + +	if (unlikely(result_code != MAX3421_HRSL_OK)) { +		max3421_handle_error(hcd, hrsl); +		return; +	} + +	max3421_ep->naks = 0; +	max3421_ep->retries = 0; +	switch (max3421_ep->pkt_state) { + +	case PKT_STATE_SETUP: +		if (urb->transfer_buffer_length > 0) +			max3421_ep->pkt_state = PKT_STATE_TRANSFER; +		else +			max3421_ep->pkt_state = PKT_STATE_TERMINATE; +		break; + +	case PKT_STATE_TRANSFER: +		if (usb_urb_dir_in(urb)) +			urb_done = max3421_transfer_in_done(hcd, urb); +		else +			urb_done = max3421_transfer_out_done(hcd, urb); +		if (urb_done > 0 && usb_pipetype(urb->pipe) == PIPE_CONTROL) { +			/* +			 * We aren't really done - we still need to +			 * terminate the control transfer: +			 */ +			max3421_hcd->urb_done = urb_done = 0; +			max3421_ep->pkt_state = PKT_STATE_TERMINATE; +		} +		break; + +	case PKT_STATE_TERMINATE: +		urb_done = 1; +		break; +	} + +	if (urb_done) +		max3421_hcd->urb_done = urb_done; +	else +		max3421_next_transfer(hcd, 0); +} + +/* + * Caller must NOT hold HCD spinlock. + */ +static void +max3421_detect_conn(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	unsigned int jk, have_conn = 0; +	u32 old_port_status, chg; +	unsigned long flags; +	u8 hrsl, mode; + +	hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); + +	jk = ((((hrsl >> MAX3421_HRSL_JSTATUS_BIT) & 1) << 0) | +	      (((hrsl >> MAX3421_HRSL_KSTATUS_BIT) & 1) << 1)); + +	mode = max3421_hcd->mode; + +	switch (jk) { +	case 0x0: /* SE0: disconnect */ +		/* +		 * Turn off SOFKAENAB bit to avoid getting interrupt +		 * every milli-second: +		 */ +		mode &= ~BIT(MAX3421_MODE_SOFKAENAB_BIT); +		break; + +	case 0x1: /* J=0,K=1: low-speed (in full-speed or vice versa) */ +	case 0x2: /* J=1,K=0: full-speed (in full-speed or vice versa) */ +		if (jk == 0x2) +			/* need to switch to the other speed: */ +			mode ^= BIT(MAX3421_MODE_LOWSPEED_BIT); +		/* turn on SOFKAENAB bit: */ +		mode |= BIT(MAX3421_MODE_SOFKAENAB_BIT); +		have_conn = 1; +		break; + +	case 0x3: /* illegal */ +		break; +	} + +	max3421_hcd->mode = mode; +	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); + +	spin_lock_irqsave(&max3421_hcd->lock, flags); +	old_port_status = max3421_hcd->port_status; +	if (have_conn) +		max3421_hcd->port_status |=  USB_PORT_STAT_CONNECTION; +	else +		max3421_hcd->port_status &= ~USB_PORT_STAT_CONNECTION; +	if (mode & BIT(MAX3421_MODE_LOWSPEED_BIT)) +		max3421_hcd->port_status |=  USB_PORT_STAT_LOW_SPEED; +	else +		max3421_hcd->port_status &= ~USB_PORT_STAT_LOW_SPEED; +	chg = (old_port_status ^ max3421_hcd->port_status); +	max3421_hcd->port_status |= chg << 16; +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +} + +static irqreturn_t +max3421_irq_handler(int irq, void *dev_id) +{ +	struct usb_hcd *hcd = dev_id; +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); + +	if (max3421_hcd->spi_thread && +	    max3421_hcd->spi_thread->state != TASK_RUNNING) +		wake_up_process(max3421_hcd->spi_thread); +	if (!max3421_hcd->do_enable_irq) { +		max3421_hcd->do_enable_irq = 1; +		disable_irq_nosync(spi->irq); +	} +	return IRQ_HANDLED; +} + +#ifdef DEBUG + +static void +dump_eps(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct max3421_ep *max3421_ep; +	struct usb_host_endpoint *ep; +	struct list_head *pos, *upos; +	char ubuf[512], *dp, *end; +	unsigned long flags; +	struct urb *urb; +	int epnum, ret; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); +	list_for_each(pos, &max3421_hcd->ep_list) { +		max3421_ep = container_of(pos, struct max3421_ep, ep_list); +		ep = max3421_ep->ep; + +		dp = ubuf; +		end = dp + sizeof(ubuf); +		*dp = '\0'; +		list_for_each(upos, &ep->urb_list) { +			urb = container_of(upos, struct urb, urb_list); +			ret = snprintf(dp, end - dp, " %p(%d.%s %d/%d)", urb, +				       usb_pipetype(urb->pipe), +				       usb_urb_dir_in(urb) ? "IN" : "OUT", +				       urb->actual_length, +				       urb->transfer_buffer_length); +			if (ret < 0 || ret >= end - dp) +				break;	/* error or buffer full */ +			dp += ret; +		} + +		epnum = usb_endpoint_num(&ep->desc); +		pr_info("EP%0u %u lst %04u rtr %u nak %6u rxmt %u: %s\n", +			epnum, max3421_ep->pkt_state, max3421_ep->last_active, +			max3421_ep->retries, max3421_ep->naks, +			max3421_ep->retransmit, ubuf); +	} +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +} + +#endif /* DEBUG */ + +/* Return zero if no work was performed, 1 otherwise.  */ +static int +max3421_handle_irqs(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	u32 chg, old_port_status; +	unsigned long flags; +	u8 hirq; + +	/* +	 * Read and ack pending interrupts (CPU must never +	 * clear SNDBAV directly and RCVDAV must be cleared by +	 * max3421_recv_data_available()!): +	 */ +	hirq = spi_rd8(hcd, MAX3421_REG_HIRQ); +	hirq &= max3421_hcd->hien; +	if (!hirq) +		return 0; + +	spi_wr8(hcd, MAX3421_REG_HIRQ, +		hirq & ~(BIT(MAX3421_HI_SNDBAV_BIT) | +			 BIT(MAX3421_HI_RCVDAV_BIT))); + +	if (hirq & BIT(MAX3421_HI_FRAME_BIT)) { +		max3421_hcd->frame_number = ((max3421_hcd->frame_number + 1) +					     & USB_MAX_FRAME_NUMBER); +		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; +	} + +	if (hirq & BIT(MAX3421_HI_RCVDAV_BIT)) +		max3421_recv_data_available(hcd); + +	if (hirq & BIT(MAX3421_HI_HXFRDN_BIT)) +		max3421_host_transfer_done(hcd); + +	if (hirq & BIT(MAX3421_HI_CONDET_BIT)) +		max3421_detect_conn(hcd); + +	/* +	 * Now process interrupts that may affect HCD state +	 * other than the end-points: +	 */ +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	old_port_status = max3421_hcd->port_status; +	if (hirq & BIT(MAX3421_HI_BUSEVENT_BIT)) { +		if (max3421_hcd->port_status & USB_PORT_STAT_RESET) { +			/* BUSEVENT due to completion of Bus Reset */ +			max3421_hcd->port_status &= ~USB_PORT_STAT_RESET; +			max3421_hcd->port_status |=  USB_PORT_STAT_ENABLE; +		} else { +			/* BUSEVENT due to completion of Bus Resume */ +			pr_info("%s: BUSEVENT Bus Resume Done\n", __func__); +		} +	} +	if (hirq & BIT(MAX3421_HI_RWU_BIT)) +		pr_info("%s: RWU\n", __func__); +	if (hirq & BIT(MAX3421_HI_SUSDN_BIT)) +		pr_info("%s: SUSDN\n", __func__); + +	chg = (old_port_status ^ max3421_hcd->port_status); +	max3421_hcd->port_status |= chg << 16; + +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); + +#ifdef DEBUG +	{ +		static unsigned long last_time; +		char sbuf[16 * 16], *dp, *end; +		int i; + +		if (jiffies - last_time > 5*HZ) { +			dp = sbuf; +			end = sbuf + sizeof(sbuf); +			*dp = '\0'; +			for (i = 0; i < 16; ++i) { +				int ret = snprintf(dp, end - dp, " %lu", +						   max3421_hcd->err_stat[i]); +				if (ret < 0 || ret >= end - dp) +					break;	/* error or buffer full */ +				dp += ret; +			} +			pr_info("%s: hrsl_stats %s\n", __func__, sbuf); +			memset(max3421_hcd->err_stat, 0, +			       sizeof(max3421_hcd->err_stat)); +			last_time = jiffies; + +			dump_eps(hcd); +		} +	} +#endif +	return 1; +} + +static int +max3421_reset_hcd(struct usb_hcd *hcd) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	int timeout; + +	/* perform a chip reset and wait for OSCIRQ signal to appear: */ +	spi_wr8(hcd, MAX3421_REG_USBCTL, BIT(MAX3421_USBCTL_CHIPRES_BIT)); +	/* clear reset: */ +	spi_wr8(hcd, MAX3421_REG_USBCTL, 0); +	timeout = 1000; +	while (1) { +		if (spi_rd8(hcd, MAX3421_REG_USBIRQ) +		    & BIT(MAX3421_USBIRQ_OSCOKIRQ_BIT)) +			break; +		if (--timeout < 0) { +			dev_err(&spi->dev, +				"timed out waiting for oscillator OK signal"); +			return 1; +		} +		cond_resched(); +	} + +	/* +	 * Turn on host mode, automatic generation of SOF packets, and +	 * enable pull-down registers on DM/DP: +	 */ +	max3421_hcd->mode = (BIT(MAX3421_MODE_HOST_BIT) | +			     BIT(MAX3421_MODE_SOFKAENAB_BIT) | +			     BIT(MAX3421_MODE_DMPULLDN_BIT) | +			     BIT(MAX3421_MODE_DPPULLDN_BIT)); +	spi_wr8(hcd, MAX3421_REG_MODE, max3421_hcd->mode); + +	/* reset frame-number: */ +	max3421_hcd->frame_number = USB_MAX_FRAME_NUMBER; +	spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_FRMRST_BIT)); + +	/* sample the state of the D+ and D- lines */ +	spi_wr8(hcd, MAX3421_REG_HCTL, BIT(MAX3421_HCTL_SAMPLEBUS_BIT)); +	max3421_detect_conn(hcd); + +	/* enable frame, connection-detected, and bus-event interrupts: */ +	max3421_hcd->hien = (BIT(MAX3421_HI_FRAME_BIT) | +			     BIT(MAX3421_HI_CONDET_BIT) | +			     BIT(MAX3421_HI_BUSEVENT_BIT)); +	spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); + +	/* enable interrupts: */ +	spi_wr8(hcd, MAX3421_REG_CPUCTL, BIT(MAX3421_CPUCTL_IE_BIT)); +	return 1; +} + +static int +max3421_urb_done(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	unsigned long flags; +	struct urb *urb; +	int status; + +	status = max3421_hcd->urb_done; +	max3421_hcd->urb_done = 0; +	if (status > 0) +		status = 0; +	urb = max3421_hcd->curr_urb; +	if (urb) { +		max3421_hcd->curr_urb = NULL; +		spin_lock_irqsave(&max3421_hcd->lock, flags); +		usb_hcd_unlink_urb_from_ep(hcd, urb); +		spin_unlock_irqrestore(&max3421_hcd->lock, flags); + +		/* must be called without the HCD spinlock: */ +		usb_hcd_giveback_urb(hcd, urb, status); +	} +	return 1; +} + +static int +max3421_spi_thread(void *dev_id) +{ +	struct usb_hcd *hcd = dev_id; +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	int i, i_worked = 1; + +	/* set full-duplex SPI mode, low-active interrupt pin: */ +	spi_wr8(hcd, MAX3421_REG_PINCTL, +		(BIT(MAX3421_PINCTL_FDUPSPI_BIT) |	/* full-duplex */ +		 BIT(MAX3421_PINCTL_INTLEVEL_BIT)));	/* low-active irq */ + +	while (!kthread_should_stop()) { +		max3421_hcd->rev = spi_rd8(hcd, MAX3421_REG_REVISION); +		if (max3421_hcd->rev == 0x12 || max3421_hcd->rev == 0x13) +			break; +		dev_err(&spi->dev, "bad rev 0x%02x", max3421_hcd->rev); +		msleep(10000); +	} +	dev_info(&spi->dev, "rev 0x%x, SPI clk %dHz, bpw %u, irq %d\n", +		 max3421_hcd->rev, spi->max_speed_hz, spi->bits_per_word, +		 spi->irq); + +	while (!kthread_should_stop()) { +		if (!i_worked) { +			/* +			 * We'll be waiting for wakeups from the hard +			 * interrupt handler, so now is a good time to +			 * sync our hien with the chip: +			 */ +			spi_wr8(hcd, MAX3421_REG_HIEN, max3421_hcd->hien); + +			set_current_state(TASK_INTERRUPTIBLE); +			if (max3421_hcd->do_enable_irq) { +				max3421_hcd->do_enable_irq = 0; +				enable_irq(spi->irq); +			} +			schedule(); +			__set_current_state(TASK_RUNNING); +		} + +		i_worked = 0; + +		if (max3421_hcd->urb_done) +			i_worked |= max3421_urb_done(hcd); +		else if (max3421_handle_irqs(hcd)) +			i_worked = 1; +		else if (!max3421_hcd->curr_urb) +			i_worked |= max3421_select_and_start_urb(hcd); + +		if (max3421_hcd->do_reset_hcd) { +			/* reset the HCD: */ +			max3421_hcd->do_reset_hcd = 0; +			i_worked |= max3421_reset_hcd(hcd); +		} +		if (max3421_hcd->do_reset_port) { +			/* perform a USB bus reset: */ +			max3421_hcd->do_reset_port = 0; +			spi_wr8(hcd, MAX3421_REG_HCTL, +				BIT(MAX3421_HCTL_BUSRST_BIT)); +			i_worked = 1; +		} +		if (max3421_hcd->do_check_unlink) { +			max3421_hcd->do_check_unlink = 0; +			i_worked |= max3421_check_unlink(hcd); +		} +		if (max3421_hcd->do_iopin_update) { +			/* +			 * IOPINS1/IOPINS2 do not auto-increment, so we can't +			 * use spi_wr_buf(). +			 */ +			for (i = 0; i < ARRAY_SIZE(max3421_hcd->iopins); ++i) { +				u8 val = spi_rd8(hcd, MAX3421_REG_IOPINS1); + +				val = ((val & 0xf0) | +				       (max3421_hcd->iopins[i] & 0x0f)); +				spi_wr8(hcd, MAX3421_REG_IOPINS1 + i, val); +				max3421_hcd->iopins[i] = val; +			} +			max3421_hcd->do_iopin_update = 0; +			i_worked = 1; +		} +	} +	set_current_state(TASK_RUNNING); +	dev_info(&spi->dev, "SPI thread exiting"); +	return 0; +} + +static int +max3421_reset_port(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); + +	max3421_hcd->port_status &= ~(USB_PORT_STAT_ENABLE | +				      USB_PORT_STAT_LOW_SPEED); +	max3421_hcd->do_reset_port = 1; +	wake_up_process(max3421_hcd->spi_thread); +	return 0; +} + +static int +max3421_reset(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); + +	hcd->self.sg_tablesize = 0; +	hcd->speed = HCD_USB2; +	hcd->self.root_hub->speed = USB_SPEED_FULL; +	max3421_hcd->do_reset_hcd = 1; +	wake_up_process(max3421_hcd->spi_thread); +	return 0; +} + +static int +max3421_start(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); + +	spin_lock_init(&max3421_hcd->lock); +	max3421_hcd->rh_state = MAX3421_RH_RUNNING; + +	INIT_LIST_HEAD(&max3421_hcd->ep_list); + +	hcd->power_budget = POWER_BUDGET; +	hcd->state = HC_STATE_RUNNING; +	hcd->uses_new_polling = 1; +	return 0; +} + +static void +max3421_stop(struct usb_hcd *hcd) +{ +} + +static int +max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct max3421_ep *max3421_ep; +	unsigned long flags; +	int retval; + +	switch (usb_pipetype(urb->pipe)) { +	case PIPE_INTERRUPT: +	case PIPE_ISOCHRONOUS: +		if (urb->interval < 0) { +			dev_err(&spi->dev, +			  "%s: interval=%d for intr-/iso-pipe; expected > 0\n", +				__func__, urb->interval); +			return -EINVAL; +		} +	default: +		break; +	} + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	max3421_ep = urb->ep->hcpriv; +	if (!max3421_ep) { +		/* gets freed in max3421_endpoint_disable: */ +		max3421_ep = kzalloc(sizeof(struct max3421_ep), mem_flags); +		if (!max3421_ep) { +			retval = -ENOMEM; +			goto out; +		} +		max3421_ep->ep = urb->ep; +		max3421_ep->last_active = max3421_hcd->frame_number; +		urb->ep->hcpriv = max3421_ep; + +		list_add_tail(&max3421_ep->ep_list, &max3421_hcd->ep_list); +	} + +	retval = usb_hcd_link_urb_to_ep(hcd, urb); +	if (retval == 0) { +		/* Since we added to the queue, restart scheduling: */ +		max3421_hcd->sched_pass = SCHED_PASS_PERIODIC; +		wake_up_process(max3421_hcd->spi_thread); +	} + +out: +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +	return retval; +} + +static int +max3421_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	unsigned long flags; +	int retval; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	/* +	 * This will set urb->unlinked which in turn causes the entry +	 * to be dropped at the next opportunity. +	 */ +	retval = usb_hcd_check_unlink_urb(hcd, urb, status); +	if (retval == 0) { +		max3421_hcd->do_check_unlink = 1; +		wake_up_process(max3421_hcd->spi_thread); +	} +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +	return retval; +} + +static void +max3421_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *ep) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	unsigned long flags; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	if (ep->hcpriv) { +		struct max3421_ep *max3421_ep = ep->hcpriv; + +		/* remove myself from the ep_list: */ +		if (!list_empty(&max3421_ep->ep_list)) +			list_del(&max3421_ep->ep_list); +		kfree(max3421_ep); +		ep->hcpriv = NULL; +	} + +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +} + +static int +max3421_get_frame_number(struct usb_hcd *hcd) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	return max3421_hcd->frame_number; +} + +/* + * Should return a non-zero value when any port is undergoing a resume + * transition while the root hub is suspended. + */ +static int +max3421_hub_status_data(struct usb_hcd *hcd, char *buf) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	unsigned long flags; +	int retval = 0; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); +	if (!HCD_HW_ACCESSIBLE(hcd)) +		goto done; + +	*buf = 0; +	if ((max3421_hcd->port_status & PORT_C_MASK) != 0) { +		*buf = (1 << 1); /* a hub over-current condition exists */ +		dev_dbg(hcd->self.controller, +			"port status 0x%08x has changes\n", +			max3421_hcd->port_status); +		retval = 1; +		if (max3421_hcd->rh_state == MAX3421_RH_SUSPENDED) +			usb_hcd_resume_root_hub(hcd); +	} +done: +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +	return retval; +} + +static inline void +hub_descriptor(struct usb_hub_descriptor *desc) +{ +	memset(desc, 0, sizeof(*desc)); +	/* +	 * See Table 11-13: Hub Descriptor in USB 2.0 spec. +	 */ +	desc->bDescriptorType = 0x29;	/* hub descriptor */ +	desc->bDescLength = 9; +	desc->wHubCharacteristics = cpu_to_le16(0x0001); +	desc->bNbrPorts = 1; +} + +/* + * Set the MAX3421E general-purpose output with number PIN_NUMBER to + * VALUE (0 or 1).  PIN_NUMBER may be in the range from 1-8.  For + * any other value, this function acts as a no-op. + */ +static void +max3421_gpout_set_value(struct usb_hcd *hcd, u8 pin_number, u8 value) +{ +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	u8 mask, idx; + +	--pin_number; +	if (pin_number > 7) +		return; + +	mask = 1u << pin_number; +	idx = pin_number / 4; + +	if (value) +		max3421_hcd->iopins[idx] |=  mask; +	else +		max3421_hcd->iopins[idx] &= ~mask; +	max3421_hcd->do_iopin_update = 1; +	wake_up_process(max3421_hcd->spi_thread); +} + +static int +max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index, +		    char *buf, u16 length) +{ +	struct spi_device *spi = to_spi_device(hcd->self.controller); +	struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); +	struct max3421_hcd_platform_data *pdata; +	unsigned long flags; +	int retval = 0; + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	pdata = spi->dev.platform_data; + +	switch (type_req) { +	case ClearHubFeature: +		break; +	case ClearPortFeature: +		switch (value) { +		case USB_PORT_FEAT_SUSPEND: +			break; +		case USB_PORT_FEAT_POWER: +			dev_dbg(hcd->self.controller, "power-off\n"); +			max3421_gpout_set_value(hcd, pdata->vbus_gpout, +						!pdata->vbus_active_level); +			/* FALLS THROUGH */ +		default: +			max3421_hcd->port_status &= ~(1 << value); +		} +		break; +	case GetHubDescriptor: +		hub_descriptor((struct usb_hub_descriptor *) buf); +		break; + +	case DeviceRequest | USB_REQ_GET_DESCRIPTOR: +	case GetPortErrorCount: +	case SetHubDepth: +		/* USB3 only */ +		goto error; + +	case GetHubStatus: +		*(__le32 *) buf = cpu_to_le32(0); +		break; + +	case GetPortStatus: +		if (index != 1) { +			retval = -EPIPE; +			goto error; +		} +		((__le16 *) buf)[0] = cpu_to_le16(max3421_hcd->port_status); +		((__le16 *) buf)[1] = +			cpu_to_le16(max3421_hcd->port_status >> 16); +		break; + +	case SetHubFeature: +		retval = -EPIPE; +		break; + +	case SetPortFeature: +		switch (value) { +		case USB_PORT_FEAT_LINK_STATE: +		case USB_PORT_FEAT_U1_TIMEOUT: +		case USB_PORT_FEAT_U2_TIMEOUT: +		case USB_PORT_FEAT_BH_PORT_RESET: +			goto error; +		case USB_PORT_FEAT_SUSPEND: +			if (max3421_hcd->active) +				max3421_hcd->port_status |= +					USB_PORT_STAT_SUSPEND; +			break; +		case USB_PORT_FEAT_POWER: +			dev_dbg(hcd->self.controller, "power-on\n"); +			max3421_hcd->port_status |= USB_PORT_STAT_POWER; +			max3421_gpout_set_value(hcd, pdata->vbus_gpout, +						pdata->vbus_active_level); +			break; +		case USB_PORT_FEAT_RESET: +			max3421_reset_port(hcd); +			/* FALLS THROUGH */ +		default: +			if ((max3421_hcd->port_status & USB_PORT_STAT_POWER) +			    != 0) +				max3421_hcd->port_status |= (1 << value); +		} +		break; + +	default: +		dev_dbg(hcd->self.controller, +			"hub control req%04x v%04x i%04x l%d\n", +			type_req, value, index, length); +error:		/* "protocol stall" on error */ +		retval = -EPIPE; +	} + +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); +	return retval; +} + +static int +max3421_bus_suspend(struct usb_hcd *hcd) +{ +	return -1; +} + +static int +max3421_bus_resume(struct usb_hcd *hcd) +{ +	return -1; +} + +/* + * The SPI driver already takes care of DMA-mapping/unmapping, so no + * reason to do it twice. + */ +static int +max3421_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) +{ +	return 0; +} + +static void +max3421_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) +{ +} + +static struct hc_driver max3421_hcd_desc = { +	.description =		"max3421", +	.product_desc =		DRIVER_DESC, +	.hcd_priv_size =	sizeof(struct max3421_hcd), +	.flags =		HCD_USB11, +	.reset =		max3421_reset, +	.start =		max3421_start, +	.stop =			max3421_stop, +	.get_frame_number =	max3421_get_frame_number, +	.urb_enqueue =		max3421_urb_enqueue, +	.urb_dequeue =		max3421_urb_dequeue, +	.map_urb_for_dma =	max3421_map_urb_for_dma, +	.unmap_urb_for_dma =	max3421_unmap_urb_for_dma, +	.endpoint_disable =	max3421_endpoint_disable, +	.hub_status_data =	max3421_hub_status_data, +	.hub_control =		max3421_hub_control, +	.bus_suspend =		max3421_bus_suspend, +	.bus_resume =		max3421_bus_resume, +}; + +static int +max3421_probe(struct spi_device *spi) +{ +	struct max3421_hcd *max3421_hcd; +	struct usb_hcd *hcd = NULL; +	int retval = -ENOMEM; + +	if (spi_setup(spi) < 0) { +		dev_err(&spi->dev, "Unable to setup SPI bus"); +		return -EFAULT; +	} + +	hcd = usb_create_hcd(&max3421_hcd_desc, &spi->dev, +			     dev_name(&spi->dev)); +	if (!hcd) { +		dev_err(&spi->dev, "failed to create HCD structure\n"); +		goto error; +	} +	set_bit(HCD_FLAG_POLL_RH, &hcd->flags); +	max3421_hcd = hcd_to_max3421(hcd); +	max3421_hcd->next = max3421_hcd_list; +	max3421_hcd_list = max3421_hcd; +	INIT_LIST_HEAD(&max3421_hcd->ep_list); + +	max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); +	if (!max3421_hcd->tx) { +		dev_err(&spi->dev, "failed to kmalloc tx buffer\n"); +		goto error; +	} +	max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); +	if (!max3421_hcd->rx) { +		dev_err(&spi->dev, "failed to kmalloc rx buffer\n"); +		goto error; +	} + +	max3421_hcd->spi_thread = kthread_run(max3421_spi_thread, hcd, +					      "max3421_spi_thread"); +	if (max3421_hcd->spi_thread == ERR_PTR(-ENOMEM)) { +		dev_err(&spi->dev, +			"failed to create SPI thread (out of memory)\n"); +		goto error; +	} + +	retval = usb_add_hcd(hcd, 0, 0); +	if (retval) { +		dev_err(&spi->dev, "failed to add HCD\n"); +		goto error; +	} + +	retval = request_irq(spi->irq, max3421_irq_handler, +			     IRQF_TRIGGER_LOW, "max3421", hcd); +	if (retval < 0) { +		dev_err(&spi->dev, "failed to request irq %d\n", spi->irq); +		goto error; +	} +	return 0; + +error: +	if (hcd) { +		kfree(max3421_hcd->tx); +		kfree(max3421_hcd->rx); +		if (max3421_hcd->spi_thread) +			kthread_stop(max3421_hcd->spi_thread); +		usb_put_hcd(hcd); +	} +	return retval; +} + +static int +max3421_remove(struct spi_device *spi) +{ +	struct max3421_hcd *max3421_hcd = NULL, **prev; +	struct usb_hcd *hcd = NULL; +	unsigned long flags; + +	for (prev = &max3421_hcd_list; *prev; prev = &(*prev)->next) { +		max3421_hcd = *prev; +		hcd = max3421_to_hcd(max3421_hcd); +		if (hcd->self.controller == &spi->dev) +			break; +	} +	if (!max3421_hcd) { +		dev_err(&spi->dev, "no MAX3421 HCD found for SPI device %p\n", +			spi); +		return -ENODEV; +	} + +	usb_remove_hcd(hcd); + +	spin_lock_irqsave(&max3421_hcd->lock, flags); + +	kthread_stop(max3421_hcd->spi_thread); +	*prev = max3421_hcd->next; + +	spin_unlock_irqrestore(&max3421_hcd->lock, flags); + +	free_irq(spi->irq, hcd); + +	usb_put_hcd(hcd); +	return 0; +} + +static struct spi_driver max3421_driver = { +	.probe		= max3421_probe, +	.remove		= max3421_remove, +	.driver		= { +		.name	= "max3421-hcd", +		.owner	= THIS_MODULE, +	}, +}; + +module_spi_driver(max3421_driver); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("David Mosberger <davidm@egauge.net>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index caa3764a340..e49eb4f90f5 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -13,19 +13,24 @@   */  #include <linux/clk.h> -#include <linux/platform_device.h> +#include <linux/dma-mapping.h>  #include <linux/of_platform.h>  #include <linux/of_gpio.h> +#include <linux/platform_device.h>  #include <linux/platform_data/atmel.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h>  #include <mach/hardware.h>  #include <asm/gpio.h>  #include <mach/cpu.h> -#ifndef CONFIG_ARCH_AT91 -#error "CONFIG_ARCH_AT91 must be defined." -#endif + +#include "ohci.h"  #define valid_port(index)	((index) >= 0 && (index) < AT91_MAX_USBH_PORTS)  #define at91_for_each_port(index)	\ @@ -33,6 +38,13 @@  /* interface, function and usb clocks; sometimes also an AHB clock */  static struct clk *iclk, *fclk, *uclk, *hclk; +/* interface and function clocks; sometimes also an AHB clock */ + +#define DRIVER_DESC "OHCI Atmel driver" + +static const char hcd_name[] = "ohci-atmel"; + +static struct hc_driver __read_mostly ohci_at91_hc_driver;  static int clocked;  extern int usb_disabled(void); @@ -117,92 +129,80 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);  static int usb_hcd_at91_probe(const struct hc_driver *driver,  			struct platform_device *pdev)  { +	struct at91_usbh_data *board; +	struct ohci_hcd *ohci;  	int retval;  	struct usb_hcd *hcd = NULL; - -	if (pdev->num_resources != 2) { -		pr_debug("hcd probe: invalid num_resources"); -		return -ENODEV; +	struct device *dev = &pdev->dev; +	struct resource *res; +	int irq; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_dbg(dev, "hcd probe: missing memory resource\n"); +		return -ENXIO;  	} -	if ((pdev->resource[0].flags != IORESOURCE_MEM) -			|| (pdev->resource[1].flags != IORESOURCE_IRQ)) { -		pr_debug("hcd probe: invalid resource type\n"); -		return -ENODEV; +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_dbg(dev, "hcd probe: missing irq resource\n"); +		return irq;  	} -	hcd = usb_create_hcd(driver, &pdev->dev, "at91"); +	hcd = usb_create_hcd(driver, dev, "at91");  	if (!hcd)  		return -ENOMEM; -	hcd->rsrc_start = pdev->resource[0].start; -	hcd->rsrc_len = resource_size(&pdev->resource[0]); - -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		pr_debug("request_mem_region failed\n"); -		retval = -EBUSY; -		goto err1; -	} +	hcd->rsrc_start = res->start; +	hcd->rsrc_len = resource_size(res); -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		pr_debug("ioremap failed\n"); -		retval = -EIO; -		goto err2; +	hcd->regs = devm_ioremap_resource(dev, res); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs); +		goto err;  	} -	iclk = clk_get(&pdev->dev, "ohci_clk"); +	iclk = devm_clk_get(dev, "ohci_clk");  	if (IS_ERR(iclk)) { -		dev_err(&pdev->dev, "failed to get ohci_clk\n"); +		dev_err(dev, "failed to get ohci_clk\n");  		retval = PTR_ERR(iclk); -		goto err3; +		goto err;  	} -	fclk = clk_get(&pdev->dev, "uhpck"); +	fclk = devm_clk_get(dev, "uhpck");  	if (IS_ERR(fclk)) { -		dev_err(&pdev->dev, "failed to get uhpck\n"); +		dev_err(dev, "failed to get uhpck\n");  		retval = PTR_ERR(fclk); -		goto err4; +		goto err;  	} -	hclk = clk_get(&pdev->dev, "hclk"); +	hclk = devm_clk_get(dev, "hclk");  	if (IS_ERR(hclk)) { -		dev_err(&pdev->dev, "failed to get hclk\n"); +		dev_err(dev, "failed to get hclk\n");  		retval = PTR_ERR(hclk); -		goto err5; +		goto err;  	}  	if (IS_ENABLED(CONFIG_COMMON_CLK)) { -		uclk = clk_get(&pdev->dev, "usb_clk"); +		uclk = devm_clk_get(dev, "usb_clk");  		if (IS_ERR(uclk)) { -			dev_err(&pdev->dev, "failed to get uclk\n"); +			dev_err(dev, "failed to get uclk\n");  			retval = PTR_ERR(uclk); -			goto err6; +			goto err;  		}  	} +	board = hcd->self.controller->platform_data; +	ohci = hcd_to_ohci(hcd); +	ohci->num_ports = board->ports;  	at91_start_hc(pdev); -	ohci_hcd_init(hcd_to_ohci(hcd)); -	retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED); -	if (retval == 0) +	retval = usb_add_hcd(hcd, irq, IRQF_SHARED); +	if (retval == 0) { +		device_wakeup_enable(hcd->self.controller);  		return retval; +	}  	/* Error handling */  	at91_stop_hc(pdev); -	if (IS_ENABLED(CONFIG_COMMON_CLK)) -		clk_put(uclk); - err6: -	clk_put(hclk); - err5: -	clk_put(fclk); - err4: -	clk_put(iclk); - - err3: -	iounmap(hcd->regs); - - err2: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - - err1: + err:  	usb_put_hcd(hcd);  	return retval;  } @@ -225,49 +225,10 @@ static void usb_hcd_at91_remove(struct usb_hcd *hcd,  {  	usb_remove_hcd(hcd);  	at91_stop_hc(pdev); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd); - -	if (IS_ENABLED(CONFIG_COMMON_CLK)) -		clk_put(uclk); -	clk_put(hclk); -	clk_put(fclk); -	clk_put(iclk); -	fclk = iclk = hclk = NULL;  }  /*-------------------------------------------------------------------------*/ - -static int -ohci_at91_reset (struct usb_hcd *hcd) -{ -	struct at91_usbh_data	*board = dev_get_platdata(hcd->self.controller); -	struct ohci_hcd		*ohci = hcd_to_ohci (hcd); -	int			ret; - -	if ((ret = ohci_init(ohci)) < 0) -		return ret; - -	ohci->num_ports = board->ports; -	return 0; -} - -static int -ohci_at91_start (struct usb_hcd *hcd) -{ -	struct ohci_hcd		*ohci = hcd_to_ohci (hcd); -	int			ret; - -	if ((ret = ohci_run(ohci)) < 0) { -		dev_err(hcd->self.controller, "can't start %s\n", -			hcd->self.bus_name); -		ohci_stop(hcd); -		return ret; -	} -	return 0; -} -  static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int enable)  {  	if (!valid_port(port)) @@ -297,7 +258,7 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)   */  static int ohci_at91_hub_status_data(struct usb_hcd *hcd, char *buf)  { -	struct at91_usbh_data *pdata = dev_get_platdata(hcd->self.controller); +	struct at91_usbh_data *pdata = hcd->self.controller->platform_data;  	int length = ohci_hub_status_data(hcd, buf);  	int port; @@ -430,51 +391,6 @@ static int ohci_at91_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  /*-------------------------------------------------------------------------*/ -static const struct hc_driver ohci_at91_hc_driver = { -	.description =		hcd_name, -	.product_desc =		"AT91 OHCI", -	.hcd_priv_size =	sizeof(struct ohci_hcd), - -	/* -	 * generic hardware linkage -	 */ -	.irq =			ohci_irq, -	.flags =		HCD_USB11 | HCD_MEMORY, - -	/* -	 * basic lifecycle operations -	 */ -	.reset =		ohci_at91_reset, -	.start =		ohci_at91_start, -	.stop =			ohci_stop, -	.shutdown =		ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue =		ohci_urb_enqueue, -	.urb_dequeue =		ohci_urb_dequeue, -	.endpoint_disable =	ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number =	ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data =	ohci_at91_hub_status_data, -	.hub_control =		ohci_at91_hub_control, -#ifdef CONFIG_PM -	.bus_suspend =		ohci_bus_suspend, -	.bus_resume =		ohci_bus_resume, -#endif -	.start_port_reset =	ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ -  static irqreturn_t ohci_hcd_at91_overcurrent_irq(int irq, void *data)  {  	struct platform_device *pdev = data; @@ -524,7 +440,7 @@ MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids);  static int ohci_at91_of_init(struct platform_device *pdev)  {  	struct device_node *np = pdev->dev.of_node; -	int i, gpio; +	int i, gpio, ret;  	enum of_gpio_flags flags;  	struct at91_usbh_data	*pdata;  	u32 ports; @@ -536,10 +452,9 @@ static int ohci_at91_of_init(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret;  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);  	if (!pdata) @@ -691,10 +606,17 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)  {  	struct usb_hcd	*hcd = platform_get_drvdata(pdev);  	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); +	bool		do_wakeup = device_may_wakeup(&pdev->dev); +	int		ret; -	if (device_may_wakeup(&pdev->dev)) +	if (do_wakeup)  		enable_irq_wake(hcd->irq); +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) { +		disable_irq_wake(hcd->irq); +		return ret; +	}  	/*  	 * The integrated transceivers seem unable to notice disconnect,  	 * reconnect, or wakeup without the 48 MHz clock active.  so for @@ -703,13 +625,17 @@ 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()) { -		ohci_usb_reset (ohci); +		ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); +		ohci->hc_control &= OHCI_CTRL_RWC; +		ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); +		ohci->rh_state = OHCI_RH_HALTED; +  		/* flush the writes */  		(void) ohci_readl (ohci, &ohci->regs->control);  		at91_stop_clock();  	} -	return 0; +	return ret;  }  static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) @@ -730,8 +656,6 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)  #define ohci_hcd_at91_drv_resume  NULL  #endif -MODULE_ALIAS("platform:at91_ohci"); -  static struct platform_driver ohci_hcd_at91_driver = {  	.probe		= ohci_hcd_at91_drv_probe,  	.remove		= ohci_hcd_at91_drv_remove, @@ -744,3 +668,37 @@ static struct platform_driver ohci_hcd_at91_driver = {  		.of_match_table	= of_match_ptr(at91_ohci_dt_ids),  	},  }; + +static int __init ohci_at91_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); +	ohci_init_driver(&ohci_at91_hc_driver, NULL); + +	/* +	 * The Atmel HW has some unusual quirks, which require Atmel-specific +	 * workarounds. We override certain hc_driver functions here to +	 * achieve that. We explicitly do not enhance ohci_driver_overrides to +	 * allow this more easily, since this is an unusual case, and we don't +	 * want to encourage others to override these functions by making it +	 * too easy. +	 */ + +	ohci_at91_hc_driver.hub_status_data	= ohci_at91_hub_status_data; +	ohci_at91_hc_driver.hub_control		= ohci_at91_hub_control; + +	return platform_driver_register(&ohci_hcd_at91_driver); +} +module_init(ohci_at91_init); + +static void __exit ohci_at91_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_at91_driver); +} +module_exit(ohci_at91_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:at91_ohci"); diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 9be59f11e05..df06be6b47f 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -300,41 +300,28 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,  	if (hub == NULL)  		return -ENODEV; -	usb11_clk = clk_get(&pdev->dev, "usb11"); +	usb11_clk = devm_clk_get(&pdev->dev, "usb11");  	if (IS_ERR(usb11_clk))  		return PTR_ERR(usb11_clk); -	usb20_clk = clk_get(&pdev->dev, "usb20"); -	if (IS_ERR(usb20_clk)) { -		error = PTR_ERR(usb20_clk); -		goto err0; -	} +	usb20_clk = devm_clk_get(&pdev->dev, "usb20"); +	if (IS_ERR(usb20_clk)) +		return PTR_ERR(usb20_clk);  	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); -	if (!hcd) { -		error = -ENOMEM; -		goto err1; -	} +	if (!hcd) +		return -ENOMEM;  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!mem) { -		error = -ENODEV; -		goto err2; -	} +	if (!mem) +		return -ENODEV;  	hcd->rsrc_start = mem->start;  	hcd->rsrc_len = resource_size(mem); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		dev_dbg(&pdev->dev, "request_mem_region failed\n"); -		error = -EBUSY; -		goto err2; -	} - -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "ioremap failed\n"); -		error = -ENOMEM; -		goto err3; +	hcd->regs = devm_ioremap_resource(&pdev->dev, mem); +	if (IS_ERR(hcd->regs)) { +		error = PTR_ERR(hcd->regs); +		goto err;  	}  	ohci_hcd_init(hcd_to_ohci(hcd)); @@ -342,11 +329,13 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		error = -ENODEV; -		goto err4; +		goto err;  	}  	error = usb_add_hcd(hcd, irq, 0);  	if (error) -		goto err4; +		goto err; + +	device_wakeup_enable(hcd->self.controller);  	if (hub->ocic_notify) {  		error = hub->ocic_notify(ohci_da8xx_ocic_handler); @@ -355,16 +344,8 @@ static int usb_hcd_da8xx_probe(const struct hc_driver *driver,  	}  	usb_remove_hcd(hcd); -err4: -	iounmap(hcd->regs); -err3: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -err2: +err:  	usb_put_hcd(hcd); -err1: -	clk_put(usb20_clk); -err0: -	clk_put(usb11_clk);  	return error;  } @@ -384,11 +365,7 @@ usb_hcd_da8xx_remove(struct usb_hcd *hcd, struct platform_device *pdev)  	hub->ocic_notify(NULL);  	usb_remove_hcd(hcd); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd); -	clk_put(usb20_clk); -	clk_put(usb11_clk);  }  static int ohci_hcd_da8xx_drv_probe(struct platform_device *dev) @@ -406,19 +383,27 @@ static int ohci_hcd_da8xx_drv_remove(struct platform_device *dev)  }  #ifdef CONFIG_PM -static int ohci_da8xx_suspend(struct platform_device *dev, pm_message_t message) +static int ohci_da8xx_suspend(struct platform_device *pdev, +				pm_message_t message)  { -	struct usb_hcd	*hcd	= platform_get_drvdata(dev); +	struct usb_hcd	*hcd	= platform_get_drvdata(pdev);  	struct ohci_hcd	*ohci	= hcd_to_ohci(hcd); +	bool		do_wakeup	= device_may_wakeup(&pdev->dev); +	int		ret; +  	if (time_before(jiffies, ohci->next_statechange))  		msleep(5);  	ohci->next_statechange = jiffies; +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret; +  	ohci_da8xx_clock(0);  	hcd->state = HC_STATE_SUSPENDED; -	dev->dev.power.power_state = PMSG_SUSPEND; -	return 0; + +	return ret;  }  static int ohci_da8xx_resume(struct platform_device *dev) diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 31b81f9eacd..45032e933e1 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -9,68 +9,15 @@  /*-------------------------------------------------------------------------*/ -#ifdef DEBUG -  #define edstring(ed_type) ({ char *temp; \  	switch (ed_type) { \  	case PIPE_CONTROL:	temp = "ctrl"; break; \  	case PIPE_BULK:		temp = "bulk"; break; \  	case PIPE_INTERRUPT:	temp = "intr"; break; \  	default:		temp = "isoc"; break; \ -	}; temp;}) +	} temp;})  #define pipestring(pipe) edstring(usb_pipetype(pipe)) -/* debug| print the main components of an URB - * small: 0) header + data packets 1) just header - */ -static void __maybe_unused -urb_print(struct urb * urb, char * str, int small, int status) -{ -	unsigned int pipe= urb->pipe; - -	if (!urb->dev || !urb->dev->bus) { -		printk(KERN_DEBUG "%s URB: no dev\n", str); -		return; -	} - -#ifndef	OHCI_VERBOSE_DEBUG -	if (status != 0) -#endif -	printk(KERN_DEBUG "%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d\n", -		    str, -		    urb, -		    usb_pipedevice (pipe), -		    usb_pipeendpoint (pipe), -		    usb_pipeout (pipe)? "out" : "in", -		    pipestring (pipe), -		    urb->transfer_flags, -		    urb->actual_length, -		    urb->transfer_buffer_length, -		    status); - -#ifdef	OHCI_VERBOSE_DEBUG -	if (!small) { -		int i, len; - -		if (usb_pipecontrol (pipe)) { -			printk (KERN_DEBUG "%s: setup(8):", __FILE__); -			for (i = 0; i < 8 ; i++) -				printk (" %02x", ((__u8 *) urb->setup_packet) [i]); -			printk ("\n"); -		} -		if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) { -			printk (KERN_DEBUG "%s: data(%d/%d):", __FILE__, -				urb->actual_length, -				urb->transfer_buffer_length); -			len = usb_pipeout (pipe)? -						urb->transfer_buffer_length: urb->actual_length; -			for (i = 0; i < 16 && i < len; i++) -				printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); -			printk ("%s stat:%d\n", i < len? "...": "", status); -		} -	} -#endif -}  #define ohci_dbg_sw(ohci, next, size, format, arg...) \  	do { \ @@ -407,22 +354,8 @@ ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,  	}  } -#else -static inline void ohci_dump (struct ohci_hcd *controller, int verbose) {} - -#undef OHCI_VERBOSE_DEBUG - -#endif /* DEBUG */ -  /*-------------------------------------------------------------------------*/ -#ifdef STUB_DEBUG_FILES - -static inline void create_debug_files (struct ohci_hcd *bus) { } -static inline void remove_debug_files (struct ohci_hcd *bus) { } - -#else -  static int debug_async_open(struct inode *, struct file *);  static int debug_periodic_open(struct inode *, struct file *);  static int debug_registers_open(struct inode *, struct file *); @@ -871,7 +804,5 @@ static inline void remove_debug_files (struct ohci_hcd *ohci)  	debugfs_remove(ohci->debug_dir);  } -#endif -  /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c deleted file mode 100644 index 84a20d5223b..00000000000 --- a/drivers/usb/host/ohci-ep93xx.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * OHCI HCD (Host Controller Driver) for USB. - * - * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> - * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> - * (C) Copyright 2002 Hewlett-Packard Company - * - * Bus Glue for ep93xx. - * - * Written by Christopher Hoover <ch@hpl.hp.com> - * Based on fragments of previous driver by Russell King et al. - * - * Modified for LH7A404 from ohci-sa1111.c - *  by Durgesh Pattamatta <pattamattad@sharpsec.com> - * - * Modified for pxa27x from ohci-lh7a404.c - *  by Nick Bane <nick@cecomputing.co.uk> 26-8-2004 - * - * Modified for ep93xx from ohci-pxa27x.c - *  by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006 - *  Based on an earlier driver by Ray Lehtiniemi - * - * This file is licenced under the GPL. - */ - -#include <linux/clk.h> -#include <linux/device.h> -#include <linux/signal.h> -#include <linux/platform_device.h> - -static struct clk *usb_host_clock; - -static int ohci_ep93xx_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	int ret; - -	if ((ret = ohci_init(ohci)) < 0) -		return ret; - -	if ((ret = ohci_run(ohci)) < 0) { -		dev_err(hcd->self.controller, "can't start %s\n", -			hcd->self.bus_name); -		ohci_stop(hcd); -		return ret; -	} - -	return 0; -} - -static struct hc_driver ohci_ep93xx_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "EP93xx OHCI", -	.hcd_priv_size		= sizeof(struct ohci_hcd), -	.irq			= ohci_irq, -	.flags			= HCD_USB11 | HCD_MEMORY, -	.start			= ohci_ep93xx_start, -	.stop			= ohci_stop, -	.shutdown		= ohci_shutdown, -	.urb_enqueue		= ohci_urb_enqueue, -	.urb_dequeue		= ohci_urb_dequeue, -	.endpoint_disable	= ohci_endpoint_disable, -	.get_frame_number	= ohci_get_frame, -	.hub_status_data	= ohci_hub_status_data, -	.hub_control		= ohci_hub_control, -#ifdef CONFIG_PM -	.bus_suspend		= ohci_bus_suspend, -	.bus_resume		= ohci_bus_resume, -#endif -	.start_port_reset	= ohci_start_port_reset, -}; - -static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev) -{ -	struct usb_hcd *hcd; -	struct resource *res; -	int irq; -	int ret; - -	if (usb_disabled()) -		return -ENODEV; - -	irq = platform_get_irq(pdev, 0); -	if (irq < 0) -		return irq; - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -	if (!res) -		return -ENXIO; - -	hcd = usb_create_hcd(&ohci_ep93xx_hc_driver, &pdev->dev, "ep93xx"); -	if (!hcd) -		return -ENOMEM; - -	hcd->rsrc_start = res->start; -	hcd->rsrc_len = resource_size(res); - -	hcd->regs = devm_ioremap_resource(&pdev->dev, res); -	if (IS_ERR(hcd->regs)) { -		ret = PTR_ERR(hcd->regs); -		goto err_put_hcd; -	} - -	usb_host_clock = devm_clk_get(&pdev->dev, NULL); -	if (IS_ERR(usb_host_clock)) { -		ret = PTR_ERR(usb_host_clock); -		goto err_put_hcd; -	} - -	clk_enable(usb_host_clock); - -	ohci_hcd_init(hcd_to_ohci(hcd)); - -	ret = usb_add_hcd(hcd, irq, 0); -	if (ret) -		goto err_clk_disable; - -	return 0; - -err_clk_disable: -	clk_disable(usb_host_clock); -err_put_hcd: -	usb_put_hcd(hcd); - -	return ret; -} - -static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); - -	usb_remove_hcd(hcd); -	clk_disable(usb_host_clock); -	usb_put_hcd(hcd); - -	return 0; -} - -#ifdef CONFIG_PM -static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); - -	if (time_before(jiffies, ohci->next_statechange)) -		msleep(5); -	ohci->next_statechange = jiffies; - -	clk_disable(usb_host_clock); -	return 0; -} - -static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) -{ -	struct usb_hcd *hcd = platform_get_drvdata(pdev); -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); - -	if (time_before(jiffies, ohci->next_statechange)) -		msleep(5); -	ohci->next_statechange = jiffies; - -	clk_enable(usb_host_clock); - -	ohci_resume(hcd, false); -	return 0; -} -#endif - - -static struct platform_driver ohci_hcd_ep93xx_driver = { -	.probe		= ohci_hcd_ep93xx_drv_probe, -	.remove		= ohci_hcd_ep93xx_drv_remove, -	.shutdown	= usb_hcd_platform_shutdown, -#ifdef CONFIG_PM -	.suspend	= ohci_hcd_ep93xx_drv_suspend, -	.resume		= ohci_hcd_ep93xx_drv_resume, -#endif -	.driver		= { -		.name	= "ep93xx-ohci", -		.owner	= THIS_MODULE, -	}, -}; - -MODULE_ALIAS("platform:ep93xx-ohci"); diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index dc6ee9adacf..060a6a41475 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c @@ -12,100 +12,139 @@   */  #include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/of.h>  #include <linux/platform_device.h> -#include <linux/platform_data/usb-ohci-exynos.h> +#include <linux/phy/phy.h>  #include <linux/usb/phy.h>  #include <linux/usb/samsung_usb_phy.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> +#include <linux/usb/otg.h> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI EXYNOS driver" + +static const char hcd_name[] = "ohci-exynos"; +static struct hc_driver __read_mostly exynos_ohci_hc_driver; + +#define to_exynos_ohci(hcd) (struct exynos_ohci_hcd *)(hcd_to_ohci(hcd)->priv) + +#define PHY_NUMBER 3  struct exynos_ohci_hcd { -	struct device *dev; -	struct usb_hcd *hcd;  	struct clk *clk;  	struct usb_phy *phy;  	struct usb_otg *otg; -	struct exynos4_ohci_platdata *pdata; +	struct phy *phy_g[PHY_NUMBER];  }; -static void exynos_ohci_phy_enable(struct exynos_ohci_hcd *exynos_ohci) +static int exynos_ohci_get_phy(struct device *dev, +				struct exynos_ohci_hcd *exynos_ohci)  { -	struct platform_device *pdev = to_platform_device(exynos_ohci->dev); +	struct device_node *child; +	struct phy *phy; +	int phy_number; +	int ret = 0; + +	exynos_ohci->phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2); +	if (IS_ERR(exynos_ohci->phy)) { +		ret = PTR_ERR(exynos_ohci->phy); +		if (ret != -ENXIO && ret != -ENODEV) { +			dev_err(dev, "no usb2 phy configured\n"); +			return ret; +		} +		dev_dbg(dev, "Failed to get usb2 phy\n"); +	} else { +		exynos_ohci->otg = exynos_ohci->phy->otg; +	} -	if (exynos_ohci->phy) -		usb_phy_init(exynos_ohci->phy); -	else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_init) -		exynos_ohci->pdata->phy_init(pdev, USB_PHY_TYPE_HOST); -} +	/* +	 * Getting generic phy: +	 * We are keeping both types of phys as a part of transiting OHCI +	 * to generic phy framework, so as to maintain backward compatibilty +	 * with old DTB. +	 * If there are existing devices using DTB files built from them, +	 * to remove the support for old bindings in this driver, +	 * we need to make sure that such devices have their DTBs +	 * updated to ones built from new DTS. +	 */ +	for_each_available_child_of_node(dev->of_node, child) { +		ret = of_property_read_u32(child, "reg", &phy_number); +		if (ret) { +			dev_err(dev, "Failed to parse device tree\n"); +			of_node_put(child); +			return ret; +		} -static void exynos_ohci_phy_disable(struct exynos_ohci_hcd *exynos_ohci) -{ -	struct platform_device *pdev = to_platform_device(exynos_ohci->dev); +		if (phy_number >= PHY_NUMBER) { +			dev_err(dev, "Invalid number of PHYs\n"); +			of_node_put(child); +			return -EINVAL; +		} -	if (exynos_ohci->phy) -		usb_phy_shutdown(exynos_ohci->phy); -	else if (exynos_ohci->pdata && exynos_ohci->pdata->phy_exit) -		exynos_ohci->pdata->phy_exit(pdev, USB_PHY_TYPE_HOST); +		phy = devm_of_phy_get(dev, child, 0); +		of_node_put(child); +		if (IS_ERR(phy)) { +			ret = PTR_ERR(phy); +			if (ret != -ENOSYS && ret != -ENODEV) { +				dev_err(dev, "no usb2 phy configured\n"); +				return ret; +			} +			dev_dbg(dev, "Failed to get usb2 phy\n"); +		} +		exynos_ohci->phy_g[phy_number] = phy; +	} + +	return ret;  } -static int ohci_exynos_reset(struct usb_hcd *hcd) +static int exynos_ohci_phy_enable(struct device *dev)  { -	return ohci_init(hcd_to_ohci(hcd)); +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); +	int i; +	int ret = 0; + +	if (!IS_ERR(exynos_ohci->phy)) +		return usb_phy_init(exynos_ohci->phy); + +	for (i = 0; ret == 0 && i < PHY_NUMBER; i++) +		if (!IS_ERR(exynos_ohci->phy_g[i])) +			ret = phy_power_on(exynos_ohci->phy_g[i]); +	if (ret) +		for (i--; i >= 0; i--) +			if (!IS_ERR(exynos_ohci->phy_g[i])) +				phy_power_off(exynos_ohci->phy_g[i]); + +	return ret;  } -static int ohci_exynos_start(struct usb_hcd *hcd) +static void exynos_ohci_phy_disable(struct device *dev)  { -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	int ret; - -	ohci_dbg(ohci, "ohci_exynos_start, ohci:%p", ohci); +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); +	int i; -	ret = ohci_run(ohci); -	if (ret < 0) { -		dev_err(hcd->self.controller, "can't start %s\n", -			hcd->self.bus_name); -		ohci_stop(hcd); -		return ret; +	if (!IS_ERR(exynos_ohci->phy)) { +		usb_phy_shutdown(exynos_ohci->phy); +		return;  	} -	return 0; +	for (i = 0; i < PHY_NUMBER; i++) +		if (!IS_ERR(exynos_ohci->phy_g[i])) +			phy_power_off(exynos_ohci->phy_g[i]);  } -static const struct hc_driver exynos_ohci_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "EXYNOS OHCI Host Controller", -	.hcd_priv_size		= sizeof(struct ohci_hcd), - -	.irq			= ohci_irq, -	.flags			= HCD_MEMORY|HCD_USB11, - -	.reset			= ohci_exynos_reset, -	.start			= ohci_exynos_start, -	.stop			= ohci_stop, -	.shutdown		= ohci_shutdown, - -	.get_frame_number	= ohci_get_frame, - -	.urb_enqueue		= ohci_urb_enqueue, -	.urb_dequeue		= ohci_urb_dequeue, -	.endpoint_disable	= ohci_endpoint_disable, - -	.hub_status_data	= ohci_hub_status_data, -	.hub_control		= ohci_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend		= ohci_bus_suspend, -	.bus_resume		= ohci_bus_resume, -#endif -	.start_port_reset	= ohci_start_port_reset, -}; -  static int exynos_ohci_probe(struct platform_device *pdev)  { -	struct exynos4_ohci_platdata *pdata = dev_get_platdata(&pdev->dev);  	struct exynos_ohci_hcd *exynos_ohci;  	struct usb_hcd *hcd; -	struct ohci_hcd *ohci;  	struct resource *res; -	struct usb_phy *phy;  	int irq;  	int err; @@ -114,46 +153,28 @@ static int exynos_ohci_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we move to full device tree support this will vanish off.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); - -	exynos_ohci = devm_kzalloc(&pdev->dev, sizeof(struct exynos_ohci_hcd), -					GFP_KERNEL); -	if (!exynos_ohci) +	err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (err) +		return err; + +	hcd = usb_create_hcd(&exynos_ohci_hc_driver, +				&pdev->dev, dev_name(&pdev->dev)); +	if (!hcd) { +		dev_err(&pdev->dev, "Unable to create HCD\n");  		return -ENOMEM; +	} + +	exynos_ohci = to_exynos_ohci(hcd);  	if (of_device_is_compatible(pdev->dev.of_node,  					"samsung,exynos5440-ohci"))  		goto skip_phy; -	phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); -	if (IS_ERR(phy)) { -		/* Fallback to pdata */ -		if (!pdata) { -			dev_warn(&pdev->dev, "no platform data or transceiver defined\n"); -			return -EPROBE_DEFER; -		} else { -			exynos_ohci->pdata = pdata; -		} -	} else { -		exynos_ohci->phy = phy; -		exynos_ohci->otg = phy->otg; -	} +	err = exynos_ohci_get_phy(&pdev->dev, exynos_ohci); +	if (err) +		goto fail_clk;  skip_phy: - -	exynos_ohci->dev = &pdev->dev; - -	hcd = usb_create_hcd(&exynos_ohci_hc_driver, &pdev->dev, -					dev_name(&pdev->dev)); -	if (!hcd) { -		dev_err(&pdev->dev, "Unable to create HCD\n"); -		return -ENOMEM; -	} - -	exynos_ohci->hcd = hcd;  	exynos_ohci->clk = devm_clk_get(&pdev->dev, "usbhost");  	if (IS_ERR(exynos_ohci->clk)) { @@ -175,10 +196,9 @@ skip_phy:  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	hcd->regs = devm_ioremap(&pdev->dev, res->start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "Failed to remap I/O memory\n"); -		err = -ENOMEM; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		err = PTR_ERR(hcd->regs);  		goto fail_io;  	} @@ -190,26 +210,26 @@ skip_phy:  	}  	if (exynos_ohci->otg) -		exynos_ohci->otg->set_host(exynos_ohci->otg, -					&exynos_ohci->hcd->self); +		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); -	exynos_ohci_phy_enable(exynos_ohci); +	platform_set_drvdata(pdev, hcd); -	ohci = hcd_to_ohci(hcd); -	ohci_hcd_init(ohci); +	err = exynos_ohci_phy_enable(&pdev->dev); +	if (err) { +		dev_err(&pdev->dev, "Failed to enable USB phy\n"); +		goto fail_io; +	}  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (err) {  		dev_err(&pdev->dev, "Failed to add USB HCD\n");  		goto fail_add_hcd;  	} - -	platform_set_drvdata(pdev, exynos_ohci); - +	device_wakeup_enable(hcd->self.controller);  	return 0;  fail_add_hcd: -	exynos_ohci_phy_disable(exynos_ohci); +	exynos_ohci_phy_disable(&pdev->dev);  fail_io:  	clk_disable_unprepare(exynos_ohci->clk);  fail_clk: @@ -219,16 +239,15 @@ fail_clk:  static int exynos_ohci_remove(struct platform_device *pdev)  { -	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = exynos_ohci->hcd; +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd);  	usb_remove_hcd(hcd);  	if (exynos_ohci->otg) -		exynos_ohci->otg->set_host(exynos_ohci->otg, -					&exynos_ohci->hcd->self); +		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); -	exynos_ohci_phy_disable(exynos_ohci); +	exynos_ohci_phy_disable(&pdev->dev);  	clk_disable_unprepare(exynos_ohci->clk); @@ -239,8 +258,7 @@ static int exynos_ohci_remove(struct platform_device *pdev)  static void exynos_ohci_shutdown(struct platform_device *pdev)  { -	struct exynos_ohci_hcd *exynos_ohci = platform_get_drvdata(pdev); -	struct usb_hcd *hcd = exynos_ohci->hcd; +	struct usb_hcd *hcd = platform_get_drvdata(pdev);  	if (hcd->driver->shutdown)  		hcd->driver->shutdown(hcd); @@ -249,53 +267,41 @@ static void exynos_ohci_shutdown(struct platform_device *pdev)  #ifdef CONFIG_PM  static int exynos_ohci_suspend(struct device *dev)  { -	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); -	struct usb_hcd *hcd = exynos_ohci->hcd; -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	unsigned long flags; -	int rc = 0; - -	/* -	 * Root hub was already suspended. Disable irq emission and -	 * mark HW unaccessible, bail out if RH has been resumed. Use -	 * the spinlock to properly synchronize with possible pending -	 * RH suspend or resume activity. -	 */ -	spin_lock_irqsave(&ohci->lock, flags); -	if (ohci->rh_state != OHCI_RH_SUSPENDED && -			ohci->rh_state != OHCI_RH_HALTED) { -		rc = -EINVAL; -		goto fail; -	} +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct exynos_ohci_hcd *exynos_ohci = to_exynos_ohci(hcd); +	bool do_wakeup = device_may_wakeup(dev); +	int rc = ohci_suspend(hcd, do_wakeup); -	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	if (rc) +		return rc;  	if (exynos_ohci->otg) -		exynos_ohci->otg->set_host(exynos_ohci->otg, -					&exynos_ohci->hcd->self); +		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); -	exynos_ohci_phy_disable(exynos_ohci); +	exynos_ohci_phy_disable(dev);  	clk_disable_unprepare(exynos_ohci->clk); -fail: -	spin_unlock_irqrestore(&ohci->lock, flags); - -	return rc; +	return 0;  }  static int exynos_ohci_resume(struct device *dev)  { -	struct exynos_ohci_hcd *exynos_ohci = dev_get_drvdata(dev); -	struct usb_hcd *hcd = exynos_ohci->hcd; +	struct usb_hcd *hcd			= dev_get_drvdata(dev); +	struct exynos_ohci_hcd *exynos_ohci	= to_exynos_ohci(hcd); +	int ret;  	clk_prepare_enable(exynos_ohci->clk);  	if (exynos_ohci->otg) -		exynos_ohci->otg->set_host(exynos_ohci->otg, -					&exynos_ohci->hcd->self); +		exynos_ohci->otg->set_host(exynos_ohci->otg, &hcd->self); -	exynos_ohci_phy_enable(exynos_ohci); +	ret = exynos_ohci_phy_enable(dev); +	if (ret) { +		dev_err(dev, "Failed to enable USB phy\n"); +		clk_disable_unprepare(exynos_ohci->clk); +		return ret; +	}  	ohci_resume(hcd, false); @@ -306,6 +312,10 @@ static int exynos_ohci_resume(struct device *dev)  #define exynos_ohci_resume	NULL  #endif +static const struct ohci_driver_overrides exynos_overrides __initconst = { +	.extra_priv_size =	sizeof(struct exynos_ohci_hcd), +}; +  static const struct dev_pm_ops exynos_ohci_pm_ops = {  	.suspend	= exynos_ohci_suspend,  	.resume		= exynos_ohci_resume, @@ -331,6 +341,23 @@ static struct platform_driver exynos_ohci_driver = {  		.of_match_table	= of_match_ptr(exynos_ohci_match),  	}  }; +static int __init ohci_exynos_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); +	ohci_init_driver(&exynos_ohci_hc_driver, &exynos_overrides); +	return platform_driver_register(&exynos_ohci_driver); +} +module_init(ohci_exynos_init); + +static void __exit ohci_exynos_cleanup(void) +{ +	platform_driver_unregister(&exynos_ohci_driver); +} +module_exit(ohci_exynos_cleanup);  MODULE_ALIAS("platform:exynos-ohci");  MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 8f6b695af6a..f98d03f3144 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -51,8 +51,6 @@  /*-------------------------------------------------------------------------*/ -#undef OHCI_VERBOSE_DEBUG	/* not always helpful */ -  /* For initializing controller (mask in an HCFS mode too) */  #define	OHCI_CONTROL_INIT	OHCI_CTRL_CBSR  #define	OHCI_INTR_INIT \ @@ -127,10 +125,6 @@ static int ohci_urb_enqueue (  	unsigned long	flags;  	int		retval = 0; -#ifdef OHCI_VERBOSE_DEBUG -	urb_print(urb, "SUB", usb_pipein(pipe), -EINPROGRESS); -#endif -  	/* every endpoint has a ed, locate and maybe (re)initialize it */  	if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval)))  		return -ENOMEM; @@ -216,31 +210,26 @@ static int ohci_urb_enqueue (  			frame &= ~(ed->interval - 1);  			frame |= ed->branch;  			urb->start_frame = frame; +			ed->last_iso = frame + ed->interval * (size - 1);  		}  	} else if (ed->type == PIPE_ISOCHRONOUS) {  		u16	next = ohci_frame_no(ohci) + 1;  		u16	frame = ed->last_iso + ed->interval; +		u16	length = ed->interval * (size - 1);  		/* Behind the scheduling threshold? */  		if (unlikely(tick_before(frame, next))) { -			/* USB_ISO_ASAP: Round up to the first available slot */ +			/* URB_ISO_ASAP: Round up to the first available slot */  			if (urb->transfer_flags & URB_ISO_ASAP) {  				frame += (next - frame + ed->interval - 1) &  						-ed->interval;  			/* -			 * Not ASAP: Use the next slot in the stream.  If -			 * the entire URB falls before the threshold, fail. +			 * Not ASAP: Use the next slot in the stream, +			 * no matter what.  			 */  			} else { -				if (tick_before(frame + ed->interval * -					(urb->number_of_packets - 1), next)) { -					retval = -EXDEV; -					usb_hcd_unlink_urb_from_ep(hcd, urb); -					goto fail; -				} -  				/*  				 * Some OHCI hardware doesn't handle late TDs  				 * correctly.  After retiring them it proceeds @@ -251,9 +240,16 @@ static int ohci_urb_enqueue (  				urb_priv->td_cnt = DIV_ROUND_UP(  						(u16) (next - frame),  						ed->interval); +				if (urb_priv->td_cnt >= urb_priv->length) { +					++urb_priv->td_cnt;	/* Mark it */ +					ohci_dbg(ohci, "iso underrun %p (%u+%u < %u)\n", +							urb, frame, length, +							next); +				}  			}  		}  		urb->start_frame = frame; +		ed->last_iso = frame + length;  	}  	/* fill the TDs and link them to the ed; and @@ -282,10 +278,6 @@ static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  	unsigned long		flags;  	int			rc; -#ifdef OHCI_VERBOSE_DEBUG -	urb_print(urb, "UNLINK", 1, status); -#endif -  	spin_lock_irqsave (&ohci->lock, flags);  	rc = usb_hcd_check_unlink_urb(hcd, urb, status);  	if (rc) { @@ -838,7 +830,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  	}  	if (ints & OHCI_INTR_RHSC) { -		ohci_vdbg(ohci, "rhsc\n"); +		ohci_dbg(ohci, "rhsc\n");  		ohci->next_statechange = jiffies + STATECHANGE_DELAY;  		ohci_writel(ohci, OHCI_INTR_RD | OHCI_INTR_RHSC,  				®s->intrstatus); @@ -860,7 +852,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)  	 * this might not happen.  	 */  	else if (ints & OHCI_INTR_RD) { -		ohci_vdbg(ohci, "resume detect\n"); +		ohci_dbg(ohci, "resume detect\n");  		ohci_writel(ohci, OHCI_INTR_RD, ®s->intrstatus);  		set_bit(HCD_FLAG_POLL_RH, &hcd->flags);  		if (ohci->autostop) { @@ -1034,6 +1026,7 @@ int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)  {  	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);  	unsigned long	flags; +	int		rc = 0;  	/* Disable irq emission and mark HW unaccessible. Use  	 * the spinlock to properly synchronize with possible pending @@ -1046,7 +1039,13 @@ int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)  	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);  	spin_unlock_irqrestore (&ohci->lock, flags); -	return 0; +	synchronize_irq(hcd->irq); + +	if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { +		ohci_resume(hcd, false); +		rc = -EBUSY; +	} +	return rc;  }  EXPORT_SYMBOL_GPL(ohci_suspend); @@ -1159,10 +1158,12 @@ void ohci_init_driver(struct hc_driver *drv,  	/* Copy the generic table to drv and then apply the overrides */  	*drv = ohci_hc_driver; -	drv->product_desc = over->product_desc; -	drv->hcd_priv_size += over->extra_priv_size; -	if (over->reset) -		drv->reset = over->reset; +	if (over) { +		drv->product_desc = over->product_desc; +		drv->hcd_priv_size += over->extra_priv_size; +		if (over->reset) +			drv->reset = over->reset; +	}  }  EXPORT_SYMBOL_GPL(ohci_init_driver); @@ -1177,47 +1178,7 @@ MODULE_LICENSE ("GPL");  #define SA1111_DRIVER		ohci_hcd_sa1111_driver  #endif -#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S3C64XX) -#include "ohci-s3c2410.c" -#define S3C2410_PLATFORM_DRIVER	ohci_hcd_s3c2410_driver -#endif - -#ifdef CONFIG_USB_OHCI_EXYNOS -#include "ohci-exynos.c" -#define EXYNOS_PLATFORM_DRIVER	exynos_ohci_driver -#endif - -#ifdef CONFIG_USB_OHCI_HCD_OMAP1 -#include "ohci-omap.c" -#define OMAP1_PLATFORM_DRIVER	ohci_hcd_omap_driver -#endif - -#ifdef CONFIG_USB_OHCI_HCD_OMAP3 -#include "ohci-omap3.c" -#define OMAP3_PLATFORM_DRIVER	ohci_hcd_omap3_driver -#endif - -#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) -#include "ohci-pxa27x.c" -#define PLATFORM_DRIVER		ohci_hcd_pxa27x_driver -#endif - -#ifdef CONFIG_ARCH_EP93XX -#include "ohci-ep93xx.c" -#define EP93XX_PLATFORM_DRIVER	ohci_hcd_ep93xx_driver -#endif - -#ifdef CONFIG_ARCH_AT91 -#include "ohci-at91.c" -#define AT91_PLATFORM_DRIVER	ohci_hcd_at91_driver -#endif - -#ifdef CONFIG_ARCH_LPC32XX -#include "ohci-nxp.c" -#define NXP_PLATFORM_DRIVER	usb_hcd_nxp_driver -#endif - -#ifdef CONFIG_ARCH_DAVINCI_DA8XX +#ifdef CONFIG_USB_OHCI_HCD_DAVINCI  #include "ohci-da8xx.c"  #define DAVINCI_PLATFORM_DRIVER	ohci_hcd_da8xx_driver  #endif @@ -1227,11 +1188,6 @@ MODULE_LICENSE ("GPL");  #define OF_PLATFORM_DRIVER	ohci_hcd_ppc_of_driver  #endif -#ifdef CONFIG_PLAT_SPEAR -#include "ohci-spear.c" -#define SPEAR_PLATFORM_DRIVER	spear_ohci_hcd_driver -#endif -  #ifdef CONFIG_PPC_PS3  #include "ohci-ps3.c"  #define PS3_SYSTEM_BUS_DRIVER	ps3_ohci_driver @@ -1274,13 +1230,11 @@ static int __init ohci_hcd_mod_init(void)  		sizeof (struct ed), sizeof (struct td));  	set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); -#ifdef DEBUG  	ohci_debug_root = debugfs_create_dir("ohci", usb_debug_root);  	if (!ohci_debug_root) {  		retval = -ENOENT;  		goto error_debug;  	} -#endif  #ifdef PS3_SYSTEM_BUS_DRIVER  	retval = ps3_ohci_driver_register(&PS3_SYSTEM_BUS_DRIVER); @@ -1294,18 +1248,6 @@ static int __init ohci_hcd_mod_init(void)  		goto error_platform;  #endif -#ifdef OMAP1_PLATFORM_DRIVER -	retval = platform_driver_register(&OMAP1_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_omap1_platform; -#endif - -#ifdef OMAP3_PLATFORM_DRIVER -	retval = platform_driver_register(&OMAP3_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_omap3_platform; -#endif -  #ifdef OF_PLATFORM_DRIVER  	retval = platform_driver_register(&OF_PLATFORM_DRIVER);  	if (retval < 0) @@ -1330,79 +1272,19 @@ static int __init ohci_hcd_mod_init(void)  		goto error_tmio;  #endif -#ifdef S3C2410_PLATFORM_DRIVER -	retval = platform_driver_register(&S3C2410_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_s3c2410; -#endif - -#ifdef EXYNOS_PLATFORM_DRIVER -	retval = platform_driver_register(&EXYNOS_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_exynos; -#endif - -#ifdef EP93XX_PLATFORM_DRIVER -	retval = platform_driver_register(&EP93XX_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_ep93xx; -#endif - -#ifdef AT91_PLATFORM_DRIVER -	retval = platform_driver_register(&AT91_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_at91; -#endif - -#ifdef NXP_PLATFORM_DRIVER -	retval = platform_driver_register(&NXP_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_nxp; -#endif -  #ifdef DAVINCI_PLATFORM_DRIVER  	retval = platform_driver_register(&DAVINCI_PLATFORM_DRIVER);  	if (retval < 0)  		goto error_davinci;  #endif -#ifdef SPEAR_PLATFORM_DRIVER -	retval = platform_driver_register(&SPEAR_PLATFORM_DRIVER); -	if (retval < 0) -		goto error_spear; -#endif -  	return retval;  	/* Error path */ -#ifdef SPEAR_PLATFORM_DRIVER -	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER); - error_spear: -#endif  #ifdef DAVINCI_PLATFORM_DRIVER  	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);   error_davinci:  #endif -#ifdef NXP_PLATFORM_DRIVER -	platform_driver_unregister(&NXP_PLATFORM_DRIVER); - error_nxp: -#endif -#ifdef AT91_PLATFORM_DRIVER -	platform_driver_unregister(&AT91_PLATFORM_DRIVER); - error_at91: -#endif -#ifdef EP93XX_PLATFORM_DRIVER -	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); - error_ep93xx: -#endif -#ifdef EXYNOS_PLATFORM_DRIVER -	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER); - error_exynos: -#endif -#ifdef S3C2410_PLATFORM_DRIVER -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER); - error_s3c2410: -#endif  #ifdef TMIO_OHCI_DRIVER  	platform_driver_unregister(&TMIO_OHCI_DRIVER);   error_tmio: @@ -1419,14 +1301,6 @@ static int __init ohci_hcd_mod_init(void)  	platform_driver_unregister(&OF_PLATFORM_DRIVER);   error_of_platform:  #endif -#ifdef OMAP3_PLATFORM_DRIVER -	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER); - error_omap3_platform: -#endif -#ifdef OMAP1_PLATFORM_DRIVER -	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER); - error_omap1_platform: -#endif  #ifdef PLATFORM_DRIVER  	platform_driver_unregister(&PLATFORM_DRIVER);   error_platform: @@ -1435,11 +1309,9 @@ static int __init ohci_hcd_mod_init(void)  	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);   error_ps3:  #endif -#ifdef DEBUG  	debugfs_remove(ohci_debug_root);  	ohci_debug_root = NULL;   error_debug: -#endif  	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);  	return retval; @@ -1448,27 +1320,9 @@ module_init(ohci_hcd_mod_init);  static void __exit ohci_hcd_mod_exit(void)  { -#ifdef SPEAR_PLATFORM_DRIVER -	platform_driver_unregister(&SPEAR_PLATFORM_DRIVER); -#endif  #ifdef DAVINCI_PLATFORM_DRIVER  	platform_driver_unregister(&DAVINCI_PLATFORM_DRIVER);  #endif -#ifdef NXP_PLATFORM_DRIVER -	platform_driver_unregister(&NXP_PLATFORM_DRIVER); -#endif -#ifdef AT91_PLATFORM_DRIVER -	platform_driver_unregister(&AT91_PLATFORM_DRIVER); -#endif -#ifdef EP93XX_PLATFORM_DRIVER -	platform_driver_unregister(&EP93XX_PLATFORM_DRIVER); -#endif -#ifdef EXYNOS_PLATFORM_DRIVER -	platform_driver_unregister(&EXYNOS_PLATFORM_DRIVER); -#endif -#ifdef S3C2410_PLATFORM_DRIVER -	platform_driver_unregister(&S3C2410_PLATFORM_DRIVER); -#endif  #ifdef TMIO_OHCI_DRIVER  	platform_driver_unregister(&TMIO_OHCI_DRIVER);  #endif @@ -1481,21 +1335,13 @@ static void __exit ohci_hcd_mod_exit(void)  #ifdef OF_PLATFORM_DRIVER  	platform_driver_unregister(&OF_PLATFORM_DRIVER);  #endif -#ifdef OMAP3_PLATFORM_DRIVER -	platform_driver_unregister(&OMAP3_PLATFORM_DRIVER); -#endif -#ifdef OMAP1_PLATFORM_DRIVER -	platform_driver_unregister(&OMAP1_PLATFORM_DRIVER); -#endif  #ifdef PLATFORM_DRIVER  	platform_driver_unregister(&PLATFORM_DRIVER);  #endif  #ifdef PS3_SYSTEM_BUS_DRIVER  	ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);  #endif -#ifdef DEBUG  	debugfs_remove(ohci_debug_root); -#endif  	clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);  }  module_exit(ohci_hcd_mod_exit); diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2347ab83f04..b4940de1eba 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c @@ -90,6 +90,24 @@ __acquires(ohci->lock)  	dl_done_list (ohci);  	finish_unlinks (ohci, ohci_frame_no(ohci)); +	/* +	 * Some controllers don't handle "global" suspend properly if +	 * there are unsuspended ports.  For these controllers, put all +	 * the enabled ports into suspend before suspending the root hub. +	 */ +	if (ohci->flags & OHCI_QUIRK_GLOBAL_SUSPEND) { +		__hc32 __iomem	*portstat = ohci->regs->roothub.portstatus; +		int		i; +		unsigned	temp; + +		for (i = 0; i < ohci->num_ports; (++i, ++portstat)) { +			temp = ohci_readl(ohci, portstat); +			if ((temp & (RH_PS_PES | RH_PS_PSS)) == +					RH_PS_PES) +				ohci_writel(ohci, RH_PS_PSS, portstat); +		} +	} +  	/* maybe resume can wake root hub */  	if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) {  		ohci->hc_control |= OHCI_CTRL_RWE; @@ -212,10 +230,11 @@ __acquires(ohci->lock)  	/* Sometimes PCI D3 suspend trashes frame timings ... */  	periodic_reinit (ohci); -	/* the following code is executed with ohci->lock held and -	 * irqs disabled if and only if autostopped is true +	/* +	 * The following code is executed with ohci->lock held and +	 * irqs disabled if and only if autostopped is true.  This +	 * will cause sparse to warn about a "context imbalance".  	 */ -  skip_resume:  	/* interrupts might have been disabled */  	ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable); @@ -437,8 +456,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,  /* build "status change" packet (one or two bytes) from HC registers */ -static int -ohci_hub_status_data (struct usb_hcd *hcd, char *buf) +int ohci_hub_status_data(struct usb_hcd *hcd, char *buf)  {  	struct ohci_hcd	*ohci = hcd_to_ohci (hcd);  	int		i, changed = 0, length = 1; @@ -503,6 +521,7 @@ done:  	return changed ? length : 0;  } +EXPORT_SYMBOL_GPL(ohci_hub_status_data);  /*-------------------------------------------------------------------------*/ @@ -531,7 +550,7 @@ ohci_hub_descriptor (  	    temp |= 0x0010;  	else if (rh & RH_A_OCPM)	/* per-port overcurrent reporting? */  	    temp |= 0x0008; -	desc->wHubCharacteristics = (__force __u16)cpu_to_hc16(ohci, temp); +	desc->wHubCharacteristics = cpu_to_le16(temp);  	/* ports removable, and usb 1.0 legacy PortPwrCtrlMask */  	rh = roothub_b (ohci); @@ -645,7 +664,7 @@ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port)  	return 0;  } -static int ohci_hub_control ( +int ohci_hub_control(  	struct usb_hcd	*hcd,  	u16		typeReq,  	u16		wValue, @@ -724,10 +743,8 @@ static int ohci_hub_control (  		temp = roothub_portstatus (ohci, wIndex);  		put_unaligned_le32(temp, buf); -#ifndef	OHCI_VERBOSE_DEBUG -	if (*(u16*)(buf+2))	/* only if wPortChange is interesting */ -#endif -		dbg_port (ohci, "GetStatus", wIndex, temp); +		if (*(u16*)(buf+2))	/* only if wPortChange is interesting */ +			dbg_port(ohci, "GetStatus", wIndex, temp);  		break;  	case SetHubFeature:  		switch (wValue) { @@ -773,4 +790,4 @@ error:  	}  	return retval;  } - +EXPORT_SYMBOL_GPL(ohci_hub_control); diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index d4ef53990d7..c2c221a332e 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -82,14 +82,14 @@ static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  	u16 wIndex, char *buf, u16 wLength)  {  	struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd); -	int ret; +	int ret = 0;  	switch (typeReq) { -	case SetHubFeature: +	case SetPortFeature:  		if (wValue == USB_PORT_FEAT_POWER)  			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true);  		break; -	case ClearHubFeature: +	case ClearPortFeature:  		if (wValue == USB_PORT_FEAT_POWER)  			ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false);  		break; @@ -174,31 +174,23 @@ static int jz4740_ohci_probe(struct platform_device *pdev)  	jz4740_ohci = hcd_to_jz4740_hcd(hcd); -	res = request_mem_region(res->start, resource_size(res), hcd_name); -	if (!res) { -		dev_err(&pdev->dev, "Failed to request mem region.\n"); -		ret = -EBUSY; -		goto err_free; -	} -  	hcd->rsrc_start = res->start;  	hcd->rsrc_len = resource_size(res); -	hcd->regs = ioremap(res->start, resource_size(res)); -	if (!hcd->regs) { -		dev_err(&pdev->dev, "Failed to ioremap registers.\n"); -		ret = -EBUSY; -		goto err_release_mem; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		ret = PTR_ERR(hcd->regs); +		goto err_free;  	} -	jz4740_ohci->clk = clk_get(&pdev->dev, "uhc"); +	jz4740_ohci->clk = devm_clk_get(&pdev->dev, "uhc");  	if (IS_ERR(jz4740_ohci->clk)) {  		ret = PTR_ERR(jz4740_ohci->clk);  		dev_err(&pdev->dev, "Failed to get clock: %d\n", ret); -		goto err_iounmap; +		goto err_free;  	} -	jz4740_ohci->vbus = regulator_get(&pdev->dev, "vbus"); +	jz4740_ohci->vbus = devm_regulator_get(&pdev->dev, "vbus");  	if (IS_ERR(jz4740_ohci->vbus))  		jz4740_ohci->vbus = NULL; @@ -217,21 +209,15 @@ static int jz4740_ohci_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "Failed to add hcd: %d\n", ret);  		goto err_disable;  	} +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_disable: -	if (jz4740_ohci->vbus) { +	if (jz4740_ohci->vbus)  		regulator_disable(jz4740_ohci->vbus); -		regulator_put(jz4740_ohci->vbus); -	}  	clk_disable(jz4740_ohci->clk); -	clk_put(jz4740_ohci->clk); -err_iounmap: -	iounmap(hcd->regs); -err_release_mem: -	release_mem_region(res->start, resource_size(res));  err_free:  	usb_put_hcd(hcd); @@ -245,16 +231,10 @@ static int jz4740_ohci_remove(struct platform_device *pdev)  	usb_remove_hcd(hcd); -	if (jz4740_ohci->vbus) { +	if (jz4740_ohci->vbus)  		regulator_disable(jz4740_ohci->vbus); -		regulator_put(jz4740_ohci->vbus); -	}  	clk_disable(jz4740_ohci->clk); -	clk_put(jz4740_ohci->clk); - -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd); diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index 7d7d507d54e..ba180ed0f81 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -19,10 +19,19 @@   * or implied.   */  #include <linux/clk.h> -#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/io.h>  #include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/of.h> +#include <linux/platform_device.h>  #include <linux/usb/isp1301.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include "ohci.h" +  #include <mach/hardware.h>  #include <asm/mach-types.h> @@ -57,6 +66,11 @@  #define start_int_umask(irq)  #endif +#define DRIVER_DESC "OHCI NXP driver" + +static const char hcd_name[] = "ohci-nxp"; +static struct hc_driver __read_mostly ohci_nxp_hc_driver; +  static struct i2c_client *isp1301_i2c_client;  extern int usb_disabled(void); @@ -132,14 +146,14 @@ static inline void isp1301_vbus_off(void)  		OTG1_VBUS_DRV);  } -static void nxp_start_hc(void) +static void ohci_nxp_start_hc(void)  {  	unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;  	__raw_writel(tmp, USB_OTG_STAT_CONTROL);  	isp1301_vbus_on();  } -static void nxp_stop_hc(void) +static void ohci_nxp_stop_hc(void)  {  	unsigned long tmp;  	isp1301_vbus_off(); @@ -147,68 +161,9 @@ static void nxp_stop_hc(void)  	__raw_writel(tmp, USB_OTG_STAT_CONTROL);  } -static int ohci_nxp_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	int ret; - -	if ((ret = ohci_init(ohci)) < 0) -		return ret; - -	if ((ret = ohci_run(ohci)) < 0) { -		dev_err(hcd->self.controller, "can't start\n"); -		ohci_stop(hcd); -		return ret; -	} -	return 0; -} - -static const struct hc_driver ohci_nxp_hc_driver = { -	.description = hcd_name, -	.product_desc =		"nxp OHCI", - -	/* -	 * generic hardware linkage -	 */ -	.irq = ohci_irq, -	.flags = HCD_USB11 | HCD_MEMORY, - -	.hcd_priv_size =	sizeof(struct ohci_hcd), -	/* -	 * basic lifecycle operations -	 */ -	.start = ohci_nxp_start, -	.stop = ohci_stop, -	.shutdown = ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue = ohci_urb_enqueue, -	.urb_dequeue = ohci_urb_dequeue, -	.endpoint_disable = ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number = ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data = ohci_hub_status_data, -	.hub_control = ohci_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend = ohci_bus_suspend, -	.bus_resume = ohci_bus_resume, -#endif -	.start_port_reset = ohci_start_port_reset, -}; - -static int usb_hcd_nxp_probe(struct platform_device *pdev) +static int ohci_hcd_nxp_probe(struct platform_device *pdev)  {  	struct usb_hcd *hcd = 0; -	struct ohci_hcd *ohci;  	const struct hc_driver *driver = &ohci_nxp_hc_driver;  	struct resource *res;  	int ret = 0, irq; @@ -226,8 +181,9 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)  		return -EPROBE_DEFER;  	} -	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; +	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		goto fail_disable;  	dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (nxp)\n", hcd_name);  	if (usb_disabled()) { @@ -240,17 +196,17 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)  	__raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL);  	/* Enable USB PLL */ -	usb_pll_clk = clk_get(&pdev->dev, "ck_pll5"); +	usb_pll_clk = devm_clk_get(&pdev->dev, "ck_pll5");  	if (IS_ERR(usb_pll_clk)) {  		dev_err(&pdev->dev, "failed to acquire USB PLL\n");  		ret = PTR_ERR(usb_pll_clk); -		goto fail_pll; +		goto fail_disable;  	}  	ret = clk_enable(usb_pll_clk);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to start USB PLL\n"); -		goto fail_pllen; +		goto fail_disable;  	}  	ret = clk_set_rate(usb_pll_clk, 48000); @@ -260,21 +216,21 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)  	}  	/* Enable USB device clock */ -	usb_dev_clk = clk_get(&pdev->dev, "ck_usbd"); +	usb_dev_clk = devm_clk_get(&pdev->dev, "ck_usbd");  	if (IS_ERR(usb_dev_clk)) {  		dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");  		ret = PTR_ERR(usb_dev_clk); -		goto fail_dev; +		goto fail_rate;  	}  	ret = clk_enable(usb_dev_clk);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); -		goto fail_deven; +		goto fail_rate;  	}  	/* Enable USB otg clocks */ -	usb_otg_clk = clk_get(&pdev->dev, "ck_usb_otg"); +	usb_otg_clk = devm_clk_get(&pdev->dev, "ck_usb_otg");  	if (IS_ERR(usb_otg_clk)) {  		dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n");  		ret = PTR_ERR(usb_otg_clk); @@ -286,7 +242,7 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)  	ret = clk_enable(usb_otg_clk);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); -		goto fail_otgen; +		goto fail_otg;  	}  	isp1301_configure(); @@ -313,49 +269,39 @@ static int usb_hcd_nxp_probe(struct platform_device *pdev)  		goto fail_resource;  	} -	nxp_start_hc(); +	ohci_nxp_start_hc();  	platform_set_drvdata(pdev, hcd); -	ohci = hcd_to_ohci(hcd); -	ohci_hcd_init(ohci);  	dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);  	ret = usb_add_hcd(hcd, irq, 0); -	if (ret == 0) +	if (ret == 0) { +		device_wakeup_enable(hcd->self.controller);  		return ret; +	} -	nxp_stop_hc(); +	ohci_nxp_stop_hc();  fail_resource:  	usb_put_hcd(hcd);  fail_hcd:  	clk_disable(usb_otg_clk); -fail_otgen: -	clk_put(usb_otg_clk);  fail_otg:  	clk_disable(usb_dev_clk); -fail_deven: -	clk_put(usb_dev_clk); -fail_dev:  fail_rate:  	clk_disable(usb_pll_clk); -fail_pllen: -	clk_put(usb_pll_clk); -fail_pll:  fail_disable:  	isp1301_i2c_client = NULL;  	return ret;  } -static int usb_hcd_nxp_remove(struct platform_device *pdev) +static int ohci_hcd_nxp_remove(struct platform_device *pdev)  {  	struct usb_hcd *hcd = platform_get_drvdata(pdev);  	usb_remove_hcd(hcd); -	nxp_stop_hc(); +	ohci_nxp_stop_hc();  	usb_put_hcd(hcd);  	clk_disable(usb_pll_clk); -	clk_put(usb_pll_clk);  	clk_disable(usb_dev_clk); -	clk_put(usb_dev_clk);  	i2c_unregister_device(isp1301_i2c_client);  	isp1301_i2c_client = NULL; @@ -366,20 +312,40 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev)  MODULE_ALIAS("platform:usb-ohci");  #ifdef CONFIG_OF -static const struct of_device_id usb_hcd_nxp_match[] = { +static const struct of_device_id ohci_hcd_nxp_match[] = {  	{ .compatible = "nxp,ohci-nxp" },  	{},  }; -MODULE_DEVICE_TABLE(of, usb_hcd_nxp_match); +MODULE_DEVICE_TABLE(of, ohci_hcd_nxp_match);  #endif -static struct platform_driver usb_hcd_nxp_driver = { +static struct platform_driver ohci_hcd_nxp_driver = {  	.driver = {  		.name = "usb-ohci",  		.owner	= THIS_MODULE, -		.of_match_table = of_match_ptr(usb_hcd_nxp_match), +		.of_match_table = of_match_ptr(ohci_hcd_nxp_match),  	}, -	.probe = usb_hcd_nxp_probe, -	.remove = usb_hcd_nxp_remove, +	.probe = ohci_hcd_nxp_probe, +	.remove = ohci_hcd_nxp_remove,  }; +static int __init ohci_nxp_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ohci_init_driver(&ohci_nxp_hc_driver, NULL); +	return platform_driver_register(&ohci_hcd_nxp_driver); +} +module_init(ohci_nxp_init); + +static void __exit ohci_nxp_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_nxp_driver); +} +module_exit(ohci_nxp_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/usb/host/ohci-octeon.c b/drivers/usb/host/ohci-octeon.c index 342dc7e543b..15af8954085 100644 --- a/drivers/usb/host/ohci-octeon.c +++ b/drivers/usb/host/ohci-octeon.c @@ -127,8 +127,9 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)  	}  	/* Ohci is a 32-bit device. */ -	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); -	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; +	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret;  	hcd = usb_create_hcd(&ohci_octeon_hc_driver, &pdev->dev, "octeon");  	if (!hcd) @@ -137,20 +138,12 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)  	hcd->rsrc_start = res_mem->start;  	hcd->rsrc_len = resource_size(res_mem); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, -				OCTEON_OHCI_HCD_NAME)) { -		dev_err(&pdev->dev, "request_mem_region failed\n"); -		ret = -EBUSY; +	reg_base = devm_ioremap_resource(&pdev->dev, res_mem); +	if (IS_ERR(reg_base)) { +		ret = PTR_ERR(reg_base);  		goto err1;  	} -	reg_base = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!reg_base) { -		dev_err(&pdev->dev, "ioremap failed\n"); -		ret = -ENOMEM; -		goto err2; -	} -  	ohci_octeon_hw_start();  	hcd->regs = reg_base; @@ -167,19 +160,18 @@ static int ohci_octeon_drv_probe(struct platform_device *pdev)  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret) {  		dev_dbg(&pdev->dev, "failed to add hcd with err %d\n", ret); -		goto err3; +		goto err2;  	} +	device_wakeup_enable(hcd->self.controller); +  	platform_set_drvdata(pdev, hcd);  	return 0; -err3: +err2:  	ohci_octeon_hw_stop(); -	iounmap(hcd->regs); -err2: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  err1:  	usb_put_hcd(hcd);  	return ret; @@ -192,8 +184,6 @@ static int ohci_octeon_drv_remove(struct platform_device *pdev)  	usb_remove_hcd(hcd);  	ohci_octeon_hw_stop(); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd);  	return 0; diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 31d3a12eb48..c923cafcaca 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -14,12 +14,21 @@   * This file is licenced under the GPL.   */ -#include <linux/signal.h> -#include <linux/jiffies.h> -#include <linux/platform_device.h>  #include <linux/clk.h> +#include <linux/dma-mapping.h>  #include <linux/err.h>  #include <linux/gpio.h> +#include <linux/io.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/usb/otg.h> +#include <linux/platform_device.h> +#include <linux/signal.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include "ohci.h"  #include <asm/io.h>  #include <asm/mach-types.h> @@ -42,10 +51,7 @@  #define OMAP1510_LB_MMU_RAM_H	0xfffec234  #define OMAP1510_LB_MMU_RAM_L	0xfffec238 - -#ifndef CONFIG_ARCH_OMAP -#error "This file is OMAP bus glue.  CONFIG_OMAP must be defined." -#endif +#define DRIVER_DESC "OHCI OMAP driver"  #ifdef CONFIG_TPS65010  #include <linux/i2c/tps65010.h> @@ -68,8 +74,9 @@ extern int ocpi_enable(void);  static struct clk *usb_host_ck;  static struct clk *usb_dc_ck; -static int host_enabled; -static int host_initialized; + +static const char hcd_name[] = "ohci-omap"; +static struct hc_driver __read_mostly ohci_omap_hc_driver;  static void omap_ohci_clock_power(int on)  { @@ -188,7 +195,7 @@ static void start_hnp(struct ohci_hcd *ohci)  /*-------------------------------------------------------------------------*/ -static int ohci_omap_init(struct usb_hcd *hcd) +static int ohci_omap_reset(struct usb_hcd *hcd)  {  	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);  	struct omap_usb_config	*config = dev_get_platdata(hcd->self.controller); @@ -198,9 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)  	dev_dbg(hcd->self.controller, "starting USB Controller\n");  	if (config->otg) { -		ohci_to_hcd(ohci)->self.otg_port = config->otg; +		hcd->self.otg_port = config->otg;  		/* default/minimum OTG power budget:  8 mA */ -		ohci_to_hcd(ohci)->power_budget = 8; +		hcd->power_budget = 8;  	}  	/* boards can use OTG transceivers in non-OTG modes */ @@ -238,9 +245,15 @@ static int ohci_omap_init(struct usb_hcd *hcd)  		omap_1510_local_bus_init();  	} -	if ((ret = ohci_init(ohci)) < 0) +	ret = ohci_setup(hcd); +	if (ret < 0)  		return ret; +	if (config->otg || config->rwc) { +		ohci->hc_control = OHCI_CTRL_RWC; +		writel(OHCI_CTRL_RWC, &ohci->regs->control); +	} +  	/* board-specific power switching and overcurrent support */  	if (machine_is_omap_osk() || machine_is_omap_innovator()) {  		u32	rh = roothub_a (ohci); @@ -281,14 +294,6 @@ static int ohci_omap_init(struct usb_hcd *hcd)  	return 0;  } -static void ohci_omap_stop(struct usb_hcd *hcd) -{ -	dev_dbg(hcd->self.controller, "stopping USB Controller\n"); -	ohci_stop(hcd); -	omap_ohci_clock_power(0); -} - -  /*-------------------------------------------------------------------------*/  /** @@ -304,17 +309,16 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,  {  	int retval, irq;  	struct usb_hcd *hcd = 0; -	struct ohci_hcd *ohci;  	if (pdev->num_resources != 2) { -		printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", +		dev_err(&pdev->dev, "invalid num_resources: %i\n",  		       pdev->num_resources);  		return -ENODEV;  	}  	if (pdev->resource[0].flags != IORESOURCE_MEM  			|| pdev->resource[1].flags != IORESOURCE_IRQ) { -		printk(KERN_ERR "hcd probe: invalid resource type\n"); +		dev_err(&pdev->dev, "invalid resource type\n");  		return -ENODEV;  	} @@ -354,12 +358,6 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,  		goto err2;  	} -	ohci = hcd_to_ohci(hcd); -	ohci_hcd_init(ohci); - -	host_initialized = 0; -	host_enabled = 1; -  	irq = platform_get_irq(pdev, 0);  	if (irq < 0) {  		retval = -ENXIO; @@ -369,11 +367,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,  	if (retval)  		goto err3; -	host_initialized = 1; - -	if (!host_enabled) -		omap_ohci_clock_power(0); - +	device_wakeup_enable(hcd->self.controller);  	return 0;  err3:  	iounmap(hcd->regs); @@ -402,7 +396,9 @@ err0:  static inline void  usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)  { +	dev_dbg(hcd->self.controller, "stopping USB Controller\n");  	usb_remove_hcd(hcd); +	omap_ohci_clock_power(0);  	if (!IS_ERR_OR_NULL(hcd->phy)) {  		(void) otg_set_host(hcd->phy->otg, 0);  		usb_put_phy(hcd->phy); @@ -418,76 +414,6 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)  /*-------------------------------------------------------------------------*/ -static int -ohci_omap_start (struct usb_hcd *hcd) -{ -	struct omap_usb_config *config; -	struct ohci_hcd	*ohci = hcd_to_ohci (hcd); -	int		ret; - -	if (!host_enabled) -		return 0; -	config = dev_get_platdata(hcd->self.controller); -	if (config->otg || config->rwc) { -		ohci->hc_control = OHCI_CTRL_RWC; -		writel(OHCI_CTRL_RWC, &ohci->regs->control); -	} - -	if ((ret = ohci_run (ohci)) < 0) { -		dev_err(hcd->self.controller, "can't start\n"); -		ohci_stop (hcd); -		return ret; -	} -	return 0; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_omap_hc_driver = { -	.description =		hcd_name, -	.product_desc =		"OMAP OHCI", -	.hcd_priv_size =	sizeof(struct ohci_hcd), - -	/* -	 * generic hardware linkage -	 */ -	.irq =			ohci_irq, -	.flags =		HCD_USB11 | HCD_MEMORY, - -	/* -	 * basic lifecycle operations -	 */ -	.reset =		ohci_omap_init, -	.start =		ohci_omap_start, -	.stop =			ohci_omap_stop, -	.shutdown =		ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue =		ohci_urb_enqueue, -	.urb_dequeue =		ohci_urb_dequeue, -	.endpoint_disable =	ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number =	ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data =	ohci_hub_status_data, -	.hub_control =		ohci_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend =		ohci_bus_suspend, -	.bus_resume =		ohci_bus_resume, -#endif -	.start_port_reset =	ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ -  static int ohci_hcd_omap_drv_probe(struct platform_device *dev)  {  	return usb_hcd_omap_probe(&ohci_omap_hc_driver, dev); @@ -506,16 +432,23 @@ static int ohci_hcd_omap_drv_remove(struct platform_device *dev)  #ifdef	CONFIG_PM -static int ohci_omap_suspend(struct platform_device *dev, pm_message_t message) +static int ohci_omap_suspend(struct platform_device *pdev, pm_message_t message)  { -	struct ohci_hcd	*ohci = hcd_to_ohci(platform_get_drvdata(dev)); +	struct usb_hcd *hcd = platform_get_drvdata(pdev); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); +	bool do_wakeup = device_may_wakeup(&pdev->dev); +	int ret;  	if (time_before(jiffies, ohci->next_statechange))  		msleep(5);  	ohci->next_statechange = jiffies; +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret; +  	omap_ohci_clock_power(0); -	return 0; +	return ret;  }  static int ohci_omap_resume(struct platform_device *dev) @@ -553,4 +486,29 @@ static struct platform_driver ohci_hcd_omap_driver = {  	},  }; +static const struct ohci_driver_overrides omap_overrides __initconst = { +	.product_desc	= "OMAP OHCI", +	.reset		= ohci_omap_reset +}; + +static int __init ohci_omap_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ohci_init_driver(&ohci_omap_hc_driver, &omap_overrides); +	return platform_driver_register(&ohci_hcd_omap_driver); +} +module_init(ohci_omap_init); + +static void __exit ohci_omap_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_omap_driver); +} +module_exit(ohci_omap_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_ALIAS("platform:ohci"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/ohci-omap3.c b/drivers/usb/host/ohci-omap3.c index a09af26f69e..ec15aebe878 100644 --- a/drivers/usb/host/ohci-omap3.c +++ b/drivers/usb/host/ohci-omap3.c @@ -29,90 +29,22 @@   *	- add kernel-doc   */ +#include <linux/dma-mapping.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/usb/otg.h>  #include <linux/platform_device.h>  #include <linux/pm_runtime.h> -#include <linux/of.h> -#include <linux/dma-mapping.h> - -/*-------------------------------------------------------------------------*/ - -static int ohci_omap3_init(struct usb_hcd *hcd) -{ -	dev_dbg(hcd->self.controller, "starting OHCI controller\n"); - -	return ohci_init(hcd_to_ohci(hcd)); -} - -/*-------------------------------------------------------------------------*/ - -static int ohci_omap3_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	int ret; - -	/* -	 * RemoteWakeupConnected has to be set explicitly before -	 * calling ohci_run. The reset value of RWC is 0. -	 */ -	ohci->hc_control = OHCI_CTRL_RWC; -	writel(OHCI_CTRL_RWC, &ohci->regs->control); - -	ret = ohci_run(ohci); - -	if (ret < 0) { -		dev_err(hcd->self.controller, "can't start\n"); -		ohci_stop(hcd); -	} - -	return ret; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver ohci_omap3_hc_driver = { -	.description =		hcd_name, -	.product_desc =		"OMAP3 OHCI Host Controller", -	.hcd_priv_size =	sizeof(struct ohci_hcd), - -	/* -	 * generic hardware linkage -	 */ -	.irq =			ohci_irq, -	.flags =		HCD_USB11 | HCD_MEMORY, - -	/* -	 * basic lifecycle operations -	 */ -	.reset =		ohci_omap3_init, -	.start =		ohci_omap3_start, -	.stop =			ohci_stop, -	.shutdown =		ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue =		ohci_urb_enqueue, -	.urb_dequeue =		ohci_urb_dequeue, -	.endpoint_disable =	ohci_endpoint_disable, +#include <linux/usb.h> +#include <linux/usb/hcd.h> -	/* -	 * scheduling support -	 */ -	.get_frame_number =	ohci_get_frame, +#include "ohci.h" -	/* -	 * root hub support -	 */ -	.hub_status_data =	ohci_hub_status_data, -	.hub_control =		ohci_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend =		ohci_bus_suspend, -	.bus_resume =		ohci_bus_resume, -#endif -	.start_port_reset =	ohci_start_port_reset, -}; +#define DRIVER_DESC "OHCI OMAP3 driver" -/*-------------------------------------------------------------------------*/ +static const char hcd_name[] = "ohci-omap3"; +static struct hc_driver __read_mostly ohci_omap3_hc_driver;  /*   * configure so an HC device and id are always provided @@ -129,10 +61,11 @@ static const struct hc_driver ohci_omap3_hc_driver = {  static int ohci_hcd_omap3_probe(struct platform_device *pdev)  {  	struct device		*dev = &pdev->dev; +	struct ohci_hcd		*ohci;  	struct usb_hcd		*hcd = NULL;  	void __iomem		*regs = NULL;  	struct resource		*res; -	int			ret = -ENODEV; +	int			ret;  	int			irq;  	if (usb_disabled()) @@ -166,11 +99,11 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!dev->dma_mask) -		dev->dma_mask = &dev->coherent_dma_mask; -	if (!dev->coherent_dma_mask) -		dev->coherent_dma_mask = DMA_BIT_MASK(32); +	ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); +	if (ret) +		goto err_io; +	ret = -ENODEV;  	hcd = usb_create_hcd(&ohci_omap3_hc_driver, dev,  			dev_name(dev));  	if (!hcd) { @@ -185,13 +118,19 @@ static int ohci_hcd_omap3_probe(struct platform_device *pdev)  	pm_runtime_enable(dev);  	pm_runtime_get_sync(dev); -	ohci_hcd_init(hcd_to_ohci(hcd)); +	ohci = hcd_to_ohci(hcd); +	/* +	 * RemoteWakeupConnected has to be set explicitly before +	 * calling ohci_run. The reset value of RWC is 0. +	 */ +	ohci->hc_control = OHCI_CTRL_RWC;  	ret = usb_add_hcd(hcd, irq, 0);  	if (ret) {  		dev_dbg(dev, "failed to add hcd with err %d\n", ret);  		goto err_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return 0; @@ -248,5 +187,25 @@ static struct platform_driver ohci_hcd_omap3_driver = {  	},  }; +static int __init ohci_omap3_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ohci_init_driver(&ohci_omap3_hc_driver, NULL); +	return platform_driver_register(&ohci_hcd_omap3_driver); +} +module_init(ohci_omap3_init); + +static void __exit ohci_omap3_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_omap3_driver); +} +module_exit(ohci_omap3_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_ALIAS("platform:ohci-omap3");  MODULE_AUTHOR("Anand Gadiyar <gadiyar@ti.com>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index ec337c2bd5e..bb150967572 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -150,28 +150,17 @@ static int ohci_quirk_nec(struct usb_hcd *hcd)  static int ohci_quirk_amd700(struct usb_hcd *hcd)  {  	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	struct pci_dev *amd_smbus_dev; -	u8 rev;  	if (usb_amd_find_chipset_info())  		ohci->flags |= OHCI_QUIRK_AMD_PLL; -	amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, -			PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); -	if (!amd_smbus_dev) -		return 0; - -	rev = amd_smbus_dev->revision; -  	/* SB800 needs pre-fetch fix */ -	if ((rev >= 0x40) && (rev <= 0x4f)) { +	if (usb_amd_prefetch_quirk()) {  		ohci->flags |= OHCI_QUIRK_AMD_PREFETCH;  		ohci_dbg(ohci, "enabled AMD prefetch quirk\n");  	} -	pci_dev_put(amd_smbus_dev); -	amd_smbus_dev = NULL; - +	ohci->flags |= OHCI_QUIRK_GLOBAL_SUSPEND;  	return 0;  } @@ -323,3 +312,4 @@ module_exit(ohci_pci_cleanup);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL"); +MODULE_SOFTDEP("pre: ehci_pci"); diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index a4c6410f0ed..4369299064c 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -3,6 +3,7 @@   *   * Copyright 2007 Michael Buesch <m@bues.ch>   * Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de> + * Copyright 2014 Hans de Goede <hdegoede@redhat.com>   *   * Derived from the OCHI-SSB driver   * Derived from the OHCI-PCI driver @@ -14,12 +15,16 @@   * Licensed under the GNU/GPL. See COPYING for details.   */ +#include <linux/clk.h> +#include <linux/dma-mapping.h>  #include <linux/hrtimer.h>  #include <linux/io.h>  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/err.h> +#include <linux/phy/phy.h>  #include <linux/platform_device.h> +#include <linux/reset.h>  #include <linux/usb/ohci_pdriver.h>  #include <linux/usb.h>  #include <linux/usb/hcd.h> @@ -27,6 +32,14 @@  #include "ohci.h"  #define DRIVER_DESC "OHCI generic platform driver" +#define OHCI_MAX_CLKS 3 +#define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + +struct ohci_platform_priv { +	struct clk *clks[OHCI_MAX_CLKS]; +	struct reset_control *rst; +	struct phy *phy; +};  static const char hcd_name[] = "ohci-platform"; @@ -36,10 +49,6 @@ static int ohci_platform_reset(struct usb_hcd *hcd)  	struct usb_ohci_pdata *pdata = dev_get_platdata(&pdev->dev);  	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	if (pdata->big_endian_desc) -		ohci->flags |= OHCI_QUIRK_BE_DESC; -	if (pdata->big_endian_mmio) -		ohci->flags |= OHCI_QUIRK_BE_MMIO;  	if (pdata->no_big_frame_no)  		ohci->flags |= OHCI_QUIRK_FRAME_NO;  	if (pdata->num_ports) @@ -48,11 +57,67 @@ static int ohci_platform_reset(struct usb_hcd *hcd)  	return ohci_setup(hcd);  } +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; + +	for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) { +		ret = clk_prepare_enable(priv->clks[clk]); +		if (ret) +			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; +	} + +	return 0; + +err_exit_phy: +	phy_exit(priv->phy); +err_disable_clks: +	while (--clk >= 0) +		clk_disable_unprepare(priv->clks[clk]); + +	return ret; +} + +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; + +	if (priv->phy) { +		phy_power_off(priv->phy); +		phy_exit(priv->phy); +	} + +	for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--) +		if (priv->clks[clk]) +			clk_disable_unprepare(priv->clks[clk]); +} +  static struct hc_driver __read_mostly ohci_platform_hc_driver;  static const struct ohci_driver_overrides platform_overrides __initconst = { -	.product_desc =	"Generic Platform OHCI controller", -	.reset =	ohci_platform_reset, +	.product_desc =		"Generic Platform OHCI controller", +	.reset =		ohci_platform_reset, +	.extra_priv_size =	sizeof(struct ohci_platform_priv), +}; + +static struct usb_ohci_pdata ohci_platform_defaults = { +	.power_on =		ohci_platform_power_on, +	.power_suspend =	ohci_platform_power_off, +	.power_off =		ohci_platform_power_off,  };  static int ohci_platform_probe(struct platform_device *dev) @@ -60,17 +125,24 @@ static int ohci_platform_probe(struct platform_device *dev)  	struct usb_hcd *hcd;  	struct resource *res_mem;  	struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); -	int irq; -	int err = -ENOMEM; - -	if (!pdata) { -		WARN_ON(1); -		return -ENODEV; -	} +	struct ohci_platform_priv *priv; +	struct ohci_hcd *ohci; +	int err, irq, clk = 0;  	if (usb_disabled())  		return -ENODEV; +	/* +	 * Use reasonable defaults so platforms don't have to provide these +	 * with DT probing on ARM. +	 */ +	if (!pdata) +		pdata = &ohci_platform_defaults; + +	err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); +	if (err) +		return err; +  	irq = platform_get_irq(dev, 0);  	if (irq < 0) {  		dev_err(&dev->dev, "no irq provided"); @@ -83,17 +155,85 @@ static int ohci_platform_probe(struct platform_device *dev)  		return -ENXIO;  	} +	hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, +			dev_name(&dev->dev)); +	if (!hcd) +		return -ENOMEM; + +	platform_set_drvdata(dev, hcd); +	dev->dev.platform_data = pdata; +	priv = hcd_to_ohci_priv(hcd); +	ohci = hcd_to_ohci(hcd); + +	if (pdata == &ohci_platform_defaults && dev->dev.of_node) { +		if (of_property_read_bool(dev->dev.of_node, "big-endian-regs")) +			ohci->flags |= OHCI_QUIRK_BE_MMIO; + +		if (of_property_read_bool(dev->dev.of_node, "big-endian-desc")) +			ohci->flags |= OHCI_QUIRK_BE_DESC; + +		if (of_property_read_bool(dev->dev.of_node, "big-endian")) +			ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; + +		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; +		} + +		for (clk = 0; clk < OHCI_MAX_CLKS; clk++) { +			priv->clks[clk] = of_clk_get(dev->dev.of_node, clk); +			if (IS_ERR(priv->clks[clk])) { +				err = PTR_ERR(priv->clks[clk]); +				if (err == -EPROBE_DEFER) +					goto err_put_clks; +				priv->clks[clk] = NULL; +				break; +			} +		} + +	} + +	priv->rst = devm_reset_control_get_optional(&dev->dev, NULL); +	if (IS_ERR(priv->rst)) { +		err = PTR_ERR(priv->rst); +		if (err == -EPROBE_DEFER) +			goto err_put_clks; +		priv->rst = NULL; +	} else { +		err = reset_control_deassert(priv->rst); +		if (err) +			goto err_put_clks; +	} + +	if (pdata->big_endian_desc) +		ohci->flags |= OHCI_QUIRK_BE_DESC; +	if (pdata->big_endian_mmio) +		ohci->flags |= OHCI_QUIRK_BE_MMIO; + +#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO +	if (ohci->flags & OHCI_QUIRK_BE_MMIO) { +		dev_err(&dev->dev, +			"Error: CONFIG_USB_OHCI_BIG_ENDIAN_MMIO not set\n"); +		err = -EINVAL; +		goto err_reset; +	} +#endif +#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC +	if (ohci->flags & OHCI_QUIRK_BE_DESC) { +		dev_err(&dev->dev, +			"Error: CONFIG_USB_OHCI_BIG_ENDIAN_DESC not set\n"); +		err = -EINVAL; +		goto err_reset; +	} +#endif +  	if (pdata->power_on) {  		err = pdata->power_on(dev);  		if (err < 0) -			return err; -	} - -	hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev, -			dev_name(&dev->dev)); -	if (!hcd) { -		err = -ENOMEM; -		goto err_power; +			goto err_reset;  	}  	hcd->rsrc_start = res_mem->start; @@ -102,21 +242,32 @@ static int ohci_platform_probe(struct platform_device *dev)  	hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);  	if (IS_ERR(hcd->regs)) {  		err = PTR_ERR(hcd->regs); -		goto err_put_hcd; +		goto err_power;  	}  	err = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (err) -		goto err_put_hcd; +		goto err_power; + +	device_wakeup_enable(hcd->self.controller);  	platform_set_drvdata(dev, hcd);  	return err; -err_put_hcd: -	usb_put_hcd(hcd);  err_power:  	if (pdata->power_off)  		pdata->power_off(dev); +err_reset: +	if (priv->rst) +		reset_control_assert(priv->rst); +err_put_clks: +	while (--clk >= 0) +		clk_put(priv->clks[clk]); +err_put_hcd: +	if (pdata == &ohci_platform_defaults) +		dev->dev.platform_data = NULL; + +	usb_put_hcd(hcd);  	return err;  } @@ -125,13 +276,25 @@ static int ohci_platform_remove(struct platform_device *dev)  {  	struct usb_hcd *hcd = platform_get_drvdata(dev);  	struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev); +	struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd); +	int clk;  	usb_remove_hcd(hcd); -	usb_put_hcd(hcd);  	if (pdata->power_off)  		pdata->power_off(dev); +	if (priv->rst) +		reset_control_assert(priv->rst); + +	for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) +		clk_put(priv->clks[clk]); + +	usb_put_hcd(hcd); + +	if (pdata == &ohci_platform_defaults) +		dev->dev.platform_data = NULL; +  	return 0;  } @@ -139,14 +302,21 @@ static int ohci_platform_remove(struct platform_device *dev)  static int ohci_platform_suspend(struct device *dev)  { -	struct usb_ohci_pdata *pdata = dev_get_platdata(dev); +	struct usb_hcd *hcd = dev_get_drvdata(dev); +	struct usb_ohci_pdata *pdata = dev->platform_data;  	struct platform_device *pdev =  		container_of(dev, struct platform_device, dev); +	bool do_wakeup = device_may_wakeup(dev); +	int ret; + +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret;  	if (pdata->power_suspend)  		pdata->power_suspend(pdev); -	return 0; +	return ret;  }  static int ohci_platform_resume(struct device *dev) @@ -171,6 +341,12 @@ static int ohci_platform_resume(struct device *dev)  #define ohci_platform_resume	NULL  #endif /* CONFIG_PM */ +static const struct of_device_id ohci_platform_ids[] = { +	{ .compatible = "generic-ohci", }, +	{ } +}; +MODULE_DEVICE_TABLE(of, ohci_platform_ids); +  static const struct platform_device_id ohci_platform_table[] = {  	{ "ohci-platform", 0 },  	{ } @@ -191,6 +367,7 @@ static struct platform_driver ohci_platform_driver = {  		.owner	= THIS_MODULE,  		.name	= "ohci-platform",  		.pm	= &ohci_platform_pm_ops, +		.of_match_table = ohci_platform_ids,  	}  }; diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index 75f5a1e2f01..965e3e9e688 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c @@ -14,6 +14,8 @@   */  #include <linux/signal.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <linux/of_platform.h>  #include <asm/prom.h> @@ -113,24 +115,18 @@ static int ohci_hcd_ppc_of_probe(struct platform_device *op)  	hcd->rsrc_start = res.start;  	hcd->rsrc_len = resource_size(&res); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		printk(KERN_ERR "%s: request_mem_region failed\n", __FILE__); -		rv = -EBUSY; +	hcd->regs = devm_ioremap_resource(&op->dev, &res); +	if (IS_ERR(hcd->regs)) { +		rv = PTR_ERR(hcd->regs);  		goto err_rmr;  	}  	irq = irq_of_parse_and_map(dn, 0);  	if (irq == NO_IRQ) { -		printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", __FILE__); +		dev_err(&op->dev, "%s: irq_of_parse_and_map failed\n", +			__FILE__);  		rv = -EBUSY; -		goto err_irq; -	} - -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		printk(KERN_ERR "%s: ioremap failed\n", __FILE__); -		rv = -ENOMEM; -		goto err_ioremap; +		goto err_rmr;  	}  	ohci = hcd_to_ohci(hcd); @@ -145,8 +141,10 @@ static int ohci_hcd_ppc_of_probe(struct platform_device *op)  	ohci_hcd_init(ohci);  	rv = usb_add_hcd(hcd, irq, 0); -	if (rv == 0) +	if (rv == 0) { +		device_wakeup_enable(hcd->self.controller);  		return 0; +	}  	/* by now, 440epx is known to show usb_23 erratum */  	np = of_find_compatible_node(NULL, NULL, "ibm,usb-ehci-440epx"); @@ -172,11 +170,7 @@ static int ohci_hcd_ppc_of_probe(struct platform_device *op)  			pr_debug("%s: cannot get ehci offset from fdt\n", __FILE__);  	} -	iounmap(hcd->regs); -err_ioremap:  	irq_dispose_mapping(irq); -err_irq: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  err_rmr:   	usb_put_hcd(hcd); @@ -191,9 +185,7 @@ static int ohci_hcd_ppc_of_remove(struct platform_device *op)  	usb_remove_hcd(hcd); -	iounmap(hcd->regs);  	irq_dispose_mapping(hcd->irq); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd); diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c index 7d35cd9e286..71d8bc4c27f 100644 --- a/drivers/usb/host/ohci-ps3.c +++ b/drivers/usb/host/ohci-ps3.c @@ -173,6 +173,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)  		goto fail_add_hcd;  	} +	device_wakeup_enable(hcd->self.controller);  	return result;  fail_add_hcd: diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index 93371a235e8..e68f3d02cd1 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -19,15 +19,28 @@   * This file is licenced under the GPL.   */ -#include <linux/device.h> -#include <linux/signal.h> -#include <linux/platform_device.h>  #include <linux/clk.h> +#include <linux/device.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/of_platform.h>  #include <linux/of_gpio.h> -#include <mach/hardware.h>  #include <linux/platform_data/usb-ohci-pxa27x.h>  #include <linux/platform_data/usb-pxa3xx-ulpi.h> +#include <linux/platform_device.h> +#include <linux/regulator/consumer.h> +#include <linux/signal.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> +#include <linux/usb/otg.h> + +#include <mach/hardware.h> + +#include "ohci.h" + +#define DRIVER_DESC "OHCI PXA27x/PXA3x driver"  /*   * UHC: USB Host Controller (OHCI-like) register definitions @@ -101,16 +114,18 @@  #define PXA_UHC_MAX_PORTNUM    3 -struct pxa27x_ohci { -	/* must be 1st member here for hcd_to_ohci() to work */ -	struct ohci_hcd ohci; +static const char hcd_name[] = "ohci-pxa27x"; -	struct device	*dev; +static struct hc_driver __read_mostly ohci_pxa27x_hc_driver; + +struct pxa27x_ohci {  	struct clk	*clk;  	void __iomem	*mmio_base; +	struct regulator *vbus[3]; +	bool		vbus_enabled[3];  }; -#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)hcd_to_ohci(hcd) +#define to_pxa27x_ohci(hcd)	(struct pxa27x_ohci *)(hcd_to_ohci(hcd)->priv)  /*    PMM_NPS_MODE -- PMM Non-power switching mode @@ -122,10 +137,10 @@ struct pxa27x_ohci {    PMM_PERPORT_MODE -- PMM per port switching mode        Ports are powered individually.   */ -static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode) +static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *pxa_ohci, int mode)  { -	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA); -	uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB); +	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA); +	uint32_t uhcrhdb = __raw_readl(pxa_ohci->mmio_base + UHCRHDB);  	switch (mode) {  	case PMM_NPS_MODE: @@ -149,20 +164,64 @@ static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)  		uhcrhda |= RH_A_NPS;  	} -	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA); -	__raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB); +	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA); +	__raw_writel(uhcrhdb, pxa_ohci->mmio_base + UHCRHDB);  	return 0;  } -extern int usb_disabled(void); +static int pxa27x_ohci_set_vbus_power(struct pxa27x_ohci *pxa_ohci, +				      unsigned int port, bool enable) +{ +	struct regulator *vbus = pxa_ohci->vbus[port]; +	int ret = 0; + +	if (IS_ERR_OR_NULL(vbus)) +		return 0; + +	if (enable && !pxa_ohci->vbus_enabled[port]) +		ret = regulator_enable(vbus); +	else if (!enable && pxa_ohci->vbus_enabled[port]) +		ret = regulator_disable(vbus); + +	if (ret < 0) +		return ret; + +	pxa_ohci->vbus_enabled[port] = enable; + +	return 0; +} +static int pxa27x_ohci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, +				   u16 wIndex, char *buf, u16 wLength) +{ +	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd); +	int ret; + +	switch (typeReq) { +	case SetPortFeature: +	case ClearPortFeature: +		if (!wIndex || wIndex > 3) +			return -EPIPE; + +		if (wValue != USB_PORT_FEAT_POWER) +			break; + +		ret = pxa27x_ohci_set_vbus_power(pxa_ohci, wIndex - 1, +						 typeReq == SetPortFeature); +		if (ret) +			return ret; +		break; +	} + +	return ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +}  /*-------------------------------------------------------------------------*/ -static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci, +static inline void pxa27x_setup_hc(struct pxa27x_ohci *pxa_ohci,  				   struct pxaohci_platform_data *inf)  { -	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR); -	uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA); +	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR); +	uint32_t uhcrhda = __raw_readl(pxa_ohci->mmio_base + UHCRHDA);  	if (inf->flags & ENABLE_PORT1)  		uhchr &= ~UHCHR_SSEP1; @@ -194,17 +253,17 @@ static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,  		uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);  	} -	__raw_writel(uhchr, ohci->mmio_base + UHCHR); -	__raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA); +	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR); +	__raw_writel(uhcrhda, pxa_ohci->mmio_base + UHCRHDA);  } -static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci) +static inline void pxa27x_reset_hc(struct pxa27x_ohci *pxa_ohci)  { -	uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR); +	uint32_t uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR); -	__raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR); +	__raw_writel(uhchr | UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);  	udelay(11); -	__raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR); +	__raw_writel(uhchr & ~UHCHR_FHR, pxa_ohci->mmio_base + UHCHR);  }  #ifdef CONFIG_PXA27x @@ -213,25 +272,26 @@ extern void pxa27x_clear_otgph(void);  #define pxa27x_clear_otgph()	do {} while (0)  #endif -static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev) +static int pxa27x_start_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)  {  	int retval = 0;  	struct pxaohci_platform_data *inf;  	uint32_t uhchr; +	struct usb_hcd *hcd = dev_get_drvdata(dev);  	inf = dev_get_platdata(dev); -	clk_prepare_enable(ohci->clk); +	clk_prepare_enable(pxa_ohci->clk); -	pxa27x_reset_hc(ohci); +	pxa27x_reset_hc(pxa_ohci); -	uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR; -	__raw_writel(uhchr, ohci->mmio_base + UHCHR); +	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) | UHCHR_FSBIR; +	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR); -	while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR) +	while (__raw_readl(pxa_ohci->mmio_base + UHCHR) & UHCHR_FSBIR)  		cpu_relax(); -	pxa27x_setup_hc(ohci, inf); +	pxa27x_setup_hc(pxa_ohci, inf);  	if (inf->init)  		retval = inf->init(dev); @@ -240,38 +300,39 @@ static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)  		return retval;  	if (cpu_is_pxa3xx()) -		pxa3xx_u2d_start_hc(&ohci_to_hcd(&ohci->ohci)->self); +		pxa3xx_u2d_start_hc(&hcd->self); -	uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE; -	__raw_writel(uhchr, ohci->mmio_base + UHCHR); -	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE); +	uhchr = __raw_readl(pxa_ohci->mmio_base + UHCHR) & ~UHCHR_SSE; +	__raw_writel(uhchr, pxa_ohci->mmio_base + UHCHR); +	__raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, pxa_ohci->mmio_base + UHCHIE);  	/* Clear any OTG Pin Hold */  	pxa27x_clear_otgph();  	return 0;  } -static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev) +static void pxa27x_stop_hc(struct pxa27x_ohci *pxa_ohci, struct device *dev)  {  	struct pxaohci_platform_data *inf; +	struct usb_hcd *hcd = dev_get_drvdata(dev);  	uint32_t uhccoms;  	inf = dev_get_platdata(dev);  	if (cpu_is_pxa3xx()) -		pxa3xx_u2d_stop_hc(&ohci_to_hcd(&ohci->ohci)->self); +		pxa3xx_u2d_stop_hc(&hcd->self);  	if (inf->exit)  		inf->exit(dev); -	pxa27x_reset_hc(ohci); +	pxa27x_reset_hc(pxa_ohci);  	/* Host Controller Reset */ -	uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01; -	__raw_writel(uhccoms, ohci->mmio_base + UHCCOMS); +	uhccoms = __raw_readl(pxa_ohci->mmio_base + UHCCOMS) | 0x01; +	__raw_writel(uhccoms, pxa_ohci->mmio_base + UHCCOMS);  	udelay(10); -	clk_disable_unprepare(ohci->clk); +	clk_disable_unprepare(pxa_ohci->clk);  }  #ifdef CONFIG_OF @@ -287,6 +348,7 @@ static int ohci_pxa_of_init(struct platform_device *pdev)  	struct device_node *np = pdev->dev.of_node;  	struct pxaohci_platform_data *pdata;  	u32 tmp; +	int ret;  	if (!np)  		return 0; @@ -295,10 +357,9 @@ static int ohci_pxa_of_init(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret;  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);  	if (!pdata) @@ -356,9 +417,11 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device  	int retval, irq;  	struct usb_hcd *hcd;  	struct pxaohci_platform_data *inf; -	struct pxa27x_ohci *ohci; +	struct pxa27x_ohci *pxa_ohci; +	struct ohci_hcd *ohci;  	struct resource *r;  	struct clk *usb_clk; +	unsigned int i;  	retval = ohci_pxa_of_init(pdev);  	if (retval) @@ -375,71 +438,70 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device  		return -ENXIO;  	} -	usb_clk = clk_get(&pdev->dev, NULL); +	usb_clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(usb_clk))  		return PTR_ERR(usb_clk);  	hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x"); -	if (!hcd) { -		retval = -ENOMEM; -		goto err0; -	} +	if (!hcd) +		return -ENOMEM;  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!r) {  		pr_err("no resource of IORESOURCE_MEM");  		retval = -ENXIO; -		goto err1; +		goto err;  	}  	hcd->rsrc_start = r->start;  	hcd->rsrc_len = resource_size(r); -	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { -		pr_debug("request_mem_region failed"); -		retval = -EBUSY; -		goto err1; -	} - -	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		pr_debug("ioremap failed"); -		retval = -ENOMEM; -		goto err2; +	hcd->regs = devm_ioremap_resource(&pdev->dev, r); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs); +		goto err;  	}  	/* initialize "struct pxa27x_ohci" */ -	ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd); -	ohci->dev = &pdev->dev; -	ohci->clk = usb_clk; -	ohci->mmio_base = (void __iomem *)hcd->regs; +	pxa_ohci = to_pxa27x_ohci(hcd); +	pxa_ohci->clk = usb_clk; +	pxa_ohci->mmio_base = (void __iomem *)hcd->regs; -	if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) { +	for (i = 0; i < 3; ++i) { +		char name[6]; + +		if (!(inf->flags & (ENABLE_PORT1 << i))) +			continue; + +		sprintf(name, "vbus%u", i + 1); +		pxa_ohci->vbus[i] = devm_regulator_get(&pdev->dev, name); +	} + +	retval = pxa27x_start_hc(pxa_ohci, &pdev->dev); +	if (retval < 0) {  		pr_debug("pxa27x_start_hc failed"); -		goto err3; +		goto err;  	}  	/* Select Power Management Mode */ -	pxa27x_ohci_select_pmm(ohci, inf->port_mode); +	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);  	if (inf->power_budget)  		hcd->power_budget = inf->power_budget; -	ohci_hcd_init(hcd_to_ohci(hcd)); +	/* The value of NDP in roothub_a is incorrect on this hardware */ +	ohci = hcd_to_ohci(hcd); +	ohci->num_ports = 3;  	retval = usb_add_hcd(hcd, irq, 0); -	if (retval == 0) +	if (retval == 0) { +		device_wakeup_enable(hcd->self.controller);  		return retval; +	} -	pxa27x_stop_hc(ohci, &pdev->dev); - err3: -	iounmap(hcd->regs); - err2: -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - err1: +	pxa27x_stop_hc(pxa_ohci, &pdev->dev); + err:  	usb_put_hcd(hcd); - err0: -	clk_put(usb_clk);  	return retval;  } @@ -459,88 +521,20 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device   */  void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)  { -	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd); +	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd); +	unsigned int i;  	usb_remove_hcd(hcd); -	pxa27x_stop_hc(ohci, &pdev->dev); -	iounmap(hcd->regs); -	release_mem_region(hcd->rsrc_start, hcd->rsrc_len); -	usb_put_hcd(hcd); -	clk_put(ohci->clk); -} - -/*-------------------------------------------------------------------------*/ +	pxa27x_stop_hc(pxa_ohci, &pdev->dev); -static int -ohci_pxa27x_start (struct usb_hcd *hcd) -{ -	struct ohci_hcd	*ohci = hcd_to_ohci (hcd); -	int		ret; - -	ohci_dbg (ohci, "ohci_pxa27x_start, ohci:%p", ohci); - -	/* The value of NDP in roothub_a is incorrect on this hardware */ -	ohci->num_ports = 3; - -	if ((ret = ohci_init(ohci)) < 0) -		return ret; - -	if ((ret = ohci_run (ohci)) < 0) { -		dev_err(hcd->self.controller, "can't start %s", -			hcd->self.bus_name); -		ohci_stop (hcd); -		return ret; -	} +	for (i = 0; i < 3; ++i) +		pxa27x_ohci_set_vbus_power(pxa_ohci, i, false); -	return 0; +	usb_put_hcd(hcd);  }  /*-------------------------------------------------------------------------*/ -static const struct hc_driver ohci_pxa27x_hc_driver = { -	.description =		hcd_name, -	.product_desc =		"PXA27x OHCI", -	.hcd_priv_size =	sizeof(struct pxa27x_ohci), - -	/* -	 * generic hardware linkage -	 */ -	.irq =			ohci_irq, -	.flags =		HCD_USB11 | HCD_MEMORY, - -	/* -	 * basic lifecycle operations -	 */ -	.start =		ohci_pxa27x_start, -	.stop =			ohci_stop, -	.shutdown =		ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue =		ohci_urb_enqueue, -	.urb_dequeue =		ohci_urb_dequeue, -	.endpoint_disable =	ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number =	ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data =	ohci_hub_status_data, -	.hub_control =		ohci_hub_control, -#ifdef  CONFIG_PM -	.bus_suspend =		ohci_bus_suspend, -	.bus_resume =		ohci_bus_resume, -#endif -	.start_port_reset =	ohci_start_port_reset, -}; - -/*-------------------------------------------------------------------------*/ -  static int ohci_hcd_pxa27x_drv_probe(struct platform_device *pdev)  {  	pr_debug ("In ohci_hcd_pxa27x_drv_probe"); @@ -563,32 +557,42 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)  static int ohci_hcd_pxa27x_drv_suspend(struct device *dev)  {  	struct usb_hcd *hcd = dev_get_drvdata(dev); -	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd); +	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd); +	bool do_wakeup = device_may_wakeup(dev); +	int ret; -	if (time_before(jiffies, ohci->ohci.next_statechange)) + +	if (time_before(jiffies, ohci->next_statechange))  		msleep(5); -	ohci->ohci.next_statechange = jiffies; +	ohci->next_statechange = jiffies; -	pxa27x_stop_hc(ohci, dev); -	return 0; +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret; + +	pxa27x_stop_hc(pxa_ohci, dev); +	return ret;  }  static int ohci_hcd_pxa27x_drv_resume(struct device *dev)  {  	struct usb_hcd *hcd = dev_get_drvdata(dev); -	struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd); +	struct pxa27x_ohci *pxa_ohci = to_pxa27x_ohci(hcd);  	struct pxaohci_platform_data *inf = dev_get_platdata(dev); +	struct ohci_hcd *ohci = hcd_to_ohci(hcd);  	int status; -	if (time_before(jiffies, ohci->ohci.next_statechange)) +	if (time_before(jiffies, ohci->next_statechange))  		msleep(5); -	ohci->ohci.next_statechange = jiffies; +	ohci->next_statechange = jiffies; -	if ((status = pxa27x_start_hc(ohci, dev)) < 0) +	status = pxa27x_start_hc(pxa_ohci, dev); +	if (status < 0)  		return status;  	/* Select Power Management Mode */ -	pxa27x_ohci_select_pmm(ohci, inf->port_mode); +	pxa27x_ohci_select_pmm(pxa_ohci, inf->port_mode);  	ohci_resume(hcd, false);  	return 0; @@ -600,9 +604,6 @@ static const struct dev_pm_ops ohci_hcd_pxa27x_pm_ops = {  };  #endif -/* work with hotplug and coldplug */ -MODULE_ALIAS("platform:pxa27x-ohci"); -  static struct platform_driver ohci_hcd_pxa27x_driver = {  	.probe		= ohci_hcd_pxa27x_drv_probe,  	.remove		= ohci_hcd_pxa27x_drv_remove, @@ -617,3 +618,30 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {  	},  }; +static const struct ohci_driver_overrides pxa27x_overrides __initconst = { +	.extra_priv_size =      sizeof(struct pxa27x_ohci), +}; + +static int __init ohci_pxa27x_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ohci_init_driver(&ohci_pxa27x_hc_driver, &pxa27x_overrides); +	ohci_pxa27x_hc_driver.hub_control = pxa27x_ohci_hub_control; + +	return platform_driver_register(&ohci_hcd_pxa27x_driver); +} +module_init(ohci_pxa27x_init); + +static void __exit ohci_pxa27x_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_pxa27x_driver); +} +module_exit(ohci_pxa27x_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:pxa27x-ohci"); diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index df4a6707322..d4253e31942 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -41,9 +41,13 @@ finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status)  __releases(ohci->lock)  __acquires(ohci->lock)  { -	 struct device *dev = ohci_to_hcd(ohci)->self.controller; +	struct device *dev = ohci_to_hcd(ohci)->self.controller; +	struct usb_host_endpoint *ep = urb->ep; +	struct urb_priv *urb_priv; +  	// ASSERT (urb->hcpriv != 0); + restart:  	urb_free_priv (ohci, urb->hcpriv);  	urb->hcpriv = NULL;  	if (likely(status == -EINPROGRESS)) @@ -64,10 +68,6 @@ __acquires(ohci->lock)  		break;  	} -#ifdef OHCI_VERBOSE_DEBUG -	urb_print(urb, "RET", usb_pipeout (urb->pipe), status); -#endif -  	/* urb->complete() can reenter this HCD */  	usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb);  	spin_unlock (&ohci->lock); @@ -80,6 +80,21 @@ __acquires(ohci->lock)  		ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);  		ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);  	} + +	/* +	 * An isochronous URB that is sumitted too late won't have any TDs +	 * (marked by the fact that the td_cnt value is larger than the +	 * actual number of TDs).  If the next URB on this endpoint is like +	 * that, give it back now. +	 */ +	if (!list_empty(&ep->urb_list)) { +		urb = list_first_entry(&ep->urb_list, struct urb, urb_list); +		urb_priv = urb->hcpriv; +		if (urb_priv->td_cnt > urb_priv->length) { +			status = 0; +			goto restart; +		} +	}  } @@ -128,7 +143,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed)  {  	unsigned	i; -	ohci_vdbg (ohci, "link %sed %p branch %d [%dus.], interval %d\n", +	ohci_dbg(ohci, "link %sed %p branch %d [%dus.], interval %d\n",  		(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",  		ed, ed->branch, ed->load, ed->interval); @@ -275,7 +290,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed)  	}  	ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; -	ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", +	ohci_dbg(ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",  		(ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",  		ed, ed->branch, ed->load, ed->interval);  } @@ -546,7 +561,6 @@ td_fill (struct ohci_hcd *ohci, u32 info,  		td->hwCBP = cpu_to_hc32 (ohci, data & 0xFFFFF000);  		*ohci_hwPSWp(ohci, td, 0) = cpu_to_hc16 (ohci,  						(data & 0x0FFF) | 0xE000); -		td->ed->last_iso = info & 0xffff;  	} else {  		td->hwCBP = cpu_to_hc32 (ohci, data);  	} @@ -747,7 +761,7 @@ static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td)  		urb->iso_frame_desc [td->index].status = cc_to_error [cc];  		if (cc != TD_CC_NOERROR) -			ohci_vdbg (ohci, +			ohci_dbg(ohci,  				"urb %p iso td %p (%d) len %d cc %d\n",  				urb, td, 1 + td->index, dlen, cc); @@ -779,7 +793,7 @@ static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td)  		}  		if (cc != TD_CC_NOERROR && cc < 0x0E) -			ohci_vdbg (ohci, +			ohci_dbg(ohci,  				"urb %p td %p (%d) cc %d, len=%d/%d\n",  				urb, td, 1 + td->index, cc,  				urb->actual_length, @@ -996,7 +1010,7 @@ rescan_this:  			urb_priv->td_cnt++;  			/* if URB is done, clean up */ -			if (urb_priv->td_cnt == urb_priv->length) { +			if (urb_priv->td_cnt >= urb_priv->length) {  				modified = completed = 1;  				finish_urb(ohci, urb, 0);  			} @@ -1086,7 +1100,7 @@ static void takeback_td(struct ohci_hcd *ohci, struct td *td)  	urb_priv->td_cnt++;  	/* If all this urb's TDs are done, call complete() */ -	if (urb_priv->td_cnt == urb_priv->length) +	if (urb_priv->td_cnt >= urb_priv->length)  		finish_urb(ohci, urb, status);  	/* clean schedule:  unlink EDs that are no longer busy */ diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 4919afa4125..3d753a9d314 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -19,14 +19,27 @@   * This file is licenced under the GPL.  */ -#include <linux/platform_device.h>  #include <linux/clk.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/platform_device.h>  #include <linux/platform_data/usb-ohci-s3c2410.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> + +#include "ohci.h" +  #define valid_port(idx) ((idx) == 1 || (idx) == 2)  /* clock device associated with the hcd */ + +#define DRIVER_DESC "OHCI S3C2410 driver" + +static const char hcd_name[] = "ohci-s3c2410"; +  static struct clk *clk;  static struct clk *usb_clk; @@ -47,10 +60,10 @@ static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)  	dev_dbg(&dev->dev, "s3c2410_start_hc:\n"); -	clk_enable(usb_clk); +	clk_prepare_enable(usb_clk);  	mdelay(2);			/* let the bus clock stabilise */ -	clk_enable(clk); +	clk_prepare_enable(clk);  	if (info != NULL) {  		info->hcd	= hcd; @@ -75,8 +88,8 @@ static void s3c2410_stop_hc(struct platform_device *dev)  			(info->enable_oc)(info, 0);  	} -	clk_disable(clk); -	clk_disable(usb_clk); +	clk_disable_unprepare(clk); +	clk_disable_unprepare(usb_clk);  }  /* ohci_s3c2410_hub_status_data @@ -93,7 +106,7 @@ ohci_s3c2410_hub_status_data(struct usb_hcd *hcd, char *buf)  	int orig;  	int portno; -	orig  = ohci_hub_status_data(hcd, buf); +	orig = ohci_hub_status_data(hcd, buf);  	if (info == NULL)  		return orig; @@ -374,12 +387,11 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,  	s3c2410_start_hc(dev, hcd); -	ohci_hcd_init(hcd_to_ohci(hcd)); -  	retval = usb_add_hcd(hcd, dev->resource[1].start, 0);  	if (retval != 0)  		goto err_ioremap; +	device_wakeup_enable(hcd->self.controller);  	return 0;   err_ioremap: @@ -392,71 +404,7 @@ static int usb_hcd_s3c2410_probe(const struct hc_driver *driver,  /*-------------------------------------------------------------------------*/ -static int -ohci_s3c2410_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); -	int ret; - -	ret = ohci_init(ohci); -	if (ret < 0) -		return ret; - -	ret = ohci_run(ohci); -	if (ret < 0) { -		dev_err(hcd->self.controller, "can't start %s\n", -			hcd->self.bus_name); -		ohci_stop(hcd); -		return ret; -	} - -	return 0; -} - - -static const struct hc_driver ohci_s3c2410_hc_driver = { -	.description =		hcd_name, -	.product_desc =		"S3C24XX OHCI", -	.hcd_priv_size =	sizeof(struct ohci_hcd), - -	/* -	 * generic hardware linkage -	 */ -	.irq =			ohci_irq, -	.flags =		HCD_USB11 | HCD_MEMORY, - -	/* -	 * basic lifecycle operations -	 */ -	.start =		ohci_s3c2410_start, -	.stop =			ohci_stop, -	.shutdown =		ohci_shutdown, - -	/* -	 * managing i/o requests and associated device resources -	 */ -	.urb_enqueue =		ohci_urb_enqueue, -	.urb_dequeue =		ohci_urb_dequeue, -	.endpoint_disable =	ohci_endpoint_disable, - -	/* -	 * scheduling support -	 */ -	.get_frame_number =	ohci_get_frame, - -	/* -	 * root hub support -	 */ -	.hub_status_data =	ohci_s3c2410_hub_status_data, -	.hub_control =		ohci_s3c2410_hub_control, -#ifdef	CONFIG_PM -	.bus_suspend =		ohci_bus_suspend, -	.bus_resume =		ohci_bus_resume, -#endif -	.start_port_reset =	ohci_start_port_reset, -}; - -/* device driver */ +static struct hc_driver __read_mostly ohci_s3c2410_hc_driver;  static int ohci_hcd_s3c2410_drv_probe(struct platform_device *pdev)  { @@ -475,28 +423,15 @@ static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev)  static int ohci_hcd_s3c2410_drv_suspend(struct device *dev)  {  	struct usb_hcd *hcd = dev_get_drvdata(dev); -	struct ohci_hcd *ohci = hcd_to_ohci(hcd);  	struct platform_device *pdev = to_platform_device(dev); -	unsigned long flags; +	bool do_wakeup = device_may_wakeup(dev);  	int rc = 0; -	/* -	 * Root hub was already suspended. Disable irq emission and -	 * mark HW unaccessible, bail out if RH has been resumed. Use -	 * the spinlock to properly synchronize with possible pending -	 * RH suspend or resume activity. -	 */ -	spin_lock_irqsave(&ohci->lock, flags); -	if (ohci->rh_state != OHCI_RH_SUSPENDED) { -		rc = -EINVAL; -		goto bail; -	} - -	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); +	rc = ohci_suspend(hcd, do_wakeup); +	if (rc) +		return rc;  	s3c2410_stop_hc(pdev); -bail: -	spin_unlock_irqrestore(&ohci->lock, flags);  	return rc;  } @@ -533,4 +468,36 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {  	},  }; +static int __init ohci_s3c2410_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); +	ohci_init_driver(&ohci_s3c2410_hc_driver, NULL); + +	/* +	 * The Samsung HW has some unusual quirks, which require +	 * Sumsung-specific workarounds. We override certain hc_driver +	 * functions here to achieve that. We explicitly do not enhance +	 * ohci_driver_overrides to allow this more easily, since this +	 * is an unusual case, and we don't want to encourage others to +	 * override these functions by making it too easy. +	 */ + +	ohci_s3c2410_hc_driver.hub_status_data	= ohci_s3c2410_hub_status_data; +	ohci_s3c2410_hc_driver.hub_control	= ohci_s3c2410_hub_control; + +	return platform_driver_register(&ohci_hcd_s3c2410_driver); +} +module_init(ohci_s3c2410_init); + +static void __exit ohci_s3c2410_cleanup(void) +{ +	platform_driver_unregister(&ohci_hcd_s3c2410_driver); +} +module_exit(ohci_s3c2410_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:s3c2410-ohci"); diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 17b2a7dad77..2ac266d692a 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c @@ -185,6 +185,12 @@ static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev)  	if (usb_disabled())  		return -ENODEV; +	/* +	 * We don't call dma_set_mask_and_coherent() here because the +	 * DMA mask has already been appropraitely setup by the core +	 * SA-1111 bus code (which includes bug workarounds.) +	 */ +  	hcd = usb_create_hcd(&ohci_sa1111_hc_driver, &dev->dev, "sa1111");  	if (!hcd)  		return -ENOMEM; @@ -205,8 +211,10 @@ static int ohci_hcd_sa1111_probe(struct sa1111_dev *dev)  		goto err2;  	ret = usb_add_hcd(hcd, dev->irq[1], 0); -	if (ret == 0) +	if (ret == 0) { +		device_wakeup_enable(hcd->self.controller);  		return ret; +	}  	sa1111_stop_hc(dev);   err2: diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c index d479d5ddab8..4e81c804c73 100644 --- a/drivers/usb/host/ohci-sm501.c +++ b/drivers/usb/host/ohci-sm501.c @@ -168,6 +168,7 @@ static int ohci_hcd_sm501_drv_probe(struct platform_device *pdev)  	retval = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (retval)  		goto err5; +	device_wakeup_enable(hcd->self.controller);  	/* enable power and unmask interrupts */ @@ -216,14 +217,21 @@ static int ohci_hcd_sm501_drv_remove(struct platform_device *pdev)  static int ohci_sm501_suspend(struct platform_device *pdev, pm_message_t msg)  {  	struct device *dev = &pdev->dev; -	struct ohci_hcd	*ohci = hcd_to_ohci(platform_get_drvdata(pdev)); +	struct usb_hcd  *hcd = platform_get_drvdata(pdev); +	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); +	bool do_wakeup = device_may_wakeup(dev); +	int ret;  	if (time_before(jiffies, ohci->next_statechange))  		msleep(5);  	ohci->next_statechange = jiffies; +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret; +  	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 0); -	return 0; +	return ret;  }  static int ohci_sm501_resume(struct platform_device *pdev) diff --git a/drivers/usb/host/ohci-spear.c b/drivers/usb/host/ohci-spear.c index cc9dd9e4f05..8b29a0c04c2 100644 --- a/drivers/usb/host/ohci-spear.c +++ b/drivers/usb/host/ohci-spear.c @@ -11,92 +11,37 @@  * warranty of any kind, whether express or implied.  */ -#include <linux/signal.h> -#include <linux/platform_device.h>  #include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h>  #include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/signal.h> +#include <linux/usb.h> +#include <linux/usb/hcd.h> +#include "ohci.h" + +#define DRIVER_DESC "OHCI SPEAr driver" + +static const char hcd_name[] = "SPEAr-ohci";  struct spear_ohci { -	struct ohci_hcd ohci;  	struct clk *clk;  }; -#define to_spear_ohci(hcd)	(struct spear_ohci *)hcd_to_ohci(hcd) - -static void spear_start_ohci(struct spear_ohci *ohci) -{ -	clk_prepare_enable(ohci->clk); -} - -static void spear_stop_ohci(struct spear_ohci *ohci) -{ -	clk_disable_unprepare(ohci->clk); -} - -static int ohci_spear_start(struct usb_hcd *hcd) -{ -	struct ohci_hcd *ohci = hcd_to_ohci(hcd); -	int ret; - -	ret = ohci_init(ohci); -	if (ret < 0) -		return ret; -	ohci->regs = hcd->regs; - -	ret = ohci_run(ohci); -	if (ret < 0) { -		dev_err(hcd->self.controller, "can't start\n"); -		ohci_stop(hcd); -		return ret; -	} - -	create_debug_files(ohci); - -#ifdef DEBUG -	ohci_dump(ohci, 1); -#endif -	return 0; -} - -static const struct hc_driver ohci_spear_hc_driver = { -	.description		= hcd_name, -	.product_desc		= "SPEAr OHCI", -	.hcd_priv_size		= sizeof(struct spear_ohci), - -	/* generic hardware linkage */ -	.irq			= ohci_irq, -	.flags			= HCD_USB11 | HCD_MEMORY, - -	/* basic lifecycle operations */ -	.start			= ohci_spear_start, -	.stop			= ohci_stop, -	.shutdown		= ohci_shutdown, -#ifdef	CONFIG_PM -	.bus_suspend		= ohci_bus_suspend, -	.bus_resume		= ohci_bus_resume, -#endif - -	/* managing i/o requests and associated device resources */ -	.urb_enqueue		= ohci_urb_enqueue, -	.urb_dequeue		= ohci_urb_dequeue, -	.endpoint_disable	= ohci_endpoint_disable, - -	/* scheduling support */ -	.get_frame_number	= ohci_get_frame, +#define to_spear_ohci(hcd)     (struct spear_ohci *)(hcd_to_ohci(hcd)->priv) -	/* root hub support */ -	.hub_status_data	= ohci_hub_status_data, -	.hub_control		= ohci_hub_control, - -	.start_port_reset	= ohci_start_port_reset, -}; +static struct hc_driver __read_mostly ohci_spear_hc_driver;  static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)  {  	const struct hc_driver *driver = &ohci_spear_hc_driver; +	struct ohci_hcd *ohci;  	struct usb_hcd *hcd = NULL;  	struct clk *usbh_clk; -	struct spear_ohci *ohci_p; +	struct spear_ohci *sohci_p;  	struct resource *res;  	int retval, irq; @@ -111,10 +56,9 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	retval = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (retval) +		goto fail;  	usbh_clk = devm_clk_get(&pdev->dev, NULL);  	if (IS_ERR(usbh_clk)) { @@ -137,30 +81,27 @@ static int spear_ohci_hcd_drv_probe(struct platform_device *pdev)  	hcd->rsrc_start = pdev->resource[0].start;  	hcd->rsrc_len = resource_size(res); -	if (!devm_request_mem_region(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len, -				hcd_name)) { -		dev_dbg(&pdev->dev, "request_mem_region failed\n"); -		retval = -EBUSY; -		goto err_put_hcd; -	} -	hcd->regs = devm_ioremap(&pdev->dev, hcd->rsrc_start, hcd->rsrc_len); -	if (!hcd->regs) { -		dev_dbg(&pdev->dev, "ioremap failed\n"); -		retval = -ENOMEM; +	hcd->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(hcd->regs)) { +		retval = PTR_ERR(hcd->regs);  		goto err_put_hcd;  	} -	ohci_p = (struct spear_ohci *)hcd_to_ohci(hcd); -	ohci_p->clk = usbh_clk; -	spear_start_ohci(ohci_p); -	ohci_hcd_init(hcd_to_ohci(hcd)); +	sohci_p = to_spear_ohci(hcd); +	sohci_p->clk = usbh_clk; + +	clk_prepare_enable(sohci_p->clk); + +	ohci = hcd_to_ohci(hcd);  	retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), 0); -	if (retval == 0) +	if (retval == 0) { +		device_wakeup_enable(hcd->self.controller);  		return retval; +	} -	spear_stop_ohci(ohci_p); +	clk_disable_unprepare(sohci_p->clk);  err_put_hcd:  	usb_put_hcd(hcd);  fail: @@ -172,43 +113,50 @@ fail:  static int spear_ohci_hcd_drv_remove(struct platform_device *pdev)  {  	struct usb_hcd *hcd = platform_get_drvdata(pdev); -	struct spear_ohci *ohci_p = to_spear_ohci(hcd); +	struct spear_ohci *sohci_p = to_spear_ohci(hcd);  	usb_remove_hcd(hcd); -	if (ohci_p->clk) -		spear_stop_ohci(ohci_p); +	if (sohci_p->clk) +		clk_disable_unprepare(sohci_p->clk);  	usb_put_hcd(hcd);  	return 0;  }  #if defined(CONFIG_PM) -static int spear_ohci_hcd_drv_suspend(struct platform_device *dev, +static int spear_ohci_hcd_drv_suspend(struct platform_device *pdev,  		pm_message_t message)  { -	struct usb_hcd *hcd = platform_get_drvdata(dev); +	struct usb_hcd *hcd = platform_get_drvdata(pdev);  	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); -	struct spear_ohci *ohci_p = to_spear_ohci(hcd); +	struct spear_ohci *sohci_p = to_spear_ohci(hcd); +	bool do_wakeup = device_may_wakeup(&pdev->dev); +	int ret;  	if (time_before(jiffies, ohci->next_statechange))  		msleep(5);  	ohci->next_statechange = jiffies; -	spear_stop_ohci(ohci_p); -	return 0; +	ret = ohci_suspend(hcd, do_wakeup); +	if (ret) +		return ret; + +	clk_disable_unprepare(sohci_p->clk); + +	return ret;  }  static int spear_ohci_hcd_drv_resume(struct platform_device *dev)  {  	struct usb_hcd *hcd = platform_get_drvdata(dev);  	struct ohci_hcd	*ohci = hcd_to_ohci(hcd); -	struct spear_ohci *ohci_p = to_spear_ohci(hcd); +	struct spear_ohci *sohci_p = to_spear_ohci(hcd);  	if (time_before(jiffies, ohci->next_statechange))  		msleep(5);  	ohci->next_statechange = jiffies; -	spear_start_ohci(ohci_p); +	clk_prepare_enable(sohci_p->clk);  	ohci_resume(hcd, false);  	return 0;  } @@ -234,4 +182,28 @@ static struct platform_driver spear_ohci_hcd_driver = {  	},  }; +static const struct ohci_driver_overrides spear_overrides __initconst = { +	.extra_priv_size = sizeof(struct spear_ohci), +}; +static int __init ohci_spear_init(void) +{ +	if (usb_disabled()) +		return -ENODEV; + +	pr_info("%s: " DRIVER_DESC "\n", hcd_name); + +	ohci_init_driver(&ohci_spear_hc_driver, &spear_overrides); +	return platform_driver_register(&spear_ohci_hcd_driver); +} +module_init(ohci_spear_init); + +static void __exit ohci_spear_cleanup(void) +{ +	platform_driver_unregister(&spear_ohci_hcd_driver); +} +module_exit(ohci_spear_cleanup); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("Deepak Sikri"); +MODULE_LICENSE("GPL v2");  MODULE_ALIAS("platform:spear-ohci"); diff --git a/drivers/usb/host/ohci-tilegx.c b/drivers/usb/host/ohci-tilegx.c index 22540ab71f5..bef6dfb0405 100644 --- a/drivers/usb/host/ohci-tilegx.c +++ b/drivers/usb/host/ohci-tilegx.c @@ -129,8 +129,8 @@ static int ohci_hcd_tilegx_drv_probe(struct platform_device *pdev)  	tilegx_start_ohc();  	/* Create our IRQs and register them. */ -	pdata->irq = create_irq(); -	if (pdata->irq < 0) { +	pdata->irq = irq_alloc_hwirq(-1); +	if (!pdata->irq) {  		ret = -ENXIO;  		goto err_no_irq;  	} @@ -159,11 +159,12 @@ static int ohci_hcd_tilegx_drv_probe(struct platform_device *pdev)  	ret = usb_add_hcd(hcd, pdata->irq, IRQF_SHARED);  	if (ret == 0) {  		platform_set_drvdata(pdev, hcd); +		device_wakeup_enable(hcd->self.controller);  		return ret;  	}  err_have_irq: -	destroy_irq(pdata->irq); +	irq_free_hwirq(pdata->irq);  err_no_irq:  	tilegx_stop_ohc();  	usb_put_hcd(hcd); @@ -181,7 +182,7 @@ static int ohci_hcd_tilegx_drv_remove(struct platform_device *pdev)  	usb_put_hcd(hcd);  	tilegx_stop_ohc();  	gxio_usb_host_destroy(&pdata->usb_ctx); -	destroy_irq(pdata->irq); +	irq_free_hwirq(pdata->irq);  	return 0;  } diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c index ecb09a5ada9..bb409588d39 100644 --- a/drivers/usb/host/ohci-tmio.c +++ b/drivers/usb/host/ohci-tmio.c @@ -27,7 +27,6 @@  /*#include <linux/fs.h>  #include <linux/mount.h>  #include <linux/pagemap.h> -#include <linux/init.h>  #include <linux/namei.h>  #include <linux/sched.h>*/  #include <linux/platform_device.h> @@ -250,6 +249,7 @@ static int ohci_hcd_tmio_drv_probe(struct platform_device *dev)  	if (ret)  		goto err_add_hcd; +	device_wakeup_enable(hcd->self.controller);  	if (ret == 0)  		return ret; diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index e2e5faa5a40..05e02a709d4 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -405,6 +405,8 @@ struct ohci_hcd {  #define	OHCI_QUIRK_HUB_POWER	0x100			/* distrust firmware power/oc setup */  #define	OHCI_QUIRK_AMD_PLL	0x200			/* AMD PLL quirk*/  #define	OHCI_QUIRK_AMD_PREFETCH	0x400			/* pre-fetch for ISO transfer */ +#define	OHCI_QUIRK_GLOBAL_SUSPEND	0x800		/* must suspend ports */ +  	// there are also chip quirks/bugs in init logic  	struct work_struct	nec_work;	/* Worker for NEC quirk */ @@ -415,12 +417,11 @@ struct ohci_hcd {  	struct ed		*ed_to_check;  	unsigned		zf_delay; -#ifdef DEBUG  	struct dentry		*debug_dir;  	struct dentry		*debug_async;  	struct dentry		*debug_periodic;  	struct dentry		*debug_registers; -#endif +  	/* platform-specific data -- must come last */  	unsigned long           priv[0] __aligned(sizeof(s64)); @@ -474,10 +475,6 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)  /*-------------------------------------------------------------------------*/ -#ifndef DEBUG -#define STUB_DEBUG_FILES -#endif	/* DEBUG */ -  #define ohci_dbg(ohci, fmt, args...) \  	dev_dbg (ohci_to_hcd(ohci)->self.controller , fmt , ## args )  #define ohci_err(ohci, fmt, args...) \ @@ -487,12 +484,6 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)  #define ohci_warn(ohci, fmt, args...) \  	dev_warn (ohci_to_hcd(ohci)->self.controller , fmt , ## args ) -#ifdef OHCI_VERBOSE_DEBUG -#	define ohci_vdbg ohci_dbg -#else -#	define ohci_vdbg(ohci, fmt, args...) do { } while (0) -#endif -  /*-------------------------------------------------------------------------*/  /* @@ -738,3 +729,6 @@ extern int	ohci_setup(struct usb_hcd *hcd);  extern int	ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);  extern int	ohci_resume(struct usb_hcd *hcd, bool hibernated);  #endif +extern int	ohci_hub_control(struct usb_hcd	*hcd, u16 typeReq, u16 wValue, +				 u16 wIndex, char *buf, u16 wLength); +extern int	ohci_hub_status_data(struct usb_hcd *hcd, char *buf); diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 4a6df2d8f90..e07248b6ab6 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -29,7 +29,6 @@  #include <linux/sched.h>  #include <linux/slab.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/timer.h>  #include <linux/list.h>  #include <linux/interrupt.h> @@ -60,6 +59,10 @@  #define oxu_info(oxu, fmt, args...) \  		dev_info(oxu_to_hcd(oxu)->self.controller , fmt , ## args) +#ifdef CONFIG_DYNAMIC_DEBUG +#define DEBUG +#endif +  static inline struct usb_hcd *oxu_to_hcd(struct oxu_hcd *oxu)  {  	return container_of((void *) oxu, struct usb_hcd, hcd_priv); @@ -3747,6 +3750,7 @@ static struct usb_hcd *oxu_create(struct platform_device *pdev,  	if (ret < 0)  		return ERR_PTR(ret); +	device_wakeup_enable(hcd->self.controller);  	return hcd;  } diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 2c76ef1320e..2f3acebb577 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -12,7 +12,6 @@  #include <linux/kconfig.h>  #include <linux/kernel.h>  #include <linux/pci.h> -#include <linux/init.h>  #include <linux/delay.h>  #include <linux/export.h>  #include <linux/acpi.h> @@ -79,11 +78,30 @@  #define USB_INTEL_USB3_PSSEN   0xD8  #define USB_INTEL_USB3PRM      0xDC +/* + * amd_chipset_gen values represent AMD different chipset generations + */ +enum amd_chipset_gen { +	NOT_AMD_CHIPSET = 0, +	AMD_CHIPSET_SB600, +	AMD_CHIPSET_SB700, +	AMD_CHIPSET_SB800, +	AMD_CHIPSET_HUDSON2, +	AMD_CHIPSET_BOLTON, +	AMD_CHIPSET_YANGTZE, +	AMD_CHIPSET_UNKNOWN, +}; + +struct amd_chipset_type { +	enum amd_chipset_gen gen; +	u8 rev; +}; +  static struct amd_chipset_info {  	struct pci_dev	*nb_dev;  	struct pci_dev	*smbus_dev;  	int nb_type; -	int sb_type; +	struct amd_chipset_type sb_type;  	int isoc_reqs;  	int probe_count;  	int probe_result; @@ -91,6 +109,51 @@ static struct amd_chipset_info {  static DEFINE_SPINLOCK(amd_lock); +/* + * amd_chipset_sb_type_init - initialize amd chipset southbridge type + * + * AMD FCH/SB generation and revision is identified by SMBus controller + * vendor, device and revision IDs. + * + * Returns: 1 if it is an AMD chipset, 0 otherwise. + */ +static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo) +{ +	u8 rev = 0; +	pinfo->sb_type.gen = AMD_CHIPSET_UNKNOWN; + +	pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, +			PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); +	if (pinfo->smbus_dev) { +		rev = pinfo->smbus_dev->revision; +		if (rev >= 0x10 && rev <= 0x1f) +			pinfo->sb_type.gen = AMD_CHIPSET_SB600; +		else if (rev >= 0x30 && rev <= 0x3f) +			pinfo->sb_type.gen = AMD_CHIPSET_SB700; +		else if (rev >= 0x40 && rev <= 0x4f) +			pinfo->sb_type.gen = AMD_CHIPSET_SB800; +	} else { +		pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, +				PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL); + +		if (!pinfo->smbus_dev) { +			pinfo->sb_type.gen = NOT_AMD_CHIPSET; +			return 0; +		} + +		rev = pinfo->smbus_dev->revision; +		if (rev >= 0x11 && rev <= 0x14) +			pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2; +		else if (rev >= 0x15 && rev <= 0x18) +			pinfo->sb_type.gen = AMD_CHIPSET_BOLTON; +		else if (rev >= 0x39 && rev <= 0x3a) +			pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE; +	} + +	pinfo->sb_type.rev = rev; +	return 1; +} +  void sb800_prefetch(struct device *dev, int on)  {  	u16 misc; @@ -106,7 +169,6 @@ EXPORT_SYMBOL_GPL(sb800_prefetch);  int usb_amd_find_chipset_info(void)  { -	u8 rev = 0;  	unsigned long flags;  	struct amd_chipset_info info;  	int ret; @@ -122,27 +184,17 @@ int usb_amd_find_chipset_info(void)  	memset(&info, 0, sizeof(info));  	spin_unlock_irqrestore(&amd_lock, flags); -	info.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); -	if (info.smbus_dev) { -		rev = info.smbus_dev->revision; -		if (rev >= 0x40) -			info.sb_type = 1; -		else if (rev >= 0x30 && rev <= 0x3b) -			info.sb_type = 3; -	} else { -		info.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, -						0x780b, NULL); -		if (!info.smbus_dev) { -			ret = 0; -			goto commit; -		} - -		rev = info.smbus_dev->revision; -		if (rev >= 0x11 && rev <= 0x18) -			info.sb_type = 2; +	if (!amd_chipset_sb_type_init(&info)) { +		ret = 0; +		goto commit;  	} -	if (info.sb_type == 0) { +	/* Below chipset generations needn't enable AMD PLL quirk */ +	if (info.sb_type.gen == AMD_CHIPSET_UNKNOWN || +			info.sb_type.gen == AMD_CHIPSET_SB600 || +			info.sb_type.gen == AMD_CHIPSET_YANGTZE || +			(info.sb_type.gen == AMD_CHIPSET_SB700 && +			info.sb_type.rev > 0x3b)) {  		if (info.smbus_dev) {  			pci_dev_put(info.smbus_dev);  			info.smbus_dev = NULL; @@ -197,6 +249,39 @@ commit:  }  EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); +int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev) +{ +	/* Make sure amd chipset type has already been initialized */ +	usb_amd_find_chipset_info(); +	if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE) +		return 0; + +	dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n"); +	return 1; +} +EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk); + +bool usb_amd_hang_symptom_quirk(void) +{ +	u8 rev; + +	usb_amd_find_chipset_info(); +	rev = amd_chipset.sb_type.rev; +	/* SB600 and old version of SB700 have hang symptom bug */ +	return amd_chipset.sb_type.gen == AMD_CHIPSET_SB600 || +			(amd_chipset.sb_type.gen == AMD_CHIPSET_SB700 && +			 rev >= 0x3a && rev <= 0x3b); +} +EXPORT_SYMBOL_GPL(usb_amd_hang_symptom_quirk); + +bool usb_amd_prefetch_quirk(void) +{ +	usb_amd_find_chipset_info(); +	/* SB800 needs pre-fetch fix */ +	return amd_chipset.sb_type.gen == AMD_CHIPSET_SB800; +} +EXPORT_SYMBOL_GPL(usb_amd_prefetch_quirk); +  /*   * The hardware normally enables the A-link power management feature, which   * lets the system lower the power consumption in idle states. @@ -229,7 +314,9 @@ static void usb_amd_quirk_pll(int disable)  		}  	} -	if (amd_chipset.sb_type == 1 || amd_chipset.sb_type == 2) { +	if (amd_chipset.sb_type.gen == AMD_CHIPSET_SB800 || +			amd_chipset.sb_type.gen == AMD_CHIPSET_HUDSON2 || +			amd_chipset.sb_type.gen == AMD_CHIPSET_BOLTON) {  		outb_p(AB_REG_BAR_LOW, 0xcd6);  		addr_low = inb_p(0xcd7);  		outb_p(AB_REG_BAR_HIGH, 0xcd6); @@ -240,7 +327,8 @@ static void usb_amd_quirk_pll(int disable)  		outl_p(0x40, AB_DATA(addr));  		outl_p(0x34, AB_INDX(addr));  		val = inl_p(AB_DATA(addr)); -	} else if (amd_chipset.sb_type == 3) { +	} else if (amd_chipset.sb_type.gen == AMD_CHIPSET_SB700 && +			amd_chipset.sb_type.rev <= 0x3b) {  		pci_read_config_dword(amd_chipset.smbus_dev,  					AB_REG_BAR_SB700, &addr);  		outl(AX_INDXC, AB_INDX(addr)); @@ -353,7 +441,7 @@ void usb_amd_dev_put(void)  	amd_chipset.nb_dev = NULL;  	amd_chipset.smbus_dev = NULL;  	amd_chipset.nb_type = 0; -	amd_chipset.sb_type = 0; +	memset(&amd_chipset.sb_type, 0, sizeof(amd_chipset.sb_type));  	amd_chipset.isoc_reqs = 0;  	amd_chipset.probe_result = 0; @@ -568,6 +656,14 @@ static const struct dmi_system_id ehci_dmi_nohandoff_table[] = {  			DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),  		},  	}, +	{ +		/* HASEE E200 */ +		.matches = { +			DMI_MATCH(DMI_BOARD_VENDOR, "HASEE"), +			DMI_MATCH(DMI_BOARD_NAME, "E210"), +			DMI_MATCH(DMI_BIOS_VERSION, "6.00"), +		}, +	},  	{ }  }; @@ -577,9 +673,14 @@ static void ehci_bios_handoff(struct pci_dev *pdev,  {  	int try_handoff = 1, tried_handoff = 0; -	/* The Pegatron Lucid tablet sporadically waits for 98 seconds trying -	 * the handoff on its unused controller.  Skip it. */ -	if (pdev->vendor == 0x8086 && pdev->device == 0x283a) { +	/* +	 * The Pegatron Lucid tablet sporadically waits for 98 seconds trying +	 * the handoff on its unused controller.  Skip it. +	 * +	 * The HASEE E200 hangs when the semaphore is set (bugzilla #77021). +	 */ +	if (pdev->vendor == 0x8086 && (pdev->device == 0x283a || +			pdev->device == 0x27cc)) {  		if (dmi_check_system(ehci_dmi_nohandoff_table))  			try_handoff = 0;  	} @@ -759,6 +860,13 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)  	bool		ehci_found = false;  	struct pci_dev	*companion = NULL; +	/* Sony VAIO t-series with subsystem device ID 90a8 is not capable of +	 * switching ports from EHCI to xHCI +	 */ +	if (xhci_pdev->subsystem_vendor == PCI_VENDOR_ID_SONY && +	    xhci_pdev->subsystem_device == 0x90a8) +		return; +  	/* make sure an intel EHCI controller exists */  	for_each_pci_dev(companion) {  		if (companion->class == PCI_CLASS_SERIAL_USB_EHCI && @@ -799,7 +907,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)  	 * switchable ports.  	 */  	pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, -			cpu_to_le32(ports_available)); +			ports_available);  	pci_read_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN,  			&ports_available); @@ -821,7 +929,7 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev)  	 * host.  	 */  	pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, -			cpu_to_le32(ports_available)); +			ports_available);  	pci_read_config_dword(xhci_pdev, USB_INTEL_XUSB2PR,  			&ports_available); diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ed6700d00fe..c622ddf21c9 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h @@ -5,6 +5,9 @@  void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);  int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);  int usb_amd_find_chipset_info(void); +int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev); +bool usb_amd_hang_symptom_quirk(void); +bool usb_amd_prefetch_quirk(void);  void usb_amd_dev_put(void);  void usb_amd_quirk_pll_disable(void);  void usb_amd_quirk_pll_enable(void); diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 2ad004ae747..110b4b9ebea 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -27,7 +27,6 @@  #include <linux/kernel.h>  #include <linux/sched.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/timer.h>  #include <linux/delay.h>  #include <linux/list.h> @@ -95,7 +94,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)  	int i = 0;  	if (r8a66597->pdata->on_chip) { -		clk_enable(r8a66597->clk); +		clk_prepare_enable(r8a66597->clk);  		do {  			r8a66597_write(r8a66597, SCKE, SYSCFG0);  			tmp = r8a66597_read(r8a66597, SYSCFG0); @@ -139,7 +138,7 @@ static void r8a66597_clock_disable(struct r8a66597 *r8a66597)  	udelay(1);  	if (r8a66597->pdata->on_chip) { -		clk_disable(r8a66597->clk); +		clk_disable_unprepare(r8a66597->clk);  	} else {  		r8a66597_bclr(r8a66597, PLLC, SYSCFG0);  		r8a66597_bclr(r8a66597, XCKE, SYSCFG0); @@ -2514,6 +2513,7 @@ static int r8a66597_probe(struct platform_device *pdev)  		dev_err(&pdev->dev, "Failed to add hcd\n");  		goto clean_up3;  	} +	device_wakeup_enable(hcd->self.controller);  	return 0; @@ -2534,7 +2534,7 @@ static struct platform_driver r8a66597_driver = {  	.probe =	r8a66597_probe,  	.remove =	r8a66597_remove,  	.driver		= { -		.name = (char *) hcd_name, +		.name = hcd_name,  		.owner	= THIS_MODULE,  		.pm	= R8A66597_DEV_PM_OPS,  	}, diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 5477bf5df21..a517151867a 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -39,7 +39,6 @@  #include <linux/sched.h>  #include <linux/slab.h>  #include <linux/errno.h> -#include <linux/init.h>  #include <linux/timer.h>  #include <linux/list.h>  #include <linux/interrupt.h> @@ -1413,7 +1412,7 @@ static int sl811h_show(struct seq_file *s, void *unused)  			case SL11H_CTL1MASK_SE0: s = " se0/reset"; break;  			case SL11H_CTL1MASK_K: s = " k/resume"; break;  			default: s = "j"; break; -			}; s; }), +			} s; }),  			(t & SL11H_CTL1MASK_LSPD) ? " lowspeed" : "",  			(t & SL11H_CTL1MASK_SUSPEND) ? " suspend" : ""); @@ -1446,7 +1445,7 @@ static int sl811h_show(struct seq_file *s, void *unused)  			case USB_PID_SETUP: s = "setup"; break;  			case USB_PID_ACK: s = "status"; break;  			default: s = "?"; break; -			}; s;}), +			} s;}),  			ep->maxpacket,  			ep->nak_count, ep->error_count);  		list_for_each_entry (urb, &ep->hep->urb_list, urb_list) { @@ -1732,6 +1731,8 @@ sl811h_probe(struct platform_device *dev)  	if (retval != 0)  		goto err6; +	device_wakeup_enable(hcd->self.controller); +  	create_debug_file(sl811);  	return retval; diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 469564e57a5..88a9bffe93d 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -12,7 +12,6 @@  #include <linux/kernel.h>  #include <linux/module.h> -#include <linux/init.h>  #include <linux/ptrace.h>  #include <linux/slab.h>  #include <linux/string.h> diff --git a/drivers/usb/host/ssb-hcd.c b/drivers/usb/host/ssb-hcd.c index 74af2c6287d..0196f766df7 100644 --- a/drivers/usb/host/ssb-hcd.c +++ b/drivers/usb/host/ssb-hcd.c @@ -163,8 +163,7 @@ static int ssb_hcd_probe(struct ssb_device *dev,  	/* TODO: Probably need checks here; is the core connected? */ -	if (dma_set_mask(dev->dma_dev, DMA_BIT_MASK(32)) || -	    dma_set_coherent_mask(dev->dma_dev, DMA_BIT_MASK(32))) +	if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32)))  		return -EOPNOTSUPP;  	usb_dev = kzalloc(sizeof(struct ssb_hcd_device), GFP_KERNEL); diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index e402beb5a06..c0671750671 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -3133,6 +3133,7 @@ static int u132_probe(struct platform_device *pdev)  			u132_u132_put_kref(u132);  			return retval;  		} else { +			device_wakeup_enable(hcd->self.controller);  			u132_monitor_queue_work(u132, 100);  			return 0;  		} @@ -3217,7 +3218,7 @@ static struct platform_driver u132_platform_driver = {  	.suspend = u132_suspend,  	.resume = u132_resume,  	.driver = { -		   .name = (char *)hcd_name, +		   .name = hcd_name,  		   .owner = THIS_MODULE,  		   },  }; diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 45573754652..1b28a000d5c 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -20,7 +20,7 @@  static struct dentry *uhci_debugfs_root; -#ifdef DEBUG +#ifdef CONFIG_DYNAMIC_DEBUG  /* Handle REALLY large printks so we don't overflow buffers */  static void lprintk(char *buf) @@ -310,14 +310,14 @@ static int uhci_show_status(struct uhci_hcd *uhci, char *buf, int len)  	unsigned short portsc1, portsc2; -	usbcmd    = uhci_readw(uhci, 0); -	usbstat   = uhci_readw(uhci, 2); -	usbint    = uhci_readw(uhci, 4); -	usbfrnum  = uhci_readw(uhci, 6); -	flbaseadd = uhci_readl(uhci, 8); -	sof       = uhci_readb(uhci, 12); -	portsc1   = uhci_readw(uhci, 16); -	portsc2   = uhci_readw(uhci, 18); +	usbcmd    = uhci_readw(uhci, USBCMD); +	usbstat   = uhci_readw(uhci, USBSTS); +	usbint    = uhci_readw(uhci, USBINTR); +	usbfrnum  = uhci_readw(uhci, USBFRNUM); +	flbaseadd = uhci_readl(uhci, USBFLBASEADD); +	sof       = uhci_readb(uhci, USBSOF); +	portsc1   = uhci_readw(uhci, USBPORTSC1); +	portsc2   = uhci_readw(uhci, USBPORTSC2);  	out += sprintf(out, "  usbcmd    =     %04x   %s%s%s%s%s%s%s%s\n",  		usbcmd, @@ -635,7 +635,7 @@ static const struct file_operations uhci_debug_operations = {  #endif	/* CONFIG_DEBUG_FS */ -#else	/* DEBUG */ +#else	/* CONFIG_DYNAMIC_DEBUG*/  static inline void lprintk(char *buf)  {} diff --git a/drivers/usb/host/uhci-grlib.c b/drivers/usb/host/uhci-grlib.c index 53c23ff7d68..ab25dc397e8 100644 --- a/drivers/usb/host/uhci-grlib.c +++ b/drivers/usb/host/uhci-grlib.c @@ -141,6 +141,7 @@ static int uhci_hcd_grlib_probe(struct platform_device *op)  	if (rv)  		goto err_uhci; +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_uhci: diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 4a86b63745b..27f35e8f161 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -69,18 +69,21 @@ MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");   *            show all queues in /sys/kernel/debug/uhci/[pci_addr]   * debug = 3, show all TDs in URBs when dumping   */ -#ifdef DEBUG -#define DEBUG_CONFIGURED	1 +#ifdef CONFIG_DYNAMIC_DEBUG +  static int debug = 1;  module_param(debug, int, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(debug, "Debug level"); +static char *errbuf;  #else -#define DEBUG_CONFIGURED	0 -#define debug			0 + +#define debug 0 +#define errbuf NULL +  #endif -static char *errbuf; +  #define ERRBUF_LEN    (32 * 1024)  static struct kmem_cache *uhci_up_cachep;	/* urb_priv */ @@ -516,13 +519,12 @@ static void release_uhci(struct uhci_hcd *uhci)  {  	int i; -	if (DEBUG_CONFIGURED) { -		spin_lock_irq(&uhci->lock); -		uhci->is_initialized = 0; -		spin_unlock_irq(&uhci->lock); -		debugfs_remove(uhci->dentry); -	} +	spin_lock_irq(&uhci->lock); +	uhci->is_initialized = 0; +	spin_unlock_irq(&uhci->lock); + +	debugfs_remove(uhci->dentry);  	for (i = 0; i < UHCI_NUM_SKELQH; i++)  		uhci_free_qh(uhci, uhci->skelqh[i]); @@ -868,14 +870,14 @@ static int __init uhci_hcd_init(void)  			ignore_oc ? ", overcurrent ignored" : "");  	set_bit(USB_UHCI_LOADED, &usb_hcds_loaded); -	if (DEBUG_CONFIGURED) { -		errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); -		if (!errbuf) -			goto errbuf_failed; -		uhci_debugfs_root = debugfs_create_dir("uhci", usb_debug_root); -		if (!uhci_debugfs_root) -			goto debug_failed; -	} +#ifdef CONFIG_DYNAMIC_DEBUG +	errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); +	if (!errbuf) +		goto errbuf_failed; +	uhci_debugfs_root = debugfs_create_dir("uhci", usb_debug_root); +	if (!uhci_debugfs_root) +		goto debug_failed; +#endif  	uhci_up_cachep = kmem_cache_create("uhci_urb_priv",  		sizeof(struct urb_priv), 0, 0, NULL); @@ -906,12 +908,14 @@ clean0:  	kmem_cache_destroy(uhci_up_cachep);  up_failed: +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)  	debugfs_remove(uhci_debugfs_root);  debug_failed:  	kfree(errbuf);  errbuf_failed: +#endif  	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);  	return retval; @@ -927,7 +931,9 @@ static void __exit uhci_hcd_cleanup(void)  #endif  	kmem_cache_destroy(uhci_up_cachep);  	debugfs_remove(uhci_debugfs_root); +#ifdef CONFIG_DYNAMIC_DEBUG  	kfree(errbuf); +#endif  	clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);  } diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index 9189bc984c9..93e17b12fb3 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c @@ -75,8 +75,6 @@ static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)  	return !!*buf;  } -#define OK(x)			len = (x); break -  #define CLR_RH_PORTSTAT(x) \  	status = uhci_readw(uhci, port_addr);	\  	status &= ~(RWC_BITS|WZ_BITS); \ @@ -244,7 +242,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			u16 wIndex, char *buf, u16 wLength)  {  	struct uhci_hcd *uhci = hcd_to_uhci(hcd); -	int status, lstatus, retval = 0, len = 0; +	int status, lstatus, retval = 0;  	unsigned int port = wIndex - 1;  	unsigned long port_addr = USBPORTSC1 + 2 * port;  	u16 wPortChange, wPortStatus; @@ -258,7 +256,8 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  	case GetHubStatus:  		*(__le32 *)buf = cpu_to_le32(0); -		OK(4);		/* hub power */ +		retval = 4; /* hub power */ +		break;  	case GetPortStatus:  		if (port >= uhci->rh_numports)  			goto err; @@ -311,13 +310,14 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		*(__le16 *)buf = cpu_to_le16(wPortStatus);  		*(__le16 *)(buf + 2) = cpu_to_le16(wPortChange); -		OK(4); +		retval = 4; +		break;  	case SetHubFeature:		/* We don't implement these */  	case ClearHubFeature:  		switch (wValue) {  		case C_HUB_OVER_CURRENT:  		case C_HUB_LOCAL_POWER: -			OK(0); +			break;  		default:  			goto err;  		} @@ -329,7 +329,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		switch (wValue) {  		case USB_PORT_FEAT_SUSPEND:  			SET_RH_PORTSTAT(USBPORTSC_SUSP); -			OK(0); +			break;  		case USB_PORT_FEAT_RESET:  			SET_RH_PORTSTAT(USBPORTSC_PR); @@ -338,10 +338,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			/* USB v2.0 7.1.7.5 */  			uhci->ports_timeout = jiffies + msecs_to_jiffies(50); -			OK(0); +			break;  		case USB_PORT_FEAT_POWER:  			/* UHCI has no power switching */ -			OK(0); +			break;  		default:  			goto err;  		} @@ -356,10 +356,10 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			/* Disable terminates Resume signalling */  			uhci_finish_suspend(uhci, port, port_addr); -			OK(0); +			break;  		case USB_PORT_FEAT_C_ENABLE:  			CLR_RH_PORTSTAT(USBPORTSC_PEC); -			OK(0); +			break;  		case USB_PORT_FEAT_SUSPEND:  			if (!(uhci_readw(uhci, port_addr) & USBPORTSC_SUSP)) { @@ -382,32 +382,32 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  					uhci->ports_timeout = jiffies +  						msecs_to_jiffies(20);  			} -			OK(0); +			break;  		case USB_PORT_FEAT_C_SUSPEND:  			clear_bit(port, &uhci->port_c_suspend); -			OK(0); +			break;  		case USB_PORT_FEAT_POWER:  			/* UHCI has no power switching */  			goto err;  		case USB_PORT_FEAT_C_CONNECTION:  			CLR_RH_PORTSTAT(USBPORTSC_CSC); -			OK(0); +			break;  		case USB_PORT_FEAT_C_OVER_CURRENT:  			CLR_RH_PORTSTAT(USBPORTSC_OCC); -			OK(0); +			break;  		case USB_PORT_FEAT_C_RESET:  			/* this driver won't report these */ -			OK(0); +			break;  		default:  			goto err;  		}  		break;  	case GetHubDescriptor: -		len = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); -		memcpy(buf, root_hub_hub_des, len); -		if (len > 2) +		retval = min_t(unsigned int, sizeof(root_hub_hub_des), wLength); +		memcpy(buf, root_hub_hub_des, retval); +		if (retval > 2)  			buf[2] = uhci->rh_numports; -		OK(len); +		break;  	default:  err:  		retval = -EPIPE; diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c index c300bd2f7d1..940304c3322 100644 --- a/drivers/usb/host/uhci-pci.c +++ b/drivers/usb/host/uhci-pci.c @@ -162,6 +162,8 @@ static void uhci_shutdown(struct pci_dev *pdev)  #ifdef CONFIG_PM +static int uhci_pci_resume(struct usb_hcd *hcd, bool hibernated); +  static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)  {  	struct uhci_hcd *uhci = hcd_to_uhci(hcd); @@ -174,12 +176,6 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)  	if (!HCD_HW_ACCESSIBLE(hcd) || uhci->dead)  		goto done_okay;		/* Already suspended or dead */ -	if (uhci->rh_state > UHCI_RH_SUSPENDED) { -		dev_warn(uhci_dev(uhci), "Root hub isn't suspended!\n"); -		rc = -EBUSY; -		goto done; -	}; -  	/* All PCI host controllers are required to disable IRQ generation  	 * at the source, so we must turn off PIRQ.  	 */ @@ -195,8 +191,15 @@ static int uhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)  done_okay:  	clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); -done:  	spin_unlock_irq(&uhci->lock); + +	synchronize_irq(hcd->irq); + +	/* Check for race with a wakeup request */ +	if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) { +		uhci_pci_resume(hcd, false); +		rc = -EBUSY; +	}  	return rc;  } @@ -276,7 +279,7 @@ static const struct hc_driver uhci_driver = {  	.hub_control =		uhci_hub_control,  }; -static DEFINE_PCI_DEVICE_TABLE(uhci_pci_ids) = { { +static const struct pci_device_id uhci_pci_ids[] = { {  	/* handle any USB UHCI controller */  	PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),  	.driver_data =	(unsigned long) &uhci_driver, @@ -293,9 +296,11 @@ static struct pci_driver uhci_pci_driver = {  	.remove =	usb_hcd_pci_remove,  	.shutdown =	uhci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM  	.driver =	{  		.pm =	&usb_hcd_pci_pm_ops  	},  #endif  }; + +MODULE_SOFTDEP("pre: ehci_pci"); diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index d033a0ec7f0..01833ab2b5c 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -75,10 +75,9 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)  	 * Since shared usb code relies on it, set it here for now.  	 * Once we have dma capability bindings this can go away.  	 */ -	if (!pdev->dev.dma_mask) -		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; -	if (!pdev->dev.coherent_dma_mask) -		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +	ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); +	if (ret) +		return ret;  	hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,  			pdev->name); @@ -105,11 +104,11 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)  	uhci->regs = hcd->regs; -	ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED | -								IRQF_SHARED); +	ret = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_SHARED);  	if (ret)  		goto err_uhci; +	device_wakeup_enable(hcd->self.controller);  	return 0;  err_uhci: @@ -149,6 +148,7 @@ static void uhci_hcd_platform_shutdown(struct platform_device *op)  }  static const struct of_device_id platform_uhci_ids[] = { +	{ .compatible = "generic-uhci", },  	{ .compatible = "platform-uhci", },  	{}  }; diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 041c6ddb695..da6f56d996c 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c @@ -1303,7 +1303,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,  		}  		/* Fell behind? */ -		if (uhci_frame_before_eq(frame, next)) { +		if (!uhci_frame_before_eq(next, frame)) {  			/* USB_ISO_ASAP: Round up to the first available slot */  			if (urb->transfer_flags & URB_ISO_ASAP) @@ -1311,13 +1311,17 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,  						-qh->period;  			/* -			 * Not ASAP: Use the next slot in the stream.  If -			 * the entire URB falls before the threshold, fail. +			 * Not ASAP: Use the next slot in the stream, +			 * no matter what.  			 */  			else if (!uhci_frame_before_eq(next,  					frame + (urb->number_of_packets - 1) *  						qh->period)) -				return -EXDEV; +				dev_dbg(uhci_dev(uhci), "iso underrun %p (%u+%u < %u)\n", +						urb, frame, +						(urb->number_of_packets - 1) * +							qh->period, +						next);  		}  	} diff --git a/drivers/usb/host/whci/hcd.c b/drivers/usb/host/whci/hcd.c index ecc88db804e..d7b363a418d 100644 --- a/drivers/usb/host/whci/hcd.c +++ b/drivers/usb/host/whci/hcd.c @@ -134,7 +134,7 @@ static int whc_urb_enqueue(struct usb_hcd *usb_hcd, struct urb *urb,  	default:  		ret = asl_urb_enqueue(whc, urb, mem_flags);  		break; -	}; +	}  	return ret;  } @@ -160,7 +160,7 @@ static int whc_urb_dequeue(struct usb_hcd *usb_hcd, struct urb *urb, int status)  	default:  		ret = asl_urb_dequeue(whc, urb, status);  		break; -	}; +	}  	return ret;  } @@ -293,6 +293,7 @@ static int whc_probe(struct umc_dev *umc)  		dev_err(dev, "cannot add HCD: %d\n", ret);  		goto error_usb_add_hcd;  	} +	device_wakeup_enable(usb_hcd->self.controller);  	ret = wusbhc_b_create(wusbhc);  	if (ret) { diff --git a/drivers/usb/host/whci/int.c b/drivers/usb/host/whci/int.c index 6aae7002810..0c086b2790d 100644 --- a/drivers/usb/host/whci/int.c +++ b/drivers/usb/host/whci/int.c @@ -16,7 +16,6 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/uwb/umc.h>  #include "../../wusbcore/wusbhc.h" diff --git a/drivers/usb/host/whci/wusb.c b/drivers/usb/host/whci/wusb.c index f24efdebad1..8d276268286 100644 --- a/drivers/usb/host/whci/wusb.c +++ b/drivers/usb/host/whci/wusb.c @@ -16,7 +16,6 @@   * along with this program.  If not, see <http://www.gnu.org/licenses/>.   */  #include <linux/kernel.h> -#include <linux/init.h>  #include <linux/uwb/umc.h>  #include "../../wusbcore/wusbhc.h" diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 73503a81ee8..eb009a457fb 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c @@ -32,7 +32,7 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "// xHCI capability registers at %p:\n",  			xhci->cap_regs); -	temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); +	temp = readl(&xhci->cap_regs->hc_capbase);  	xhci_dbg(xhci, "// @%p = 0x%x (CAPLENGTH AND HCIVERSION)\n",  			&xhci->cap_regs->hc_capbase, temp);  	xhci_dbg(xhci, "//   CAPLENGTH: 0x%x\n", @@ -44,13 +44,13 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "// xHCI operational registers at %p:\n", xhci->op_regs); -	temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off); +	temp = readl(&xhci->cap_regs->run_regs_off);  	xhci_dbg(xhci, "// @%p = 0x%x RTSOFF\n",  			&xhci->cap_regs->run_regs_off,  			(unsigned int) temp & RTSOFF_MASK);  	xhci_dbg(xhci, "// xHCI runtime registers at %p:\n", xhci->run_regs); -	temp = xhci_readl(xhci, &xhci->cap_regs->db_off); +	temp = readl(&xhci->cap_regs->db_off);  	xhci_dbg(xhci, "// @%p = 0x%x DBOFF\n", &xhci->cap_regs->db_off, temp);  	xhci_dbg(xhci, "// Doorbell array at %p:\n", xhci->dba);  } @@ -61,7 +61,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "xHCI capability registers at %p:\n", xhci->cap_regs); -	temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); +	temp = readl(&xhci->cap_regs->hc_capbase);  	xhci_dbg(xhci, "CAPLENGTH AND HCIVERSION 0x%x:\n",  			(unsigned int) temp);  	xhci_dbg(xhci, "CAPLENGTH: 0x%x\n", @@ -69,7 +69,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "HCIVERSION: 0x%x\n",  			(unsigned int) HC_VERSION(temp)); -	temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params1); +	temp = readl(&xhci->cap_regs->hcs_params1);  	xhci_dbg(xhci, "HCSPARAMS 1: 0x%x\n",  			(unsigned int) temp);  	xhci_dbg(xhci, "  Max device slots: %u\n", @@ -79,7 +79,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "  Max ports: %u\n",  			(unsigned int) HCS_MAX_PORTS(temp)); -	temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params2); +	temp = readl(&xhci->cap_regs->hcs_params2);  	xhci_dbg(xhci, "HCSPARAMS 2: 0x%x\n",  			(unsigned int) temp);  	xhci_dbg(xhci, "  Isoc scheduling threshold: %u\n", @@ -87,7 +87,7 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "  Maximum allowed segments in event ring: %u\n",  			(unsigned int) HCS_ERST_MAX(temp)); -	temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); +	temp = readl(&xhci->cap_regs->hcs_params3);  	xhci_dbg(xhci, "HCSPARAMS 3 0x%x:\n",  			(unsigned int) temp);  	xhci_dbg(xhci, "  Worst case U1 device exit latency: %u\n", @@ -95,14 +95,14 @@ static void xhci_print_cap_regs(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "  Worst case U2 device exit latency: %u\n",  			(unsigned int) HCS_U2_LATENCY(temp)); -	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); +	temp = readl(&xhci->cap_regs->hcc_params);  	xhci_dbg(xhci, "HCC PARAMS 0x%x:\n", (unsigned int) temp);  	xhci_dbg(xhci, "  HC generates %s bit addresses\n",  			HCC_64BIT_ADDR(temp) ? "64" : "32");  	/* FIXME */  	xhci_dbg(xhci, "  FIXME: more HCCPARAMS debugging\n"); -	temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off); +	temp = readl(&xhci->cap_regs->run_regs_off);  	xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK);  } @@ -110,7 +110,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)  {  	u32 temp; -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	xhci_dbg(xhci, "USBCMD 0x%x:\n", temp);  	xhci_dbg(xhci, "  HC is %s\n",  			(temp & CMD_RUN) ? "running" : "being stopped"); @@ -128,7 +128,7 @@ static void xhci_print_status(struct xhci_hcd *xhci)  {  	u32 temp; -	temp = xhci_readl(xhci, &xhci->op_regs->status); +	temp = readl(&xhci->op_regs->status);  	xhci_dbg(xhci, "USBSTS 0x%x:\n", temp);  	xhci_dbg(xhci, "  Event ring is %sempty\n",  			(temp & STS_EINT) ? "not " : ""); @@ -163,7 +163,7 @@ static void xhci_print_ports(struct xhci_hcd *xhci)  		for (j = 0; j < NUM_PORT_REGS; ++j) {  			xhci_dbg(xhci, "%p port %s reg = 0x%x\n",  					addr, names[j], -					(unsigned int) xhci_readl(xhci, addr)); +					(unsigned int) readl(addr));  			addr++;  		}  	} @@ -177,7 +177,7 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num)  	u64 temp_64;  	addr = &ir_set->irq_pending; -	temp = xhci_readl(xhci, addr); +	temp = readl(addr);  	if (temp == XHCI_INIT_VALUE)  		return; @@ -187,17 +187,17 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, int set_num)  			(unsigned int)temp);  	addr = &ir_set->irq_control; -	temp = xhci_readl(xhci, addr); +	temp = readl(addr);  	xhci_dbg(xhci, "  %p: ir_set.control = 0x%x\n", addr,  			(unsigned int)temp);  	addr = &ir_set->erst_size; -	temp = xhci_readl(xhci, addr); +	temp = readl(addr);  	xhci_dbg(xhci, "  %p: ir_set.erst_size = 0x%x\n", addr,  			(unsigned int)temp);  	addr = &ir_set->rsvd; -	temp = xhci_readl(xhci, addr); +	temp = readl(addr);  	if (temp != XHCI_INIT_VALUE)  		xhci_dbg(xhci, "  WARN: %p: ir_set.rsvd = 0x%x\n",  				addr, (unsigned int)temp); @@ -219,12 +219,12 @@ void xhci_print_run_regs(struct xhci_hcd *xhci)  	int i;  	xhci_dbg(xhci, "xHCI runtime registers at %p:\n", xhci->run_regs); -	temp = xhci_readl(xhci, &xhci->run_regs->microframe_index); +	temp = readl(&xhci->run_regs->microframe_index);  	xhci_dbg(xhci, "  %p: Microframe index = 0x%x\n",  			&xhci->run_regs->microframe_index,  			(unsigned int) temp);  	for (i = 0; i < 7; ++i) { -		temp = xhci_readl(xhci, &xhci->run_regs->rsvd[i]); +		temp = readl(&xhci->run_regs->rsvd[i]);  		if (temp != XHCI_INIT_VALUE)  			xhci_dbg(xhci, "  WARN: %p: Rsvd[%i] = 0x%x\n",  					&xhci->run_regs->rsvd[i], diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index fae697ed0b7..aa79e874904 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -20,7 +20,9 @@   * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */ -#include <linux/gfp.h> + +#include <linux/slab.h> +#include <linux/device.h>  #include <asm/unaligned.h>  #include "xhci.h" @@ -94,7 +96,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,  	 */  	memset(port_removable, 0, sizeof(port_removable));  	for (i = 0; i < ports; i++) { -		portsc = xhci_readl(xhci, xhci->usb2_ports[i]); +		portsc = readl(xhci->usb2_ports[i]);  		/* If a device is removable, PORTSC reports a 0, same as in the  		 * hub descriptor DeviceRemovable bits.  		 */ @@ -148,7 +150,7 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,  	port_removable = 0;  	/* bit 0 is reserved, bit 1 is for port 1, etc. */  	for (i = 0; i < ports; i++) { -		portsc = xhci_readl(xhci, xhci->usb3_ports[i]); +		portsc = readl(xhci->usb3_ports[i]);  		if (portsc & PORT_DEV_REMOVE)  			port_removable |= 1 << (i + 1);  	} @@ -270,7 +272,6 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)  	struct xhci_virt_device *virt_dev;  	struct xhci_command *cmd;  	unsigned long flags; -	int timeleft;  	int ret;  	int i; @@ -284,34 +285,31 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)  	spin_lock_irqsave(&xhci->lock, flags);  	for (i = LAST_EP_INDEX; i > 0; i--) { -		if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) -			xhci_queue_stop_endpoint(xhci, slot_id, i, suspend); +		if (virt_dev->eps[i].ring && virt_dev->eps[i].ring->dequeue) { +			struct xhci_command *command; +			command = xhci_alloc_command(xhci, false, false, +						     GFP_NOWAIT); +			if (!command) { +				spin_unlock_irqrestore(&xhci->lock, flags); +				xhci_free_command(xhci, cmd); +				return -ENOMEM; + +			} +			xhci_queue_stop_endpoint(xhci, command, slot_id, i, +						 suspend); +		}  	} -	cmd->command_trb = xhci->cmd_ring->enqueue; -	list_add_tail(&cmd->cmd_list, &virt_dev->cmd_list); -	xhci_queue_stop_endpoint(xhci, slot_id, 0, suspend); +	xhci_queue_stop_endpoint(xhci, cmd, slot_id, 0, suspend);  	xhci_ring_cmd_db(xhci);  	spin_unlock_irqrestore(&xhci->lock, flags);  	/* Wait for last stop endpoint command to finish */ -	timeleft = wait_for_completion_interruptible_timeout( -			cmd->completion, -			USB_CTRL_SET_TIMEOUT); -	if (timeleft <= 0) { -		xhci_warn(xhci, "%s while waiting for stop endpoint command\n", -				timeleft == 0 ? "Timeout" : "Signal"); -		spin_lock_irqsave(&xhci->lock, flags); -		/* The timeout might have raced with the event ring handler, so -		 * only delete from the list if the item isn't poisoned. -		 */ -		if (cmd->cmd_list.next != LIST_POISON1) -			list_del(&cmd->cmd_list); -		spin_unlock_irqrestore(&xhci->lock, flags); +	wait_for_completion(cmd->completion); + +	if (cmd->status == COMP_CMD_ABORT || cmd->status == COMP_CMD_STOP) { +		xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");  		ret = -ETIME; -		goto command_cleanup;  	} - -command_cleanup:  	xhci_free_command(xhci, cmd);  	return ret;  } @@ -342,8 +340,8 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,  	}  	/* Write 1 to disable the port */ -	xhci_writel(xhci, port_status | PORT_PE, addr); -	port_status = xhci_readl(xhci, addr); +	writel(port_status | PORT_PE, addr); +	port_status = readl(addr);  	xhci_dbg(xhci, "disable port, actual port %d status  = 0x%x\n",  			wIndex, port_status);  } @@ -388,8 +386,8 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,  		return;  	}  	/* Change bits are all write 1 to clear */ -	xhci_writel(xhci, port_status | status, addr); -	port_status = xhci_readl(xhci, addr); +	writel(port_status | status, addr); +	port_status = readl(addr);  	xhci_dbg(xhci, "clear port %s change, actual port %d status  = 0x%x\n",  			port_change_bit, wIndex, port_status);  } @@ -415,11 +413,11 @@ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,  {  	u32 temp; -	temp = xhci_readl(xhci, port_array[port_id]); +	temp = readl(port_array[port_id]);  	temp = xhci_port_state_to_neutral(temp);  	temp &= ~PORT_PLS_MASK;  	temp |= PORT_LINK_STROBE | link_state; -	xhci_writel(xhci, temp, port_array[port_id]); +	writel(temp, port_array[port_id]);  }  static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci, @@ -427,7 +425,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,  {  	u32 temp; -	temp = xhci_readl(xhci, port_array[port_id]); +	temp = readl(port_array[port_id]);  	temp = xhci_port_state_to_neutral(temp);  	if (wake_mask & USB_PORT_FEAT_REMOTE_WAKE_CONNECT) @@ -445,7 +443,7 @@ static void xhci_set_remote_wake_mask(struct xhci_hcd *xhci,  	else  		temp &= ~PORT_WKOC_E; -	xhci_writel(xhci, temp, port_array[port_id]); +	writel(temp, port_array[port_id]);  }  /* Test and clear port RWC bit */ @@ -454,11 +452,11 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,  {  	u32 temp; -	temp = xhci_readl(xhci, port_array[port_id]); +	temp = readl(port_array[port_id]);  	if (temp & port_bit) {  		temp = xhci_port_state_to_neutral(temp);  		temp |= port_bit; -		xhci_writel(xhci, temp, port_array[port_id]); +		writel(temp, port_array[port_id]);  	}  } @@ -524,7 +522,8 @@ static void xhci_hub_report_usb3_link_state(u32 *status, u32 status_reg)   * the compliance mode timer is deleted. A port won't enter   * compliance mode if it has previously entered U0.   */ -void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) +static void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, +				    u16 wIndex)  {  	u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1);  	bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); @@ -552,11 +551,15 @@ void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex)   *  - Mark a port as being done with device resume,   *    and ring the endpoint doorbells.   *  - Stop the Synopsys redriver Compliance Mode polling. + *  - Drop and reacquire the xHCI lock, in order to wait for port resume.   */  static u32 xhci_get_port_status(struct usb_hcd *hcd,  		struct xhci_bus_state *bus_state,  		__le32 __iomem **port_array, -		u16 wIndex, u32 raw_port_status) +		u16 wIndex, u32 raw_port_status, +		unsigned long flags) +	__releases(&xhci->lock) +	__acquires(&xhci->lock)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);  	u32 status = 0; @@ -591,21 +594,41 @@ static u32 xhci_get_port_status(struct usb_hcd *hcd,  			return 0xffffffff;  		if (time_after_eq(jiffies,  					bus_state->resume_done[wIndex])) { +			int time_left; +  			xhci_dbg(xhci, "Resume USB2 port %d\n",  					wIndex + 1);  			bus_state->resume_done[wIndex] = 0;  			clear_bit(wIndex, &bus_state->resuming_ports); + +			set_bit(wIndex, &bus_state->rexit_ports);  			xhci_set_link_state(xhci, port_array, wIndex,  					XDEV_U0); -			xhci_dbg(xhci, "set port %d resume\n", -					wIndex + 1); -			slot_id = xhci_find_slot_id_by_port(hcd, xhci, -					wIndex + 1); -			if (!slot_id) { -				xhci_dbg(xhci, "slot_id is zero\n"); -				return 0xffffffff; + +			spin_unlock_irqrestore(&xhci->lock, flags); +			time_left = wait_for_completion_timeout( +					&bus_state->rexit_done[wIndex], +					msecs_to_jiffies( +						XHCI_MAX_REXIT_TIMEOUT)); +			spin_lock_irqsave(&xhci->lock, flags); + +			if (time_left) { +				slot_id = xhci_find_slot_id_by_port(hcd, +						xhci, wIndex + 1); +				if (!slot_id) { +					xhci_dbg(xhci, "slot_id is zero\n"); +					return 0xffffffff; +				} +				xhci_ring_device(xhci, slot_id); +			} else { +				int port_status = readl(port_array[wIndex]); +				xhci_warn(xhci, "Port resume took longer than %i msec, port status = 0x%x\n", +						XHCI_MAX_REXIT_TIMEOUT, +						port_status); +				status |= USB_PORT_STAT_SUSPEND; +				clear_bit(wIndex, &bus_state->rexit_ports);  			} -			xhci_ring_device(xhci, slot_id); +  			bus_state->port_c_suspend |= 1 << wIndex;  			bus_state->suspended_ports &= ~(1 << wIndex);  		} else { @@ -707,12 +730,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		/* Set the U1 and U2 exit latencies. */  		memcpy(buf, &usb_bos_descriptor,  				USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE); -		temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); -		buf[12] = HCS_U1_LATENCY(temp); -		put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); +		if ((xhci->quirks & XHCI_LPM_SUPPORT)) { +			temp = readl(&xhci->cap_regs->hcs_params3); +			buf[12] = HCS_U1_LATENCY(temp); +			put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); +		}  		/* Indicate whether the host has LTM support. */ -		temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); +		temp = readl(&xhci->cap_regs->hcc_params);  		if (HCC_LTC(temp))  			buf[8] |= USB_LTM_SUPPORT; @@ -722,13 +747,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		if (!wIndex || wIndex > max_ports)  			goto error;  		wIndex--; -		temp = xhci_readl(xhci, port_array[wIndex]); +		temp = readl(port_array[wIndex]);  		if (temp == 0xffffffff) {  			retval = -ENODEV;  			break;  		}  		status = xhci_get_port_status(hcd, bus_state, port_array, -				wIndex, temp); +				wIndex, temp, flags);  		if (status == 0xffffffff)  			goto error; @@ -749,7 +774,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		if (!wIndex || wIndex > max_ports)  			goto error;  		wIndex--; -		temp = xhci_readl(xhci, port_array[wIndex]); +		temp = readl(port_array[wIndex]);  		if (temp == 0xffffffff) {  			retval = -ENODEV;  			break; @@ -758,7 +783,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		/* FIXME: What new port features do we need to support? */  		switch (wValue) {  		case USB_PORT_FEAT_SUSPEND: -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			if ((temp & PORT_PLS_MASK) != XDEV_U0) {  				/* Resume the port to U0 first */  				xhci_set_link_state(xhci, port_array, wIndex, @@ -771,7 +796,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			 * a port unless the port reports that it is in the  			 * enabled (PED = ‘1’,PLS < ‘3’) state.  			 */ -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			if ((temp & PORT_PE) == 0 || (temp & PORT_RESET)  				|| (temp & PORT_PLS_MASK) >= XDEV_U3) {  				xhci_warn(xhci, "USB core suspending device " @@ -796,11 +821,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			msleep(10); /* wait device to enter */  			spin_lock_irqsave(&xhci->lock, flags); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			bus_state->suspended_ports |= 1 << wIndex;  			break;  		case USB_PORT_FEAT_LINK_STATE: -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			/* Disable port */  			if (link_state == USB_SS_PORT_LS_SS_DISABLED) { @@ -813,9 +838,8 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  				temp |= PORT_CSC | PORT_PEC | PORT_WRC |  					PORT_OCC | PORT_RC | PORT_PLC |  					PORT_CEC; -				xhci_writel(xhci, temp | PORT_PE, -					port_array[wIndex]); -				temp = xhci_readl(xhci, port_array[wIndex]); +				writel(temp | PORT_PE, port_array[wIndex]); +				temp = readl(port_array[wIndex]);  				break;  			} @@ -824,7 +848,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  				xhci_dbg(xhci, "Enable port %d\n", wIndex);  				xhci_set_link_state(xhci, port_array, wIndex,  						link_state); -				temp = xhci_readl(xhci, port_array[wIndex]); +				temp = readl(port_array[wIndex]);  				break;  			} @@ -858,7 +882,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			msleep(20); /* wait device to enter */  			spin_lock_irqsave(&xhci->lock, flags); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			if (link_state == USB_SS_PORT_LS_U3)  				bus_state->suspended_ports |= 1 << wIndex;  			break; @@ -869,10 +893,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			 * However, khubd will ignore the roothub events until  			 * the roothub is registered.  			 */ -			xhci_writel(xhci, temp | PORT_POWER, -					port_array[wIndex]); +			writel(temp | PORT_POWER, port_array[wIndex]); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			xhci_dbg(xhci, "set port power, actual port %d status  = 0x%x\n", wIndex, temp);  			spin_unlock_irqrestore(&xhci->lock, flags); @@ -885,52 +908,52 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  			break;  		case USB_PORT_FEAT_RESET:  			temp = (temp | PORT_RESET); -			xhci_writel(xhci, temp, port_array[wIndex]); +			writel(temp, port_array[wIndex]); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			xhci_dbg(xhci, "set port reset, actual port %d status  = 0x%x\n", wIndex, temp);  			break;  		case USB_PORT_FEAT_REMOTE_WAKE_MASK:  			xhci_set_remote_wake_mask(xhci, port_array,  					wIndex, wake_mask); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			xhci_dbg(xhci, "set port remote wake mask, "  					"actual port %d status  = 0x%x\n",  					wIndex, temp);  			break;  		case USB_PORT_FEAT_BH_PORT_RESET:  			temp |= PORT_WR; -			xhci_writel(xhci, temp, port_array[wIndex]); +			writel(temp, port_array[wIndex]); -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			break;  		case USB_PORT_FEAT_U1_TIMEOUT:  			if (hcd->speed != HCD_USB3)  				goto error; -			temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); +			temp = readl(port_array[wIndex] + PORTPMSC);  			temp &= ~PORT_U1_TIMEOUT_MASK;  			temp |= PORT_U1_TIMEOUT(timeout); -			xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); +			writel(temp, port_array[wIndex] + PORTPMSC);  			break;  		case USB_PORT_FEAT_U2_TIMEOUT:  			if (hcd->speed != HCD_USB3)  				goto error; -			temp = xhci_readl(xhci, port_array[wIndex] + PORTPMSC); +			temp = readl(port_array[wIndex] + PORTPMSC);  			temp &= ~PORT_U2_TIMEOUT_MASK;  			temp |= PORT_U2_TIMEOUT(timeout); -			xhci_writel(xhci, temp, port_array[wIndex] + PORTPMSC); +			writel(temp, port_array[wIndex] + PORTPMSC);  			break;  		default:  			goto error;  		}  		/* unblock any posted writes */ -		temp = xhci_readl(xhci, port_array[wIndex]); +		temp = readl(port_array[wIndex]);  		break;  	case ClearPortFeature:  		if (!wIndex || wIndex > max_ports)  			goto error;  		wIndex--; -		temp = xhci_readl(xhci, port_array[wIndex]); +		temp = readl(port_array[wIndex]);  		if (temp == 0xffffffff) {  			retval = -ENODEV;  			break; @@ -939,7 +962,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  		temp = xhci_port_state_to_neutral(temp);  		switch (wValue) {  		case USB_PORT_FEAT_SUSPEND: -			temp = xhci_readl(xhci, port_array[wIndex]); +			temp = readl(port_array[wIndex]);  			xhci_dbg(xhci, "clear USB_PORT_FEAT_SUSPEND\n");  			xhci_dbg(xhci, "PORTSC %04x\n", temp);  			if (temp & PORT_RESET) @@ -982,8 +1005,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,  					port_array[wIndex], temp);  			break;  		case USB_PORT_FEAT_POWER: -			xhci_writel(xhci, temp & ~PORT_POWER, -				port_array[wIndex]); +			writel(temp & ~PORT_POWER, port_array[wIndex]);  			spin_unlock_irqrestore(&xhci->lock, flags);  			temp = usb_acpi_power_manageable(hcd->self.root_hub, @@ -1044,7 +1066,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)  	spin_lock_irqsave(&xhci->lock, flags);  	/* For each port, did anything change?  If so, set that bit in buf. */  	for (i = 0; i < max_ports; i++) { -		temp = xhci_readl(xhci, port_array[i]); +		temp = readl(port_array[i]);  		if (temp == 0xffffffff) {  			retval = -ENODEV;  			break; @@ -1098,7 +1120,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)  		u32 t1, t2;  		int slot_id; -		t1 = xhci_readl(xhci, port_array[port_index]); +		t1 = readl(port_array[port_index]);  		t2 = xhci_port_state_to_neutral(t1);  		if ((t1 & PORT_PE) && !(t1 & PORT_PLS_MASK)) { @@ -1118,7 +1140,9 @@ int xhci_bus_suspend(struct usb_hcd *hcd)  		 * including the USB 3.0 roothub, but only if CONFIG_PM_RUNTIME  		 * is enabled, so also enable remote wake here.  		 */ -		if (hcd->self.root_hub->do_remote_wakeup) { +		if (hcd->self.root_hub->do_remote_wakeup +				&& device_may_wakeup(hcd->self.controller)) { +  			if (t1 & PORT_CONNECT) {  				t2 |= PORT_WKOC_E | PORT_WKDISC_E;  				t2 &= ~PORT_WKCONN_E; @@ -1131,19 +1155,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)  		t1 = xhci_port_state_to_neutral(t1);  		if (t1 != t2) -			xhci_writel(xhci, t2, port_array[port_index]); - -		if (hcd->speed != HCD_USB3) { -			/* enable remote wake up for USB 2.0 */ -			__le32 __iomem *addr; -			u32 tmp; - -			/* Get the port power control register address. */ -			addr = port_array[port_index] + PORTPMSC; -			tmp = xhci_readl(xhci, addr); -			tmp |= PORT_RWE; -			xhci_writel(xhci, tmp, addr); -		} +			writel(t2, port_array[port_index]);  	}  	hcd->state = HC_STATE_SUSPENDED;  	bus_state->next_statechange = jiffies + msecs_to_jiffies(10); @@ -1173,9 +1185,9 @@ int xhci_bus_resume(struct usb_hcd *hcd)  	}  	/* delay the irqs */ -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	temp &= ~CMD_EIE; -	xhci_writel(xhci, temp, &xhci->op_regs->command); +	writel(temp, &xhci->op_regs->command);  	port_index = max_ports;  	while (port_index--) { @@ -1184,7 +1196,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)  		u32 temp;  		int slot_id; -		temp = xhci_readl(xhci, port_array[port_index]); +		temp = readl(port_array[port_index]);  		if (DEV_SUPERSPEED(temp))  			temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);  		else @@ -1221,31 +1233,17 @@ int xhci_bus_resume(struct usb_hcd *hcd)  			if (slot_id)  				xhci_ring_device(xhci, slot_id);  		} else -			xhci_writel(xhci, temp, port_array[port_index]); - -		if (hcd->speed != HCD_USB3) { -			/* disable remote wake up for USB 2.0 */ -			__le32 __iomem *addr; -			u32 tmp; - -			/* Add one to the port status register address to get -			 * the port power control register address. -			 */ -			addr = port_array[port_index] + PORTPMSC; -			tmp = xhci_readl(xhci, addr); -			tmp &= ~PORT_RWE; -			xhci_writel(xhci, tmp, addr); -		} +			writel(temp, port_array[port_index]);  	} -	(void) xhci_readl(xhci, &xhci->op_regs->command); +	(void) readl(&xhci->op_regs->command);  	bus_state->next_statechange = jiffies + msecs_to_jiffies(5);  	/* re-enable irqs */ -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	temp |= CMD_EIE; -	xhci_writel(xhci, temp, &xhci->op_regs->command); -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	writel(temp, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	spin_unlock_irqrestore(&xhci->lock, flags);  	return 0; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 53b972c2a09..8056d90690e 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -57,7 +57,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,  	/* If the cycle state is 0, set the cycle bit to 1 for all the TRBs */  	if (cycle_state == 0) {  		for (i = 0; i < TRBS_PER_SEGMENT; i++) -			seg->trbs[i].link.control |= TRB_CYCLE; +			seg->trbs[i].link.control |= cpu_to_le32(TRB_CYCLE);  	}  	seg->dma = dma;  	seg->next = NULL; @@ -149,14 +149,140 @@ static void xhci_link_rings(struct xhci_hcd *xhci, struct xhci_ring *ring,  	}  } +/* + * We need a radix tree for mapping physical addresses of TRBs to which stream + * ID they belong to.  We need to do this because the host controller won't tell + * us which stream ring the TRB came from.  We could store the stream ID in an + * event data TRB, but that doesn't help us for the cancellation case, since the + * endpoint may stop before it reaches that event data TRB. + * + * The radix tree maps the upper portion of the TRB DMA address to a ring + * segment that has the same upper portion of DMA addresses.  For example, say I + * have segments of size 1KB, that are always 1KB aligned.  A segment may + * start at 0x10c91000 and end at 0x10c913f0.  If I use the upper 10 bits, the + * key to the stream ID is 0x43244.  I can use the DMA address of the TRB to + * pass the radix tree a key to get the right stream ID: + * + *	0x10c90fff >> 10 = 0x43243 + *	0x10c912c0 >> 10 = 0x43244 + *	0x10c91400 >> 10 = 0x43245 + * + * Obviously, only those TRBs with DMA addresses that are within the segment + * will make the radix tree return the stream ID for that ring. + * + * Caveats for the radix tree: + * + * The radix tree uses an unsigned long as a key pair.  On 32-bit systems, an + * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be + * 64-bits.  Since we only request 32-bit DMA addresses, we can use that as the + * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit + * PCI DMA addresses on a 64-bit system).  There might be a problem on 32-bit + * extended systems (where the DMA address can be bigger than 32-bits), + * if we allow the PCI dma mask to be bigger than 32-bits.  So don't do that. + */ +static int xhci_insert_segment_mapping(struct radix_tree_root *trb_address_map, +		struct xhci_ring *ring, +		struct xhci_segment *seg, +		gfp_t mem_flags) +{ +	unsigned long key; +	int ret; + +	key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); +	/* Skip any segments that were already added. */ +	if (radix_tree_lookup(trb_address_map, key)) +		return 0; + +	ret = radix_tree_maybe_preload(mem_flags); +	if (ret) +		return ret; +	ret = radix_tree_insert(trb_address_map, +			key, ring); +	radix_tree_preload_end(); +	return ret; +} + +static void xhci_remove_segment_mapping(struct radix_tree_root *trb_address_map, +		struct xhci_segment *seg) +{ +	unsigned long key; + +	key = (unsigned long)(seg->dma >> TRB_SEGMENT_SHIFT); +	if (radix_tree_lookup(trb_address_map, key)) +		radix_tree_delete(trb_address_map, key); +} + +static int xhci_update_stream_segment_mapping( +		struct radix_tree_root *trb_address_map, +		struct xhci_ring *ring, +		struct xhci_segment *first_seg, +		struct xhci_segment *last_seg, +		gfp_t mem_flags) +{ +	struct xhci_segment *seg; +	struct xhci_segment *failed_seg; +	int ret; + +	if (WARN_ON_ONCE(trb_address_map == NULL)) +		return 0; + +	seg = first_seg; +	do { +		ret = xhci_insert_segment_mapping(trb_address_map, +				ring, seg, mem_flags); +		if (ret) +			goto remove_streams; +		if (seg == last_seg) +			return 0; +		seg = seg->next; +	} while (seg != first_seg); + +	return 0; + +remove_streams: +	failed_seg = seg; +	seg = first_seg; +	do { +		xhci_remove_segment_mapping(trb_address_map, seg); +		if (seg == failed_seg) +			return ret; +		seg = seg->next; +	} while (seg != first_seg); + +	return ret; +} + +static void xhci_remove_stream_mapping(struct xhci_ring *ring) +{ +	struct xhci_segment *seg; + +	if (WARN_ON_ONCE(ring->trb_address_map == NULL)) +		return; + +	seg = ring->first_seg; +	do { +		xhci_remove_segment_mapping(ring->trb_address_map, seg); +		seg = seg->next; +	} while (seg != ring->first_seg); +} + +static int xhci_update_stream_mapping(struct xhci_ring *ring, gfp_t mem_flags) +{ +	return xhci_update_stream_segment_mapping(ring->trb_address_map, ring, +			ring->first_seg, ring->last_seg, mem_flags); +} +  /* XXX: Do we need the hcd structure in all these functions? */  void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring)  {  	if (!ring)  		return; -	if (ring->first_seg) +	if (ring->first_seg) { +		if (ring->type == TYPE_STREAM) +			xhci_remove_stream_mapping(ring);  		xhci_free_segments_for_ring(xhci, ring->first_seg); +	}  	kfree(ring);  } @@ -308,7 +434,8 @@ static void xhci_reinit_cached_ring(struct xhci_hcd *xhci,  				sizeof(union xhci_trb)*TRBS_PER_SEGMENT);  		if (cycle_state == 0) {  			for (i = 0; i < TRBS_PER_SEGMENT; i++) -				seg->trbs[i].link.control |= TRB_CYCLE; +				seg->trbs[i].link.control |= +					cpu_to_le32(TRB_CYCLE);  		}  		/* All endpoint rings have link TRBs */  		xhci_link_segments(xhci, seg, seg->next, type); @@ -348,6 +475,21 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,  	if (ret)  		return -ENOMEM; +	if (ring->type == TYPE_STREAM) +		ret = xhci_update_stream_segment_mapping(ring->trb_address_map, +						ring, first, last, flags); +	if (ret) { +		struct xhci_segment *next; +		do { +			next = first->next; +			xhci_segment_free(xhci, first); +			if (first == last) +				break; +			first = next; +		} while (true); +		return ret; +	} +  	xhci_link_rings(xhci, ring, first, last, num_segs);  	xhci_dbg_trace(xhci, trace_xhci_dbg_ring_expansion,  			"ring expansion succeed, now has %d segments", @@ -432,13 +574,13 @@ static void xhci_free_stream_ctx(struct xhci_hcd *xhci,  		unsigned int num_stream_ctxs,  		struct xhci_stream_ctx *stream_ctx, dma_addr_t dma)  { -	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); +	struct device *dev = xhci_to_hcd(xhci)->self.controller; +	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs; -	if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) -		dma_free_coherent(&pdev->dev, -				sizeof(struct xhci_stream_ctx)*num_stream_ctxs, +	if (size > MEDIUM_STREAM_ARRAY_SIZE) +		dma_free_coherent(dev, size,  				stream_ctx, dma); -	else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) +	else if (size <= SMALL_STREAM_ARRAY_SIZE)  		return dma_pool_free(xhci->small_streams_pool,  				stream_ctx, dma);  	else @@ -460,13 +602,13 @@ static struct xhci_stream_ctx *xhci_alloc_stream_ctx(struct xhci_hcd *xhci,  		unsigned int num_stream_ctxs, dma_addr_t *dma,  		gfp_t mem_flags)  { -	struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); +	struct device *dev = xhci_to_hcd(xhci)->self.controller; +	size_t size = sizeof(struct xhci_stream_ctx) * num_stream_ctxs; -	if (num_stream_ctxs > MEDIUM_STREAM_ARRAY_SIZE) -		return dma_alloc_coherent(&pdev->dev, -				sizeof(struct xhci_stream_ctx)*num_stream_ctxs, +	if (size > MEDIUM_STREAM_ARRAY_SIZE) +		return dma_alloc_coherent(dev, size,  				dma, mem_flags); -	else if (num_stream_ctxs <= SMALL_STREAM_ARRAY_SIZE) +	else if (size <= SMALL_STREAM_ARRAY_SIZE)  		return dma_pool_alloc(xhci->small_streams_pool,  				mem_flags, dma);  	else @@ -509,36 +651,6 @@ struct xhci_ring *xhci_stream_id_to_ring(   * The number of stream contexts in the stream context array may be bigger than   * the number of streams the driver wants to use.  This is because the number of   * stream context array entries must be a power of two. - * - * We need a radix tree for mapping physical addresses of TRBs to which stream - * ID they belong to.  We need to do this because the host controller won't tell - * us which stream ring the TRB came from.  We could store the stream ID in an - * event data TRB, but that doesn't help us for the cancellation case, since the - * endpoint may stop before it reaches that event data TRB. - * - * The radix tree maps the upper portion of the TRB DMA address to a ring - * segment that has the same upper portion of DMA addresses.  For example, say I - * have segments of size 1KB, that are always 64-byte aligned.  A segment may - * start at 0x10c91000 and end at 0x10c913f0.  If I use the upper 10 bits, the - * key to the stream ID is 0x43244.  I can use the DMA address of the TRB to - * pass the radix tree a key to get the right stream ID: - * - * 	0x10c90fff >> 10 = 0x43243 - * 	0x10c912c0 >> 10 = 0x43244 - * 	0x10c91400 >> 10 = 0x43245 - * - * Obviously, only those TRBs with DMA addresses that are within the segment - * will make the radix tree return the stream ID for that ring. - * - * Caveats for the radix tree: - * - * The radix tree uses an unsigned long as a key pair.  On 32-bit systems, an - * unsigned long will be 32-bits; on a 64-bit system an unsigned long will be - * 64-bits.  Since we only request 32-bit DMA addresses, we can use that as the - * key on 32-bit or 64-bit systems (it would also be fine if we asked for 64-bit - * PCI DMA addresses on a 64-bit system).  There might be a problem on 32-bit - * extended systems (where the DMA address can be bigger than 32-bits), - * if we allow the PCI dma mask to be bigger than 32-bits.  So don't do that.   */  struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,  		unsigned int num_stream_ctxs, @@ -547,7 +659,6 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,  	struct xhci_stream_info *stream_info;  	u32 cur_stream;  	struct xhci_ring *cur_ring; -	unsigned long key;  	u64 addr;  	int ret; @@ -602,6 +713,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,  		if (!cur_ring)  			goto cleanup_rings;  		cur_ring->stream_id = cur_stream; +		cur_ring->trb_address_map = &stream_info->trb_address_map;  		/* Set deq ptr, cycle bit, and stream context type */  		addr = cur_ring->first_seg->dma |  			SCT_FOR_CTX(SCT_PRI_TR) | @@ -611,10 +723,7 @@ struct xhci_stream_info *xhci_alloc_stream_info(struct xhci_hcd *xhci,  		xhci_dbg(xhci, "Setting stream %d ring ptr to 0x%08llx\n",  				cur_stream, (unsigned long long) addr); -		key = (unsigned long) -			(cur_ring->first_seg->dma >> TRB_SEGMENT_SHIFT); -		ret = radix_tree_insert(&stream_info->trb_address_map, -				key, cur_ring); +		ret = xhci_update_stream_mapping(cur_ring, mem_flags);  		if (ret) {  			xhci_ring_free(xhci, cur_ring);  			stream_info->stream_rings[cur_stream] = NULL; @@ -634,9 +743,6 @@ cleanup_rings:  	for (cur_stream = 1; cur_stream < num_streams; cur_stream++) {  		cur_ring = stream_info->stream_rings[cur_stream];  		if (cur_ring) { -			addr = cur_ring->first_seg->dma; -			radix_tree_delete(&stream_info->trb_address_map, -					addr >> TRB_SEGMENT_SHIFT);  			xhci_ring_free(xhci, cur_ring);  			stream_info->stream_rings[cur_stream] = NULL;  		} @@ -697,7 +803,6 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,  {  	int cur_stream;  	struct xhci_ring *cur_ring; -	dma_addr_t addr;  	if (!stream_info)  		return; @@ -706,9 +811,6 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,  			cur_stream++) {  		cur_ring = stream_info->stream_rings[cur_stream];  		if (cur_ring) { -			addr = cur_ring->first_seg->dma; -			radix_tree_delete(&stream_info->trb_address_map, -					addr >> TRB_SEGMENT_SHIFT);  			xhci_ring_free(xhci, cur_ring);  			stream_info->stream_rings[cur_stream] = NULL;  		} @@ -721,8 +823,7 @@ void xhci_free_stream_info(struct xhci_hcd *xhci,  				stream_info->stream_ctx_array,  				stream_info->ctx_array_dma); -	if (stream_info) -		kfree(stream_info->stream_rings); +	kfree(stream_info->stream_rings);  	kfree(stream_info);  } @@ -919,7 +1020,6 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,  	dev->num_rings_cached = 0;  	init_completion(&dev->cmd_completion); -	INIT_LIST_HEAD(&dev->cmd_list);  	dev->udev = udev;  	/* Point to output device context in dcbaa. */ @@ -1616,7 +1716,7 @@ static void scratchpad_free(struct xhci_hcd *xhci)  {  	int num_sp;  	int i; -	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); +	struct device *dev = xhci_to_hcd(xhci)->self.controller;  	if (!xhci->scratchpad)  		return; @@ -1624,13 +1724,13 @@ static void scratchpad_free(struct xhci_hcd *xhci)  	num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);  	for (i = 0; i < num_sp; i++) { -		dma_free_coherent(&pdev->dev, xhci->page_size, +		dma_free_coherent(dev, xhci->page_size,  				    xhci->scratchpad->sp_buffers[i],  				    xhci->scratchpad->sp_dma_buffers[i]);  	}  	kfree(xhci->scratchpad->sp_dma_buffers);  	kfree(xhci->scratchpad->sp_buffers); -	dma_free_coherent(&pdev->dev, num_sp * sizeof(u64), +	dma_free_coherent(dev, num_sp * sizeof(u64),  			    xhci->scratchpad->sp_array,  			    xhci->scratchpad->sp_dma);  	kfree(xhci->scratchpad); @@ -1692,17 +1792,16 @@ void xhci_free_command(struct xhci_hcd *xhci,  void xhci_mem_cleanup(struct xhci_hcd *xhci)  { -	struct pci_dev	*pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller); -	struct dev_info	*dev_info, *next; -	struct xhci_cd  *cur_cd, *next_cd; -	unsigned long	flags; +	struct device	*dev = xhci_to_hcd(xhci)->self.controller;  	int size;  	int i, j, num_ports; +	del_timer_sync(&xhci->cmd_timer); +  	/* Free the Event Ring Segment Table and the actual Event Ring */  	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);  	if (xhci->erst.entries) -		dma_free_coherent(&pdev->dev, size, +		dma_free_coherent(dev, size,  				xhci->erst.entries, xhci->erst.erst_dma_addr);  	xhci->erst.entries = NULL;  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed ERST"); @@ -1713,15 +1812,20 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  	if (xhci->lpm_command)  		xhci_free_command(xhci, xhci->lpm_command); -	xhci->cmd_ring_reserved_trbs = 0;  	if (xhci->cmd_ring)  		xhci_ring_free(xhci, xhci->cmd_ring);  	xhci->cmd_ring = NULL;  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed command ring"); -	list_for_each_entry_safe(cur_cd, next_cd, -			&xhci->cancel_cmd_list, cancel_cmd_list) { -		list_del(&cur_cd->cancel_cmd_list); -		kfree(cur_cd); +	xhci_cleanup_command_queue(xhci); + +	num_ports = HCS_MAX_PORTS(xhci->hcs_params1); +	for (i = 0; i < num_ports; i++) { +		struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; +		for (j = 0; j < XHCI_MAX_INTERVAL; j++) { +			struct list_head *ep = &bwt->interval_bw[j].endpoints; +			while (!list_empty(ep)) +				list_del_init(ep->next); +		}  	}  	for (i = 1; i < MAX_HC_SLOTS; ++i) @@ -1750,32 +1854,15 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  			"Freed medium stream array pool");  	if (xhci->dcbaa) -		dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa), +		dma_free_coherent(dev, sizeof(*xhci->dcbaa),  				xhci->dcbaa, xhci->dcbaa->dma);  	xhci->dcbaa = NULL;  	scratchpad_free(xhci); -	spin_lock_irqsave(&xhci->lock, flags); -	list_for_each_entry_safe(dev_info, next, &xhci->lpm_failed_devs, list) { -		list_del(&dev_info->list); -		kfree(dev_info); -	} -	spin_unlock_irqrestore(&xhci->lock, flags); -  	if (!xhci->rh_bw)  		goto no_bw; -	num_ports = HCS_MAX_PORTS(xhci->hcs_params1); -	for (i = 0; i < num_ports; i++) { -		struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table; -		for (j = 0; j < XHCI_MAX_INTERVAL; j++) { -			struct list_head *ep = &bwt->interval_bw[j].endpoints; -			while (!list_empty(ep)) -				list_del_init(ep->next); -		} -	} -  	for (i = 0; i < num_ports; i++) {  		struct xhci_tt_bw_info *tt, *n;  		list_for_each_entry_safe(tt, n, &xhci->rh_bw[i].tts, tt_list) { @@ -1785,6 +1872,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)  	}  no_bw: +	xhci->cmd_ring_reserved_trbs = 0;  	xhci->num_usb2_ports = 0;  	xhci->num_usb3_ports = 0;  	xhci->num_active_eps = 0; @@ -1995,7 +2083,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,  	}  	/* Port offset and count in the third dword, see section 7.2 */ -	temp = xhci_readl(xhci, addr + 2); +	temp = readl(addr + 2);  	port_offset = XHCI_EXT_PORT_OFF(temp);  	port_count = XHCI_EXT_PORT_COUNT(temp);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, @@ -2078,7 +2166,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)  	int cap_count = 0;  	addr = &xhci->cap_regs->hcc_params; -	offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr)); +	offset = XHCI_HCC_EXT_CAPS(readl(addr));  	if (offset == 0) {  		xhci_err(xhci, "No Extended Capability registers, "  				"unable to set up roothub.\n"); @@ -2115,7 +2203,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)  	/* count extended protocol capability entries for later caching */  	do {  		u32 cap_id; -		cap_id = xhci_readl(xhci, tmp_addr); +		cap_id = readl(tmp_addr);  		if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)  			cap_count++;  		tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id); @@ -2129,7 +2217,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)  	while (1) {  		u32 cap_id; -		cap_id = xhci_readl(xhci, addr); +		cap_id = readl(addr);  		if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)  			xhci_add_in_port(xhci, num_ports, addr,  					(u8) XHCI_EXT_PORT_MAJOR(cap_id), @@ -2231,10 +2319,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	u32 page_size, temp;  	int i; -	INIT_LIST_HEAD(&xhci->lpm_failed_devs); -	INIT_LIST_HEAD(&xhci->cancel_cmd_list); +	INIT_LIST_HEAD(&xhci->cmd_list); -	page_size = xhci_readl(xhci, &xhci->op_regs->page_size); +	page_size = readl(&xhci->op_regs->page_size);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"Supported page size register = 0x%x", page_size);  	for (i = 0; i < 16; i++) { @@ -2257,14 +2344,14 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	 * Program the Number of Device Slots Enabled field in the CONFIG  	 * register with the max value of slots the HC can handle.  	 */ -	val = HCS_MAX_SLOTS(xhci_readl(xhci, &xhci->cap_regs->hcs_params1)); +	val = HCS_MAX_SLOTS(readl(&xhci->cap_regs->hcs_params1));  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// xHC can handle at most %d device slots.", val); -	val2 = xhci_readl(xhci, &xhci->op_regs->config_reg); +	val2 = readl(&xhci->op_regs->config_reg);  	val |= (val2 & ~HCS_SLOTS_MASK);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Setting Max device slots reg = 0x%x.", val); -	xhci_writel(xhci, val, &xhci->op_regs->config_reg); +	writel(val, &xhci->op_regs->config_reg);  	/*  	 * Section 5.4.8 - doorbell array must be @@ -2284,11 +2371,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	/*  	 * Initialize the ring segment pool.  The ring must be a contiguous  	 * structure comprised of TRBs.  The TRBs must be 16 byte aligned, -	 * however, the command ring segment needs 64-byte aligned segments, -	 * so we pick the greater alignment need. +	 * however, the command ring segment needs 64-byte aligned segments +	 * and our use of dma addresses in the trb_address_map radix tree needs +	 * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need.  	 */  	xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, -			TRB_SEGMENT_SIZE, 64, xhci->page_size); +			TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size);  	/* See Table 46 and Note on Figure 55 */  	xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, @@ -2341,7 +2429,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	 */  	xhci->cmd_ring_reserved_trbs++; -	val = xhci_readl(xhci, &xhci->cap_regs->db_off); +	val = readl(&xhci->cap_regs->db_off);  	val &= DBOFF_MASK;  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Doorbell array is located at offset 0x%x" @@ -2392,13 +2480,13 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	}  	/* set ERST count with the number of entries in the segment table */ -	val = xhci_readl(xhci, &xhci->ir_set->erst_size); +	val = readl(&xhci->ir_set->erst_size);  	val &= ERST_SIZE_MASK;  	val |= ERST_NUM_SEGS;  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Write ERST size = %i to ir_set 0 (some bits preserved)",  			val); -	xhci_writel(xhci, val, &xhci->ir_set->erst_size); +	writel(val, &xhci->ir_set->erst_size);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Set ERST entries to point to event ring."); @@ -2417,6 +2505,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  			"Wrote ERST address to ir_set 0.");  	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; +  	/*  	 * XXX: Might need to set the Interrupter Moderation Register to  	 * something other than the default (~1ms minimum between interrupts). @@ -2428,6 +2521,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	for (i = 0; i < USB_MAXCHILDREN; ++i) {  		xhci->bus_state[0].resume_done[i] = 0;  		xhci->bus_state[1].resume_done[i] = 0; +		/* Only the USB 2.0 completions will ever be used. */ +		init_completion(&xhci->bus_state[1].rexit_done[i]);  	}  	if (scratchpad_alloc(xhci, flags)) @@ -2439,10 +2534,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)  	 * is necessary for allowing USB 3.0 devices to do remote wakeup from  	 * U3 (device suspend).  	 */ -	temp = xhci_readl(xhci, &xhci->op_regs->dev_notification); +	temp = readl(&xhci->op_regs->dev_notification);  	temp &= ~DEV_NOTE_MASK;  	temp |= DEV_NOTE_FWAKE; -	xhci_writel(xhci, temp, &xhci->op_regs->dev_notification); +	writel(temp, &xhci->op_regs->dev_notification);  	return 0; diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c new file mode 100644 index 00000000000..1eefc988192 --- /dev/null +++ b/drivers/usb/host/xhci-mvebu.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 Marvell + * Author: Gregory CLEMENT <gregory.clement@free-electrons.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include <linux/io.h> +#include <linux/mbus.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +#include "xhci-mvebu.h" + +#define USB3_MAX_WINDOWS	4 +#define USB3_WIN_CTRL(w)	(0x0 + ((w) * 8)) +#define USB3_WIN_BASE(w)	(0x4 + ((w) * 8)) + +static void xhci_mvebu_mbus_config(void __iomem *base, +			const struct mbus_dram_target_info *dram) +{ +	int win; + +	/* Clear all existing windows */ +	for (win = 0; win < USB3_MAX_WINDOWS; win++) { +		writel(0, base + USB3_WIN_CTRL(win)); +		writel(0, base + USB3_WIN_BASE(win)); +	} + +	/* Program each DRAM CS in a seperate window */ +	for (win = 0; win < dram->num_cs; win++) { +		const struct mbus_dram_window *cs = dram->cs + win; + +		writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) | +		       (dram->mbus_dram_target_id << 4) | 1, +		       base + USB3_WIN_CTRL(win)); + +		writel((cs->base & 0xffff0000), base + USB3_WIN_BASE(win)); +	} +} + +int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev) +{ +	struct resource	*res; +	void __iomem *base; +	const struct mbus_dram_target_info *dram; + +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1); +	if (!res) +		return -ENODEV; + +	/* +	 * We don't use devm_ioremap() because this mapping should +	 * only exists for the duration of this probe function. +	 */ +	base = ioremap(res->start, resource_size(res)); +	if (!base) +		return -ENODEV; + +	dram = mv_mbus_dram_info(); +	xhci_mvebu_mbus_config(base, dram); + +	/* +	 * This memory area was only needed to configure the MBus +	 * windows, and is therefore no longer useful. +	 */ +	iounmap(base); + +	return 0; +} diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h new file mode 100644 index 00000000000..7ede92aa41f --- /dev/null +++ b/drivers/usb/host/xhci-mvebu.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 Marvell + * + * Gregory Clement <gregory.clement@free-electrons.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2.  This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __LINUX_XHCI_MVEBU_H +#define __LINUX_XHCI_MVEBU_H +#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) +int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev); +#else +static inline int xhci_mvebu_mbus_init_quirk(struct platform_device *pdev) +{ +	return 0; +} +#endif +#endif /* __LINUX_XHCI_MVEBU_H */ diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c2d495057eb..e20520f4275 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -35,6 +35,9 @@  #define PCI_VENDOR_ID_ETRON		0x1b6f  #define PCI_DEVICE_ID_ASROCK_P67	0x7023 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31 +  static const char hcd_name[] = "xhci_hcd";  /* called after powerup, by probe or system-pm "wakeup" */ @@ -69,6 +72,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  				"QUIRK: Fresco Logic xHC needs configure"  				" endpoint cmd after reset endpoint");  		} +		if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && +				pdev->revision == 0x4) { +			xhci->quirks |= XHCI_SLOW_SUSPEND; +			xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +				"QUIRK: Fresco Logic xHC revision %u" +				"must be suspended extra slowly", +				pdev->revision); +		}  		/* Fresco Logic confirms: all revisions of this chip do not  		 * support MSI, even though some of them claim to in their PCI  		 * capabilities. @@ -110,15 +121,38 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)  		xhci->quirks |= XHCI_SPURIOUS_REBOOT;  		xhci->quirks |= XHCI_AVOID_BEI;  	} +	if (pdev->vendor == PCI_VENDOR_ID_INTEL && +	    (pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI || +	     pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) { +		/* Workaround for occasional spurious wakeups from S5 (or +		 * any other sleep) on Haswell machines with LPT and LPT-LP +		 * with the new Intel BIOS +		 */ +		/* Limit the quirk to only known vendors, as this triggers +		 * yet another BIOS bug on some other machines +		 * https://bugzilla.kernel.org/show_bug.cgi?id=66171 +		 */ +		if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP) +			xhci->quirks |= XHCI_SPURIOUS_WAKEUP; +	} +	if (pdev->vendor == PCI_VENDOR_ID_INTEL && +		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) { +		xhci->quirks |= XHCI_SPURIOUS_REBOOT; +	}  	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&  			pdev->device == PCI_DEVICE_ID_ASROCK_P67) {  		xhci->quirks |= XHCI_RESET_ON_RESUME; -		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, -				"QUIRK: Resetting on resume");  		xhci->quirks |= XHCI_TRUST_TX_LENGTH;  	} +	if (pdev->vendor == PCI_VENDOR_ID_RENESAS && +			pdev->device == 0x0015) +		xhci->quirks |= XHCI_RESET_ON_RESUME;  	if (pdev->vendor == PCI_VENDOR_ID_VIA)  		xhci->quirks |= XHCI_RESET_ON_RESUME; + +	if (xhci->quirks & XHCI_RESET_ON_RESUME) +		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +				"QUIRK: Resetting on resume");  }  /* called during probe() after chip reset completes */ @@ -160,6 +194,10 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	struct usb_hcd *hcd;  	driver = (struct hc_driver *)id->driver_data; + +	/* Prevent runtime suspending between USB-2 and USB-3 initialization */ +	pm_runtime_get_noresume(&dev->dev); +  	/* Register the USB 2.0 roothub.  	 * FIXME: USB core must know to register the USB 2.0 roothub first.  	 * This is sort of silly, because we could just set the HCD driver flags @@ -169,7 +207,7 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	retval = usb_hcd_pci_probe(dev, id);  	if (retval) -		return retval; +		goto put_runtime_pm;  	/* USB 2.0 roothub is stored in the PCI device now. */  	hcd = dev_get_drvdata(&dev->dev); @@ -192,11 +230,11 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  		goto put_usb3_hcd;  	/* Roothub already marked as USB 3.0 speed */ -	/* We know the LPM timeout algorithms for this host, let the USB core -	 * enable and disable LPM for devices under the USB 3.0 roothub. -	 */ -	if (xhci->quirks & XHCI_LPM_SUPPORT) -		hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1; +	if (HCC_MAX_PSA(xhci->hcc_params) >= 4) +		xhci->shared_hcd->can_do_streams = 1; + +	/* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ +	pm_runtime_put_noidle(&dev->dev);  	return 0; @@ -204,6 +242,8 @@ put_usb3_hcd:  	usb_put_hcd(xhci->shared_hcd);  dealloc_usb2_hcd:  	usb_hcd_pci_remove(dev); +put_runtime_pm: +	pm_runtime_put_noidle(&dev->dev);  	return retval;  } @@ -217,6 +257,11 @@ static void xhci_pci_remove(struct pci_dev *dev)  		usb_put_hcd(xhci->shared_hcd);  	}  	usb_hcd_pci_remove(dev); + +	/* Workaround for spurious wakeups at shutdown with HSW */ +	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) +		pci_set_power_state(dev, PCI_D3hot); +  	kfree(xhci);  } @@ -306,6 +351,7 @@ static const struct hc_driver xhci_pci_hc_driver = {  	.check_bandwidth =	xhci_check_bandwidth,  	.reset_bandwidth =	xhci_reset_bandwidth,  	.address_device =	xhci_address_device, +	.enable_device =	xhci_enable_device,  	.update_hub_device =	xhci_update_hub_device,  	.reset_device =		xhci_discover_or_reset_device, @@ -351,7 +397,7 @@ static struct pci_driver xhci_pci_driver = {  	/* suspend and resume implemented later */  	.shutdown = 	usb_hcd_pci_shutdown, -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM  	.driver = {  		.pm = &usb_hcd_pci_pm_ops  	}, diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index d9c169f470d..29d8adb5c8d 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -11,13 +11,15 @@   * version 2 as published by the Free Software Foundation.   */ -#include <linux/platform_device.h> +#include <linux/clk.h> +#include <linux/dma-mapping.h>  #include <linux/module.h> -#include <linux/slab.h>  #include <linux/of.h> -#include <linux/dma-mapping.h> +#include <linux/platform_device.h> +#include <linux/slab.h>  #include "xhci.h" +#include "xhci-mvebu.h"  static void xhci_plat_quirks(struct device *dev, struct xhci_hcd *xhci)  { @@ -35,6 +37,11 @@ static int xhci_plat_setup(struct usb_hcd *hcd)  	return xhci_gen_setup(hcd, xhci_plat_quirks);  } +static int xhci_plat_start(struct usb_hcd *hcd) +{ +	return xhci_run(hcd); +} +  static const struct hc_driver xhci_plat_xhci_driver = {  	.description =		"xhci-hcd",  	.product_desc =		"xHCI Host Controller", @@ -50,7 +57,7 @@ static const struct hc_driver xhci_plat_xhci_driver = {  	 * basic lifecycle operations  	 */  	.reset =		xhci_plat_setup, -	.start =		xhci_run, +	.start =		xhci_plat_start,  	.stop =			xhci_stop,  	.shutdown =		xhci_shutdown, @@ -69,6 +76,7 @@ static const struct hc_driver xhci_plat_xhci_driver = {  	.check_bandwidth =	xhci_check_bandwidth,  	.reset_bandwidth =	xhci_reset_bandwidth,  	.address_device =	xhci_address_device, +	.enable_device =	xhci_enable_device,  	.update_hub_device =	xhci_update_hub_device,  	.reset_device =		xhci_discover_or_reset_device, @@ -90,6 +98,7 @@ static int xhci_plat_probe(struct platform_device *pdev)  	struct xhci_hcd		*xhci;  	struct resource         *res;  	struct usb_hcd		*hcd; +	struct clk              *clk;  	int			ret;  	int			irq; @@ -106,6 +115,15 @@ static int xhci_plat_probe(struct platform_device *pdev)  	if (!res)  		return -ENODEV; +	if (of_device_is_compatible(pdev->dev.of_node, +				    "marvell,armada-375-xhci") || +	    of_device_is_compatible(pdev->dev.of_node, +				    "marvell,armada-380-xhci")) { +		ret = xhci_mvebu_mbus_init_quirk(pdev); +		if (ret) +			return ret; +	} +  	/* Initialize dma_mask and coherent_dma_mask to 32-bits */  	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));  	if (ret) @@ -136,13 +154,27 @@ static int xhci_plat_probe(struct platform_device *pdev)  		goto release_mem_region;  	} +	/* +	 * Not all platforms have a clk so it is not an error if the +	 * clock does not exists. +	 */ +	clk = devm_clk_get(&pdev->dev, NULL); +	if (!IS_ERR(clk)) { +		ret = clk_prepare_enable(clk); +		if (ret) +			goto unmap_registers; +	} +  	ret = usb_add_hcd(hcd, irq, IRQF_SHARED);  	if (ret) -		goto unmap_registers; +		goto disable_clk; + +	device_wakeup_enable(hcd->self.controller);  	/* USB 2.0 roothub is stored in the platform_device now. */  	hcd = platform_get_drvdata(pdev);  	xhci = hcd_to_xhci(hcd); +	xhci->clk = clk;  	xhci->shared_hcd = usb_create_shared_hcd(driver, &pdev->dev,  			dev_name(&pdev->dev), hcd);  	if (!xhci->shared_hcd) { @@ -156,6 +188,9 @@ static int xhci_plat_probe(struct platform_device *pdev)  	 */  	*((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; +	if (HCC_MAX_PSA(xhci->hcc_params) >= 4) +		xhci->shared_hcd->can_do_streams = 1; +  	ret = usb_add_hcd(xhci->shared_hcd, irq, IRQF_SHARED);  	if (ret)  		goto put_usb3_hcd; @@ -168,6 +203,10 @@ put_usb3_hcd:  dealloc_usb2_hcd:  	usb_remove_hcd(hcd); +disable_clk: +	if (!IS_ERR(clk)) +		clk_disable_unprepare(clk); +  unmap_registers:  	iounmap(hcd->regs); @@ -184,11 +223,14 @@ static int xhci_plat_remove(struct platform_device *dev)  {  	struct usb_hcd	*hcd = platform_get_drvdata(dev);  	struct xhci_hcd	*xhci = hcd_to_xhci(hcd); +	struct clk *clk = xhci->clk;  	usb_remove_hcd(xhci->shared_hcd);  	usb_put_hcd(xhci->shared_hcd);  	usb_remove_hcd(hcd); +	if (!IS_ERR(clk)) +		clk_disable_unprepare(clk);  	iounmap(hcd->regs);  	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);  	usb_put_hcd(hcd); @@ -197,7 +239,7 @@ static int xhci_plat_remove(struct platform_device *dev)  	return 0;  } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP  static int xhci_plat_suspend(struct device *dev)  {  	struct usb_hcd	*hcd = dev_get_drvdata(dev); @@ -224,7 +266,10 @@ static const struct dev_pm_ops xhci_plat_pm_ops = {  #ifdef CONFIG_OF  static const struct of_device_id usb_xhci_of_match[] = { +	{ .compatible = "generic-xhci" },  	{ .compatible = "xhci-platform" }, +	{ .compatible = "marvell,armada-375-xhci"}, +	{ .compatible = "marvell,armada-380-xhci"},  	{ },  };  MODULE_DEVICE_TABLE(of, usb_xhci_of_match); diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 411da1fc7ae..749fc68eb5c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -69,10 +69,6 @@  #include "xhci.h"  #include "xhci-trace.h" -static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, -		struct xhci_virt_device *virt_dev, -		struct xhci_event_cmd *event); -  /*   * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA   * address of the TRB. @@ -146,8 +142,6 @@ static void next_trb(struct xhci_hcd *xhci,   */  static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)  { -	unsigned long long addr; -  	ring->deq_updates++;  	/* @@ -168,7 +162,7 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)  			if (ring->type == TYPE_EVENT &&  					last_trb_on_last_seg(xhci, ring,  						ring->deq_seg, ring->dequeue)) { -				ring->cycle_state = (ring->cycle_state ? 0 : 1); +				ring->cycle_state ^= 1;  			}  			ring->deq_seg = ring->deq_seg->next;  			ring->dequeue = ring->deq_seg->trbs; @@ -176,8 +170,6 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring)  			ring->dequeue++;  		}  	} while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); - -	addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);  }  /* @@ -202,7 +194,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,  {  	u32 chain;  	union xhci_trb *next; -	unsigned long long addr;  	chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN;  	/* If this is not event ring, there is one less usable TRB */ @@ -254,7 +245,6 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring,  		ring->enqueue = ring->enq_seg->trbs;  		next = ring->enqueue;  	} -	addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);  }  /* @@ -285,9 +275,9 @@ void xhci_ring_cmd_db(struct xhci_hcd *xhci)  		return;  	xhci_dbg(xhci, "// Ding dong!\n"); -	xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]); +	writel(DB_VALUE_HOST, &xhci->dba->doorbell[0]);  	/* Flush PCI posted writes */ -	xhci_readl(xhci, &xhci->dba->doorbell[0]); +	readl(&xhci->dba->doorbell[0]);  }  static int xhci_abort_cmd_ring(struct xhci_hcd *xhci) @@ -297,17 +287,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)  	xhci_dbg(xhci, "Abort command ring\n"); -	if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) { -		xhci_dbg(xhci, "The command ring isn't running, " -				"Have the command ring been stopped?\n"); -		return 0; -	} -  	temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); -	if (!(temp_64 & CMD_RING_RUNNING)) { -		xhci_dbg(xhci, "Command ring had been stopped\n"); -		return 0; -	}  	xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;  	xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,  			&xhci->op_regs->cmd_ring); @@ -333,71 +313,6 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)  	return 0;  } -static int xhci_queue_cd(struct xhci_hcd *xhci, -		struct xhci_command *command, -		union xhci_trb *cmd_trb) -{ -	struct xhci_cd *cd; -	cd = kzalloc(sizeof(struct xhci_cd), GFP_ATOMIC); -	if (!cd) -		return -ENOMEM; -	INIT_LIST_HEAD(&cd->cancel_cmd_list); - -	cd->command = command; -	cd->cmd_trb = cmd_trb; -	list_add_tail(&cd->cancel_cmd_list, &xhci->cancel_cmd_list); - -	return 0; -} - -/* - * Cancel the command which has issue. - * - * Some commands may hang due to waiting for acknowledgement from - * usb device. It is outside of the xHC's ability to control and - * will cause the command ring is blocked. When it occurs software - * should intervene to recover the command ring. - * See Section 4.6.1.1 and 4.6.1.2 - */ -int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, -		union xhci_trb *cmd_trb) -{ -	int retval = 0; -	unsigned long flags; - -	spin_lock_irqsave(&xhci->lock, flags); - -	if (xhci->xhc_state & XHCI_STATE_DYING) { -		xhci_warn(xhci, "Abort the command ring," -				" but the xHCI is dead.\n"); -		retval = -ESHUTDOWN; -		goto fail; -	} - -	/* queue the cmd desriptor to cancel_cmd_list */ -	retval = xhci_queue_cd(xhci, command, cmd_trb); -	if (retval) { -		xhci_warn(xhci, "Queuing command descriptor failed.\n"); -		goto fail; -	} - -	/* abort command ring */ -	retval = xhci_abort_cmd_ring(xhci); -	if (retval) { -		xhci_err(xhci, "Abort command ring failed\n"); -		if (unlikely(retval == -ESHUTDOWN)) { -			spin_unlock_irqrestore(&xhci->lock, flags); -			usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); -			xhci_dbg(xhci, "xHCI host controller is dead.\n"); -			return retval; -		} -	} - -fail: -	spin_unlock_irqrestore(&xhci->lock, flags); -	return retval; -} -  void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,  		unsigned int slot_id,  		unsigned int ep_index, @@ -417,7 +332,7 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,  	if ((ep_state & EP_HALT_PENDING) || (ep_state & SET_DEQ_PENDING) ||  	    (ep_state & EP_HALTED))  		return; -	xhci_writel(xhci, DB_VALUE(ep_index, stream_id), db_addr); +	writel(DB_VALUE(ep_index, stream_id), db_addr);  	/* The CPU has better things to do at this point than wait for a  	 * write-posting flush.  It'll get there soon enough.  	 */ @@ -542,10 +457,11 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,  		struct xhci_dequeue_state *state)  {  	struct xhci_virt_device *dev = xhci->devs[slot_id]; +	struct xhci_virt_ep *ep = &dev->eps[ep_index];  	struct xhci_ring *ep_ring;  	struct xhci_generic_trb *trb; -	struct xhci_ep_ctx *ep_ctx;  	dma_addr_t addr; +	u64 hw_dequeue;  	ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id,  			ep_index, stream_id); @@ -555,56 +471,65 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,  				stream_id);  		return;  	} -	state->new_cycle_state = 0; -	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, -			"Finding segment containing stopped TRB."); -	state->new_deq_seg = find_trb_seg(cur_td->start_seg, -			dev->eps[ep_index].stopped_trb, -			&state->new_cycle_state); -	if (!state->new_deq_seg) { -		WARN_ON(1); -		return; -	}  	/* Dig out the cycle state saved by the xHC during the stop ep cmd */  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,  			"Finding endpoint context"); -	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); -	state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); +	/* 4.6.9 the css flag is written to the stream context for streams */ +	if (ep->ep_state & EP_HAS_STREAMS) { +		struct xhci_stream_ctx *ctx = +			&ep->stream_info->stream_ctx_array[stream_id]; +		hw_dequeue = le64_to_cpu(ctx->stream_ring); +	} else { +		struct xhci_ep_ctx *ep_ctx +			= xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); +		hw_dequeue = le64_to_cpu(ep_ctx->deq); +	} + +	/* Find virtual address and segment of hardware dequeue pointer */ +	state->new_deq_seg = ep_ring->deq_seg; +	state->new_deq_ptr = ep_ring->dequeue; +	while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr) +			!= (dma_addr_t)(hw_dequeue & ~0xf)) { +		next_trb(xhci, ep_ring, &state->new_deq_seg, +					&state->new_deq_ptr); +		if (state->new_deq_ptr == ep_ring->dequeue) { +			WARN_ON(1); +			return; +		} +	} +	/* +	 * Find cycle state for last_trb, starting at old cycle state of +	 * hw_dequeue. If there is only one segment ring, find_trb_seg() will +	 * return immediately and cannot toggle the cycle state if this search +	 * wraps around, so add one more toggle manually in that case. +	 */ +	state->new_cycle_state = hw_dequeue & 0x1; +	if (ep_ring->first_seg == ep_ring->first_seg->next && +			cur_td->last_trb < state->new_deq_ptr) +		state->new_cycle_state ^= 0x1;  	state->new_deq_ptr = cur_td->last_trb;  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,  			"Finding segment containing last TRB in TD.");  	state->new_deq_seg = find_trb_seg(state->new_deq_seg, -			state->new_deq_ptr, -			&state->new_cycle_state); +			state->new_deq_ptr, &state->new_cycle_state);  	if (!state->new_deq_seg) {  		WARN_ON(1);  		return;  	} +	/* Increment to find next TRB after last_trb. Cycle if appropriate. */  	trb = &state->new_deq_ptr->generic;  	if (TRB_TYPE_LINK_LE32(trb->field[3]) &&  	    (trb->field[3] & cpu_to_le32(LINK_TOGGLE)))  		state->new_cycle_state ^= 0x1;  	next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); -	/* -	 * If there is only one segment in a ring, find_trb_seg()'s while loop -	 * will not run, and it will return before it has a chance to see if it -	 * needs to toggle the cycle bit.  It can't tell if the stalled transfer -	 * ended just before the link TRB on a one-segment ring, or if the TD -	 * wrapped around the top of the ring, because it doesn't have the TD in -	 * question.  Look for the one-segment case where stalled TRB's address -	 * is greater than the new dequeue pointer address. -	 */ -	if (ep_ring->first_seg == ep_ring->first_seg->next && -			state->new_deq_ptr < dev->eps[ep_index].stopped_trb) -		state->new_cycle_state ^= 0x1; +	/* Don't update the ring cycle state for the producer (us). */  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,  			"Cycle state = 0x%x", state->new_cycle_state); -	/* Don't update the ring cycle state for the producer (us). */  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,  			"New dequeue segment = %p (virtual)",  			state->new_deq_seg); @@ -670,12 +595,14 @@ static void td_to_noop(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,  	}  } -static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, +static int queue_set_tr_deq(struct xhci_hcd *xhci, +		struct xhci_command *cmd, int slot_id,  		unsigned int ep_index, unsigned int stream_id,  		struct xhci_segment *deq_seg,  		union xhci_trb *deq_ptr, u32 cycle_state);  void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, +		struct xhci_command *cmd,  		unsigned int slot_id, unsigned int ep_index,  		unsigned int stream_id,  		struct xhci_dequeue_state *deq_state) @@ -690,7 +617,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,  			deq_state->new_deq_ptr,  			(unsigned long long)xhci_trb_virt_to_dma(deq_state->new_deq_seg, deq_state->new_deq_ptr),  			deq_state->new_cycle_state); -	queue_set_tr_deq(xhci, slot_id, ep_index, stream_id, +	queue_set_tr_deq(xhci, cmd, slot_id, ep_index, stream_id,  			deq_state->new_deq_seg,  			deq_state->new_deq_ptr,  			(u32) deq_state->new_cycle_state); @@ -716,7 +643,7 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci,  /* Must be called with xhci->lock held in interrupt context */  static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, -		struct xhci_td *cur_td, int status, char *adjective) +		struct xhci_td *cur_td, int status)  {  	struct usb_hcd *hcd;  	struct urb	*urb; @@ -755,12 +682,10 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci,   *  2. Otherwise, we turn all the TRBs in the TD into No-op TRBs (with the chain   *     bit cleared) so that the HW will skip over them.   */ -static void handle_stopped_endpoint(struct xhci_hcd *xhci, +static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id,  		union xhci_trb *trb, struct xhci_event_cmd *event)  { -	unsigned int slot_id;  	unsigned int ep_index; -	struct xhci_virt_device *virt_dev;  	struct xhci_ring *ep_ring;  	struct xhci_virt_ep *ep;  	struct list_head *entry; @@ -769,15 +694,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,  	struct xhci_dequeue_state deq_state; -	if (unlikely(TRB_TO_SUSPEND_PORT( -			     le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])))) { -		slot_id = TRB_TO_SLOT_ID( -			le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])); -		virt_dev = xhci->devs[slot_id]; -		if (virt_dev) -			handle_cmd_in_cmd_wait_list(xhci, virt_dev, -				event); -		else +	if (unlikely(TRB_TO_SUSPEND_PORT(le32_to_cpu(trb->generic.field[3])))) { +		if (!xhci->devs[slot_id])  			xhci_warn(xhci, "Stop endpoint command "  				"completion for disabled slot %u\n",  				slot_id); @@ -785,14 +703,12 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,  	}  	memset(&deq_state, 0, sizeof(deq_state)); -	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));  	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));  	ep = &xhci->devs[slot_id]->eps[ep_index];  	if (list_empty(&ep->cancelled_td_list)) {  		xhci_stop_watchdog_timer_in_irq(xhci, ep);  		ep->stopped_td = NULL; -		ep->stopped_trb = NULL;  		ring_doorbell_for_active_rings(xhci, slot_id, ep_index);  		return;  	} @@ -850,7 +766,9 @@ remove_finished_td:  	/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */  	if (deq_state.new_deq_ptr && deq_state.new_deq_seg) { -		xhci_queue_new_dequeue_state(xhci, +		struct xhci_command *command; +		command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); +		xhci_queue_new_dequeue_state(xhci, command,  				slot_id, ep_index,  				ep->stopped_td->urb->stream_id,  				&deq_state); @@ -859,8 +777,10 @@ remove_finished_td:  		/* Otherwise ring the doorbell(s) to restart queued transfers */  		ring_doorbell_for_active_rings(xhci, slot_id, ep_index);  	} -	ep->stopped_td = NULL; -	ep->stopped_trb = NULL; + +	/* Clear stopped_td if endpoint is not halted */ +	if (!(ep->ep_state & EP_HALTED)) +		ep->stopped_td = NULL;  	/*  	 * Drop the lock and complete the URBs in the cancelled TD list. @@ -877,7 +797,7 @@ remove_finished_td:  		/* Doesn't matter what we pass for status, since the core will  		 * just overwrite it (because the URB has been unlinked).  		 */ -		xhci_giveback_urb_in_irq(xhci, cur_td, 0, "cancelled"); +		xhci_giveback_urb_in_irq(xhci, cur_td, 0);  		/* Stop processing the cancelled list if the watchdog timer is  		 * running. @@ -889,6 +809,57 @@ remove_finished_td:  	/* Return to the event handler with xhci->lock re-acquired */  } +static void xhci_kill_ring_urbs(struct xhci_hcd *xhci, struct xhci_ring *ring) +{ +	struct xhci_td *cur_td; + +	while (!list_empty(&ring->td_list)) { +		cur_td = list_first_entry(&ring->td_list, +				struct xhci_td, td_list); +		list_del_init(&cur_td->td_list); +		if (!list_empty(&cur_td->cancelled_td_list)) +			list_del_init(&cur_td->cancelled_td_list); +		xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN); +	} +} + +static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, +		int slot_id, int ep_index) +{ +	struct xhci_td *cur_td; +	struct xhci_virt_ep *ep; +	struct xhci_ring *ring; + +	ep = &xhci->devs[slot_id]->eps[ep_index]; +	if ((ep->ep_state & EP_HAS_STREAMS) || +			(ep->ep_state & EP_GETTING_NO_STREAMS)) { +		int stream_id; + +		for (stream_id = 0; stream_id < ep->stream_info->num_streams; +				stream_id++) { +			xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, +					"Killing URBs for slot ID %u, ep index %u, stream %u", +					slot_id, ep_index, stream_id + 1); +			xhci_kill_ring_urbs(xhci, +					ep->stream_info->stream_rings[stream_id]); +		} +	} else { +		ring = ep->ring; +		if (!ring) +			return; +		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, +				"Killing URBs for slot ID %u, ep index %u", +				slot_id, ep_index); +		xhci_kill_ring_urbs(xhci, ring); +	} +	while (!list_empty(&ep->cancelled_td_list)) { +		cur_td = list_first_entry(&ep->cancelled_td_list, +				struct xhci_td, cancelled_td_list); +		list_del_init(&cur_td->cancelled_td_list); +		xhci_giveback_urb_in_irq(xhci, cur_td, -ESHUTDOWN); +	} +} +  /* Watchdog timer function for when a stop endpoint command fails to complete.   * In this case, we assume the host controller is broken or dying or dead.  The   * host may still be completing some other events, so we have to be careful to @@ -912,9 +883,6 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)  {  	struct xhci_hcd *xhci;  	struct xhci_virt_ep *ep; -	struct xhci_virt_ep *temp_ep; -	struct xhci_ring *ring; -	struct xhci_td *cur_td;  	int ret, i, j;  	unsigned long flags; @@ -971,34 +939,8 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)  	for (i = 0; i < MAX_HC_SLOTS; i++) {  		if (!xhci->devs[i])  			continue; -		for (j = 0; j < 31; j++) { -			temp_ep = &xhci->devs[i]->eps[j]; -			ring = temp_ep->ring; -			if (!ring) -				continue; -			xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, -					"Killing URBs for slot ID %u, " -					"ep index %u", i, j); -			while (!list_empty(&ring->td_list)) { -				cur_td = list_first_entry(&ring->td_list, -						struct xhci_td, -						td_list); -				list_del_init(&cur_td->td_list); -				if (!list_empty(&cur_td->cancelled_td_list)) -					list_del_init(&cur_td->cancelled_td_list); -				xhci_giveback_urb_in_irq(xhci, cur_td, -						-ESHUTDOWN, "killed"); -			} -			while (!list_empty(&temp_ep->cancelled_td_list)) { -				cur_td = list_first_entry( -						&temp_ep->cancelled_td_list, -						struct xhci_td, -						cancelled_td_list); -				list_del_init(&cur_td->cancelled_td_list); -				xhci_giveback_urb_in_irq(xhci, cur_td, -						-ESHUTDOWN, "killed"); -			} -		} +		for (j = 0; j < 31; j++) +			xhci_kill_endpoint_urbs(xhci, i, j);  	}  	spin_unlock_irqrestore(&xhci->lock, flags);  	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, @@ -1063,27 +1005,25 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci,   * endpoint doorbell to restart the ring, but only if there aren't more   * cancellations pending.   */ -static void handle_set_deq_completion(struct xhci_hcd *xhci, -		struct xhci_event_cmd *event, -		union xhci_trb *trb) +static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, +		union xhci_trb *trb, u32 cmd_comp_code)  { -	unsigned int slot_id;  	unsigned int ep_index;  	unsigned int stream_id;  	struct xhci_ring *ep_ring;  	struct xhci_virt_device *dev; +	struct xhci_virt_ep *ep;  	struct xhci_ep_ctx *ep_ctx;  	struct xhci_slot_ctx *slot_ctx; -	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));  	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));  	stream_id = TRB_TO_STREAM_ID(le32_to_cpu(trb->generic.field[2]));  	dev = xhci->devs[slot_id]; +	ep = &dev->eps[ep_index];  	ep_ring = xhci_stream_id_to_ring(dev, ep_index, stream_id);  	if (!ep_ring) { -		xhci_warn(xhci, "WARN Set TR deq ptr command for " -				"freed stream ID %u\n", +		xhci_warn(xhci, "WARN Set TR deq ptr command for freed stream ID %u\n",  				stream_id);  		/* XXX: Harmless??? */  		dev->eps[ep_index].ep_state &= ~SET_DEQ_PENDING; @@ -1093,18 +1033,16 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,  	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);  	slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx); -	if (GET_COMP_CODE(le32_to_cpu(event->status)) != COMP_SUCCESS) { +	if (cmd_comp_code != COMP_SUCCESS) {  		unsigned int ep_state;  		unsigned int slot_state; -		switch (GET_COMP_CODE(le32_to_cpu(event->status))) { +		switch (cmd_comp_code) {  		case COMP_TRB_ERR: -			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because " -					"of stream ID configuration\n"); +			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd invalid because of stream ID configuration\n");  			break;  		case COMP_CTX_STATE: -			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due " -					"to incorrect slot or ep state.\n"); +			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due to incorrect slot or ep state.\n");  			ep_state = le32_to_cpu(ep_ctx->ep_info);  			ep_state &= EP_STATE_MASK;  			slot_state = le32_to_cpu(slot_ctx->dev_state); @@ -1114,13 +1052,12 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,  					slot_state, ep_state);  			break;  		case COMP_EBADSLT: -			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed because " -					"slot %u was not enabled.\n", slot_id); +			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed because slot %u was not enabled.\n", +					slot_id);  			break;  		default: -			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown " -					"completion code of %u.\n", -				  GET_COMP_CODE(le32_to_cpu(event->status))); +			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd with unknown completion code of %u.\n", +					cmd_comp_code);  			break;  		}  		/* OK what do we do now?  The endpoint state is hosed, and we @@ -1130,23 +1067,28 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,  		 * cancelling URBs, which might not be an error...  		 */  	} else { +		u64 deq; +		/* 4.6.10 deq ptr is written to the stream ctx for streams */ +		if (ep->ep_state & EP_HAS_STREAMS) { +			struct xhci_stream_ctx *ctx = +				&ep->stream_info->stream_ctx_array[stream_id]; +			deq = le64_to_cpu(ctx->stream_ring) & SCTX_DEQ_MASK; +		} else { +			deq = le64_to_cpu(ep_ctx->deq) & ~EP_CTX_CYCLE_MASK; +		}  		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, -			"Successful Set TR Deq Ptr cmd, deq = @%08llx", -			 le64_to_cpu(ep_ctx->deq)); -		if (xhci_trb_virt_to_dma(dev->eps[ep_index].queued_deq_seg, -					 dev->eps[ep_index].queued_deq_ptr) == -		    (le64_to_cpu(ep_ctx->deq) & ~(EP_CTX_CYCLE_MASK))) { +			"Successful Set TR Deq Ptr cmd, deq = @%08llx", deq); +		if (xhci_trb_virt_to_dma(ep->queued_deq_seg, +					 ep->queued_deq_ptr) == deq) {  			/* Update the ring's dequeue segment and dequeue pointer  			 * to reflect the new position.  			 */  			update_ring_for_set_deq_completion(xhci, dev,  				ep_ring, ep_index);  		} else { -			xhci_warn(xhci, "Mismatch between completed Set TR Deq " -					"Ptr command & xHCI internal state.\n"); +			xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n");  			xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", -					dev->eps[ep_index].queued_deq_seg, -					dev->eps[ep_index].queued_deq_ptr); +				  ep->queued_deq_seg, ep->queued_deq_ptr);  		}  	} @@ -1157,30 +1099,28 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,  	ring_doorbell_for_active_rings(xhci, slot_id, ep_index);  } -static void handle_reset_ep_completion(struct xhci_hcd *xhci, -		struct xhci_event_cmd *event, -		union xhci_trb *trb) +static void xhci_handle_cmd_reset_ep(struct xhci_hcd *xhci, int slot_id, +		union xhci_trb *trb, u32 cmd_comp_code)  { -	int slot_id;  	unsigned int ep_index; -	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(trb->generic.field[3]));  	ep_index = TRB_TO_EP_INDEX(le32_to_cpu(trb->generic.field[3]));  	/* This command will only fail if the endpoint wasn't halted,  	 * but we don't care.  	 */  	xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep, -		"Ignoring reset ep completion code of %u", -		 GET_COMP_CODE(le32_to_cpu(event->status))); +		"Ignoring reset ep completion code of %u", cmd_comp_code);  	/* HW with the reset endpoint quirk needs to have a configure endpoint  	 * command complete before the endpoint can be used.  Queue that here  	 * because the HW can't handle two commands being queued in a row.  	 */  	if (xhci->quirks & XHCI_RESET_EP_QUIRK) { +		struct xhci_command *command; +		command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC);  		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,  				"Queueing configure endpoint command"); -		xhci_queue_configure_endpoint(xhci, +		xhci_queue_configure_endpoint(xhci, command,  				xhci->devs[slot_id]->in_ctx->dma, slot_id,  				false);  		xhci_ring_cmd_db(xhci); @@ -1191,185 +1131,211 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,  	}  } -/* Complete the command and detele it from the devcie's command queue. - */ -static void xhci_complete_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, -		struct xhci_command *command, u32 status) +static void xhci_handle_cmd_enable_slot(struct xhci_hcd *xhci, int slot_id, +		u32 cmd_comp_code)  { -	command->status = status; -	list_del(&command->cmd_list); -	if (command->completion) -		complete(command->completion); +	if (cmd_comp_code == COMP_SUCCESS) +		xhci->slot_id = slot_id;  	else -		xhci_free_command(xhci, command); +		xhci->slot_id = 0;  } - -/* Check to see if a command in the device's command queue matches this one. - * Signal the completion or free the command, and return 1.  Return 0 if the - * completed command isn't at the head of the command list. - */ -static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci, -		struct xhci_virt_device *virt_dev, -		struct xhci_event_cmd *event) +static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id)  { -	struct xhci_command *command; - -	if (list_empty(&virt_dev->cmd_list)) -		return 0; - -	command = list_entry(virt_dev->cmd_list.next, -			struct xhci_command, cmd_list); -	if (xhci->cmd_ring->dequeue != command->command_trb) -		return 0; +	struct xhci_virt_device *virt_dev; -	xhci_complete_cmd_in_cmd_wait_list(xhci, command, -			GET_COMP_CODE(le32_to_cpu(event->status))); -	return 1; +	virt_dev = xhci->devs[slot_id]; +	if (!virt_dev) +		return; +	if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) +		/* Delete default control endpoint resources */ +		xhci_free_device_endpoint_resources(xhci, virt_dev, true); +	xhci_free_virt_device(xhci, slot_id);  } -/* - * Finding the command trb need to be cancelled and modifying it to - * NO OP command. And if the command is in device's command wait - * list, finishing and freeing it. - * - * If we can't find the command trb, we think it had already been - * executed. - */ -static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd) +static void xhci_handle_cmd_config_ep(struct xhci_hcd *xhci, int slot_id, +		struct xhci_event_cmd *event, u32 cmd_comp_code)  { -	struct xhci_segment *cur_seg; -	union xhci_trb *cmd_trb; -	u32 cycle_state; - -	if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue) -		return; +	struct xhci_virt_device *virt_dev; +	struct xhci_input_control_ctx *ctrl_ctx; +	unsigned int ep_index; +	unsigned int ep_state; +	u32 add_flags, drop_flags; -	/* find the current segment of command ring */ -	cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, -			xhci->cmd_ring->dequeue, &cycle_state); - -	if (!cur_seg) { -		xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", -				xhci->cmd_ring->dequeue, -				(unsigned long long) -				xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, -					xhci->cmd_ring->dequeue)); -		xhci_debug_ring(xhci, xhci->cmd_ring); -		xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); +	/* +	 * Configure endpoint commands can come from the USB core +	 * configuration or alt setting changes, or because the HW +	 * needed an extra configure endpoint command after a reset +	 * endpoint command or streams were being configured. +	 * If the command was for a halted endpoint, the xHCI driver +	 * 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); +	if (!ctrl_ctx) { +		xhci_warn(xhci, "Could not get input context, bad type.\n");  		return;  	} -	/* find the command trb matched by cd from command ring */ -	for (cmd_trb = xhci->cmd_ring->dequeue; -			cmd_trb != xhci->cmd_ring->enqueue; -			next_trb(xhci, xhci->cmd_ring, &cur_seg, &cmd_trb)) { -		/* If the trb is link trb, continue */ -		if (TRB_TYPE_LINK_LE32(cmd_trb->generic.field[3])) -			continue; - -		if (cur_cd->cmd_trb == cmd_trb) { +	add_flags = le32_to_cpu(ctrl_ctx->add_flags); +	drop_flags = le32_to_cpu(ctrl_ctx->drop_flags); +	/* Input ctx add_flags are the endpoint index plus one */ +	ep_index = xhci_last_valid_endpoint(add_flags) - 1; -			/* If the command in device's command list, we should -			 * finish it and free the command structure. -			 */ -			if (cur_cd->command) -				xhci_complete_cmd_in_cmd_wait_list(xhci, -					cur_cd->command, COMP_CMD_STOP); - -			/* get cycle state from the origin command trb */ -			cycle_state = le32_to_cpu(cmd_trb->generic.field[3]) -				& TRB_CYCLE; - -			/* modify the command trb to NO OP command */ -			cmd_trb->generic.field[0] = 0; -			cmd_trb->generic.field[1] = 0; -			cmd_trb->generic.field[2] = 0; -			cmd_trb->generic.field[3] = cpu_to_le32( -					TRB_TYPE(TRB_CMD_NOOP) | cycle_state); -			break; -		} +	/* A usb_set_interface() call directly after clearing a halted +	 * condition may race on this quirky hardware.  Not worth +	 * worrying about, since this is prototype hardware.  Not sure +	 * if this will work for streams, but streams support was +	 * untested on this prototype. +	 */ +	if (xhci->quirks & XHCI_RESET_EP_QUIRK && +			ep_index != (unsigned int) -1 && +			add_flags - SLOT_FLAG == drop_flags) { +		ep_state = virt_dev->eps[ep_index].ep_state; +		if (!(ep_state & EP_HALTED)) +			return; +		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +				"Completed config ep cmd - " +				"last ep index = %d, state = %d", +				ep_index, ep_state); +		/* Clear internal halted state and restart ring(s) */ +		virt_dev->eps[ep_index].ep_state &= ~EP_HALTED; +		ring_doorbell_for_active_rings(xhci, slot_id, ep_index); +		return;  	} +	return;  } -static void xhci_cancel_cmd_in_cd_list(struct xhci_hcd *xhci) +static void xhci_handle_cmd_reset_dev(struct xhci_hcd *xhci, int slot_id, +		struct xhci_event_cmd *event)  { -	struct xhci_cd *cur_cd, *next_cd; +	xhci_dbg(xhci, "Completed reset device command.\n"); +	if (!xhci->devs[slot_id]) +		xhci_warn(xhci, "Reset device command completion " +				"for disabled slot %u\n", slot_id); +} -	if (list_empty(&xhci->cancel_cmd_list)) +static void xhci_handle_cmd_nec_get_fw(struct xhci_hcd *xhci, +		struct xhci_event_cmd *event) +{ +	if (!(xhci->quirks & XHCI_NEC_HOST)) { +		xhci->error_bitmask |= 1 << 6;  		return; - -	list_for_each_entry_safe(cur_cd, next_cd, -			&xhci->cancel_cmd_list, cancel_cmd_list) { -		xhci_cmd_to_noop(xhci, cur_cd); -		list_del(&cur_cd->cancel_cmd_list); -		kfree(cur_cd);  	} +	xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, +			"NEC firmware version %2x.%02x", +			NEC_FW_MAJOR(le32_to_cpu(event->status)), +			NEC_FW_MINOR(le32_to_cpu(event->status)));  } -/* - * traversing the cancel_cmd_list. If the command descriptor according - * to cmd_trb is found, the function free it and return 1, otherwise - * return 0. - */ -static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci, -		union xhci_trb *cmd_trb) +static void xhci_complete_del_and_free_cmd(struct xhci_command *cmd, u32 status)  { -	struct xhci_cd *cur_cd, *next_cd; - -	if (list_empty(&xhci->cancel_cmd_list)) -		return 0; +	list_del(&cmd->cmd_list); -	list_for_each_entry_safe(cur_cd, next_cd, -			&xhci->cancel_cmd_list, cancel_cmd_list) { -		if (cur_cd->cmd_trb == cmd_trb) { -			if (cur_cd->command) -				xhci_complete_cmd_in_cmd_wait_list(xhci, -					cur_cd->command, COMP_CMD_STOP); -			list_del(&cur_cd->cancel_cmd_list); -			kfree(cur_cd); -			return 1; -		} +	if (cmd->completion) { +		cmd->status = status; +		complete(cmd->completion); +	} else { +		kfree(cmd);  	} +} -	return 0; +void xhci_cleanup_command_queue(struct xhci_hcd *xhci) +{ +	struct xhci_command *cur_cmd, *tmp_cmd; +	list_for_each_entry_safe(cur_cmd, tmp_cmd, &xhci->cmd_list, cmd_list) +		xhci_complete_del_and_free_cmd(cur_cmd, COMP_CMD_ABORT);  }  /* - * If the cmd_trb_comp_code is COMP_CMD_ABORT, we just check whether the - * trb pointed by the command ring dequeue pointer is the trb we want to - * cancel or not. And if the cmd_trb_comp_code is COMP_CMD_STOP, we will - * traverse the cancel_cmd_list to trun the all of the commands according - * to command descriptor to NO-OP trb. + * Turn all commands on command ring with status set to "aborted" to no-op trbs. + * If there are other commands waiting then restart the ring and kick the timer. + * This must be called with command ring stopped and xhci->lock held.   */ -static int handle_stopped_cmd_ring(struct xhci_hcd *xhci, -		int cmd_trb_comp_code) +static void xhci_handle_stopped_cmd_ring(struct xhci_hcd *xhci, +					 struct xhci_command *cur_cmd)  { -	int cur_trb_is_good = 0; +	struct xhci_command *i_cmd, *tmp_cmd; +	u32 cycle_state; -	/* Searching the cmd trb pointed by the command ring dequeue -	 * pointer in command descriptor list. If it is found, free it. -	 */ -	cur_trb_is_good = xhci_search_cmd_trb_in_cd_list(xhci, -			xhci->cmd_ring->dequeue); +	/* Turn all aborted commands in list to no-ops, then restart */ +	list_for_each_entry_safe(i_cmd, tmp_cmd, &xhci->cmd_list, +				 cmd_list) { -	if (cmd_trb_comp_code == COMP_CMD_ABORT) -		xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; -	else if (cmd_trb_comp_code == COMP_CMD_STOP) { -		/* traversing the cancel_cmd_list and canceling -		 * the command according to command descriptor -		 */ -		xhci_cancel_cmd_in_cd_list(xhci); +		if (i_cmd->status != COMP_CMD_ABORT) +			continue; + +		i_cmd->status = COMP_CMD_STOP; + +		xhci_dbg(xhci, "Turn aborted command %p to no-op\n", +			 i_cmd->command_trb); +		/* get cycle state from the original cmd trb */ +		cycle_state = le32_to_cpu( +			i_cmd->command_trb->generic.field[3]) &	TRB_CYCLE; +		/* modify the command trb to no-op command */ +		i_cmd->command_trb->generic.field[0] = 0; +		i_cmd->command_trb->generic.field[1] = 0; +		i_cmd->command_trb->generic.field[2] = 0; +		i_cmd->command_trb->generic.field[3] = cpu_to_le32( +			TRB_TYPE(TRB_CMD_NOOP) | cycle_state); -		xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;  		/* -		 * ring command ring doorbell again to restart the -		 * command ring +		 * caller waiting for completion is called when command +		 *  completion event is received for these no-op commands  		 */ -		if (xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) -			xhci_ring_cmd_db(xhci);  	} -	return cur_trb_is_good; + +	xhci->cmd_ring_state = CMD_RING_STATE_RUNNING; + +	/* ring command ring doorbell to restart the command ring */ +	if ((xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue) && +	    !(xhci->xhc_state & XHCI_STATE_DYING)) { +		xhci->current_cmd = cur_cmd; +		mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); +		xhci_ring_cmd_db(xhci); +	} +	return; +} + + +void xhci_handle_command_timeout(unsigned long data) +{ +	struct xhci_hcd *xhci; +	int ret; +	unsigned long flags; +	u64 hw_ring_state; +	struct xhci_command *cur_cmd = NULL; +	xhci = (struct xhci_hcd *) data; + +	/* mark this command to be cancelled */ +	spin_lock_irqsave(&xhci->lock, flags); +	if (xhci->current_cmd) { +		cur_cmd = xhci->current_cmd; +		cur_cmd->status = COMP_CMD_ABORT; +	} + + +	/* Make sure command ring is running before aborting it */ +	hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring); +	if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) && +	    (hw_ring_state & CMD_RING_RUNNING))  { + +		spin_unlock_irqrestore(&xhci->lock, flags); +		xhci_dbg(xhci, "Command timeout\n"); +		ret = xhci_abort_cmd_ring(xhci); +		if (unlikely(ret == -ESHUTDOWN)) { +			xhci_err(xhci, "Abort command ring failed\n"); +			xhci_cleanup_command_queue(xhci); +			usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); +			xhci_dbg(xhci, "xHCI host controller is dead.\n"); +		} +		return; +	} +	/* command timeout on stopped ring, ring can't be aborted */ +	xhci_dbg(xhci, "Command timeout on stopped ring\n"); +	xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd); +	spin_unlock_irqrestore(&xhci->lock, flags); +	return;  }  static void handle_cmd_completion(struct xhci_hcd *xhci, @@ -1378,15 +1344,15 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,  	int slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));  	u64 cmd_dma;  	dma_addr_t cmd_dequeue_dma; -	struct xhci_input_control_ctx *ctrl_ctx; -	struct xhci_virt_device *virt_dev; -	unsigned int ep_index; -	struct xhci_ring *ep_ring; -	unsigned int ep_state; +	u32 cmd_comp_code; +	union xhci_trb *cmd_trb; +	struct xhci_command *cmd; +	u32 cmd_type;  	cmd_dma = le64_to_cpu(event->cmd_trb); +	cmd_trb = xhci->cmd_ring->dequeue;  	cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, -			xhci->cmd_ring->dequeue); +			cmd_trb);  	/* Is the command ring deq ptr out of sync with the deq seg ptr? */  	if (cmd_dequeue_dma == 0) {  		xhci->error_bitmask |= 1 << 4; @@ -1398,141 +1364,101 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,  		return;  	} -	trace_xhci_cmd_completion(&xhci->cmd_ring->dequeue->generic, -					(struct xhci_generic_trb *) event); +	cmd = list_entry(xhci->cmd_list.next, struct xhci_command, cmd_list); -	if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) || -		(GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) { -		/* If the return value is 0, we think the trb pointed by -		 * command ring dequeue pointer is a good trb. The good -		 * trb means we don't want to cancel the trb, but it have -		 * been stopped by host. So we should handle it normally. -		 * Otherwise, driver should invoke inc_deq() and return. -		 */ -		if (handle_stopped_cmd_ring(xhci, -				GET_COMP_CODE(le32_to_cpu(event->status)))) { -			inc_deq(xhci, xhci->cmd_ring); -			return; -		} +	if (cmd->command_trb != xhci->cmd_ring->dequeue) { +		xhci_err(xhci, +			 "Command completion event does not match command\n"); +		return;  	} -	switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3]) -		& TRB_TYPE_BITMASK) { -	case TRB_TYPE(TRB_ENABLE_SLOT): -		if (GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_SUCCESS) -			xhci->slot_id = slot_id; -		else -			xhci->slot_id = 0; -		complete(&xhci->addr_dev); +	del_timer(&xhci->cmd_timer); + +	trace_xhci_cmd_completion(cmd_trb, (struct xhci_generic_trb *) event); + +	cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status)); + +	/* If CMD ring stopped we own the trbs between enqueue and dequeue */ +	if (cmd_comp_code == COMP_CMD_STOP) { +		xhci_handle_stopped_cmd_ring(xhci, cmd); +		return; +	} +	/* +	 * Host aborted the command ring, check if the current command was +	 * supposed to be aborted, otherwise continue normally. +	 * The command ring is stopped now, but the xHC will issue a Command +	 * Ring Stopped event which will cause us to restart it. +	 */ +	if (cmd_comp_code == COMP_CMD_ABORT) { +		xhci->cmd_ring_state = CMD_RING_STATE_STOPPED; +		if (cmd->status == COMP_CMD_ABORT) +			goto event_handled; +	} + +	cmd_type = TRB_FIELD_TO_TYPE(le32_to_cpu(cmd_trb->generic.field[3])); +	switch (cmd_type) { +	case TRB_ENABLE_SLOT: +		xhci_handle_cmd_enable_slot(xhci, slot_id, cmd_comp_code);  		break; -	case TRB_TYPE(TRB_DISABLE_SLOT): -		if (xhci->devs[slot_id]) { -			if (xhci->quirks & XHCI_EP_LIMIT_QUIRK) -				/* Delete default control endpoint resources */ -				xhci_free_device_endpoint_resources(xhci, -						xhci->devs[slot_id], true); -			xhci_free_virt_device(xhci, slot_id); -		} +	case TRB_DISABLE_SLOT: +		xhci_handle_cmd_disable_slot(xhci, slot_id);  		break; -	case TRB_TYPE(TRB_CONFIG_EP): -		virt_dev = xhci->devs[slot_id]; -		if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event)) -			break; -		/* -		 * Configure endpoint commands can come from the USB core -		 * configuration or alt setting changes, or because the HW -		 * needed an extra configure endpoint command after a reset -		 * endpoint command or streams were being configured. -		 * If the command was for a halted endpoint, the xHCI driver -		 * is not waiting on the configure endpoint command. -		 */ -		ctrl_ctx = xhci_get_input_control_ctx(xhci, -				virt_dev->in_ctx); -		if (!ctrl_ctx) { -			xhci_warn(xhci, "Could not get input context, bad type.\n"); -			break; -		} -		/* Input ctx add_flags are the endpoint index plus one */ -		ep_index = xhci_last_valid_endpoint(le32_to_cpu(ctrl_ctx->add_flags)) - 1; -		/* A usb_set_interface() call directly after clearing a halted -		 * condition may race on this quirky hardware.  Not worth -		 * worrying about, since this is prototype hardware.  Not sure -		 * if this will work for streams, but streams support was -		 * untested on this prototype. -		 */ -		if (xhci->quirks & XHCI_RESET_EP_QUIRK && -				ep_index != (unsigned int) -1 && -		    le32_to_cpu(ctrl_ctx->add_flags) - SLOT_FLAG == -		    le32_to_cpu(ctrl_ctx->drop_flags)) { -			ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; -			ep_state = xhci->devs[slot_id]->eps[ep_index].ep_state; -			if (!(ep_state & EP_HALTED)) -				goto bandwidth_change; -			xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, -					"Completed config ep cmd - " -					"last ep index = %d, state = %d", -					ep_index, ep_state); -			/* Clear internal halted state and restart ring(s) */ -			xhci->devs[slot_id]->eps[ep_index].ep_state &= -				~EP_HALTED; -			ring_doorbell_for_active_rings(xhci, slot_id, ep_index); -			break; -		} -bandwidth_change: -		xhci_dbg_trace(xhci,  trace_xhci_dbg_context_change, -				"Completed config ep cmd"); -		xhci->devs[slot_id]->cmd_status = -			GET_COMP_CODE(le32_to_cpu(event->status)); -		complete(&xhci->devs[slot_id]->cmd_completion); +	case TRB_CONFIG_EP: +		if (!cmd->completion) +			xhci_handle_cmd_config_ep(xhci, slot_id, event, +						  cmd_comp_code);  		break; -	case TRB_TYPE(TRB_EVAL_CONTEXT): -		virt_dev = xhci->devs[slot_id]; -		if (handle_cmd_in_cmd_wait_list(xhci, virt_dev, event)) -			break; -		xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status)); -		complete(&xhci->devs[slot_id]->cmd_completion); +	case TRB_EVAL_CONTEXT:  		break; -	case TRB_TYPE(TRB_ADDR_DEV): -		xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(le32_to_cpu(event->status)); -		complete(&xhci->addr_dev); +	case TRB_ADDR_DEV:  		break; -	case TRB_TYPE(TRB_STOP_RING): -		handle_stopped_endpoint(xhci, xhci->cmd_ring->dequeue, event); +	case TRB_STOP_RING: +		WARN_ON(slot_id != TRB_TO_SLOT_ID( +				le32_to_cpu(cmd_trb->generic.field[3]))); +		xhci_handle_cmd_stop_ep(xhci, slot_id, cmd_trb, event);  		break; -	case TRB_TYPE(TRB_SET_DEQ): -		handle_set_deq_completion(xhci, event, xhci->cmd_ring->dequeue); +	case TRB_SET_DEQ: +		WARN_ON(slot_id != TRB_TO_SLOT_ID( +				le32_to_cpu(cmd_trb->generic.field[3]))); +		xhci_handle_cmd_set_deq(xhci, slot_id, cmd_trb, cmd_comp_code);  		break; -	case TRB_TYPE(TRB_CMD_NOOP): +	case TRB_CMD_NOOP: +		/* Is this an aborted command turned to NO-OP? */ +		if (cmd->status == COMP_CMD_STOP) +			cmd_comp_code = COMP_CMD_STOP;  		break; -	case TRB_TYPE(TRB_RESET_EP): -		handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue); +	case TRB_RESET_EP: +		WARN_ON(slot_id != TRB_TO_SLOT_ID( +				le32_to_cpu(cmd_trb->generic.field[3]))); +		xhci_handle_cmd_reset_ep(xhci, slot_id, cmd_trb, cmd_comp_code);  		break; -	case TRB_TYPE(TRB_RESET_DEV): -		xhci_dbg(xhci, "Completed reset device command.\n"); +	case TRB_RESET_DEV: +		/* SLOT_ID field in reset device cmd completion event TRB is 0. +		 * Use the SLOT_ID from the command TRB instead (xhci 4.6.11) +		 */  		slot_id = TRB_TO_SLOT_ID( -			le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])); -		virt_dev = xhci->devs[slot_id]; -		if (virt_dev) -			handle_cmd_in_cmd_wait_list(xhci, virt_dev, event); -		else -			xhci_warn(xhci, "Reset device command completion " -					"for disabled slot %u\n", slot_id); +				le32_to_cpu(cmd_trb->generic.field[3])); +		xhci_handle_cmd_reset_dev(xhci, slot_id, event);  		break; -	case TRB_TYPE(TRB_NEC_GET_FW): -		if (!(xhci->quirks & XHCI_NEC_HOST)) { -			xhci->error_bitmask |= 1 << 6; -			break; -		} -		xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, -			"NEC firmware version %2x.%02x", -			 NEC_FW_MAJOR(le32_to_cpu(event->status)), -			 NEC_FW_MINOR(le32_to_cpu(event->status))); +	case TRB_NEC_GET_FW: +		xhci_handle_cmd_nec_get_fw(xhci, event);  		break;  	default:  		/* Skip over unknown commands on the event ring */  		xhci->error_bitmask |= 1 << 6;  		break;  	} + +	/* restart timer if this wasn't the last command */ +	if (cmd->cmd_list.next != &xhci->cmd_list) { +		xhci->current_cmd = list_entry(cmd->cmd_list.next, +					       struct xhci_command, cmd_list); +		mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); +	} + +event_handled: +	xhci_complete_del_and_free_cmd(cmd, cmd_comp_code); +  	inc_deq(xhci, xhci->cmd_ring);  } @@ -1591,7 +1517,7 @@ static void handle_device_notification(struct xhci_hcd *xhci,  	u32 slot_id;  	struct usb_device *udev; -	slot_id = TRB_TO_SLOT_ID(event->generic.field[3]); +	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->generic.field[3]));  	if (!xhci->devs[slot_id]) {  		xhci_warn(xhci, "Device Notification event for "  				"unused slot %u\n", slot_id); @@ -1675,7 +1601,7 @@ static void handle_port_status(struct xhci_hcd *xhci,  	faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci,  			port_id); -	temp = xhci_readl(xhci, port_array[faked_port_index]); +	temp = readl(port_array[faked_port_index]);  	if (hcd->state == HC_STATE_SUSPENDED) {  		xhci_dbg(xhci, "resume root hub\n");  		usb_hcd_resume_root_hub(hcd); @@ -1684,7 +1610,7 @@ static void handle_port_status(struct xhci_hcd *xhci,  	if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) {  		xhci_dbg(xhci, "port resume event for port %d\n", port_id); -		temp1 = xhci_readl(xhci, &xhci->op_regs->command); +		temp1 = readl(&xhci->op_regs->command);  		if (!(temp1 & CMD_RUN)) {  			xhci_warn(xhci, "xHC is not running.\n");  			goto cleanup; @@ -1743,6 +1669,19 @@ static void handle_port_status(struct xhci_hcd *xhci,  		}  	} +	/* +	 * Check to see if xhci-hub.c is waiting on RExit to U0 transition (or +	 * RExit to a disconnect state).  If so, let the the driver know it's +	 * out of the RExit state. +	 */ +	if (!DEV_SUPERSPEED(temp) && +			test_and_clear_bit(faked_port_index, +				&bus_state->rexit_ports)) { +		complete(&bus_state->rexit_done[faked_port_index]); +		bogus_port_status = true; +		goto cleanup; +	} +  	if (hcd->speed != HCD_USB3)  		xhci_test_and_clear_bit(xhci, port_array, faked_port_index,  					PORT_PLC); @@ -1835,16 +1774,19 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci,  		struct xhci_td *td, union xhci_trb *event_trb)  {  	struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; +	struct xhci_command *command; +	command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); +	if (!command) +		return; +  	ep->ep_state |= EP_HALTED;  	ep->stopped_td = td; -	ep->stopped_trb = event_trb;  	ep->stopped_stream = stream_id; -	xhci_queue_reset_ep(xhci, slot_id, ep_index); +	xhci_queue_reset_ep(xhci, command, slot_id, ep_index);  	xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);  	ep->stopped_td = NULL; -	ep->stopped_trb = NULL;  	ep->stopped_stream = 0;  	xhci_ring_cmd_db(xhci); @@ -1926,7 +1868,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,  		 * the ring dequeue pointer or take this TD off any lists yet.  		 */  		ep->stopped_td = td; -		ep->stopped_trb = event_trb;  		return 0;  	} else {  		if (trb_comp_code == COMP_STALL) { @@ -1938,7 +1879,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,  			 * USB class driver clear the stall later.  			 */  			ep->stopped_td = td; -			ep->stopped_trb = event_trb;  			ep->stopped_stream = ep_ring->stream_id;  		} else if (xhci_requires_manual_halt_cleanup(xhci,  					ep_ctx, trb_comp_code)) { @@ -2555,7 +2495,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,  				 * successful event after a short transfer.  				 * Ignore it.  				 */ -				if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&  +				if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) &&  						ep_ring->last_td_was_short) {  					ep_ring->last_td_was_short = false;  					ret = 0; @@ -2754,7 +2694,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)  	spin_lock(&xhci->lock);  	/* Check if the xHC generated the interrupt, or the irq is shared */ -	status = xhci_readl(xhci, &xhci->op_regs->status); +	status = readl(&xhci->op_regs->status);  	if (status == 0xffffffff)  		goto hw_died; @@ -2776,16 +2716,16 @@ hw_died:  	 * Write 1 to clear the interrupt status.  	 */  	status |= STS_EINT; -	xhci_writel(xhci, status, &xhci->op_regs->status); +	writel(status, &xhci->op_regs->status);  	/* FIXME when MSI-X is supported and there are multiple vectors */  	/* Clear the MSI-X event interrupt status */  	if (hcd->irq) {  		u32 irq_pending;  		/* Acknowledge the PCI interrupt */ -		irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); +		irq_pending = readl(&xhci->ir_set->irq_pending);  		irq_pending |= IMAN_IP; -		xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending); +		writel(irq_pending, &xhci->ir_set->irq_pending);  	}  	if (xhci->xhc_state & XHCI_STATE_DYING) { @@ -3597,7 +3537,7 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci,  		return 0;  	max_burst = urb->ep->ss_ep_comp.bMaxBurst; -	return roundup(total_packet_count, max_burst + 1) - 1; +	return DIV_ROUND_UP(total_packet_count, max_burst + 1) - 1;  }  /* @@ -3854,7 +3794,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,  	if (ret)  		return ret; -	start_frame = xhci_readl(xhci, &xhci->run_regs->microframe_index); +	start_frame = readl(&xhci->run_regs->microframe_index);  	start_frame &= 0x3fff;  	urb->start_frame = start_frame; @@ -3897,11 +3837,14 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,   * Don't decrement xhci->cmd_ring_reserved_trbs after we've queued the TRB   * because the command event handler may want to resubmit a failed command.   */ -static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2, -		u32 field3, u32 field4, bool command_must_succeed) +static int queue_command(struct xhci_hcd *xhci, struct xhci_command *cmd, +			 u32 field1, u32 field2, +			 u32 field3, u32 field4, bool command_must_succeed)  {  	int reserved_trbs = xhci->cmd_ring_reserved_trbs;  	int ret; +	if (xhci->xhc_state & XHCI_STATE_DYING) +		return -ESHUTDOWN;  	if (!command_must_succeed)  		reserved_trbs++; @@ -3915,57 +3858,71 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2,  					"unfailable commands failed.\n");  		return ret;  	} + +	cmd->command_trb = xhci->cmd_ring->enqueue; +	list_add_tail(&cmd->cmd_list, &xhci->cmd_list); + +	/* if there are no other commands queued we start the timeout timer */ +	if (xhci->cmd_list.next == &cmd->cmd_list && +	    !timer_pending(&xhci->cmd_timer)) { +		xhci->current_cmd = cmd; +		mod_timer(&xhci->cmd_timer, jiffies + XHCI_CMD_DEFAULT_TIMEOUT); +	} +  	queue_trb(xhci, xhci->cmd_ring, false, field1, field2, field3,  			field4 | xhci->cmd_ring->cycle_state);  	return 0;  }  /* Queue a slot enable or disable request on the command ring */ -int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id) +int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd, +		u32 trb_type, u32 slot_id)  { -	return queue_command(xhci, 0, 0, 0, +	return queue_command(xhci, cmd, 0, 0, 0,  			TRB_TYPE(trb_type) | SLOT_ID_FOR_TRB(slot_id), false);  }  /* Queue an address device command TRB */ -int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, -		u32 slot_id) +int xhci_queue_address_device(struct xhci_hcd *xhci, struct xhci_command *cmd, +		dma_addr_t in_ctx_ptr, u32 slot_id, enum xhci_setup_dev setup)  { -	return queue_command(xhci, lower_32_bits(in_ctx_ptr), +	return queue_command(xhci, cmd, lower_32_bits(in_ctx_ptr),  			upper_32_bits(in_ctx_ptr), 0, -			TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id), -			false); +			TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id) +			| (setup == SETUP_CONTEXT_ONLY ? TRB_BSR : 0), false);  } -int xhci_queue_vendor_command(struct xhci_hcd *xhci, +int xhci_queue_vendor_command(struct xhci_hcd *xhci, struct xhci_command *cmd,  		u32 field1, u32 field2, u32 field3, u32 field4)  { -	return queue_command(xhci, field1, field2, field3, field4, false); +	return queue_command(xhci, cmd, field1, field2, field3, field4, false);  }  /* Queue a reset device command TRB */ -int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id) +int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd, +		u32 slot_id)  { -	return queue_command(xhci, 0, 0, 0, +	return queue_command(xhci, cmd, 0, 0, 0,  			TRB_TYPE(TRB_RESET_DEV) | SLOT_ID_FOR_TRB(slot_id),  			false);  }  /* Queue a configure endpoint command TRB */ -int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, +int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, +		struct xhci_command *cmd, dma_addr_t in_ctx_ptr,  		u32 slot_id, bool command_must_succeed)  { -	return queue_command(xhci, lower_32_bits(in_ctx_ptr), +	return queue_command(xhci, cmd, lower_32_bits(in_ctx_ptr),  			upper_32_bits(in_ctx_ptr), 0,  			TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id),  			command_must_succeed);  }  /* Queue an evaluate context command TRB */ -int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, -		u32 slot_id, bool command_must_succeed) +int xhci_queue_evaluate_context(struct xhci_hcd *xhci, struct xhci_command *cmd, +		dma_addr_t in_ctx_ptr, u32 slot_id, bool command_must_succeed)  { -	return queue_command(xhci, lower_32_bits(in_ctx_ptr), +	return queue_command(xhci, cmd, lower_32_bits(in_ctx_ptr),  			upper_32_bits(in_ctx_ptr), 0,  			TRB_TYPE(TRB_EVAL_CONTEXT) | SLOT_ID_FOR_TRB(slot_id),  			command_must_succeed); @@ -3975,30 +3932,32 @@ int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,   * Suspend is set to indicate "Stop Endpoint Command" is being issued to stop   * activity on an endpoint that is about to be suspended.   */ -int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, -		unsigned int ep_index, int suspend) +int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, struct xhci_command *cmd, +			     int slot_id, unsigned int ep_index, int suspend)  {  	u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);  	u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);  	u32 type = TRB_TYPE(TRB_STOP_RING);  	u32 trb_suspend = SUSPEND_PORT_FOR_TRB(suspend); -	return queue_command(xhci, 0, 0, 0, +	return queue_command(xhci, cmd, 0, 0, 0,  			trb_slot_id | trb_ep_index | type | trb_suspend, false);  }  /* Set Transfer Ring Dequeue Pointer command.   * This should not be used for endpoints that have streams enabled.   */ -static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id, -		unsigned int ep_index, unsigned int stream_id, -		struct xhci_segment *deq_seg, -		union xhci_trb *deq_ptr, u32 cycle_state) +static int queue_set_tr_deq(struct xhci_hcd *xhci, struct xhci_command *cmd, +			int slot_id, +			unsigned int ep_index, unsigned int stream_id, +			struct xhci_segment *deq_seg, +			union xhci_trb *deq_ptr, u32 cycle_state)  {  	dma_addr_t addr;  	u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);  	u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);  	u32 trb_stream_id = STREAM_ID_FOR_TRB(stream_id); +	u32 trb_sct = 0;  	u32 type = TRB_TYPE(TRB_SET_DEQ);  	struct xhci_virt_ep *ep; @@ -4017,18 +3976,21 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,  	}  	ep->queued_deq_seg = deq_seg;  	ep->queued_deq_ptr = deq_ptr; -	return queue_command(xhci, lower_32_bits(addr) | cycle_state, +	if (stream_id) +		trb_sct = SCT_FOR_TRB(SCT_PRI_TR); +	return queue_command(xhci, cmd, +			lower_32_bits(addr) | trb_sct | cycle_state,  			upper_32_bits(addr), trb_stream_id,  			trb_slot_id | trb_ep_index | type, false);  } -int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, -		unsigned int ep_index) +int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd, +			int slot_id, unsigned int ep_index)  {  	u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);  	u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);  	u32 type = TRB_TYPE(TRB_RESET_EP); -	return queue_command(xhci, 0, 0, 0, trb_slot_id | trb_ep_index | type, -			false); +	return queue_command(xhci, cmd, 0, 0, 0, +			trb_slot_id | trb_ep_index | type, false);  } diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h index 20364cc8d2f..dde3959b7a3 100644 --- a/drivers/usb/host/xhci-trace.h +++ b/drivers/usb/host/xhci-trace.h @@ -116,12 +116,12 @@ DECLARE_EVENT_CLASS(xhci_log_event,  		__field(u64, dma)  		__field(u32, status)  		__field(u32, flags) -		__dynamic_array(__le32, trb, 4) +		__dynamic_array(u8, trb, sizeof(struct xhci_generic_trb))  	),  	TP_fast_assign(  		__entry->va = trb_va; -		__entry->dma = le64_to_cpu(((u64)ev->field[1]) << 32 | -						ev->field[0]); +		__entry->dma = ((u64)le32_to_cpu(ev->field[1])) << 32 | +					le32_to_cpu(ev->field[0]);  		__entry->status = le32_to_cpu(ev->field[2]);  		__entry->flags = le32_to_cpu(ev->field[3]);  		memcpy(__get_dynamic_array(trb), trb_va, diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 49b6edb84a7..7436d5f5e67 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -40,6 +40,10 @@ static int link_quirk;  module_param(link_quirk, int, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB"); +static unsigned int quirks; +module_param(quirks, uint, S_IRUGO); +MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); +  /* TODO: copied from ehci-hcd.c - can this be refactored? */  /*   * xhci_handshake - spin reading hc until handshake completes or fails @@ -60,7 +64,7 @@ int xhci_handshake(struct xhci_hcd *xhci, void __iomem *ptr,  	u32	result;  	do { -		result = xhci_readl(xhci, ptr); +		result = readl(ptr);  		if (result == ~(u32)0)		/* card removed */  			return -ENODEV;  		result &= mask; @@ -82,13 +86,13 @@ void xhci_quiesce(struct xhci_hcd *xhci)  	u32 mask;  	mask = ~(XHCI_IRQS); -	halted = xhci_readl(xhci, &xhci->op_regs->status) & STS_HALT; +	halted = readl(&xhci->op_regs->status) & STS_HALT;  	if (!halted)  		mask &= ~CMD_RUN; -	cmd = xhci_readl(xhci, &xhci->op_regs->command); +	cmd = readl(&xhci->op_regs->command);  	cmd &= mask; -	xhci_writel(xhci, cmd, &xhci->op_regs->command); +	writel(cmd, &xhci->op_regs->command);  }  /* @@ -124,11 +128,11 @@ static int xhci_start(struct xhci_hcd *xhci)  	u32 temp;  	int ret; -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	temp |= (CMD_RUN);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Turn on HC, cmd = 0x%x.",  			temp); -	xhci_writel(xhci, temp, &xhci->op_regs->command); +	writel(temp, &xhci->op_regs->command);  	/*  	 * Wait for the HCHalted Status bit to be 0 to indicate the host is @@ -158,16 +162,16 @@ int xhci_reset(struct xhci_hcd *xhci)  	u32 state;  	int ret, i; -	state = xhci_readl(xhci, &xhci->op_regs->status); +	state = readl(&xhci->op_regs->status);  	if ((state & STS_HALT) == 0) {  		xhci_warn(xhci, "Host controller not halted, aborting reset.\n");  		return 0;  	}  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "// Reset the HC"); -	command = xhci_readl(xhci, &xhci->op_regs->command); +	command = readl(&xhci->op_regs->command);  	command |= CMD_RESET; -	xhci_writel(xhci, command, &xhci->op_regs->command); +	writel(command, &xhci->op_regs->command);  	ret = xhci_handshake(xhci, &xhci->op_regs->command,  			CMD_RESET, 0, 10 * 1000 * 1000); @@ -287,7 +291,7 @@ static int xhci_setup_msix(struct xhci_hcd *xhci)  		xhci->msix_entries[i].vector = 0;  	} -	ret = pci_enable_msix(pdev, xhci->msix_entries, xhci->msix_count); +	ret = pci_enable_msix_exact(pdev, xhci->msix_entries, xhci->msix_count);  	if (ret) {  		xhci_dbg_trace(xhci, trace_xhci_dbg_init,  				"Failed to enable MSI-X"); @@ -321,6 +325,9 @@ static void xhci_cleanup_msix(struct xhci_hcd *xhci)  	struct usb_hcd *hcd = xhci_to_hcd(xhci);  	struct pci_dev *pdev = to_pci_dev(hcd->self.controller); +	if (xhci->quirks & XHCI_PLAT) +		return; +  	xhci_free_irq(xhci);  	if (xhci->msix_entries) { @@ -383,6 +390,10 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)  	}   legacy_irq: +	if (!strlen(hcd->irq_descr)) +		snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", +			 hcd->driver->description, hcd->self.busnum); +  	/* fall back to legacy interrupt*/  	ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,  			hcd->irq_descr, hcd); @@ -397,16 +408,16 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)  #else -static int xhci_try_enable_msi(struct usb_hcd *hcd) +static inline int xhci_try_enable_msi(struct usb_hcd *hcd)  {  	return 0;  } -static void xhci_cleanup_msix(struct xhci_hcd *xhci) +static inline void xhci_cleanup_msix(struct xhci_hcd *xhci)  {  } -static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) +static inline void xhci_msix_sync_irqs(struct xhci_hcd *xhci)  {  } @@ -422,7 +433,7 @@ static void compliance_mode_recovery(unsigned long arg)  	xhci = (struct xhci_hcd *)arg;  	for (i = 0; i < xhci->num_usb3_ports; i++) { -		temp = xhci_readl(xhci, xhci->usb3_ports[i]); +		temp = readl(xhci->usb3_ports[i]);  		if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {  			/*  			 * Compliance Mode Detected. Letting USB Core @@ -611,30 +622,33 @@ int xhci_run(struct usb_hcd *hcd)  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Set the interrupt modulation register"); -	temp = xhci_readl(xhci, &xhci->ir_set->irq_control); +	temp = readl(&xhci->ir_set->irq_control);  	temp &= ~ER_IRQ_INTERVAL_MASK;  	temp |= (u32) 160; -	xhci_writel(xhci, temp, &xhci->ir_set->irq_control); +	writel(temp, &xhci->ir_set->irq_control);  	/* Set the HCD state before we enable the irqs */ -	temp = xhci_readl(xhci, &xhci->op_regs->command); +	temp = readl(&xhci->op_regs->command);  	temp |= (CMD_EIE);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Enable interrupts, cmd = 0x%x.", temp); -	xhci_writel(xhci, temp, &xhci->op_regs->command); +	writel(temp, &xhci->op_regs->command); -	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); +	temp = readl(&xhci->ir_set->irq_pending);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Enabling event ring interrupter %p by writing 0x%x to irq_pending",  			xhci->ir_set, (unsigned int) ER_IRQ_ENABLE(temp)); -	xhci_writel(xhci, ER_IRQ_ENABLE(temp), -			&xhci->ir_set->irq_pending); +	writel(ER_IRQ_ENABLE(temp), &xhci->ir_set->irq_pending);  	xhci_print_ir_set(xhci, 0); -	if (xhci->quirks & XHCI_NEC_HOST) -		xhci_queue_vendor_command(xhci, 0, 0, 0, +	if (xhci->quirks & XHCI_NEC_HOST) { +		struct xhci_command *command; +		command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); +		if (!command) +			return -ENOMEM; +		xhci_queue_vendor_command(xhci, command, 0, 0, 0,  				TRB_TYPE(TRB_NEC_GET_FW)); - +	}  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"Finished xhci_run for USB2 roothub");  	return 0; @@ -698,18 +712,17 @@ void xhci_stop(struct usb_hcd *hcd)  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"// Disabling event ring interrupts"); -	temp = xhci_readl(xhci, &xhci->op_regs->status); -	xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); -	temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -	xhci_writel(xhci, ER_IRQ_DISABLE(temp), -			&xhci->ir_set->irq_pending); +	temp = readl(&xhci->op_regs->status); +	writel(temp & ~STS_EINT, &xhci->op_regs->status); +	temp = readl(&xhci->ir_set->irq_pending); +	writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending);  	xhci_print_ir_set(xhci, 0);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory");  	xhci_mem_cleanup(xhci);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"xhci_stop completed - status = %x", -			xhci_readl(xhci, &xhci->op_regs->status)); +			readl(&xhci->op_regs->status));  }  /* @@ -730,40 +743,47 @@ void xhci_shutdown(struct usb_hcd *hcd)  	spin_lock_irq(&xhci->lock);  	xhci_halt(xhci); +	/* Workaround for spurious wakeups at shutdown with HSW */ +	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) +		xhci_reset(xhci);  	spin_unlock_irq(&xhci->lock);  	xhci_cleanup_msix(xhci);  	xhci_dbg_trace(xhci, trace_xhci_dbg_init,  			"xhci_shutdown completed - status = %x", -			xhci_readl(xhci, &xhci->op_regs->status)); +			readl(&xhci->op_regs->status)); + +	/* Yet another workaround for spurious wakeups at shutdown with HSW */ +	if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) +		pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot);  }  #ifdef CONFIG_PM  static void xhci_save_registers(struct xhci_hcd *xhci)  { -	xhci->s3.command = xhci_readl(xhci, &xhci->op_regs->command); -	xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification); +	xhci->s3.command = readl(&xhci->op_regs->command); +	xhci->s3.dev_nt = readl(&xhci->op_regs->dev_notification);  	xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); -	xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg); -	xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size); +	xhci->s3.config_reg = readl(&xhci->op_regs->config_reg); +	xhci->s3.erst_size = readl(&xhci->ir_set->erst_size);  	xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);  	xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue); -	xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending); -	xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control); +	xhci->s3.irq_pending = readl(&xhci->ir_set->irq_pending); +	xhci->s3.irq_control = readl(&xhci->ir_set->irq_control);  }  static void xhci_restore_registers(struct xhci_hcd *xhci)  { -	xhci_writel(xhci, xhci->s3.command, &xhci->op_regs->command); -	xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification); +	writel(xhci->s3.command, &xhci->op_regs->command); +	writel(xhci->s3.dev_nt, &xhci->op_regs->dev_notification);  	xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr); -	xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg); -	xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size); +	writel(xhci->s3.config_reg, &xhci->op_regs->config_reg); +	writel(xhci->s3.erst_size, &xhci->ir_set->erst_size);  	xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);  	xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue); -	xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending); -	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control); +	writel(xhci->s3.irq_pending, &xhci->ir_set->irq_pending); +	writel(xhci->s3.irq_control, &xhci->ir_set->irq_control);  }  static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci) @@ -839,6 +859,7 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)  int xhci_suspend(struct xhci_hcd *xhci)  {  	int			rc = 0; +	unsigned int		delay = XHCI_MAX_HALT_USEC;  	struct usb_hcd		*hcd = xhci_to_hcd(xhci);  	u32			command; @@ -858,11 +879,15 @@ int xhci_suspend(struct xhci_hcd *xhci)  	/* skipped assuming that port suspend has done */  	/* step 2: clear Run/Stop bit */ -	command = xhci_readl(xhci, &xhci->op_regs->command); +	command = readl(&xhci->op_regs->command);  	command &= ~CMD_RUN; -	xhci_writel(xhci, command, &xhci->op_regs->command); +	writel(command, &xhci->op_regs->command); + +	/* 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, -		      STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) { +		      STS_HALT, STS_HALT, delay)) {  		xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");  		spin_unlock_irq(&xhci->lock);  		return -ETIMEDOUT; @@ -873,9 +898,9 @@ int xhci_suspend(struct xhci_hcd *xhci)  	xhci_save_registers(xhci);  	/* step 4: set CSS flag */ -	command = xhci_readl(xhci, &xhci->op_regs->command); +	command = readl(&xhci->op_regs->command);  	command |= CMD_CSS; -	xhci_writel(xhci, command, &xhci->op_regs->command); +	writel(command, &xhci->op_regs->command);  	if (xhci_handshake(xhci, &xhci->op_regs->status,  				STS_SAVE, 0, 10 * 1000)) {  		xhci_warn(xhci, "WARN: xHC save state timeout\n"); @@ -911,7 +936,7 @@ int xhci_suspend(struct xhci_hcd *xhci)   */  int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  { -	u32			command, temp = 0; +	u32			command, temp = 0, status;  	struct usb_hcd		*hcd = xhci_to_hcd(xhci);  	struct usb_hcd		*secondary_hcd;  	int			retval = 0; @@ -939,16 +964,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  		xhci_set_cmd_ring_deq(xhci);  		/* step 3: restore state and start state*/  		/* step 3: set CRS flag */ -		command = xhci_readl(xhci, &xhci->op_regs->command); +		command = readl(&xhci->op_regs->command);  		command |= CMD_CRS; -		xhci_writel(xhci, command, &xhci->op_regs->command); +		writel(command, &xhci->op_regs->command);  		if (xhci_handshake(xhci, &xhci->op_regs->status,  			      STS_RESTORE, 0, 10 * 1000)) {  			xhci_warn(xhci, "WARN: xHC restore state timeout\n");  			spin_unlock_irq(&xhci->lock);  			return -ETIMEDOUT;  		} -		temp = xhci_readl(xhci, &xhci->op_regs->status); +		temp = readl(&xhci->op_regs->status);  	}  	/* If restore operation fails, re-initialize the HC during resume */ @@ -972,17 +997,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  		xhci_cleanup_msix(xhci);  		xhci_dbg(xhci, "// Disabling event ring interrupts\n"); -		temp = xhci_readl(xhci, &xhci->op_regs->status); -		xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); -		temp = xhci_readl(xhci, &xhci->ir_set->irq_pending); -		xhci_writel(xhci, ER_IRQ_DISABLE(temp), -				&xhci->ir_set->irq_pending); +		temp = readl(&xhci->op_regs->status); +		writel(temp & ~STS_EINT, &xhci->op_regs->status); +		temp = readl(&xhci->ir_set->irq_pending); +		writel(ER_IRQ_DISABLE(temp), &xhci->ir_set->irq_pending);  		xhci_print_ir_set(xhci, 0);  		xhci_dbg(xhci, "cleaning up memory\n");  		xhci_mem_cleanup(xhci);  		xhci_dbg(xhci, "xhci_stop completed - status = %x\n", -			    xhci_readl(xhci, &xhci->op_regs->status)); +			    readl(&xhci->op_regs->status));  		/* USB core calls the PCI reinit and start functions twice:  		 * first with the primary HCD, and then with the secondary HCD. @@ -1011,9 +1035,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)  	}  	/* step 4: set Run/Stop bit */ -	command = xhci_readl(xhci, &xhci->op_regs->command); +	command = readl(&xhci->op_regs->command);  	command |= CMD_RUN; -	xhci_writel(xhci, command, &xhci->op_regs->command); +	writel(command, &xhci->op_regs->command);  	xhci_handshake(xhci, &xhci->op_regs->status, STS_HALT,  		  0, 250 * 1000); @@ -1030,8 +1054,12 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)   done:  	if (retval == 0) { -		usb_hcd_resume_root_hub(hcd); -		usb_hcd_resume_root_hub(xhci->shared_hcd); +		/* Resume root hubs only when have pending events. */ +		status = readl(&xhci->op_regs->status); +		if (status & STS_EINT) { +			usb_hcd_resume_root_hub(hcd); +			usb_hcd_resume_root_hub(xhci->shared_hcd); +		}  	}  	/* @@ -1167,10 +1195,10 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,  		unsigned int ep_index, struct urb *urb)  { -	struct xhci_container_ctx *in_ctx;  	struct xhci_container_ctx *out_ctx;  	struct xhci_input_control_ctx *ctrl_ctx;  	struct xhci_ep_ctx *ep_ctx; +	struct xhci_command *command;  	int max_packet_size;  	int hw_max_packet_size;  	int ret = 0; @@ -1195,18 +1223,24 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,  		/* FIXME: This won't work if a non-default control endpoint  		 * changes max packet sizes.  		 */ -		in_ctx = xhci->devs[slot_id]->in_ctx; -		ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); + +		command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); +		if (!command) +			return -ENOMEM; + +		command->in_ctx = xhci->devs[slot_id]->in_ctx; +		ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);  		if (!ctrl_ctx) {  			xhci_warn(xhci, "%s: Could not get input context, bad type.\n",  					__func__); -			return -ENOMEM; +			ret = -ENOMEM; +			goto command_cleanup;  		}  		/* Set up the modified control endpoint 0 */  		xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx,  				xhci->devs[slot_id]->out_ctx, ep_index); -		ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); +		ep_ctx = xhci_get_ep_ctx(xhci, command->in_ctx, ep_index);  		ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET_MASK);  		ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size)); @@ -1214,17 +1248,20 @@ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,  		ctrl_ctx->drop_flags = 0;  		xhci_dbg(xhci, "Slot %d input context\n", slot_id); -		xhci_dbg_ctx(xhci, in_ctx, ep_index); +		xhci_dbg_ctx(xhci, command->in_ctx, ep_index);  		xhci_dbg(xhci, "Slot %d output context\n", slot_id);  		xhci_dbg_ctx(xhci, out_ctx, ep_index); -		ret = xhci_configure_endpoint(xhci, urb->dev, NULL, +		ret = xhci_configure_endpoint(xhci, urb->dev, command,  				true, false);  		/* Clean up the input context for later use by bandwidth  		 * functions.  		 */  		ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG); +command_cleanup: +		kfree(command->completion); +		kfree(command);  	}  	return ret;  } @@ -1445,6 +1482,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  	unsigned int ep_index;  	struct xhci_ring *ep_ring;  	struct xhci_virt_ep *ep; +	struct xhci_command *command;  	xhci = hcd_to_xhci(hcd);  	spin_lock_irqsave(&xhci->lock, flags); @@ -1452,7 +1490,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  	ret = usb_hcd_check_unlink_urb(hcd, urb, status);  	if (ret || !urb->hcpriv)  		goto done; -	temp = xhci_readl(xhci, &xhci->op_regs->status); +	temp = readl(&xhci->op_regs->status);  	if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) {  		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,  				"HW died, freeing TD."); @@ -1514,12 +1552,14 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)  	 * the first cancellation to be handled.  	 */  	if (!(ep->ep_state & EP_HALT_PENDING)) { +		command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC);  		ep->ep_state |= EP_HALT_PENDING;  		ep->stop_cmds_pending++;  		ep->stop_cmd_timer.expires = jiffies +  			XHCI_STOP_EP_CMD_TIMEOUT * HZ;  		add_timer(&ep->stop_cmd_timer); -		xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index, 0); +		xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, +					 ep_index, 0);  		xhci_ring_cmd_db(xhci);  	}  done: @@ -1784,6 +1824,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,  	int ret;  	switch (*cmd_status) { +	case COMP_CMD_ABORT: +	case COMP_CMD_STOP: +		xhci_warn(xhci, "Timeout while waiting for configure endpoint command\n"); +		ret = -ETIME; +		break;  	case COMP_ENOMEM:  		dev_warn(&udev->dev, "Not enough host controller resources "  				"for new device state.\n"); @@ -1830,6 +1875,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,  	struct xhci_virt_device *virt_dev = xhci->devs[udev->slot_id];  	switch (*cmd_status) { +	case COMP_CMD_ABORT: +	case COMP_CMD_STOP: +		xhci_warn(xhci, "Timeout while waiting for evaluate context command\n"); +		ret = -ETIME; +		break;  	case COMP_EINVAL:  		dev_warn(&udev->dev, "WARN: xHCI driver setup invalid evaluate "  				"context command.\n"); @@ -1880,8 +1930,8 @@ static u32 xhci_count_num_new_endpoints(struct xhci_hcd *xhci,  	 * (bit 1).  The default control endpoint is added during the Address  	 * Device command and is never removed until the slot is disabled.  	 */ -	valid_add_flags = ctrl_ctx->add_flags >> 2; -	valid_drop_flags = ctrl_ctx->drop_flags >> 2; +	valid_add_flags = le32_to_cpu(ctrl_ctx->add_flags) >> 2; +	valid_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags) >> 2;  	/* Use hweight32 to count the number of ones in the add flags, or  	 * number of endpoints added.  Don't count endpoints that are changed @@ -1897,8 +1947,8 @@ static unsigned int xhci_count_num_dropped_endpoints(struct xhci_hcd *xhci,  	u32 valid_add_flags;  	u32 valid_drop_flags; -	valid_add_flags = ctrl_ctx->add_flags >> 2; -	valid_drop_flags = ctrl_ctx->drop_flags >> 2; +	valid_add_flags = le32_to_cpu(ctrl_ctx->add_flags) >> 2; +	valid_drop_flags = le32_to_cpu(ctrl_ctx->drop_flags) >> 2;  	return hweight32(valid_drop_flags) -  		hweight32(valid_add_flags & valid_drop_flags); @@ -2554,23 +2604,17 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  		bool ctx_change, bool must_succeed)  {  	int ret; -	int timeleft;  	unsigned long flags; -	struct xhci_container_ctx *in_ctx;  	struct xhci_input_control_ctx *ctrl_ctx; -	struct completion *cmd_completion; -	u32 *cmd_status;  	struct xhci_virt_device *virt_dev; -	union xhci_trb *cmd_trb; + +	if (!command) +		return -EINVAL;  	spin_lock_irqsave(&xhci->lock, flags);  	virt_dev = xhci->devs[udev->slot_id]; -	if (command) -		in_ctx = command->in_ctx; -	else -		in_ctx = virt_dev->in_ctx; -	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); +	ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);  	if (!ctrl_ctx) {  		spin_unlock_irqrestore(&xhci->lock, flags);  		xhci_warn(xhci, "%s: Could not get input context, bad type.\n", @@ -2587,7 +2631,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  		return -ENOMEM;  	}  	if ((xhci->quirks & XHCI_SW_BW_CHECKING) && -			xhci_reserve_bandwidth(xhci, virt_dev, in_ctx)) { +	    xhci_reserve_bandwidth(xhci, virt_dev, command->in_ctx)) {  		if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK))  			xhci_free_host_resources(xhci, ctrl_ctx);  		spin_unlock_irqrestore(&xhci->lock, flags); @@ -2595,35 +2639,15 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  		return -ENOMEM;  	} -	if (command) { -		cmd_completion = command->completion; -		cmd_status = &command->status; -		command->command_trb = xhci->cmd_ring->enqueue; - -		/* Enqueue pointer can be left pointing to the link TRB, -		 * we must handle that -		 */ -		if (TRB_TYPE_LINK_LE32(command->command_trb->link.control)) -			command->command_trb = -				xhci->cmd_ring->enq_seg->next->trbs; - -		list_add_tail(&command->cmd_list, &virt_dev->cmd_list); -	} else { -		cmd_completion = &virt_dev->cmd_completion; -		cmd_status = &virt_dev->cmd_status; -	} -	init_completion(cmd_completion); - -	cmd_trb = xhci->cmd_ring->dequeue;  	if (!ctx_change) -		ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma, +		ret = xhci_queue_configure_endpoint(xhci, command, +				command->in_ctx->dma,  				udev->slot_id, must_succeed);  	else -		ret = xhci_queue_evaluate_context(xhci, in_ctx->dma, +		ret = xhci_queue_evaluate_context(xhci, command, +				command->in_ctx->dma,  				udev->slot_id, must_succeed);  	if (ret < 0) { -		if (command) -			list_del(&command->cmd_list);  		if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK))  			xhci_free_host_resources(xhci, ctrl_ctx);  		spin_unlock_irqrestore(&xhci->lock, flags); @@ -2635,26 +2659,14 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  	spin_unlock_irqrestore(&xhci->lock, flags);  	/* Wait for the configure endpoint command to complete */ -	timeleft = wait_for_completion_interruptible_timeout( -			cmd_completion, -			XHCI_CMD_DEFAULT_TIMEOUT); -	if (timeleft <= 0) { -		xhci_warn(xhci, "%s while waiting for %s command\n", -				timeleft == 0 ? "Timeout" : "Signal", -				ctx_change == 0 ? -					"configure endpoint" : -					"evaluate context"); -		/* cancel the configure endpoint command */ -		ret = xhci_cancel_cmd(xhci, command, cmd_trb); -		if (ret < 0) -			return ret; -		return -ETIME; -	} +	wait_for_completion(command->completion);  	if (!ctx_change) -		ret = xhci_configure_endpoint_result(xhci, udev, cmd_status); +		ret = xhci_configure_endpoint_result(xhci, udev, +						     &command->status);  	else -		ret = xhci_evaluate_context_result(xhci, udev, cmd_status); +		ret = xhci_evaluate_context_result(xhci, udev, +						   &command->status);  	if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK)) {  		spin_lock_irqsave(&xhci->lock, flags); @@ -2670,6 +2682,20 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,  	return ret;  } +static void xhci_check_bw_drop_ep_streams(struct xhci_hcd *xhci, +	struct xhci_virt_device *vdev, int i) +{ +	struct xhci_virt_ep *ep = &vdev->eps[i]; + +	if (ep->ep_state & EP_HAS_STREAMS) { +		xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on set_interface, freeing streams.\n", +				xhci_get_endpoint_address(i)); +		xhci_free_stream_info(xhci, ep->stream_info); +		ep->stream_info = NULL; +		ep->ep_state &= ~EP_HAS_STREAMS; +	} +} +  /* Called after one or more calls to xhci_add_endpoint() or   * xhci_drop_endpoint().  If this call fails, the USB core is expected   * to call xhci_reset_bandwidth(). @@ -2688,6 +2714,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  	struct xhci_virt_device	*virt_dev;  	struct xhci_input_control_ctx *ctrl_ctx;  	struct xhci_slot_ctx *slot_ctx; +	struct xhci_command *command;  	ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);  	if (ret <= 0) @@ -2699,12 +2726,19 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  	xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev);  	virt_dev = xhci->devs[udev->slot_id]; +	command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); +	if (!command) +		return -ENOMEM; + +	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, virt_dev->in_ctx); +	ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);  	if (!ctrl_ctx) {  		xhci_warn(xhci, "%s: Could not get input context, bad type.\n",  				__func__); -		return -ENOMEM; +		ret = -ENOMEM; +		goto command_cleanup;  	}  	ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);  	ctrl_ctx->add_flags &= cpu_to_le32(~EP0_FLAG); @@ -2712,20 +2746,20 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  	/* Don't issue the command if there's no endpoints to update. */  	if (ctrl_ctx->add_flags == cpu_to_le32(SLOT_FLAG) && -			ctrl_ctx->drop_flags == 0) -		return 0; - +	    ctrl_ctx->drop_flags == 0) { +		ret = 0; +		goto command_cleanup; +	}  	xhci_dbg(xhci, "New Input Control Context:\n");  	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);  	xhci_dbg_ctx(xhci, virt_dev->in_ctx,  		     LAST_CTX_TO_EP_NUM(le32_to_cpu(slot_ctx->dev_info))); -	ret = xhci_configure_endpoint(xhci, udev, NULL, +	ret = xhci_configure_endpoint(xhci, udev, command,  			false, false); -	if (ret) { +	if (ret)  		/* Callee should call reset_bandwidth() */ -		return ret; -	} +		goto command_cleanup;  	xhci_dbg(xhci, "Output context after successful config ep cmd:\n");  	xhci_dbg_ctx(xhci, virt_dev->out_ctx, @@ -2734,8 +2768,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  	/* Free any rings that were dropped, but not changed. */  	for (i = 1; i < 31; ++i) {  		if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) && -		    !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) +		    !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))) {  			xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); +			xhci_check_bw_drop_ep_streams(xhci, virt_dev, i); +		}  	}  	xhci_zero_in_ctx(xhci, virt_dev);  	/* @@ -2751,9 +2787,13 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)  		if (virt_dev->eps[i].ring) {  			xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);  		} +		xhci_check_bw_drop_ep_streams(xhci, virt_dev, i);  		virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;  		virt_dev->eps[i].new_ring = NULL;  	} +command_cleanup: +	kfree(command->completion); +	kfree(command);  	return ret;  } @@ -2855,9 +2895,14 @@ void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,  	 * issue a configure endpoint command later.  	 */  	if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) { +		struct xhci_command *command; +		/* Can't sleep if we're called from cleanup_halted_endpoint() */ +		command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); +		if (!command) +			return;  		xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,  				"Queueing new dequeue state"); -		xhci_queue_new_dequeue_state(xhci, udev->slot_id, +		xhci_queue_new_dequeue_state(xhci, command, udev->slot_id,  				ep_index, ep->stopped_stream, &deq_state);  	} else {  		/* Better hope no one uses the input context between now and the @@ -2888,6 +2933,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,  	unsigned long flags;  	int ret;  	struct xhci_virt_ep *virt_ep; +	struct xhci_command *command;  	xhci = hcd_to_xhci(hcd);  	udev = (struct usb_device *) ep->hcpriv; @@ -2910,10 +2956,14 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,  		return;  	} +	command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); +	if (!command) +		return; +  	xhci_dbg_trace(xhci, trace_xhci_dbg_reset_ep,  			"Queueing reset endpoint command");  	spin_lock_irqsave(&xhci->lock, flags); -	ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); +	ret = xhci_queue_reset_ep(xhci, command, udev->slot_id, ep_index);  	/*  	 * Can't change the ring dequeue pointer until it's transitioned to the  	 * stopped state, which is only upon a successful reset endpoint @@ -2925,7 +2975,6 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,  		xhci_ring_cmd_db(xhci);  	}  	virt_ep->stopped_td = NULL; -	virt_ep->stopped_trb = NULL;  	virt_ep->stopped_stream = 0;  	spin_unlock_irqrestore(&xhci->lock, flags); @@ -2946,7 +2995,7 @@ static int xhci_check_streams_endpoint(struct xhci_hcd *xhci,  	ret = xhci_check_args(xhci_to_hcd(xhci), udev, ep, 1, true, __func__);  	if (ret <= 0)  		return -EINVAL; -	if (ep->ss_ep_comp.bmAttributes == 0) { +	if (usb_ss_max_streams(&ep->ss_ep_comp) == 0) {  		xhci_warn(xhci, "WARN: SuperSpeed Endpoint Companion"  				" descriptor for ep 0x%x does not support streams\n",  				ep->desc.bEndpointAddress); @@ -3113,6 +3162,12 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev,  	xhci_dbg(xhci, "Driver wants %u stream IDs (including stream 0).\n",  			num_streams); +	/* MaxPSASize value 0 (2 streams) means streams are not supported */ +	if (HCC_MAX_PSA(xhci->hcc_params) < 4) { +		xhci_dbg(xhci, "xHCI controller does not support streams.\n"); +		return -ENOSYS; +	} +  	config_cmd = xhci_alloc_command(xhci, true, true, mem_flags);  	if (!config_cmd) {  		xhci_dbg(xhci, "Could not allocate xHCI command structure.\n"); @@ -3382,7 +3437,6 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)  	unsigned int slot_id;  	struct xhci_virt_device *virt_dev;  	struct xhci_command *reset_device_cmd; -	int timeleft;  	int last_freed_endpoint;  	struct xhci_slot_ctx *slot_ctx;  	int old_active_eps = 0; @@ -3439,20 +3493,10 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)  	/* Attempt to submit the Reset Device command to the command ring */  	spin_lock_irqsave(&xhci->lock, flags); -	reset_device_cmd->command_trb = xhci->cmd_ring->enqueue; -	/* Enqueue pointer can be left pointing to the link TRB, -	 * we must handle that -	 */ -	if (TRB_TYPE_LINK_LE32(reset_device_cmd->command_trb->link.control)) -		reset_device_cmd->command_trb = -			xhci->cmd_ring->enq_seg->next->trbs; - -	list_add_tail(&reset_device_cmd->cmd_list, &virt_dev->cmd_list); -	ret = xhci_queue_reset_device(xhci, slot_id); +	ret = xhci_queue_reset_device(xhci, reset_device_cmd, slot_id);  	if (ret) {  		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); -		list_del(&reset_device_cmd->cmd_list);  		spin_unlock_irqrestore(&xhci->lock, flags);  		goto command_cleanup;  	} @@ -3460,22 +3504,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)  	spin_unlock_irqrestore(&xhci->lock, flags);  	/* Wait for the Reset Device command to finish */ -	timeleft = wait_for_completion_interruptible_timeout( -			reset_device_cmd->completion, -			USB_CTRL_SET_TIMEOUT); -	if (timeleft <= 0) { -		xhci_warn(xhci, "%s while waiting for reset device command\n", -				timeleft == 0 ? "Timeout" : "Signal"); -		spin_lock_irqsave(&xhci->lock, flags); -		/* The timeout might have raced with the event ring handler, so -		 * only delete from the list if the item isn't poisoned. -		 */ -		if (reset_device_cmd->cmd_list.next != LIST_POISON1) -			list_del(&reset_device_cmd->cmd_list); -		spin_unlock_irqrestore(&xhci->lock, flags); -		ret = -ETIME; -		goto command_cleanup; -	} +	wait_for_completion(reset_device_cmd->completion);  	/* The Reset Device command can't fail, according to the 0.95/0.96 spec,  	 * unless we tried to reset a slot ID that wasn't enabled, @@ -3483,6 +3512,11 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)  	 */  	ret = reset_device_cmd->status;  	switch (ret) { +	case COMP_CMD_ABORT: +	case COMP_CMD_STOP: +		xhci_warn(xhci, "Timeout waiting for reset device command\n"); +		ret = -ETIME; +		goto command_cleanup;  	case COMP_EBADSLT: /* 0.95 completion code for bad slot ID */  	case COMP_CTX_STATE: /* 0.96 completion code for same thing */  		xhci_dbg(xhci, "Can't reset device (slot ID %u) in %s state\n", @@ -3518,6 +3552,8 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)  		struct xhci_virt_ep *ep = &virt_dev->eps[i];  		if (ep->ep_state & EP_HAS_STREAMS) { +			xhci_warn(xhci, "WARN: endpoint 0x%02x has streams on device reset, freeing streams.\n", +					xhci_get_endpoint_address(i));  			xhci_free_stream_info(xhci, ep->stream_info);  			ep->stream_info = NULL;  			ep->ep_state &= ~EP_HAS_STREAMS; @@ -3560,6 +3596,11 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)  	unsigned long flags;  	u32 state;  	int i, ret; +	struct xhci_command *command; + +	command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); +	if (!command) +		return;  #ifndef CONFIG_USB_DEFAULT_PERSIST  	/* @@ -3575,8 +3616,10 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)  	/* If the host is halted due to driver unload, we still need to free the  	 * device.  	 */ -	if (ret <= 0 && ret != -ENODEV) +	if (ret <= 0 && ret != -ENODEV) { +		kfree(command);  		return; +	}  	virt_dev = xhci->devs[udev->slot_id]; @@ -3586,28 +3629,26 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)  		del_timer_sync(&virt_dev->eps[i].stop_cmd_timer);  	} -	if (udev->usb2_hw_lpm_enabled) { -		xhci_set_usb2_hardware_lpm(hcd, udev, 0); -		udev->usb2_hw_lpm_enabled = 0; -	} -  	spin_lock_irqsave(&xhci->lock, flags);  	/* Don't disable the slot if the host controller is dead. */ -	state = xhci_readl(xhci, &xhci->op_regs->status); +	state = readl(&xhci->op_regs->status);  	if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||  			(xhci->xhc_state & XHCI_STATE_HALTED)) {  		xhci_free_virt_device(xhci, udev->slot_id);  		spin_unlock_irqrestore(&xhci->lock, flags); +		kfree(command);  		return;  	} -	if (xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) { +	if (xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT, +				    udev->slot_id)) {  		spin_unlock_irqrestore(&xhci->lock, flags);  		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");  		return;  	}  	xhci_ring_cmd_db(xhci);  	spin_unlock_irqrestore(&xhci->lock, flags); +  	/*  	 * Event command completion handler will free any data structures  	 * associated with the slot.  XXX Can free sleep? @@ -3645,33 +3686,33 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);  	unsigned long flags; -	int timeleft;  	int ret; -	union xhci_trb *cmd_trb; +	struct xhci_command *command; + +	command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); +	if (!command) +		return 0;  	spin_lock_irqsave(&xhci->lock, flags); -	cmd_trb = xhci->cmd_ring->dequeue; -	ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0); +	command->completion = &xhci->addr_dev; +	ret = xhci_queue_slot_control(xhci, command, TRB_ENABLE_SLOT, 0);  	if (ret) {  		spin_unlock_irqrestore(&xhci->lock, flags);  		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n"); +		kfree(command);  		return 0;  	}  	xhci_ring_cmd_db(xhci);  	spin_unlock_irqrestore(&xhci->lock, flags); -	/* XXX: how much time for xHC slot assignment? */ -	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -			XHCI_CMD_DEFAULT_TIMEOUT); -	if (timeleft <= 0) { -		xhci_warn(xhci, "%s while waiting for a slot\n", -				timeleft == 0 ? "Timeout" : "Signal"); -		/* cancel the enable slot request */ -		return xhci_cancel_cmd(xhci, NULL, cmd_trb); -	} +	wait_for_completion(command->completion); -	if (!xhci->slot_id) { +	if (!xhci->slot_id || command->status != COMP_SUCCESS) {  		xhci_err(xhci, "Error while assigning device slot ID\n"); +		xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n", +				HCS_MAX_SLOTS( +					readl(&xhci->cap_regs->hcs_params1))); +		kfree(command);  		return 0;  	} @@ -3706,6 +3747,8 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)  		pm_runtime_get_noresume(hcd->self.controller);  #endif + +	kfree(command);  	/* Is this a LS or FS device under a HS hub? */  	/* Hub or peripherial? */  	return 1; @@ -3713,32 +3756,33 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)  disable_slot:  	/* Disable slot, if we can do it without mem alloc */  	spin_lock_irqsave(&xhci->lock, flags); -	if (!xhci_queue_slot_control(xhci, TRB_DISABLE_SLOT, udev->slot_id)) +	command->completion = NULL; +	command->status = 0; +	if (!xhci_queue_slot_control(xhci, command, TRB_DISABLE_SLOT, +				     udev->slot_id))  		xhci_ring_cmd_db(xhci);  	spin_unlock_irqrestore(&xhci->lock, flags);  	return 0;  }  /* - * Issue an Address Device command (which will issue a SetAddress request to - * the device). + * Issue an Address Device command and optionally send a corresponding + * SetAddress request to the device.   * We should be protected by the usb_address0_mutex in khubd's hub_port_init, so   * we should only issue and wait on one address command at the same time. - * - * We add one to the device address issued by the hardware because the USB core - * uses address 1 for the root hubs (even though they're not really devices).   */ -int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) +static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, +			     enum xhci_setup_dev setup)  { +	const char *act = setup == SETUP_CONTEXT_ONLY ? "context" : "address";  	unsigned long flags; -	int timeleft;  	struct xhci_virt_device *virt_dev;  	int ret = 0;  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);  	struct xhci_slot_ctx *slot_ctx;  	struct xhci_input_control_ctx *ctrl_ctx;  	u64 temp_64; -	union xhci_trb *cmd_trb; +	struct xhci_command *command;  	if (!udev->slot_id) {  		xhci_dbg_trace(xhci, trace_xhci_dbg_address, @@ -3759,11 +3803,19 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  		return -EINVAL;  	} +	command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); +	if (!command) +		return -ENOMEM; + +	command->in_ctx = virt_dev->in_ctx; +	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);  	if (!ctrl_ctx) {  		xhci_warn(xhci, "%s: Could not get input context, bad type.\n",  				__func__); +		kfree(command);  		return -EINVAL;  	}  	/* @@ -3782,61 +3834,57 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);  	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);  	trace_xhci_address_ctx(xhci, virt_dev->in_ctx, -				slot_ctx->dev_info >> 27); +				le32_to_cpu(slot_ctx->dev_info) >> 27);  	spin_lock_irqsave(&xhci->lock, flags); -	cmd_trb = xhci->cmd_ring->dequeue; -	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma, -					udev->slot_id); +	ret = xhci_queue_address_device(xhci, command, virt_dev->in_ctx->dma, +					udev->slot_id, setup);  	if (ret) {  		spin_unlock_irqrestore(&xhci->lock, flags);  		xhci_dbg_trace(xhci, trace_xhci_dbg_address,  				"FIXME: allocate a command ring segment"); +		kfree(command);  		return ret;  	}  	xhci_ring_cmd_db(xhci);  	spin_unlock_irqrestore(&xhci->lock, flags);  	/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */ -	timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev, -			XHCI_CMD_DEFAULT_TIMEOUT); +	wait_for_completion(command->completion); +  	/* FIXME: From section 4.3.4: "Software shall be responsible for timing  	 * the SetAddress() "recovery interval" required by USB and aborting the  	 * command on a timeout.  	 */ -	if (timeleft <= 0) { -		xhci_warn(xhci, "%s while waiting for address device command\n", -				timeleft == 0 ? "Timeout" : "Signal"); -		/* cancel the address device command */ -		ret = xhci_cancel_cmd(xhci, NULL, cmd_trb); -		if (ret < 0) -			return ret; -		return -ETIME; -	} - -	switch (virt_dev->cmd_status) { +	switch (command->status) { +	case COMP_CMD_ABORT: +	case COMP_CMD_STOP: +		xhci_warn(xhci, "Timeout while waiting for setup device command\n"); +		ret = -ETIME; +		break;  	case COMP_CTX_STATE:  	case COMP_EBADSLT: -		xhci_err(xhci, "Setup ERROR: address device command for slot %d.\n", -				udev->slot_id); +		xhci_err(xhci, "Setup ERROR: setup %s command for slot %d.\n", +			 act, udev->slot_id);  		ret = -EINVAL;  		break;  	case COMP_TX_ERR: -		dev_warn(&udev->dev, "Device not responding to set address.\n"); +		dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);  		ret = -EPROTO;  		break;  	case COMP_DEV_ERR: -		dev_warn(&udev->dev, "ERROR: Incompatible device for address " -				"device command.\n"); +		dev_warn(&udev->dev, +			 "ERROR: Incompatible device for setup %s command\n", act);  		ret = -ENODEV;  		break;  	case COMP_SUCCESS:  		xhci_dbg_trace(xhci, trace_xhci_dbg_address, -				"Successful Address Device command"); +			       "Successful setup %s command", act);  		break;  	default: -		xhci_err(xhci, "ERROR: unexpected command completion " -				"code 0x%x.\n", virt_dev->cmd_status); +		xhci_err(xhci, +			 "ERROR: unexpected setup %s command completion code 0x%x.\n", +			 act, command->status);  		xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);  		xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);  		trace_xhci_address_ctx(xhci, virt_dev->out_ctx, 1); @@ -3844,6 +3892,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  		break;  	}  	if (ret) { +		kfree(command);  		return ret;  	}  	temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr); @@ -3861,7 +3910,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);  	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);  	trace_xhci_address_ctx(xhci, virt_dev->in_ctx, -				slot_ctx->dev_info >> 27); +				le32_to_cpu(slot_ctx->dev_info) >> 27);  	xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);  	xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);  	/* @@ -3870,21 +3919,28 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)  	 */  	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);  	trace_xhci_address_ctx(xhci, virt_dev->out_ctx, -				slot_ctx->dev_info >> 27); -	/* Use kernel assigned address for devices; store xHC assigned -	 * address locally. */ -	virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) -		+ 1; +				le32_to_cpu(slot_ctx->dev_info) >> 27);  	/* Zero the input context control for later use */  	ctrl_ctx->add_flags = 0;  	ctrl_ctx->drop_flags = 0;  	xhci_dbg_trace(xhci, trace_xhci_dbg_address, -			"Internal device address = %d", virt_dev->address); - +		       "Internal device address = %d", +		       le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK); +	kfree(command);  	return 0;  } +int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) +{ +	return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ADDRESS); +} + +int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev) +{ +	return xhci_setup_device(hcd, udev, SETUP_CONTEXT_ONLY); +} +  /*   * Transfer the port index into real index in the HW port status   * registers. Caculate offset between the port's PORTSC register @@ -4028,133 +4084,6 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev)  	return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm);  } -static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd, -					struct usb_device *udev) -{ -	struct xhci_hcd	*xhci = hcd_to_xhci(hcd); -	struct dev_info	*dev_info; -	__le32 __iomem	**port_array; -	__le32 __iomem	*addr, *pm_addr; -	u32		temp, dev_id; -	unsigned int	port_num; -	unsigned long	flags; -	int		hird; -	int		ret; - -	if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || -			!udev->lpm_capable) -		return -EINVAL; - -	/* we only support lpm for non-hub device connected to root hub yet */ -	if (!udev->parent || udev->parent->parent || -			udev->descriptor.bDeviceClass == USB_CLASS_HUB) -		return -EINVAL; - -	spin_lock_irqsave(&xhci->lock, flags); - -	/* Look for devices in lpm_failed_devs list */ -	dev_id = le16_to_cpu(udev->descriptor.idVendor) << 16 | -			le16_to_cpu(udev->descriptor.idProduct); -	list_for_each_entry(dev_info, &xhci->lpm_failed_devs, list) { -		if (dev_info->dev_id == dev_id) { -			ret = -EINVAL; -			goto finish; -		} -	} - -	port_array = xhci->usb2_ports; -	port_num = udev->portnum - 1; - -	if (port_num > HCS_MAX_PORTS(xhci->hcs_params1)) { -		xhci_dbg(xhci, "invalid port number %d\n", udev->portnum); -		ret = -EINVAL; -		goto finish; -	} - -	/* -	 * Test USB 2.0 software LPM. -	 * FIXME: some xHCI 1.0 hosts may implement a new register to set up -	 * hardware-controlled USB 2.0 LPM. See section 5.4.11 and 4.23.5.1.1.1 -	 * in the June 2011 errata release. -	 */ -	xhci_dbg(xhci, "test port %d software LPM\n", port_num); -	/* -	 * Set L1 Device Slot and HIRD/BESL. -	 * Check device's USB 2.0 extension descriptor to determine whether -	 * HIRD or BESL shoule be used. See USB2.0 LPM errata. -	 */ -	pm_addr = port_array[port_num] + PORTPMSC; -	hird = xhci_calculate_hird_besl(xhci, udev); -	temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird); -	xhci_writel(xhci, temp, pm_addr); - -	/* Set port link state to U2(L1) */ -	addr = port_array[port_num]; -	xhci_set_link_state(xhci, port_array, port_num, XDEV_U2); - -	/* wait for ACK */ -	spin_unlock_irqrestore(&xhci->lock, flags); -	msleep(10); -	spin_lock_irqsave(&xhci->lock, flags); - -	/* Check L1 Status */ -	ret = xhci_handshake(xhci, pm_addr, -			PORT_L1S_MASK, PORT_L1S_SUCCESS, 125); -	if (ret != -ETIMEDOUT) { -		/* enter L1 successfully */ -		temp = xhci_readl(xhci, addr); -		xhci_dbg(xhci, "port %d entered L1 state, port status 0x%x\n", -				port_num, temp); -		ret = 0; -	} else { -		temp = xhci_readl(xhci, pm_addr); -		xhci_dbg(xhci, "port %d software lpm failed, L1 status %d\n", -				port_num, temp & PORT_L1S_MASK); -		ret = -EINVAL; -	} - -	/* Resume the port */ -	xhci_set_link_state(xhci, port_array, port_num, XDEV_U0); - -	spin_unlock_irqrestore(&xhci->lock, flags); -	msleep(10); -	spin_lock_irqsave(&xhci->lock, flags); - -	/* Clear PLC */ -	xhci_test_and_clear_bit(xhci, port_array, port_num, PORT_PLC); - -	/* Check PORTSC to make sure the device is in the right state */ -	if (!ret) { -		temp = xhci_readl(xhci, addr); -		xhci_dbg(xhci, "resumed port %d status 0x%x\n",	port_num, temp); -		if (!(temp & PORT_CONNECT) || !(temp & PORT_PE) || -				(temp & PORT_PLS_MASK) != XDEV_U0) { -			xhci_dbg(xhci, "port L1 resume fail\n"); -			ret = -EINVAL; -		} -	} - -	if (ret) { -		/* Insert dev to lpm_failed_devs list */ -		xhci_warn(xhci, "device LPM test failed, may disconnect and " -				"re-enumerate\n"); -		dev_info = kzalloc(sizeof(struct dev_info), GFP_ATOMIC); -		if (!dev_info) { -			ret = -ENOMEM; -			goto finish; -		} -		dev_info->dev_id = dev_id; -		INIT_LIST_HEAD(&dev_info->list); -		list_add(&dev_info->list, &xhci->lpm_failed_devs); -	} else { -		xhci_ring_device(xhci, udev->slot_id); -	} - -finish: -	spin_unlock_irqrestore(&xhci->lock, flags); -	return ret; -} -  int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,  			struct usb_device *udev, int enable)  { @@ -4183,12 +4112,12 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,  	port_array = xhci->usb2_ports;  	port_num = udev->portnum - 1;  	pm_addr = port_array[port_num] + PORTPMSC; -	pm_val = xhci_readl(xhci, pm_addr); +	pm_val = readl(pm_addr);  	hlpm_addr = port_array[port_num] + PORTHLPMC;  	field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);  	xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n", -			enable ? "enable" : "disable", port_num); +			enable ? "enable" : "disable", port_num + 1);  	if (enable) {  		/* Host supports BESL timeout instead of HIRD */ @@ -4223,26 +4152,26 @@ int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,  			spin_lock_irqsave(&xhci->lock, flags);  			hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev); -			xhci_writel(xhci, hlpm_val, hlpm_addr); +			writel(hlpm_val, hlpm_addr);  			/* flush write */ -			xhci_readl(xhci, hlpm_addr); +			readl(hlpm_addr);  		} else {  			hird = xhci_calculate_hird_besl(xhci, udev);  		}  		pm_val &= ~PORT_HIRD_MASK; -		pm_val |= PORT_HIRD(hird) | PORT_RWE; -		xhci_writel(xhci, pm_val, pm_addr); -		pm_val = xhci_readl(xhci, pm_addr); +		pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id); +		writel(pm_val, pm_addr); +		pm_val = readl(pm_addr);  		pm_val |= PORT_HLE; -		xhci_writel(xhci, pm_val, pm_addr); +		writel(pm_val, pm_addr);  		/* flush write */ -		xhci_readl(xhci, pm_addr); +		readl(pm_addr);  	} else { -		pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK); -		xhci_writel(xhci, pm_val, pm_addr); +		pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK); +		writel(pm_val, pm_addr);  		/* flush write */ -		xhci_readl(xhci, pm_addr); +		readl(pm_addr);  		if (udev->usb2_hw_lpm_besl_capable) {  			spin_unlock_irqrestore(&xhci->lock, flags);  			mutex_lock(hcd->bandwidth_mutex); @@ -4282,24 +4211,26 @@ static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,  int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)  {  	struct xhci_hcd	*xhci = hcd_to_xhci(hcd); -	int		ret;  	int		portnum = udev->portnum - 1; -	ret = xhci_usb2_software_lpm_test(hcd, udev); -	if (!ret) { -		xhci_dbg(xhci, "software LPM test succeed\n"); -		if (xhci->hw_lpm_support == 1 && -		    xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) { -			udev->usb2_hw_lpm_capable = 1; -			udev->l1_params.timeout = XHCI_L1_TIMEOUT; -			udev->l1_params.besl = XHCI_DEFAULT_BESL; -			if (xhci_check_usb2_port_capability(xhci, portnum, -							    XHCI_BLC)) -				udev->usb2_hw_lpm_besl_capable = 1; -			ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1); -			if (!ret) -				udev->usb2_hw_lpm_enabled = 1; -		} +	if (hcd->speed == HCD_USB3 || !xhci->sw_lpm_support || +			!udev->lpm_capable) +		return 0; + +	/* we only support lpm for non-hub device connected to root hub yet */ +	if (!udev->parent || udev->parent->parent || +			udev->descriptor.bDeviceClass == USB_CLASS_HUB) +		return 0; + +	if (xhci->hw_lpm_support == 1 && +			xhci_check_usb2_port_capability( +				xhci, portnum, XHCI_HLC)) { +		udev->usb2_hw_lpm_capable = 1; +		udev->l1_params.timeout = XHCI_L1_TIMEOUT; +		udev->l1_params.besl = XHCI_DEFAULT_BESL; +		if (xhci_check_usb2_port_capability(xhci, portnum, +					XHCI_BLC)) +			udev->usb2_hw_lpm_besl_capable = 1;  	}  	return 0; @@ -4594,7 +4525,7 @@ static u16 xhci_calculate_lpm_timeout(struct usb_hcd *hcd,  	if (!config)  		return timeout; -	for (i = 0; i < USB_MAXINTERFACES; i++) { +	for (i = 0; i < config->desc.bNumInterfaces; i++) {  		struct usb_driver *driver;  		struct usb_interface *intf = config->interface[i]; @@ -4843,7 +4774,7 @@ int xhci_get_frame(struct usb_hcd *hcd)  {  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);  	/* EHCI mods by the periodic size.  Why? */ -	return xhci_readl(xhci, &xhci->run_regs->microframe_index) >> 3; +	return readl(&xhci->run_regs->microframe_index) >> 3;  }  int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) @@ -4887,18 +4818,20 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)  	xhci->cap_regs = hcd->regs;  	xhci->op_regs = hcd->regs + -		HC_LENGTH(xhci_readl(xhci, &xhci->cap_regs->hc_capbase)); +		HC_LENGTH(readl(&xhci->cap_regs->hc_capbase));  	xhci->run_regs = hcd->regs + -		(xhci_readl(xhci, &xhci->cap_regs->run_regs_off) & RTSOFF_MASK); +		(readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK);  	/* Cache read-only capability registers */ -	xhci->hcs_params1 = xhci_readl(xhci, &xhci->cap_regs->hcs_params1); -	xhci->hcs_params2 = xhci_readl(xhci, &xhci->cap_regs->hcs_params2); -	xhci->hcs_params3 = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); -	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); +	xhci->hcs_params1 = readl(&xhci->cap_regs->hcs_params1); +	xhci->hcs_params2 = readl(&xhci->cap_regs->hcs_params2); +	xhci->hcs_params3 = readl(&xhci->cap_regs->hcs_params3); +	xhci->hcc_params = readl(&xhci->cap_regs->hc_capbase);  	xhci->hci_version = HC_VERSION(xhci->hcc_params); -	xhci->hcc_params = xhci_readl(xhci, &xhci->cap_regs->hcc_params); +	xhci->hcc_params = readl(&xhci->cap_regs->hcc_params);  	xhci_print_registers(xhci); +	xhci->quirks = quirks; +  	get_quirks(dev, xhci);  	/* In xhci controllers which follow xhci 1.0 spec gives a spurious diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 46aa1489414..9ffecd56600 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -383,6 +383,7 @@ struct xhci_op_regs {  #define	PORT_RWE		(1 << 3)  #define	PORT_HIRD(p)		(((p) & 0xf) << 4)  #define	PORT_HIRD_MASK		(0xf << 4) +#define	PORT_L1DS_MASK		(0xff << 8)  #define	PORT_L1DS(p)		(((p) & 0xff) << 8)  #define	PORT_HLE		(1 << 16) @@ -702,6 +703,7 @@ struct xhci_ep_ctx {  /* deq bitmasks */  #define EP_CTX_CYCLE_MASK		(1 << 0) +#define SCTX_DEQ_MASK			(~0xfL)  /** @@ -751,7 +753,7 @@ struct xhci_stream_ctx {  };  /* Stream Context Types (section 6.4.1) - bits 3:1 of stream ctx deq ptr */ -#define	SCT_FOR_CTX(p)		(((p) << 1) & 0x7) +#define	SCT_FOR_CTX(p)		(((p) & 0x7) << 1)  /* Secondary stream array type, dequeue pointer is to a transfer ring */  #define	SCT_SEC_TR		0  /* Primary stream array type, dequeue pointer is to a transfer ring */ @@ -863,8 +865,6 @@ struct xhci_virt_ep {  #define EP_GETTING_NO_STREAMS	(1 << 5)  	/* ----  Related to URB cancellation ---- */  	struct list_head	cancelled_td_list; -	/* The TRB that was last reported in a stopped endpoint ring */ -	union xhci_trb		*stopped_trb;  	struct xhci_td		*stopped_td;  	unsigned int		stopped_stream;  	/* Watchdog timer for stop endpoint command to cancel URBs */ @@ -934,14 +934,9 @@ struct xhci_virt_device {  	/* Rings saved to ensure old alt settings can be re-instated */  	struct xhci_ring		**ring_cache;  	int				num_rings_cached; -	/* Store xHC assigned device address */ -	int				address;  #define	XHCI_MAX_RINGS_CACHED	31  	struct xhci_virt_ep		eps[31];  	struct completion		cmd_completion; -	/* Status of the last command issued for this device */ -	u32				cmd_status; -	struct list_head		cmd_list;  	u8				fake_port;  	u8				real_port;  	struct xhci_interval_bw_table	*bw_table; @@ -1098,6 +1093,14 @@ struct xhci_event_cmd {  };  /* flags bitmasks */ + +/* Address device - disable SetAddress */ +#define TRB_BSR		(1<<9) +enum xhci_setup_dev { +	SETUP_CONTEXT_ONLY, +	SETUP_CONTEXT_ADDRESS, +}; +  /* bits 16:23 are the virtual function ID */  /* bits 24:31 are the slot ID */  #define TRB_TO_SLOT_ID(p)	(((p) & (0xff<<24)) >> 24) @@ -1111,9 +1114,10 @@ struct xhci_event_cmd {  #define TRB_TO_SUSPEND_PORT(p)		(((p) & (1 << 23)) >> 23)  #define LAST_EP_INDEX			30 -/* Set TR Dequeue Pointer command TRB fields */ +/* Set TR Dequeue Pointer command TRB fields, 6.4.3.9 */  #define TRB_TO_STREAM_ID(p)		((((p) & (0xffff << 16)) >> 16))  #define STREAM_ID_FOR_TRB(p)		((((p)) & 0xffff) << 16) +#define SCT_FOR_TRB(p)			(((p) << 1) & 0x7)  /* Port Status Change Event TRB fields */ @@ -1291,7 +1295,6 @@ struct xhci_td {  /* command descriptor */  struct xhci_cd { -	struct list_head	cancel_cmd_list;  	struct xhci_command	*command;  	union xhci_trb		*cmd_trb;  }; @@ -1334,6 +1337,7 @@ struct xhci_ring {  	unsigned int		num_trbs_free_temp;  	enum xhci_ring_type	type;  	bool			last_td_was_short; +	struct radix_tree_root	*trb_address_map;  };  struct xhci_erst_entry { @@ -1412,8 +1416,18 @@ struct xhci_bus_state {  	unsigned long		resume_done[USB_MAXCHILDREN];  	/* which ports have started to resume */  	unsigned long		resuming_ports; +	/* Which ports are waiting on RExit to U0 transition. */ +	unsigned long		rexit_ports; +	struct completion	rexit_done[USB_MAXCHILDREN];  }; + +/* + * It can take up to 20 ms to transition from RExit to U0 on the + * Intel Lynx Point LP xHCI host. + */ +#define	XHCI_MAX_REXIT_TIMEOUT	(20 * 1000) +  static inline unsigned int hcd_index(struct usb_hcd *hcd)  {  	if (hcd->speed == HCD_USB3) @@ -1458,6 +1472,8 @@ struct xhci_hcd {  	/* msi-x vectors */  	int		msix_count;  	struct msix_entry	*msix_entries; +	/* optional clock */ +	struct clk		*clk;  	/* data structures */  	struct xhci_device_context_array *dcbaa;  	struct xhci_ring	*cmd_ring; @@ -1465,8 +1481,10 @@ struct xhci_hcd {  #define CMD_RING_STATE_RUNNING         (1 << 0)  #define CMD_RING_STATE_ABORTED         (1 << 1)  #define CMD_RING_STATE_STOPPED         (1 << 2) -	struct list_head        cancel_cmd_list; +	struct list_head        cmd_list;  	unsigned int		cmd_ring_reserved_trbs; +	struct timer_list	cmd_timer; +	struct xhci_command	*current_cmd;  	struct xhci_ring	*event_ring;  	struct xhci_erst	erst;  	/* Scratchpad */ @@ -1538,6 +1556,8 @@ struct xhci_hcd {  #define XHCI_COMP_MODE_QUIRK	(1 << 14)  #define XHCI_AVOID_BEI		(1 << 15)  #define XHCI_PLAT		(1 << 16) +#define XHCI_SLOW_SUSPEND	(1 << 17) +#define XHCI_SPURIOUS_WAKEUP	(1 << 18)  	unsigned int		num_active_eps;  	unsigned int		limit_active_eps;  	/* There are two roothubs to keep track of bus suspend info for */ @@ -1584,19 +1604,6 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)  #define xhci_warn_ratelimited(xhci, fmt, args...) \  	dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) -/* TODO: copied from ehci.h - can be refactored? */ -/* xHCI spec says all registers are little endian */ -static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, -		__le32 __iomem *regs) -{ -	return readl(regs); -} -static inline void xhci_writel(struct xhci_hcd *xhci, -		const unsigned int val, __le32 __iomem *regs) -{ -	writel(val, regs); -} -  /*   * Registers should always be accessed with double word or quad word accesses.   * @@ -1731,8 +1738,7 @@ static inline int xhci_register_pci(void) { return 0; }  static inline void xhci_unregister_pci(void) {}  #endif -#if defined(CONFIG_USB_XHCI_PLATFORM) \ -	|| defined(CONFIG_USB_XHCI_PLATFORM_MODULE) +#if IS_ENABLED(CONFIG_USB_XHCI_PLATFORM)  int xhci_register_plat(void);  void xhci_unregister_plat(void);  #else @@ -1779,6 +1785,7 @@ int xhci_free_streams(struct usb_hcd *hcd, struct usb_device *udev,  		struct usb_host_endpoint **eps, unsigned int num_eps,  		gfp_t mem_flags);  int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); +int xhci_enable_device(struct usb_hcd *hcd, struct usb_device *udev);  int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev);  int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,  				struct usb_device *udev, int enable); @@ -1800,13 +1807,14 @@ struct xhci_segment *trb_in_td(struct xhci_segment *start_seg,  		dma_addr_t suspect_dma);  int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code);  void xhci_ring_cmd_db(struct xhci_hcd *xhci); -int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); -int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, -		u32 slot_id); -int xhci_queue_vendor_command(struct xhci_hcd *xhci, +int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd, +		u32 trb_type, u32 slot_id); +int xhci_queue_address_device(struct xhci_hcd *xhci, struct xhci_command *cmd, +		dma_addr_t in_ctx_ptr, u32 slot_id, enum xhci_setup_dev); +int xhci_queue_vendor_command(struct xhci_hcd *xhci, struct xhci_command *cmd,  		u32 field1, u32 field2, u32 field3, u32 field4); -int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, -		unsigned int ep_index, int suspend); +int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, struct xhci_command *cmd, +		int slot_id, unsigned int ep_index, int suspend);  int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,  		int slot_id, unsigned int ep_index);  int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, @@ -1815,18 +1823,21 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,  		int slot_id, unsigned int ep_index);  int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,  		struct urb *urb, int slot_id, unsigned int ep_index); -int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, -		u32 slot_id, bool command_must_succeed); -int xhci_queue_evaluate_context(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, -		u32 slot_id, bool command_must_succeed); -int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, -		unsigned int ep_index); -int xhci_queue_reset_device(struct xhci_hcd *xhci, u32 slot_id); +int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, +		struct xhci_command *cmd, dma_addr_t in_ctx_ptr, u32 slot_id, +		bool command_must_succeed); +int xhci_queue_evaluate_context(struct xhci_hcd *xhci, struct xhci_command *cmd, +		dma_addr_t in_ctx_ptr, u32 slot_id, bool command_must_succeed); +int xhci_queue_reset_ep(struct xhci_hcd *xhci, struct xhci_command *cmd, +		int slot_id, unsigned int ep_index); +int xhci_queue_reset_device(struct xhci_hcd *xhci, struct xhci_command *cmd, +		u32 slot_id);  void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,  		unsigned int slot_id, unsigned int ep_index,  		unsigned int stream_id, struct xhci_td *cur_td,  		struct xhci_dequeue_state *state);  void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, +		struct xhci_command *cmd,  		unsigned int slot_id, unsigned int ep_index,  		unsigned int stream_id,  		struct xhci_dequeue_state *deq_state); @@ -1836,10 +1847,11 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,  		unsigned int slot_id, unsigned int ep_index,  		struct xhci_dequeue_state *deq_state);  void xhci_stop_endpoint_command_watchdog(unsigned long arg); -int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command, -		union xhci_trb *cmd_trb); +void xhci_handle_command_timeout(unsigned long data); +  void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,  		unsigned int ep_index, unsigned int stream_id); +void xhci_cleanup_command_queue(struct xhci_hcd *xhci);  /* xHCI roothub code */  void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,  | 
