[adm5120] fix usb mis-cleanup after r27162 (#9581)
[openwrt.git] / target / linux / adm5120 / files / drivers / usb / host / adm5120.h
index 95616f2..52fe039 100644 (file)
@@ -1,10 +1,16 @@
 /*
 /*
- * OHCI HCD (Host Controller Driver) for USB.
+ * ADM5120 HCD (Host Controller Driver) for USB
  *
  *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * Copyright (C) 2007-2008 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was derived from: drivers/usb/host/ohci.h
+ *   (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ *   (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ *
+ *  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.
  *
  *
- * This file is licenced under the GPL.
  */
 
 /*
  */
 
 /*
@@ -58,14 +64,10 @@ struct ed {
 
        struct list_head        urb_list;       /* list of our URBs */
 
 
        struct list_head        urb_list;       /* list of our URBs */
 
-       struct list_head        ed_list;        /* list of all EDs*/
-       struct list_head        rm_list;        /* for remove list */
-
        /* host's view of schedule */
        struct ed               *ed_next;       /* on schedule list */
        struct ed               *ed_prev;       /* for non-interrupt EDs */
        struct ed               *ed_rm_next;    /* on rm list */
        /* host's view of schedule */
        struct ed               *ed_next;       /* on schedule list */
        struct ed               *ed_prev;       /* for non-interrupt EDs */
        struct ed               *ed_rm_next;    /* on rm list */
-       struct ed               *ed_soft_list;  /* on software int list */
        struct list_head        td_list;        /* "shadow list" of our TDs */
 
        /* create --> IDLE --> OPER --> ... --> IDLE --> destroy
        struct list_head        td_list;        /* "shadow list" of our TDs */
 
        /* create --> IDLE --> OPER --> ... --> IDLE --> destroy
@@ -115,16 +117,17 @@ struct td {
 #define TD_T_SHIFT     23                      /* data toggle state */
 #define TD_T_MASK      0x3
 #define TD_T           (TD_T_MASK << TD_T_SHIFT)
 #define TD_T_SHIFT     23                      /* data toggle state */
 #define TD_T_MASK      0x3
 #define TD_T           (TD_T_MASK << TD_T_SHIFT)
-#define TD_T_DATA0     (0x2 << TD_T_SHIFT)             /* DATA0 */
-#define TD_T_DATA1     (0x3 << TD_T_SHIFT)             /* DATA1 */
-#define TD_T_CARRY     (0x0 << TD_T_SHIFT)             /* uses ED_C */
+#define TD_T_DATA0     (0x2 << TD_T_SHIFT)     /* DATA0 */
+#define TD_T_DATA1     (0x3 << TD_T_SHIFT)     /* DATA1 */
+#define TD_T_CARRY     (0x0 << TD_T_SHIFT)     /* uses ED_C */
 #define TD_T_GET(x)    (((x) >> TD_T_SHIFT) & TD_T_MASK)
 #define TD_DP_SHIFT    21                      /* direction/pid */
 #define TD_DP_MASK     0x3
 #define TD_DP          (TD_DP_MASK << TD_DP_SHIFT)
 #define TD_T_GET(x)    (((x) >> TD_T_SHIFT) & TD_T_MASK)
 #define TD_DP_SHIFT    21                      /* direction/pid */
 #define TD_DP_MASK     0x3
 #define TD_DP          (TD_DP_MASK << TD_DP_SHIFT)
-#define TD_DP_SETUP    (0x0 << TD_DP_SHIFT)            /* SETUP pid */
-#define TD_DP_OUT      (0x1 << TD_DP_SHIFT)            /* OUT pid */
-#define TD_DP_IN       (0x2 << TD_DP_SHIFT)            /* IN pid */
+#define TD_DP_GET      (((x) >> TD_DP_SHIFT) & TD_DP_MASK)
+#define TD_DP_SETUP    (0x0 << TD_DP_SHIFT)    /* SETUP pid */
+#define TD_DP_OUT      (0x1 << TD_DP_SHIFT)    /* OUT pid */
+#define TD_DP_IN       (0x2 << TD_DP_SHIFT)    /* IN pid */
 #define TD_ISI_SHIFT   8                       /* Interrupt Service Interval */
 #define TD_ISI_MASK    0x3f
 #define TD_ISI_GET(x)  (((x) >> TD_ISI_SHIFT) & TD_ISI_MASK)
 #define TD_ISI_SHIFT   8                       /* Interrupt Service Interval */
 #define TD_ISI_MASK    0x3f
 #define TD_ISI_GET(x)  (((x) >> TD_ISI_SHIFT) & TD_ISI_MASK)
@@ -184,7 +187,7 @@ struct td {
 
 
 /* map OHCI TD status codes (CC) to errno values */
 
 
 /* map OHCI TD status codes (CC) to errno values */
-static const int cc_to_error [16] = {
+static const int cc_to_error[16] = {
        /* No  Error  */        0,
        /* CRC Error  */        -EILSEQ,
        /* Bit Stuff  */        -EPROTO,
        /* No  Error  */        0,
        /* CRC Error  */        -EILSEQ,
        /* Bit Stuff  */        -EPROTO,
@@ -269,6 +272,8 @@ struct admhcd_regs {
  */
 #define ADMHC_INTR_SOFI        (1 << 4)        /* start of frame */
 #define ADMHC_INTR_RESI        (1 << 5)        /* resume detected */
  */
 #define ADMHC_INTR_SOFI        (1 << 4)        /* start of frame */
 #define ADMHC_INTR_RESI        (1 << 5)        /* resume detected */
+#define ADMHC_INTR_6   (1 << 6)        /* unknown */
+#define ADMHC_INTR_7   (1 << 7)        /* unknown */
 #define ADMHC_INTR_BABI        (1 << 8)        /* babble detected */
 #define ADMHC_INTR_INSM        (1 << 9)        /* root hub status change */
 #define ADMHC_INTR_SO  (1 << 10)       /* scheduling overrun */
 #define ADMHC_INTR_BABI        (1 << 8)        /* babble detected */
 #define ADMHC_INTR_INSM        (1 << 9)        /* root hub status change */
 #define ADMHC_INTR_SO  (1 << 10)       /* scheduling overrun */
@@ -389,8 +394,6 @@ struct admhcd {
        struct ed               *ed_tails[4];
 
        struct ed               *ed_rm_list;    /* to be removed */
        struct ed               *ed_tails[4];
 
        struct ed               *ed_rm_list;    /* to be removed */
-       struct ed               *ed_halt_list;  /* halted due to an error */
-       struct ed               *ed_soft_list;  /* for software interrupt processing */
 
        struct ed               *periodic[NUM_INTS];    /* shadow int_table */
 
 
        struct ed               *periodic[NUM_INTS];    /* shadow int_table */
 
@@ -427,7 +430,14 @@ struct admhcd {
 #define        OHCI_QUIRK_BE_DESC      0x08                    /* BE descriptors */
 #define        OHCI_QUIRK_BE_MMIO      0x10                    /* BE registers */
 #define        OHCI_QUIRK_ZFMICRO      0x20                    /* Compaq ZFMicro chipset*/
 #define        OHCI_QUIRK_BE_DESC      0x08                    /* BE descriptors */
 #define        OHCI_QUIRK_BE_MMIO      0x10                    /* BE registers */
 #define        OHCI_QUIRK_ZFMICRO      0x20                    /* Compaq ZFMicro chipset*/
-       // there are also chip quirks/bugs in init logic
+       /* there are also chip quirks/bugs in init logic */
+
+#ifdef DEBUG
+       struct dentry           *debug_dir;
+       struct dentry           *debug_async;
+       struct dentry           *debug_periodic;
+       struct dentry           *debug_registers;
+#endif
 };
 
 /* convert between an hcd pointer and the corresponding ahcd_hcd */
 };
 
 /* convert between an hcd pointer and the corresponding ahcd_hcd */
@@ -446,14 +456,19 @@ static inline struct usb_hcd *admhcd_to_hcd(const struct admhcd *ahcd)
 #define STUB_DEBUG_FILES
 #endif /* DEBUG */
 
 #define STUB_DEBUG_FILES
 #endif /* DEBUG */
 
-#define admhc_dbg(ahcd, fmt, args...) \
-       dev_dbg(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args )
+#ifdef DEBUG
+#      define admhc_dbg(ahcd, fmt, args...) \
+               printk(KERN_DEBUG "adm5120-hcd: " fmt, ## args)
+#else
+#      define admhc_dbg(ahcd, fmt, args...) do { } while (0)
+#endif
+
 #define admhc_err(ahcd, fmt, args...) \
 #define admhc_err(ahcd, fmt, args...) \
-       dev_err(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args )
-#define ahcd_info(ahcd, fmt, args...) \
-       dev_info(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args )
+       printk(KERN_ERR "adm5120-hcd: " fmt, ## args)
+#define admhc_info(ahcd, fmt, args...) \
+       printk(KERN_INFO "adm5120-hcd: " fmt, ## args)
 #define admhc_warn(ahcd, fmt, args...) \
 #define admhc_warn(ahcd, fmt, args...) \
-       dev_warn(admhcd_to_hcd(ahcd)->self.controller , fmt , ## args )
+       printk(KERN_WARNING "adm5120-hcd: " fmt, ## args)
 
 #ifdef ADMHC_VERBOSE_DEBUG
 #      define admhc_vdbg admhc_dbg
 
 #ifdef ADMHC_VERBOSE_DEBUG
 #      define admhc_vdbg admhc_dbg
@@ -557,8 +572,9 @@ static inline void admhc_writel(const struct admhcd *ahcd,
 
 static inline void admhc_writel_flush(const struct admhcd *ahcd)
 {
 
 static inline void admhc_writel_flush(const struct admhcd *ahcd)
 {
-#if 0  /* TODO: needed? */
-       (void) admhc_readl(ahcd, &ahcd->regs->control);
+#if 0
+       /* TODO: remove? */
+       (void) admhc_readl(ahcd, &ahcd->regs->gencontrol);
 #endif
 }
 
 #endif
 }
 
@@ -633,6 +649,15 @@ static inline u16 admhc_frame_no(const struct admhcd *ahcd)
        return (u16)t;
 }
 
        return (u16)t;
 }
 
+static inline u16 admhc_frame_remain(const struct admhcd *ahcd)
+{
+       u32     t;
+
+       t = admhc_readl(ahcd, &ahcd->regs->fmnumber) >> ADMHC_SFN_FR_SHIFT;
+       t &= ADMHC_SFN_FR_MASK;
+       return (u16)t;
+}
+
 /*-------------------------------------------------------------------------*/
 
 static inline void admhc_disable(struct admhcd *ahcd)
 /*-------------------------------------------------------------------------*/
 
 static inline void admhc_disable(struct admhcd *ahcd)
@@ -640,31 +665,45 @@ static inline void admhc_disable(struct admhcd *ahcd)
        admhcd_to_hcd(ahcd)->state = HC_STATE_HALT;
 }
 
        admhcd_to_hcd(ahcd)->state = HC_STATE_HALT;
 }
 
-#define        FI                      0x2edf          /* 12000 bits per frame (-1) */
-#define        FSLDP(fi)               (0x7fff & ((6 * ((fi) - 210)) / 7))
-#define        FIT                     ADMHC_SFI_FIT
-#define LSTHRESH               0x628           /* lowspeed bit threshold */
+#define        FI              0x2edf          /* 12000 bits per frame (-1) */
+#define        FSLDP(fi)       (0x7fff & ((6 * ((fi) - 1200)) / 7))
+#define        FIT             ADMHC_SFI_FIT
+#define LSTHRESH       0x628           /* lowspeed bit threshold */
 
 static inline void periodic_reinit(struct admhcd *ahcd)
 {
 
 static inline void periodic_reinit(struct admhcd *ahcd)
 {
+#if 0
        u32     fi = ahcd->fminterval & ADMHC_SFI_FI_MASK;
        u32     fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT;
 
        /* TODO: adjust FSLargestDataPacket value too? */
        admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval,
        u32     fi = ahcd->fminterval & ADMHC_SFI_FI_MASK;
        u32     fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT;
 
        /* TODO: adjust FSLargestDataPacket value too? */
        admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval,
-                                               &ahcd->regs->fminterval);
+                                       &ahcd->regs->fminterval);
+#else
+       u32     fit = admhc_readl(ahcd, &ahcd->regs->fminterval) & FIT;
+
+       /* TODO: adjust FSLargestDataPacket value too? */
+       admhc_writel(ahcd, (fit ^ FIT) | ahcd->fminterval,
+                                       &ahcd->regs->fminterval);
+#endif
 }
 
 }
 
-static inline u32 admhc_get_rhdesc(struct admhcd *ahcd)
+static inline u32 admhc_read_rhdesc(struct admhcd *ahcd)
 {
        return admhc_readl(ahcd, &ahcd->regs->rhdesc);
 }
 
 {
        return admhc_readl(ahcd, &ahcd->regs->rhdesc);
 }
 
-static inline u32 admhc_get_portstatus(struct admhcd *ahcd, int port)
+static inline u32 admhc_read_portstatus(struct admhcd *ahcd, int port)
 {
        return admhc_readl(ahcd, &ahcd->regs->portstatus[port]);
 }
 
 {
        return admhc_readl(ahcd, &ahcd->regs->portstatus[port]);
 }
 
+static inline void admhc_write_portstatus(struct admhcd *ahcd, int port,
+               u32 value)
+{
+       admhc_writel(ahcd, value, &ahcd->regs->portstatus[port]);
+}
+
 static inline void roothub_write_status(struct admhcd *ahcd, u32 value)
 {
        /* FIXME: read-only bits must be masked out */
 static inline void roothub_write_status(struct admhcd *ahcd, u32 value)
 {
        /* FIXME: read-only bits must be masked out */
@@ -698,17 +737,26 @@ static inline void admhc_intr_ack(struct admhcd *ahcd, u32 ints)
 
 static inline void admhc_dma_enable(struct admhcd *ahcd)
 {
 
 static inline void admhc_dma_enable(struct admhcd *ahcd)
 {
-       ahcd->host_control = admhc_readl(ahcd, &ahcd->regs->host_control);
-       if (ahcd->host_control & ADMHC_HC_DMAE)
+       u32 t;
+
+       t = admhc_readl(ahcd, &ahcd->regs->host_control);
+       if (t & ADMHC_HC_DMAE)
                return;
 
                return;
 
-       ahcd->host_control |= ADMHC_HC_DMAE;
-       admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control);
+       t |= ADMHC_HC_DMAE;
+       admhc_writel(ahcd, t, &ahcd->regs->host_control);
+       admhc_vdbg(ahcd, "DMA enabled\n");
 }
 
 static inline void admhc_dma_disable(struct admhcd *ahcd)
 {
 }
 
 static inline void admhc_dma_disable(struct admhcd *ahcd)
 {
-       ahcd->host_control = admhc_readl(ahcd, &ahcd->regs->host_control);
-       ahcd->host_control &= ~ADMHC_HC_DMAE;
-       admhc_writel(ahcd, ahcd->host_control, &ahcd->regs->host_control);
+       u32 t;
+
+       t = admhc_readl(ahcd, &ahcd->regs->host_control);
+       if (!(t & ADMHC_HC_DMAE))
+               return;
+
+       t &= ~ADMHC_HC_DMAE;
+       admhc_writel(ahcd, t, &ahcd->regs->host_control);
+       admhc_vdbg(ahcd, "DMA disabled\n");
 }
 }
This page took 0.034956 seconds and 4 git commands to generate.