diff options
Diffstat (limited to 'drivers/usb/host/ohci.h')
| -rw-r--r-- | drivers/usb/host/ohci.h | 137 |
1 files changed, 91 insertions, 46 deletions
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 4ada43cf138..05e02a709d4 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -344,6 +344,12 @@ typedef struct urb_priv { * a subset of what the full implementation needs. (Linus) */ +enum ohci_rh_state { + OHCI_RH_HALTED, + OHCI_RH_SUSPENDED, + OHCI_RH_RUNNING +}; + struct ohci_hcd { spinlock_t lock; @@ -366,11 +372,7 @@ struct ohci_hcd { struct ed *ed_controltail; /* last in ctrl list */ struct ed *periodic [NUM_INTS]; /* shadow int_table */ - /* - * OTG controllers and transceivers need software interaction; - * other external transceivers should be software-transparent - */ - struct otg_transceiver *transceiver; + void (*start_hnp)(struct ohci_hcd *ohci); /* * memory management for queue data structures @@ -383,6 +385,7 @@ struct ohci_hcd { /* * driver state */ + enum ohci_rh_state rh_state; int num_ports; int load [NUM_INTS]; u32 hc_control; /* copy of hc control reg */ @@ -398,11 +401,68 @@ struct ohci_hcd { #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ +#define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ +#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 */ + + /* Needed for ZF Micro quirk */ + struct timer_list unlink_watchdog; + unsigned eds_scheduled; + struct ed *ed_to_check; + unsigned zf_delay; + + struct dentry *debug_dir; + struct dentry *debug_async; + struct dentry *debug_periodic; + struct dentry *debug_registers; + + /* platform-specific data -- must come last */ + unsigned long priv[0] __aligned(sizeof(s64)); + }; +#ifdef CONFIG_PCI +static inline int quirk_nec(struct ohci_hcd *ohci) +{ + return ohci->flags & OHCI_QUIRK_NEC; +} +static inline int quirk_zfmicro(struct ohci_hcd *ohci) +{ + return ohci->flags & OHCI_QUIRK_ZFMICRO; +} +static inline int quirk_amdiso(struct ohci_hcd *ohci) +{ + return ohci->flags & OHCI_QUIRK_AMD_PLL; +} +static inline int quirk_amdprefetch(struct ohci_hcd *ohci) +{ + return ohci->flags & OHCI_QUIRK_AMD_PREFETCH; +} +#else +static inline int quirk_nec(struct ohci_hcd *ohci) +{ + return 0; +} +static inline int quirk_zfmicro(struct ohci_hcd *ohci) +{ + return 0; +} +static inline int quirk_amdiso(struct ohci_hcd *ohci) +{ + return 0; +} +static inline int quirk_amdprefetch(struct ohci_hcd *ohci) +{ + return 0; +} +#endif + /* convert between an hcd pointer and the corresponding ohci_hcd */ static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) { @@ -415,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...) \ @@ -428,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 - /*-------------------------------------------------------------------------*/ /* @@ -495,15 +545,7 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. * - * REVISIT: arch/powerpc now has readl/writel_be, so the - * definition below can die once the STB04xxx support is - * finally ported over. */ -#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) -#define readl_be(addr) in_be32((__force unsigned *)addr) -#define writel_be(val, addr) out_be32((__force unsigned *)addr, val) -#endif - static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) { @@ -528,18 +570,8 @@ static inline void _ohci_writel (const struct ohci_hcd *ohci, #endif } -#ifdef CONFIG_ARCH_LH7A404 -/* Marc Singer: at the time this code was written, the LH7A404 - * had a problem reading the USB host registers. This - * implementation of the ohci_readl function performs the read - * twice as a work-around. - */ -#define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) -#define ohci_writel(o,v,r) _ohci_writel(o,v,r) -#else #define ohci_readl(o,r) _ohci_readl(o,r) #define ohci_writel(o,v,r) _ohci_writel(o,v,r) -#endif /*-------------------------------------------------------------------------*/ @@ -607,15 +639,12 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all * hardware handles 16 bit reads. That creates a different confusion on * some big-endian SOC implementations. Same thing happens with PSW access. - * - * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over - * to arch/powerpc */ -#ifdef CONFIG_STB03xxx -#define OHCI_BE_FRAME_NO_SHIFT 16 +#ifdef CONFIG_PPC_MPC52xx +#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) #else -#define OHCI_BE_FRAME_NO_SHIFT 0 +#define big_endian_frame_no_quirk(ohci) 0 #endif static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) @@ -623,7 +652,8 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) u32 tmp; if (big_endian_desc(ohci)) { tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); - tmp >>= OHCI_BE_FRAME_NO_SHIFT; + if (!big_endian_frame_no_quirk(ohci)) + tmp >>= 16; } else tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); @@ -645,11 +675,6 @@ static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci, /*-------------------------------------------------------------------------*/ -static inline void disable (struct ohci_hcd *ohci) -{ - ohci_to_hcd(ohci)->state = HC_STATE_HALT; -} - #define FI 0x2edf /* 12000 bits per frame (-1) */ #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) #define FIT (1 << 31) @@ -673,7 +698,7 @@ static inline void periodic_reinit (struct ohci_hcd *ohci) #define read_roothub(hc, register, mask) ({ \ u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \ if (temp == -1) \ - disable (hc); \ + hc->rh_state = OHCI_RH_HALTED; \ else if (hc->flags & OHCI_QUIRK_AMD756) \ while (temp & mask) \ temp = ohci_readl (hc, &hc->regs->roothub.register); \ @@ -687,3 +712,23 @@ static inline u32 roothub_status (struct ohci_hcd *hc) { return ohci_readl (hc, &hc->regs->roothub.status); } static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) { return read_roothub (hc, portstatus [i], 0xffe0fce0); } + +/* Declarations of things exported for use by ohci platform drivers */ + +struct ohci_driver_overrides { + const char *product_desc; + size_t extra_priv_size; + int (*reset)(struct usb_hcd *hcd); +}; + +extern void ohci_init_driver(struct hc_driver *drv, + const struct ohci_driver_overrides *over); +extern int ohci_restart(struct ohci_hcd *ohci); +extern int ohci_setup(struct usb_hcd *hcd); +#ifdef CONFIG_PM +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); |
