root/arch/mips/alchemy/common/usb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __au1300_usb_phyctl
  2. __au1300_ohci_control
  3. __au1300_ehci_control
  4. __au1300_udc_control
  5. __au1300_otg_control
  6. au1300_usb_control
  7. au1300_usb_init
  8. __au1200_ohci_control
  9. __au1200_ehci_control
  10. __au1200_udc_control
  11. au1200_usb_control
  12. au1200_usb_init
  13. au1000_usb_init
  14. __au1xx0_ohci_control
  15. au1000_usb_control
  16. alchemy_usb_control
  17. au1000_usb_pm
  18. au1200_usb_pm
  19. au1300_usb_pm
  20. alchemy_usb_pm
  21. alchemy_usb_suspend
  22. alchemy_usb_resume
  23. alchemy_usb_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * USB block power/access management abstraction.
   4  *
   5  * Au1000+: The OHCI block control register is at the far end of the OHCI memory
   6  *          area. Au1550 has OHCI on different base address. No need to handle
   7  *          UDC here.
   8  * Au1200:  one register to control access and clocks to O/EHCI, UDC and OTG
   9  *          as well as the PHY for EHCI and UDC.
  10  *
  11  */
  12 
  13 #include <linux/clk.h>
  14 #include <linux/export.h>
  15 #include <linux/init.h>
  16 #include <linux/io.h>
  17 #include <linux/spinlock.h>
  18 #include <linux/syscore_ops.h>
  19 #include <asm/cpu.h>
  20 #include <asm/mach-au1x00/au1000.h>
  21 
  22 /* control register offsets */
  23 #define AU1000_OHCICFG  0x7fffc
  24 #define AU1550_OHCICFG  0x07ffc
  25 #define AU1200_USBCFG   0x04
  26 
  27 /* Au1000 USB block config bits */
  28 #define USBHEN_RD       (1 << 4)                /* OHCI reset-done indicator */
  29 #define USBHEN_CE       (1 << 3)                /* OHCI block clock enable */
  30 #define USBHEN_E        (1 << 2)                /* OHCI block enable */
  31 #define USBHEN_C        (1 << 1)                /* OHCI block coherency bit */
  32 #define USBHEN_BE       (1 << 0)                /* OHCI Big-Endian */
  33 
  34 /* Au1200 USB config bits */
  35 #define USBCFG_PFEN     (1 << 31)               /* prefetch enable (undoc) */
  36 #define USBCFG_RDCOMB   (1 << 30)               /* read combining (undoc) */
  37 #define USBCFG_UNKNOWN  (5 << 20)               /* unknown, leave this way */
  38 #define USBCFG_SSD      (1 << 23)               /* serial short detect en */
  39 #define USBCFG_PPE      (1 << 19)               /* HS PHY PLL */
  40 #define USBCFG_UCE      (1 << 18)               /* UDC clock enable */
  41 #define USBCFG_ECE      (1 << 17)               /* EHCI clock enable */
  42 #define USBCFG_OCE      (1 << 16)               /* OHCI clock enable */
  43 #define USBCFG_FLA(x)   (((x) & 0x3f) << 8)
  44 #define USBCFG_UCAM     (1 << 7)                /* coherent access (undoc) */
  45 #define USBCFG_GME      (1 << 6)                /* OTG mem access */
  46 #define USBCFG_DBE      (1 << 5)                /* UDC busmaster enable */
  47 #define USBCFG_DME      (1 << 4)                /* UDC mem enable */
  48 #define USBCFG_EBE      (1 << 3)                /* EHCI busmaster enable */
  49 #define USBCFG_EME      (1 << 2)                /* EHCI mem enable */
  50 #define USBCFG_OBE      (1 << 1)                /* OHCI busmaster enable */
  51 #define USBCFG_OME      (1 << 0)                /* OHCI mem enable */
  52 #define USBCFG_INIT_AU1200      (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
  53                                  USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
  54                                  USBCFG_GME | USBCFG_DBE | USBCFG_DME |        \
  55                                  USBCFG_EBE | USBCFG_EME | USBCFG_OBE |        \
  56                                  USBCFG_OME)
  57 
  58 /* Au1300 USB config registers */
  59 #define USB_DWC_CTRL1           0x00
  60 #define USB_DWC_CTRL2           0x04
  61 #define USB_VBUS_TIMER          0x10
  62 #define USB_SBUS_CTRL           0x14
  63 #define USB_MSR_ERR             0x18
  64 #define USB_DWC_CTRL3           0x1C
  65 #define USB_DWC_CTRL4           0x20
  66 #define USB_OTG_STATUS          0x28
  67 #define USB_DWC_CTRL5           0x2C
  68 #define USB_DWC_CTRL6           0x30
  69 #define USB_DWC_CTRL7           0x34
  70 #define USB_PHY_STATUS          0xC0
  71 #define USB_INT_STATUS          0xC4
  72 #define USB_INT_ENABLE          0xC8
  73 
  74 #define USB_DWC_CTRL1_OTGD      0x04 /* set to DISable OTG */
  75 #define USB_DWC_CTRL1_HSTRS     0x02 /* set to ENable EHCI */
  76 #define USB_DWC_CTRL1_DCRS      0x01 /* set to ENable UDC */
  77 
  78 #define USB_DWC_CTRL2_PHY1RS    0x04 /* set to enable PHY1 */
  79 #define USB_DWC_CTRL2_PHY0RS    0x02 /* set to enable PHY0 */
  80 #define USB_DWC_CTRL2_PHYRS     0x01 /* set to enable PHY */
  81 
  82 #define USB_DWC_CTRL3_OHCI1_CKEN        (1 << 19)
  83 #define USB_DWC_CTRL3_OHCI0_CKEN        (1 << 18)
  84 #define USB_DWC_CTRL3_EHCI0_CKEN        (1 << 17)
  85 #define USB_DWC_CTRL3_OTG0_CKEN         (1 << 16)
  86 
  87 #define USB_SBUS_CTRL_SBCA              0x04 /* coherent access */
  88 
  89 #define USB_INTEN_FORCE                 0x20
  90 #define USB_INTEN_PHY                   0x10
  91 #define USB_INTEN_UDC                   0x08
  92 #define USB_INTEN_EHCI                  0x04
  93 #define USB_INTEN_OHCI1                 0x02
  94 #define USB_INTEN_OHCI0                 0x01
  95 
  96 static DEFINE_SPINLOCK(alchemy_usb_lock);
  97 
  98 static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
  99 {
 100         unsigned long r, s;
 101 
 102         r = __raw_readl(base + USB_DWC_CTRL2);
 103         s = __raw_readl(base + USB_DWC_CTRL3);
 104 
 105         s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
 106                 USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
 107 
 108         if (enable) {
 109                 /* simply enable all PHYs */
 110                 r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
 111                      USB_DWC_CTRL2_PHYRS;
 112                 __raw_writel(r, base + USB_DWC_CTRL2);
 113                 wmb();
 114         } else if (!s) {
 115                 /* no USB block active, do disable all PHYs */
 116                 r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
 117                        USB_DWC_CTRL2_PHYRS);
 118                 __raw_writel(r, base + USB_DWC_CTRL2);
 119                 wmb();
 120         }
 121 }
 122 
 123 static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
 124 {
 125         unsigned long r;
 126 
 127         if (enable) {
 128                 __raw_writel(1, base + USB_DWC_CTRL7);  /* start OHCI clock */
 129                 wmb();
 130 
 131                 r = __raw_readl(base + USB_DWC_CTRL3);  /* enable OHCI block */
 132                 r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
 133                                : USB_DWC_CTRL3_OHCI1_CKEN;
 134                 __raw_writel(r, base + USB_DWC_CTRL3);
 135                 wmb();
 136 
 137                 __au1300_usb_phyctl(base, enable);      /* power up the PHYs */
 138 
 139                 r = __raw_readl(base + USB_INT_ENABLE);
 140                 r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
 141                 __raw_writel(r, base + USB_INT_ENABLE);
 142                 wmb();
 143 
 144                 /* reset the OHCI start clock bit */
 145                 __raw_writel(0, base + USB_DWC_CTRL7);
 146                 wmb();
 147         } else {
 148                 r = __raw_readl(base + USB_INT_ENABLE);
 149                 r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
 150                 __raw_writel(r, base + USB_INT_ENABLE);
 151                 wmb();
 152 
 153                 r = __raw_readl(base + USB_DWC_CTRL3);
 154                 r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
 155                                  : USB_DWC_CTRL3_OHCI1_CKEN);
 156                 __raw_writel(r, base + USB_DWC_CTRL3);
 157                 wmb();
 158 
 159                 __au1300_usb_phyctl(base, enable);
 160         }
 161 }
 162 
 163 static inline void __au1300_ehci_control(void __iomem *base, int enable)
 164 {
 165         unsigned long r;
 166 
 167         if (enable) {
 168                 r = __raw_readl(base + USB_DWC_CTRL3);
 169                 r |= USB_DWC_CTRL3_EHCI0_CKEN;
 170                 __raw_writel(r, base + USB_DWC_CTRL3);
 171                 wmb();
 172 
 173                 r = __raw_readl(base + USB_DWC_CTRL1);
 174                 r |= USB_DWC_CTRL1_HSTRS;
 175                 __raw_writel(r, base + USB_DWC_CTRL1);
 176                 wmb();
 177 
 178                 __au1300_usb_phyctl(base, enable);
 179 
 180                 r = __raw_readl(base + USB_INT_ENABLE);
 181                 r |= USB_INTEN_EHCI;
 182                 __raw_writel(r, base + USB_INT_ENABLE);
 183                 wmb();
 184         } else {
 185                 r = __raw_readl(base + USB_INT_ENABLE);
 186                 r &= ~USB_INTEN_EHCI;
 187                 __raw_writel(r, base + USB_INT_ENABLE);
 188                 wmb();
 189 
 190                 r = __raw_readl(base + USB_DWC_CTRL1);
 191                 r &= ~USB_DWC_CTRL1_HSTRS;
 192                 __raw_writel(r, base + USB_DWC_CTRL1);
 193                 wmb();
 194 
 195                 r = __raw_readl(base + USB_DWC_CTRL3);
 196                 r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
 197                 __raw_writel(r, base + USB_DWC_CTRL3);
 198                 wmb();
 199 
 200                 __au1300_usb_phyctl(base, enable);
 201         }
 202 }
 203 
 204 static inline void __au1300_udc_control(void __iomem *base, int enable)
 205 {
 206         unsigned long r;
 207 
 208         if (enable) {
 209                 r = __raw_readl(base + USB_DWC_CTRL1);
 210                 r |= USB_DWC_CTRL1_DCRS;
 211                 __raw_writel(r, base + USB_DWC_CTRL1);
 212                 wmb();
 213 
 214                 __au1300_usb_phyctl(base, enable);
 215 
 216                 r = __raw_readl(base + USB_INT_ENABLE);
 217                 r |= USB_INTEN_UDC;
 218                 __raw_writel(r, base + USB_INT_ENABLE);
 219                 wmb();
 220         } else {
 221                 r = __raw_readl(base + USB_INT_ENABLE);
 222                 r &= ~USB_INTEN_UDC;
 223                 __raw_writel(r, base + USB_INT_ENABLE);
 224                 wmb();
 225 
 226                 r = __raw_readl(base + USB_DWC_CTRL1);
 227                 r &= ~USB_DWC_CTRL1_DCRS;
 228                 __raw_writel(r, base + USB_DWC_CTRL1);
 229                 wmb();
 230 
 231                 __au1300_usb_phyctl(base, enable);
 232         }
 233 }
 234 
 235 static inline void __au1300_otg_control(void __iomem *base, int enable)
 236 {
 237         unsigned long r;
 238         if (enable) {
 239                 r = __raw_readl(base + USB_DWC_CTRL3);
 240                 r |= USB_DWC_CTRL3_OTG0_CKEN;
 241                 __raw_writel(r, base + USB_DWC_CTRL3);
 242                 wmb();
 243 
 244                 r = __raw_readl(base + USB_DWC_CTRL1);
 245                 r &= ~USB_DWC_CTRL1_OTGD;
 246                 __raw_writel(r, base + USB_DWC_CTRL1);
 247                 wmb();
 248 
 249                 __au1300_usb_phyctl(base, enable);
 250         } else {
 251                 r = __raw_readl(base + USB_DWC_CTRL1);
 252                 r |= USB_DWC_CTRL1_OTGD;
 253                 __raw_writel(r, base + USB_DWC_CTRL1);
 254                 wmb();
 255 
 256                 r = __raw_readl(base + USB_DWC_CTRL3);
 257                 r &= ~USB_DWC_CTRL3_OTG0_CKEN;
 258                 __raw_writel(r, base + USB_DWC_CTRL3);
 259                 wmb();
 260 
 261                 __au1300_usb_phyctl(base, enable);
 262         }
 263 }
 264 
 265 static inline int au1300_usb_control(int block, int enable)
 266 {
 267         void __iomem *base =
 268                 (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
 269         int ret = 0;
 270 
 271         switch (block) {
 272         case ALCHEMY_USB_OHCI0:
 273                 __au1300_ohci_control(base, enable, 0);
 274                 break;
 275         case ALCHEMY_USB_OHCI1:
 276                 __au1300_ohci_control(base, enable, 1);
 277                 break;
 278         case ALCHEMY_USB_EHCI0:
 279                 __au1300_ehci_control(base, enable);
 280                 break;
 281         case ALCHEMY_USB_UDC0:
 282                 __au1300_udc_control(base, enable);
 283                 break;
 284         case ALCHEMY_USB_OTG0:
 285                 __au1300_otg_control(base, enable);
 286                 break;
 287         default:
 288                 ret = -ENODEV;
 289         }
 290         return ret;
 291 }
 292 
 293 static inline void au1300_usb_init(void)
 294 {
 295         void __iomem *base =
 296                 (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
 297 
 298         /* set some sane defaults.  Note: we don't fiddle with DWC_CTRL4
 299          * here at all: Port 2 routing (EHCI or UDC) must be set either
 300          * by boot firmware or platform init code; I can't autodetect
 301          * a sane setting.
 302          */
 303         __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
 304         wmb();
 305         __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
 306         wmb();
 307         __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
 308         wmb();
 309         __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
 310         wmb();
 311         /* set coherent access bit */
 312         __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
 313         wmb();
 314 }
 315 
 316 static inline void __au1200_ohci_control(void __iomem *base, int enable)
 317 {
 318         unsigned long r = __raw_readl(base + AU1200_USBCFG);
 319         if (enable) {
 320                 __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
 321                 wmb();
 322                 udelay(2000);
 323         } else {
 324                 __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
 325                 wmb();
 326                 udelay(1000);
 327         }
 328 }
 329 
 330 static inline void __au1200_ehci_control(void __iomem *base, int enable)
 331 {
 332         unsigned long r = __raw_readl(base + AU1200_USBCFG);
 333         if (enable) {
 334                 __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
 335                 wmb();
 336                 udelay(1000);
 337         } else {
 338                 if (!(r & USBCFG_UCE))          /* UDC also off? */
 339                         r &= ~USBCFG_PPE;       /* yes: disable HS PHY PLL */
 340                 __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
 341                 wmb();
 342                 udelay(1000);
 343         }
 344 }
 345 
 346 static inline void __au1200_udc_control(void __iomem *base, int enable)
 347 {
 348         unsigned long r = __raw_readl(base + AU1200_USBCFG);
 349         if (enable) {
 350                 __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
 351                 wmb();
 352         } else {
 353                 if (!(r & USBCFG_ECE))          /* EHCI also off? */
 354                         r &= ~USBCFG_PPE;       /* yes: disable HS PHY PLL */
 355                 __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
 356                 wmb();
 357         }
 358 }
 359 
 360 static inline int au1200_usb_control(int block, int enable)
 361 {
 362         void __iomem *base =
 363                         (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
 364 
 365         switch (block) {
 366         case ALCHEMY_USB_OHCI0:
 367                 __au1200_ohci_control(base, enable);
 368                 break;
 369         case ALCHEMY_USB_UDC0:
 370                 __au1200_udc_control(base, enable);
 371                 break;
 372         case ALCHEMY_USB_EHCI0:
 373                 __au1200_ehci_control(base, enable);
 374                 break;
 375         default:
 376                 return -ENODEV;
 377         }
 378         return 0;
 379 }
 380 
 381 
 382 /* initialize USB block(s) to a known working state */
 383 static inline void au1200_usb_init(void)
 384 {
 385         void __iomem *base =
 386                         (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
 387         __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
 388         wmb();
 389         udelay(1000);
 390 }
 391 
 392 static inline int au1000_usb_init(unsigned long rb, int reg)
 393 {
 394         void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
 395         unsigned long r = __raw_readl(base);
 396         struct clk *c;
 397 
 398         /* 48MHz check. Don't init if no one can provide it */
 399         c = clk_get(NULL, "usbh_clk");
 400         if (IS_ERR(c))
 401                 return -ENODEV;
 402         if (clk_round_rate(c, 48000000) != 48000000) {
 403                 clk_put(c);
 404                 return -ENODEV;
 405         }
 406         if (clk_set_rate(c, 48000000)) {
 407                 clk_put(c);
 408                 return -ENODEV;
 409         }
 410         clk_put(c);
 411 
 412 #if defined(__BIG_ENDIAN)
 413         r |= USBHEN_BE;
 414 #endif
 415         r |= USBHEN_C;
 416 
 417         __raw_writel(r, base);
 418         wmb();
 419         udelay(1000);
 420 
 421         return 0;
 422 }
 423 
 424 
 425 static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
 426 {
 427         void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
 428         unsigned long r = __raw_readl(base + creg);
 429         struct clk *c = clk_get(NULL, "usbh_clk");
 430 
 431         if (IS_ERR(c))
 432                 return;
 433 
 434         if (enable) {
 435                 if (clk_prepare_enable(c))
 436                         goto out;
 437 
 438                 __raw_writel(r | USBHEN_CE, base + creg);
 439                 wmb();
 440                 udelay(1000);
 441                 __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
 442                 wmb();
 443                 udelay(1000);
 444 
 445                 /* wait for reset complete (read reg twice: au1500 erratum) */
 446                 while (__raw_readl(base + creg),
 447                         !(__raw_readl(base + creg) & USBHEN_RD))
 448                         udelay(1000);
 449         } else {
 450                 __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
 451                 wmb();
 452                 clk_disable_unprepare(c);
 453         }
 454 out:
 455         clk_put(c);
 456 }
 457 
 458 static inline int au1000_usb_control(int block, int enable, unsigned long rb,
 459                                      int creg)
 460 {
 461         int ret = 0;
 462 
 463         switch (block) {
 464         case ALCHEMY_USB_OHCI0:
 465                 __au1xx0_ohci_control(enable, rb, creg);
 466                 break;
 467         default:
 468                 ret = -ENODEV;
 469         }
 470         return ret;
 471 }
 472 
 473 /*
 474  * alchemy_usb_control - control Alchemy on-chip USB blocks
 475  * @block:      USB block to target
 476  * @enable:     set 1 to enable a block, 0 to disable
 477  */
 478 int alchemy_usb_control(int block, int enable)
 479 {
 480         unsigned long flags;
 481         int ret;
 482 
 483         spin_lock_irqsave(&alchemy_usb_lock, flags);
 484         switch (alchemy_get_cputype()) {
 485         case ALCHEMY_CPU_AU1000:
 486         case ALCHEMY_CPU_AU1500:
 487         case ALCHEMY_CPU_AU1100:
 488                 ret = au1000_usb_control(block, enable,
 489                         AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
 490                 break;
 491         case ALCHEMY_CPU_AU1550:
 492                 ret = au1000_usb_control(block, enable,
 493                         AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
 494                 break;
 495         case ALCHEMY_CPU_AU1200:
 496                 ret = au1200_usb_control(block, enable);
 497                 break;
 498         case ALCHEMY_CPU_AU1300:
 499                 ret = au1300_usb_control(block, enable);
 500                 break;
 501         default:
 502                 ret = -ENODEV;
 503         }
 504         spin_unlock_irqrestore(&alchemy_usb_lock, flags);
 505         return ret;
 506 }
 507 EXPORT_SYMBOL_GPL(alchemy_usb_control);
 508 
 509 
 510 static unsigned long alchemy_usb_pmdata[2];
 511 
 512 static void au1000_usb_pm(unsigned long br, int creg, int susp)
 513 {
 514         void __iomem *base = (void __iomem *)KSEG1ADDR(br);
 515 
 516         if (susp) {
 517                 alchemy_usb_pmdata[0] = __raw_readl(base + creg);
 518                 /* There appears to be some undocumented reset register.... */
 519                 __raw_writel(0, base + 0x04);
 520                 wmb();
 521                 __raw_writel(0, base + creg);
 522                 wmb();
 523         } else {
 524                 __raw_writel(alchemy_usb_pmdata[0], base + creg);
 525                 wmb();
 526         }
 527 }
 528 
 529 static void au1200_usb_pm(int susp)
 530 {
 531         void __iomem *base =
 532                         (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
 533         if (susp) {
 534                 /* save OTG_CAP/MUX registers which indicate port routing */
 535                 /* FIXME: write an OTG driver to do that */
 536                 alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
 537                 alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
 538         } else {
 539                 /* restore access to all MMIO areas */
 540                 au1200_usb_init();
 541 
 542                 /* restore OTG_CAP/MUX registers */
 543                 __raw_writel(alchemy_usb_pmdata[0], base + 0x00);
 544                 __raw_writel(alchemy_usb_pmdata[1], base + 0x04);
 545                 wmb();
 546         }
 547 }
 548 
 549 static void au1300_usb_pm(int susp)
 550 {
 551         void __iomem *base =
 552                         (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
 553         /* remember Port2 routing */
 554         if (susp) {
 555                 alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
 556         } else {
 557                 au1300_usb_init();
 558                 __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
 559                 wmb();
 560         }
 561 }
 562 
 563 static void alchemy_usb_pm(int susp)
 564 {
 565         switch (alchemy_get_cputype()) {
 566         case ALCHEMY_CPU_AU1000:
 567         case ALCHEMY_CPU_AU1500:
 568         case ALCHEMY_CPU_AU1100:
 569                 au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
 570                 break;
 571         case ALCHEMY_CPU_AU1550:
 572                 au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
 573                 break;
 574         case ALCHEMY_CPU_AU1200:
 575                 au1200_usb_pm(susp);
 576                 break;
 577         case ALCHEMY_CPU_AU1300:
 578                 au1300_usb_pm(susp);
 579                 break;
 580         }
 581 }
 582 
 583 static int alchemy_usb_suspend(void)
 584 {
 585         alchemy_usb_pm(1);
 586         return 0;
 587 }
 588 
 589 static void alchemy_usb_resume(void)
 590 {
 591         alchemy_usb_pm(0);
 592 }
 593 
 594 static struct syscore_ops alchemy_usb_pm_ops = {
 595         .suspend        = alchemy_usb_suspend,
 596         .resume         = alchemy_usb_resume,
 597 };
 598 
 599 static int __init alchemy_usb_init(void)
 600 {
 601         int ret = 0;
 602 
 603         switch (alchemy_get_cputype()) {
 604         case ALCHEMY_CPU_AU1000:
 605         case ALCHEMY_CPU_AU1500:
 606         case ALCHEMY_CPU_AU1100:
 607                 ret = au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR,
 608                                       AU1000_OHCICFG);
 609                 break;
 610         case ALCHEMY_CPU_AU1550:
 611                 ret = au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR,
 612                                       AU1550_OHCICFG);
 613                 break;
 614         case ALCHEMY_CPU_AU1200:
 615                 au1200_usb_init();
 616                 break;
 617         case ALCHEMY_CPU_AU1300:
 618                 au1300_usb_init();
 619                 break;
 620         }
 621 
 622         if (!ret)
 623                 register_syscore_ops(&alchemy_usb_pm_ops);
 624 
 625         return ret;
 626 }
 627 arch_initcall(alchemy_usb_init);

/* [<][>][^][v][top][bottom][index][help] */