cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

usb.c (15801B)


      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
     96static DEFINE_SPINLOCK(alchemy_usb_lock);
     97
     98static 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
    123static 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
    163static 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
    204static 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
    235static 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
    265static 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
    293static 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
    316static 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
    330static 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
    346static 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
    360static 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 */
    383static 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
    392static 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
    425static 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	}
    454out:
    455	clk_put(c);
    456}
    457
    458static 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 */
    478int 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}
    507EXPORT_SYMBOL_GPL(alchemy_usb_control);
    508
    509
    510static unsigned long alchemy_usb_pmdata[2];
    511
    512static 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
    529static 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
    549static 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
    563static 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
    583static int alchemy_usb_suspend(void)
    584{
    585	alchemy_usb_pm(1);
    586	return 0;
    587}
    588
    589static void alchemy_usb_resume(void)
    590{
    591	alchemy_usb_pm(0);
    592}
    593
    594static struct syscore_ops alchemy_usb_pm_ops = {
    595	.suspend	= alchemy_usb_suspend,
    596	.resume		= alchemy_usb_resume,
    597};
    598
    599static 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}
    627arch_initcall(alchemy_usb_init);