usb: pci-quirks: group AMD specific quirk code together
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/3 usb: pci-quirks: group AMD specific quirk code together
A follow on patch will introduce CONFIG_USB_PCI_AMD governing the AMD quirk and adding its compile time dependency on HAS_IOPORT. In order to minimize the number of #ifdefs in C files and make that patch easier to read first group the code together. This is pure code movement no functional change is intended.
--- drivers/usb/host/pci-quirks.c | 119 +++++++++++++++++----------------- drivers/usb/host/pci-quirks.h | 14 ++-- 2 files changed, 68 insertions(+), 65 deletions(-)
drivers/usb/host/pci-quirks.c +60 -59
@@ -60,6 +60,22 @@#define EHCI_USBLEGCTLSTS 4/* legacy control/status */ #define EHCI_USBLEGCTLSTS_SOOE (1 << 13)/* SMI on ownership change */ +/* ASMEDIA quirk use */ +#define ASMT_DATA_WRITE0_REG 0xF8 +#define ASMT_DATA_WRITE1_REG 0xFC +#define ASMT_CONTROL_REG 0xE0 +#define ASMT_CONTROL_WRITE_BIT 0x02 +#define ASMT_WRITEREG_CMD 0x10423 +#define ASMT_FLOWCTL_ADDR 0xFA30 +#define ASMT_FLOWCTL_DATA 0xBA +#define ASMT_PSEUDO_DATA 0 + +/* Intel quirk use */ +#define USB_INTEL_XUSB2PR 0xD0 +#define USB_INTEL_USB2PRM 0xD4 +#define USB_INTEL_USB3_PSSEN 0xD8 +#define USB_INTEL_USB3PRM 0xDC +/* AMD quirk use */ #define AB_REG_BAR_LOW 0xe0#define AB_REG_BAR_HIGH 0xe1
@@ -93,21 +109,6 @@#define NB_PIF0_PWRDOWN_0 0x01100012#define NB_PIF0_PWRDOWN_1 0x01100013 -#define USB_INTEL_XUSB2PR 0xD0 -#define USB_INTEL_USB2PRM 0xD4 -#define USB_INTEL_USB3_PSSEN 0xD8 -#define USB_INTEL_USB3PRM 0xDC - -/* ASMEDIA quirk use */ -#define ASMT_DATA_WRITE0_REG 0xF8 -#define ASMT_DATA_WRITE1_REG 0xFC -#define ASMT_CONTROL_REG 0xE0 -#define ASMT_CONTROL_WRITE_BIT 0x02 -#define ASMT_WRITEREG_CMD 0x10423 -#define ASMT_FLOWCTL_ADDR 0xFA30 -#define ASMT_FLOWCTL_DATA 0xBA -#define ASMT_PSEUDO_DATA 0 -/* * amd_chipset_gen values represent AMD different chipset generations */
@@ -458,50 +459,6 @@ void usb_amd_quirk_pll_disable(void) }EXPORT_SYMBOL_GPL (usb_amd_quirk_pll_disable); -static int usb_asmedia_wait_write (struct pci_dev *pdev) -{ -unsigned long retry_count; -unsigned char value; - -for (retry_count =1000 ; retry_count >0 ; --retry_count) { - -pci_read_config_byte (pdev,ASMT_CONTROL_REG , &value); - -if (value ==0xff ) { -dev_err (&pdev->dev,"%s: check_ready ERROR" , __func__); -return -EIO ; - } - -if ((value &ASMT_CONTROL_WRITE_BIT ) ==0 ) -return 0 ; - -udelay (50 ); - } - -dev_warn (&pdev->dev,"%s: check_write_ready timeout" , __func__); -return -ETIMEDOUT ; -} - -void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev) -{ -if (usb_asmedia_wait_write (pdev) !=0 ) -return ; - -/* send command and address to device */ -pci_write_config_dword (pdev,ASMT_DATA_WRITE0_REG ,ASMT_WRITEREG_CMD ); -pci_write_config_dword (pdev,ASMT_DATA_WRITE1_REG ,ASMT_FLOWCTL_ADDR ); -pci_write_config_byte (pdev,ASMT_CONTROL_REG ,ASMT_CONTROL_WRITE_BIT ); - -if (usb_asmedia_wait_write (pdev) !=0 ) -return ; - -/* send data to device */ -pci_write_config_dword (pdev,ASMT_DATA_WRITE0_REG ,ASMT_FLOWCTL_DATA ); -pci_write_config_dword (pdev,ASMT_DATA_WRITE1_REG ,ASMT_PSEUDO_DATA ); -pci_write_config_byte (pdev,ASMT_CONTROL_REG ,ASMT_CONTROL_WRITE_BIT ); -} -EXPORT_SYMBOL_GPL (usb_asmedia_modifyflowcontrol); -void usb_amd_quirk_pll_enable (void ) {usb_amd_quirk_pll (0 );
@@ -631,6 +588,50 @@ bool usb_amd_pt_check_port(struct device *device, int port) }EXPORT_SYMBOL_GPL (usb_amd_pt_check_port); +static int usb_asmedia_wait_write (struct pci_dev *pdev) +{ +unsigned long retry_count; +unsigned char value; + +for (retry_count =1000 ; retry_count >0 ; --retry_count) { + +pci_read_config_byte (pdev,ASMT_CONTROL_REG , &value); + +if (value ==0xff ) { +dev_err (&pdev->dev,"%s: check_ready ERROR" , __func__); +return -EIO ; + } + +if ((value &ASMT_CONTROL_WRITE_BIT ) ==0 ) +return 0 ; + +udelay (50 ); + } + +dev_warn (&pdev->dev,"%s: check_write_ready timeout" , __func__); +return -ETIMEDOUT ; +} + +void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev) +{ +if (usb_asmedia_wait_write (pdev) !=0 ) +return ; + +/* send command and address to device */ +pci_write_config_dword (pdev,ASMT_DATA_WRITE0_REG ,ASMT_WRITEREG_CMD ); +pci_write_config_dword (pdev,ASMT_DATA_WRITE1_REG ,ASMT_FLOWCTL_ADDR ); +pci_write_config_byte (pdev,ASMT_CONTROL_REG ,ASMT_CONTROL_WRITE_BIT ); + +if (usb_asmedia_wait_write (pdev) !=0 ) +return ; + +/* send data to device */ +pci_write_config_dword (pdev,ASMT_DATA_WRITE0_REG ,ASMT_FLOWCTL_DATA ); +pci_write_config_dword (pdev,ASMT_DATA_WRITE1_REG ,ASMT_PSEUDO_DATA ); +pci_write_config_byte (pdev,ASMT_CONTROL_REG ,ASMT_CONTROL_WRITE_BIT ); +} +EXPORT_SYMBOL_GPL (usb_asmedia_modifyflowcontrol); +/* * Make sure the controller is completely inactive, unable to * generate interrupts or do DMA.
drivers/usb/host/pci-quirks.h +8 -6
@@ -3,8 +3,6 @@#define __LINUX_USB_PCI_QUIRKS_H#ifdef CONFIG_USB_PCI -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_hcd_amd_remote_wakeup_quirk (struct pci_dev *pdev);bool usb_amd_hang_symptom_quirk (void );bool usb_amd_prefetch_quirk (void );
@@ -12,23 +10,27 @@ void usb_amd_dev_put(void);bool usb_amd_quirk_pll_check (void );void usb_amd_quirk_pll_disable (void );void usb_amd_quirk_pll_enable (void ); +void sb800_prefetch (struct device *dev,int on); +bool usb_amd_pt_check_port (struct device *device,int port); + +void uhci_reset_hc (struct pci_dev *pdev,unsigned long base); +int uhci_check_and_reset_hc (struct pci_dev *pdev,unsigned long base);void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev);void usb_enable_intel_xhci_ports (struct pci_dev *xhci_pdev);void usb_disable_xhci_ports (struct pci_dev *xhci_pdev); -void sb800_prefetch (struct device *dev,int on); -bool usb_amd_pt_check_port (struct device *device,int port);#else struct pci_dev ;static inline void usb_amd_quirk_pll_disable (void ) {}static inline void usb_amd_quirk_pll_enable (void ) {} -static inline void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev) {}static inline void usb_amd_dev_put (void ) {} -static inline void usb_disable_xhci_ports (struct pci_dev *xhci_pdev) {}static inline void sb800_prefetch (struct device *dev,int on) {}static inline bool usb_amd_pt_check_port (struct device *device,int port) {return false; } + +static inline void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev) {} +static inline void usb_disable_xhci_ports (struct pci_dev *xhci_pdev) {}#endif /* CONFIG_USB_PCI */ #endif /* __LINUX_USB_PCI_QUIRKS_H */
Signature · 1 line
2.39.2
PATCH 2/3 usb: pci-quirks: handle HAS_IOPORT dependency for AMD quirk
In reply to a message not in the archiveIn a future patch HAS_IOPORT=n will result in inb()/outb() and friends not being declared. In the pci-quirks case the I/O port acceses are used in the quirks for several AMD south bridges, Add a config option for the AMD quirks to depend on HAS_IOPORT and #ifdef the quirk code.
--- drivers/usb/Kconfig | 10 ++++++++++ drivers/usb/core/hcd-pci.c | 3 +-- drivers/usb/host/pci-quirks.c | 2 ++ drivers/usb/host/pci-quirks.h | 34 ++++++++++++++++++++++++---------- include/linux/usb/hcd.h | 17 +++++++++++++++++ 5 files changed, 54 insertions(+), 12 deletions(-)
drivers/usb/Kconfig +10 -0
@@ -91,6 +91,16 @@ config USB_PCI If you have such a device you may say N here and PCI related code will not be built in the USB driver. +config USB_PCI_AMD + bool "AMD PCI USB host support" + depends on USB_PCI && HAS_IOPORT + default X86 || MACH_LOONGSON64 || PPC_PASEMI + help + Enable workarounds for USB implementation quirks in SB600/SB700/SB800 + and later south bridge implementations. These are common on x86 PCs + with AMD CPUs but rarely used elsewhere, with the exception of a few + powerpc and mips desktop machines. + if USB source "drivers/usb/core/Kconfig"
drivers/usb/core/hcd-pci.c +1 -2
@@ -206,8 +206,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct hc_driver *driver) goto free_irq_vectors; } - hcd->amd_resume_bug = (usb_hcd_amd_remote_wakeup_quirk (dev) && - driver->flags & (HCD_USB11 |HCD_USB3 )) ?1 :0 ; + hcd->amd_resume_bug =usb_hcd_amd_resume_bug (dev, driver);if (driver->flags &HCD_MEMORY ) {/* EHCI, OHCI */
drivers/usb/host/pci-quirks.c +2 -0
@@ -76,6 +76,7 @@#define USB_INTEL_USB3_PSSEN 0xD8#define USB_INTEL_USB3PRM 0xDC +#ifdef CONFIG_USB_PCI_AMD /* AMD quirk use */ #define AB_REG_BAR_LOW 0xe0#define AB_REG_BAR_HIGH 0xe1
@@ -587,6 +588,7 @@ bool usb_amd_pt_check_port(struct device *device, int port) return !(value & BIT(port_shift)); }EXPORT_SYMBOL_GPL (usb_amd_pt_check_port); +#endif /* CONFIG_USB_PCI_AMD */ static int usb_asmedia_wait_write (struct pci_dev *pdev) {
drivers/usb/host/pci-quirks.h +24 -10
@@ -2,7 +2,7 @@#ifndef __LINUX_USB_PCI_QUIRKS_H#define __LINUX_USB_PCI_QUIRKS_H -#ifdef CONFIG_USB_PCI +#ifdef CONFIG_USB_PCI_AMD int usb_hcd_amd_remote_wakeup_quirk (struct pci_dev *pdev);bool usb_amd_hang_symptom_quirk (void );bool usb_amd_prefetch_quirk (void );
@@ -12,7 +12,30 @@ void usb_amd_quirk_pll_disable(void);void usb_amd_quirk_pll_enable (void );void sb800_prefetch (struct device *dev,int on);bool usb_amd_pt_check_port (struct device *device,int port); +#else +static inline bool usb_amd_hang_symptom_quirk (void ) +{ +return false; +}; +static inline bool usb_amd_prefetch_quirk (void ) +{ +return false; +} +static inline void usb_amd_quirk_pll_disable (void ) {} +static inline void usb_amd_quirk_pll_enable (void ) {} +static inline void usb_amd_dev_put (void ) {} +static inline bool usb_amd_quirk_pll_check (void ) +{ +return false; +} +static inline void sb800_prefetch (struct device *dev,int on) {} +static inline bool usb_amd_pt_check_port (struct device *device,int port) +{ +return false; +} +#endif /* CONFIG_USB_PCI_AMD */ +#ifdef CONFIG_USB_PCI void uhci_reset_hc (struct pci_dev *pdev,unsigned long base);int uhci_check_and_reset_hc (struct pci_dev *pdev,unsigned long base);void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev);
@@ -20,15 +43,6 @@ void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);void usb_disable_xhci_ports (struct pci_dev *xhci_pdev);#else struct pci_dev ; -static inline void usb_amd_quirk_pll_disable (void ) {} -static inline void usb_amd_quirk_pll_enable (void ) {} -static inline void usb_amd_dev_put (void ) {} -static inline void sb800_prefetch (struct device *dev,int on) {} -static inline bool usb_amd_pt_check_port (struct device *device,int port) -{ -return false; -} -static inline void usb_asmedia_modifyflowcontrol (struct pci_dev *pdev) {}static inline void usb_disable_xhci_ports (struct pci_dev *xhci_pdev) {}#endif /* CONFIG_USB_PCI */
include/linux/usb/hcd.h +17 -0
@@ -484,8 +484,25 @@ extern int usb_hcd_pci_probe(struct pci_dev *dev,extern void usb_hcd_pci_remove (struct pci_dev *dev);extern void usb_hcd_pci_shutdown (struct pci_dev *dev); +#ifdef CONFIG_USB_PCI_AMD extern int usb_hcd_amd_remote_wakeup_quirk (struct pci_dev *dev); +static inline bool usb_hcd_amd_resume_bug (struct pci_dev *dev, +const struct hc_driver *driver) +{ +if (!usb_hcd_amd_remote_wakeup_quirk (dev)) +return false; +if (driver->flags & (HCD_USB11 |HCD_USB3 )) +return true; +return false; +} +#else /* CONFIG_USB_PCI_AMD */ +static inline bool usb_hcd_amd_resume_bug (struct pci_dev *dev, +const struct hc_driver *driver) +{ +return false; +} +#endif extern const struct dev_pm_ops usb_hcd_pci_pm_ops;#endif /* CONFIG_USB_PCI */
Signature · 1 line
2.39.2
PATCH 3/3 usb: pci-quirks: handle HAS_IOPORT dependency for UHCI handoff
In reply to a message not in the archiveIn a future patch HAS_IOPORT=n will result in inb()/outb() and friends not being declared. With the AMD quirk handled USB PCI quirks still use inw() in uhci_check_and_reset_hc() and thus indirectly in quirk_usb_handoff_uhci(). Handle this by conditionally compiling uhci_check_and_reset_hc() and stubbing out quirk_usb_handoff_uhci() when HAS_IOPORT is not available.
--- drivers/usb/host/pci-quirks.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
drivers/usb/host/pci-quirks.c +16 -7
@@ -634,6 +634,16 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) }EXPORT_SYMBOL_GPL (usb_asmedia_modifyflowcontrol); +static inline int io_type_enabled (struct pci_dev *pdev,unsigned int mask) +{ +u16 cmd; + +return !pci_read_config_word (pdev,PCI_COMMAND , &cmd) && (cmd & mask); +} + +#define mmio_enabled (dev) io_type_enabled(dev, PCI_COMMAND_MEMORY) + +#if defined(CONFIG_HAS_IOPORT ) &&IS_ENABLED (CONFIG_USB_UHCI_HCD )/* * Make sure the controller is completely inactive, unable to * generate interrupts or do DMA.
@@ -715,14 +725,7 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base) }EXPORT_SYMBOL_GPL (uhci_check_and_reset_hc); -static inline int io_type_enabled (struct pci_dev *pdev,unsigned int mask) -{ -u16 cmd; -return !pci_read_config_word (pdev,PCI_COMMAND , &cmd) && (cmd & mask); -} -#define pio_enabled (dev) io_type_enabled(dev, PCI_COMMAND_IO) -#define mmio_enabled (dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)static void quirk_usb_handoff_uhci (struct pci_dev *pdev) {
@@ -742,6 +745,12 @@ static void quirk_usb_handoff_uhci(struct pci_dev *pdev) uhci_check_and_reset_hc(pdev, base); } +#else /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */ + +static void quirk_usb_handoff_uhci (struct pci_dev *pdev) {} + +#endif /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */ +static int mmio_resource_enabled (struct pci_dev *pdev,int idx) {return pci_resource_start (pdev, idx) &&mmio_enabled (pdev);
Signature · 1 line
2.39.2