Merge git://git.infradead.org/battery-2.6
[pandora-kernel.git] / arch / arm / mach-orion5x / common.c
1 /*
2  * arch/arm/mach-orion5x/common.c
3  *
4  * Core functions for Marvell Orion 5x SoCs
5  *
6  * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
7  *
8  * This file is licensed under the terms of the GNU General Public
9  * License version 2.  This program is licensed "as is" without any
10  * warranty of any kind, whether express or implied.
11  */
12
13 #include <linux/kernel.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/serial_8250.h>
17 #include <linux/mbus.h>
18 #include <linux/mv643xx_eth.h>
19 #include <linux/mv643xx_i2c.h>
20 #include <linux/ata_platform.h>
21 #include <linux/spi/orion_spi.h>
22 #include <net/dsa.h>
23 #include <asm/page.h>
24 #include <asm/setup.h>
25 #include <asm/timex.h>
26 #include <asm/mach/arch.h>
27 #include <asm/mach/map.h>
28 #include <asm/mach/time.h>
29 #include <mach/hardware.h>
30 #include <mach/orion5x.h>
31 #include <plat/ehci-orion.h>
32 #include <plat/mv_xor.h>
33 #include <plat/orion_nand.h>
34 #include <plat/orion_wdt.h>
35 #include <plat/time.h>
36 #include "common.h"
37
38 /*****************************************************************************
39  * I/O Address Mapping
40  ****************************************************************************/
41 static struct map_desc orion5x_io_desc[] __initdata = {
42         {
43                 .virtual        = ORION5X_REGS_VIRT_BASE,
44                 .pfn            = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
45                 .length         = ORION5X_REGS_SIZE,
46                 .type           = MT_DEVICE,
47         }, {
48                 .virtual        = ORION5X_PCIE_IO_VIRT_BASE,
49                 .pfn            = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
50                 .length         = ORION5X_PCIE_IO_SIZE,
51                 .type           = MT_DEVICE,
52         }, {
53                 .virtual        = ORION5X_PCI_IO_VIRT_BASE,
54                 .pfn            = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
55                 .length         = ORION5X_PCI_IO_SIZE,
56                 .type           = MT_DEVICE,
57         }, {
58                 .virtual        = ORION5X_PCIE_WA_VIRT_BASE,
59                 .pfn            = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
60                 .length         = ORION5X_PCIE_WA_SIZE,
61                 .type           = MT_DEVICE,
62         },
63 };
64
65 void __init orion5x_map_io(void)
66 {
67         iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
68 }
69
70
71 /*****************************************************************************
72  * EHCI
73  ****************************************************************************/
74 static struct orion_ehci_data orion5x_ehci_data = {
75         .dram           = &orion5x_mbus_dram_info,
76         .phy_version    = EHCI_PHY_ORION,
77 };
78
79 static u64 ehci_dmamask = 0xffffffffUL;
80
81
82 /*****************************************************************************
83  * EHCI0
84  ****************************************************************************/
85 static struct resource orion5x_ehci0_resources[] = {
86         {
87                 .start  = ORION5X_USB0_PHYS_BASE,
88                 .end    = ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
89                 .flags  = IORESOURCE_MEM,
90         }, {
91                 .start  = IRQ_ORION5X_USB0_CTRL,
92                 .end    = IRQ_ORION5X_USB0_CTRL,
93                 .flags  = IORESOURCE_IRQ,
94         },
95 };
96
97 static struct platform_device orion5x_ehci0 = {
98         .name           = "orion-ehci",
99         .id             = 0,
100         .dev            = {
101                 .dma_mask               = &ehci_dmamask,
102                 .coherent_dma_mask      = 0xffffffff,
103                 .platform_data          = &orion5x_ehci_data,
104         },
105         .resource       = orion5x_ehci0_resources,
106         .num_resources  = ARRAY_SIZE(orion5x_ehci0_resources),
107 };
108
109 void __init orion5x_ehci0_init(void)
110 {
111         platform_device_register(&orion5x_ehci0);
112 }
113
114
115 /*****************************************************************************
116  * EHCI1
117  ****************************************************************************/
118 static struct resource orion5x_ehci1_resources[] = {
119         {
120                 .start  = ORION5X_USB1_PHYS_BASE,
121                 .end    = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
122                 .flags  = IORESOURCE_MEM,
123         }, {
124                 .start  = IRQ_ORION5X_USB1_CTRL,
125                 .end    = IRQ_ORION5X_USB1_CTRL,
126                 .flags  = IORESOURCE_IRQ,
127         },
128 };
129
130 static struct platform_device orion5x_ehci1 = {
131         .name           = "orion-ehci",
132         .id             = 1,
133         .dev            = {
134                 .dma_mask               = &ehci_dmamask,
135                 .coherent_dma_mask      = 0xffffffff,
136                 .platform_data          = &orion5x_ehci_data,
137         },
138         .resource       = orion5x_ehci1_resources,
139         .num_resources  = ARRAY_SIZE(orion5x_ehci1_resources),
140 };
141
142 void __init orion5x_ehci1_init(void)
143 {
144         platform_device_register(&orion5x_ehci1);
145 }
146
147
148 /*****************************************************************************
149  * GigE
150  ****************************************************************************/
151 struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
152         .dram           = &orion5x_mbus_dram_info,
153 };
154
155 static struct resource orion5x_eth_shared_resources[] = {
156         {
157                 .start  = ORION5X_ETH_PHYS_BASE + 0x2000,
158                 .end    = ORION5X_ETH_PHYS_BASE + 0x3fff,
159                 .flags  = IORESOURCE_MEM,
160         }, {
161                 .start  = IRQ_ORION5X_ETH_ERR,
162                 .end    = IRQ_ORION5X_ETH_ERR,
163                 .flags  = IORESOURCE_IRQ,
164         },
165 };
166
167 static struct platform_device orion5x_eth_shared = {
168         .name           = MV643XX_ETH_SHARED_NAME,
169         .id             = 0,
170         .dev            = {
171                 .platform_data  = &orion5x_eth_shared_data,
172         },
173         .num_resources  = ARRAY_SIZE(orion5x_eth_shared_resources),
174         .resource       = orion5x_eth_shared_resources,
175 };
176
177 static struct resource orion5x_eth_resources[] = {
178         {
179                 .name   = "eth irq",
180                 .start  = IRQ_ORION5X_ETH_SUM,
181                 .end    = IRQ_ORION5X_ETH_SUM,
182                 .flags  = IORESOURCE_IRQ,
183         },
184 };
185
186 static struct platform_device orion5x_eth = {
187         .name           = MV643XX_ETH_NAME,
188         .id             = 0,
189         .num_resources  = 1,
190         .resource       = orion5x_eth_resources,
191         .dev            = {
192                 .coherent_dma_mask      = 0xffffffff,
193         },
194 };
195
196 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
197 {
198         eth_data->shared = &orion5x_eth_shared;
199         orion5x_eth.dev.platform_data = eth_data;
200
201         platform_device_register(&orion5x_eth_shared);
202         platform_device_register(&orion5x_eth);
203 }
204
205
206 /*****************************************************************************
207  * Ethernet switch
208  ****************************************************************************/
209 static struct resource orion5x_switch_resources[] = {
210         {
211                 .start  = 0,
212                 .end    = 0,
213                 .flags  = IORESOURCE_IRQ,
214         },
215 };
216
217 static struct platform_device orion5x_switch_device = {
218         .name           = "dsa",
219         .id             = 0,
220         .num_resources  = 0,
221         .resource       = orion5x_switch_resources,
222 };
223
224 void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
225 {
226         int i;
227
228         if (irq != NO_IRQ) {
229                 orion5x_switch_resources[0].start = irq;
230                 orion5x_switch_resources[0].end = irq;
231                 orion5x_switch_device.num_resources = 1;
232         }
233
234         d->netdev = &orion5x_eth.dev;
235         for (i = 0; i < d->nr_chips; i++)
236                 d->chip[i].mii_bus = &orion5x_eth_shared.dev;
237         orion5x_switch_device.dev.platform_data = d;
238
239         platform_device_register(&orion5x_switch_device);
240 }
241
242
243 /*****************************************************************************
244  * I2C
245  ****************************************************************************/
246 static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
247         .freq_m         = 8, /* assumes 166 MHz TCLK */
248         .freq_n         = 3,
249         .timeout        = 1000, /* Default timeout of 1 second */
250 };
251
252 static struct resource orion5x_i2c_resources[] = {
253         {
254                 .start  = I2C_PHYS_BASE,
255                 .end    = I2C_PHYS_BASE + 0x1f,
256                 .flags  = IORESOURCE_MEM,
257         }, {
258                 .start  = IRQ_ORION5X_I2C,
259                 .end    = IRQ_ORION5X_I2C,
260                 .flags  = IORESOURCE_IRQ,
261         },
262 };
263
264 static struct platform_device orion5x_i2c = {
265         .name           = MV64XXX_I2C_CTLR_NAME,
266         .id             = 0,
267         .num_resources  = ARRAY_SIZE(orion5x_i2c_resources),
268         .resource       = orion5x_i2c_resources,
269         .dev            = {
270                 .platform_data  = &orion5x_i2c_pdata,
271         },
272 };
273
274 void __init orion5x_i2c_init(void)
275 {
276         platform_device_register(&orion5x_i2c);
277 }
278
279
280 /*****************************************************************************
281  * SATA
282  ****************************************************************************/
283 static struct resource orion5x_sata_resources[] = {
284         {
285                 .name   = "sata base",
286                 .start  = ORION5X_SATA_PHYS_BASE,
287                 .end    = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
288                 .flags  = IORESOURCE_MEM,
289         }, {
290                 .name   = "sata irq",
291                 .start  = IRQ_ORION5X_SATA,
292                 .end    = IRQ_ORION5X_SATA,
293                 .flags  = IORESOURCE_IRQ,
294         },
295 };
296
297 static struct platform_device orion5x_sata = {
298         .name           = "sata_mv",
299         .id             = 0,
300         .dev            = {
301                 .coherent_dma_mask      = 0xffffffff,
302         },
303         .num_resources  = ARRAY_SIZE(orion5x_sata_resources),
304         .resource       = orion5x_sata_resources,
305 };
306
307 void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
308 {
309         sata_data->dram = &orion5x_mbus_dram_info;
310         orion5x_sata.dev.platform_data = sata_data;
311         platform_device_register(&orion5x_sata);
312 }
313
314
315 /*****************************************************************************
316  * SPI
317  ****************************************************************************/
318 static struct orion_spi_info orion5x_spi_plat_data = {
319         .tclk                   = 0,
320         .enable_clock_fix       = 1,
321 };
322
323 static struct resource orion5x_spi_resources[] = {
324         {
325                 .name   = "spi base",
326                 .start  = SPI_PHYS_BASE,
327                 .end    = SPI_PHYS_BASE + 0x1f,
328                 .flags  = IORESOURCE_MEM,
329         },
330 };
331
332 static struct platform_device orion5x_spi = {
333         .name           = "orion_spi",
334         .id             = 0,
335         .dev            = {
336                 .platform_data  = &orion5x_spi_plat_data,
337         },
338         .num_resources  = ARRAY_SIZE(orion5x_spi_resources),
339         .resource       = orion5x_spi_resources,
340 };
341
342 void __init orion5x_spi_init()
343 {
344         platform_device_register(&orion5x_spi);
345 }
346
347
348 /*****************************************************************************
349  * UART0
350  ****************************************************************************/
351 static struct plat_serial8250_port orion5x_uart0_data[] = {
352         {
353                 .mapbase        = UART0_PHYS_BASE,
354                 .membase        = (char *)UART0_VIRT_BASE,
355                 .irq            = IRQ_ORION5X_UART0,
356                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
357                 .iotype         = UPIO_MEM,
358                 .regshift       = 2,
359                 .uartclk        = 0,
360         }, {
361         },
362 };
363
364 static struct resource orion5x_uart0_resources[] = {
365         {
366                 .start          = UART0_PHYS_BASE,
367                 .end            = UART0_PHYS_BASE + 0xff,
368                 .flags          = IORESOURCE_MEM,
369         }, {
370                 .start          = IRQ_ORION5X_UART0,
371                 .end            = IRQ_ORION5X_UART0,
372                 .flags          = IORESOURCE_IRQ,
373         },
374 };
375
376 static struct platform_device orion5x_uart0 = {
377         .name                   = "serial8250",
378         .id                     = PLAT8250_DEV_PLATFORM,
379         .dev                    = {
380                 .platform_data  = orion5x_uart0_data,
381         },
382         .resource               = orion5x_uart0_resources,
383         .num_resources          = ARRAY_SIZE(orion5x_uart0_resources),
384 };
385
386 void __init orion5x_uart0_init(void)
387 {
388         platform_device_register(&orion5x_uart0);
389 }
390
391
392 /*****************************************************************************
393  * UART1
394  ****************************************************************************/
395 static struct plat_serial8250_port orion5x_uart1_data[] = {
396         {
397                 .mapbase        = UART1_PHYS_BASE,
398                 .membase        = (char *)UART1_VIRT_BASE,
399                 .irq            = IRQ_ORION5X_UART1,
400                 .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
401                 .iotype         = UPIO_MEM,
402                 .regshift       = 2,
403                 .uartclk        = 0,
404         }, {
405         },
406 };
407
408 static struct resource orion5x_uart1_resources[] = {
409         {
410                 .start          = UART1_PHYS_BASE,
411                 .end            = UART1_PHYS_BASE + 0xff,
412                 .flags          = IORESOURCE_MEM,
413         }, {
414                 .start          = IRQ_ORION5X_UART1,
415                 .end            = IRQ_ORION5X_UART1,
416                 .flags          = IORESOURCE_IRQ,
417         },
418 };
419
420 static struct platform_device orion5x_uart1 = {
421         .name                   = "serial8250",
422         .id                     = PLAT8250_DEV_PLATFORM1,
423         .dev                    = {
424                 .platform_data  = orion5x_uart1_data,
425         },
426         .resource               = orion5x_uart1_resources,
427         .num_resources          = ARRAY_SIZE(orion5x_uart1_resources),
428 };
429
430 void __init orion5x_uart1_init(void)
431 {
432         platform_device_register(&orion5x_uart1);
433 }
434
435
436 /*****************************************************************************
437  * XOR engine
438  ****************************************************************************/
439 struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
440         .dram           = &orion5x_mbus_dram_info,
441 };
442
443 static struct resource orion5x_xor_shared_resources[] = {
444         {
445                 .name   = "xor low",
446                 .start  = ORION5X_XOR_PHYS_BASE,
447                 .end    = ORION5X_XOR_PHYS_BASE + 0xff,
448                 .flags  = IORESOURCE_MEM,
449         }, {
450                 .name   = "xor high",
451                 .start  = ORION5X_XOR_PHYS_BASE + 0x200,
452                 .end    = ORION5X_XOR_PHYS_BASE + 0x2ff,
453                 .flags  = IORESOURCE_MEM,
454         },
455 };
456
457 static struct platform_device orion5x_xor_shared = {
458         .name           = MV_XOR_SHARED_NAME,
459         .id             = 0,
460         .dev            = {
461                 .platform_data  = &orion5x_xor_shared_data,
462         },
463         .num_resources  = ARRAY_SIZE(orion5x_xor_shared_resources),
464         .resource       = orion5x_xor_shared_resources,
465 };
466
467 static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
468
469 static struct resource orion5x_xor0_resources[] = {
470         [0] = {
471                 .start  = IRQ_ORION5X_XOR0,
472                 .end    = IRQ_ORION5X_XOR0,
473                 .flags  = IORESOURCE_IRQ,
474         },
475 };
476
477 static struct mv_xor_platform_data orion5x_xor0_data = {
478         .shared         = &orion5x_xor_shared,
479         .hw_id          = 0,
480         .pool_size      = PAGE_SIZE,
481 };
482
483 static struct platform_device orion5x_xor0_channel = {
484         .name           = MV_XOR_NAME,
485         .id             = 0,
486         .num_resources  = ARRAY_SIZE(orion5x_xor0_resources),
487         .resource       = orion5x_xor0_resources,
488         .dev            = {
489                 .dma_mask               = &orion5x_xor_dmamask,
490                 .coherent_dma_mask      = DMA_BIT_MASK(64),
491                 .platform_data          = (void *)&orion5x_xor0_data,
492         },
493 };
494
495 static struct resource orion5x_xor1_resources[] = {
496         [0] = {
497                 .start  = IRQ_ORION5X_XOR1,
498                 .end    = IRQ_ORION5X_XOR1,
499                 .flags  = IORESOURCE_IRQ,
500         },
501 };
502
503 static struct mv_xor_platform_data orion5x_xor1_data = {
504         .shared         = &orion5x_xor_shared,
505         .hw_id          = 1,
506         .pool_size      = PAGE_SIZE,
507 };
508
509 static struct platform_device orion5x_xor1_channel = {
510         .name           = MV_XOR_NAME,
511         .id             = 1,
512         .num_resources  = ARRAY_SIZE(orion5x_xor1_resources),
513         .resource       = orion5x_xor1_resources,
514         .dev            = {
515                 .dma_mask               = &orion5x_xor_dmamask,
516                 .coherent_dma_mask      = DMA_BIT_MASK(64),
517                 .platform_data          = (void *)&orion5x_xor1_data,
518         },
519 };
520
521 void __init orion5x_xor_init(void)
522 {
523         platform_device_register(&orion5x_xor_shared);
524
525         /*
526          * two engines can't do memset simultaneously, this limitation
527          * satisfied by removing memset support from one of the engines.
528          */
529         dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
530         dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
531         platform_device_register(&orion5x_xor0_channel);
532
533         dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
534         dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
535         dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
536         platform_device_register(&orion5x_xor1_channel);
537 }
538
539 static struct resource orion5x_crypto_res[] = {
540         {
541                 .name   = "regs",
542                 .start  = ORION5X_CRYPTO_PHYS_BASE,
543                 .end    = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
544                 .flags  = IORESOURCE_MEM,
545         }, {
546                 .name   = "sram",
547                 .start  = ORION5X_SRAM_PHYS_BASE,
548                 .end    = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
549                 .flags  = IORESOURCE_MEM,
550         }, {
551                 .name   = "crypto interrupt",
552                 .start  = IRQ_ORION5X_CESA,
553                 .end    = IRQ_ORION5X_CESA,
554                 .flags  = IORESOURCE_IRQ,
555         },
556 };
557
558 static struct platform_device orion5x_crypto_device = {
559         .name           = "mv_crypto",
560         .id             = -1,
561         .num_resources  = ARRAY_SIZE(orion5x_crypto_res),
562         .resource       = orion5x_crypto_res,
563 };
564
565 static int __init orion5x_crypto_init(void)
566 {
567         int ret;
568
569         ret = orion5x_setup_sram_win();
570         if (ret)
571                 return ret;
572
573         return platform_device_register(&orion5x_crypto_device);
574 }
575
576 /*****************************************************************************
577  * Watchdog
578  ****************************************************************************/
579 static struct orion_wdt_platform_data orion5x_wdt_data = {
580         .tclk                   = 0,
581 };
582
583 static struct platform_device orion5x_wdt_device = {
584         .name           = "orion_wdt",
585         .id             = -1,
586         .dev            = {
587                 .platform_data  = &orion5x_wdt_data,
588         },
589         .num_resources  = 0,
590 };
591
592 void __init orion5x_wdt_init(void)
593 {
594         orion5x_wdt_data.tclk = orion5x_tclk;
595         platform_device_register(&orion5x_wdt_device);
596 }
597
598
599 /*****************************************************************************
600  * Time handling
601  ****************************************************************************/
602 int orion5x_tclk;
603
604 int __init orion5x_find_tclk(void)
605 {
606         u32 dev, rev;
607
608         orion5x_pcie_id(&dev, &rev);
609         if (dev == MV88F6183_DEV_ID &&
610             (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
611                 return 133333333;
612
613         return 166666667;
614 }
615
616 static void orion5x_timer_init(void)
617 {
618         orion5x_tclk = orion5x_find_tclk();
619         orion_time_init(IRQ_ORION5X_BRIDGE, orion5x_tclk);
620 }
621
622 struct sys_timer orion5x_timer = {
623         .init = orion5x_timer_init,
624 };
625
626
627 /*****************************************************************************
628  * General
629  ****************************************************************************/
630 /*
631  * Identify device ID and rev from PCIe configuration header space '0'.
632  */
633 static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
634 {
635         orion5x_pcie_id(dev, rev);
636
637         if (*dev == MV88F5281_DEV_ID) {
638                 if (*rev == MV88F5281_REV_D2) {
639                         *dev_name = "MV88F5281-D2";
640                 } else if (*rev == MV88F5281_REV_D1) {
641                         *dev_name = "MV88F5281-D1";
642                 } else if (*rev == MV88F5281_REV_D0) {
643                         *dev_name = "MV88F5281-D0";
644                 } else {
645                         *dev_name = "MV88F5281-Rev-Unsupported";
646                 }
647         } else if (*dev == MV88F5182_DEV_ID) {
648                 if (*rev == MV88F5182_REV_A2) {
649                         *dev_name = "MV88F5182-A2";
650                 } else {
651                         *dev_name = "MV88F5182-Rev-Unsupported";
652                 }
653         } else if (*dev == MV88F5181_DEV_ID) {
654                 if (*rev == MV88F5181_REV_B1) {
655                         *dev_name = "MV88F5181-Rev-B1";
656                 } else if (*rev == MV88F5181L_REV_A1) {
657                         *dev_name = "MV88F5181L-Rev-A1";
658                 } else {
659                         *dev_name = "MV88F5181(L)-Rev-Unsupported";
660                 }
661         } else if (*dev == MV88F6183_DEV_ID) {
662                 if (*rev == MV88F6183_REV_B0) {
663                         *dev_name = "MV88F6183-Rev-B0";
664                 } else {
665                         *dev_name = "MV88F6183-Rev-Unsupported";
666                 }
667         } else {
668                 *dev_name = "Device-Unknown";
669         }
670 }
671
672 void __init orion5x_init(void)
673 {
674         char *dev_name;
675         u32 dev, rev;
676
677         orion5x_id(&dev, &rev, &dev_name);
678         printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
679
680         orion5x_eth_shared_data.t_clk = orion5x_tclk;
681         orion5x_spi_plat_data.tclk = orion5x_tclk;
682         orion5x_uart0_data[0].uartclk = orion5x_tclk;
683         orion5x_uart1_data[0].uartclk = orion5x_tclk;
684
685         /*
686          * Setup Orion address map
687          */
688         orion5x_setup_cpu_mbus_bridge();
689
690         /*
691          * Don't issue "Wait for Interrupt" instruction if we are
692          * running on D0 5281 silicon.
693          */
694         if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
695                 printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
696                 disable_hlt();
697         }
698
699         /*
700          * The 5082/5181l/5182/6082/6082l/6183 have crypto
701          * while 5180n/5181/5281 don't have crypto.
702          */
703         if ((dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0) ||
704             dev == MV88F5182_DEV_ID || dev == MV88F6183_DEV_ID)
705                 orion5x_crypto_init();
706
707         /*
708          * Register watchdog driver
709          */
710         orion5x_wdt_init();
711 }
712
713 /*
714  * Many orion-based systems have buggy bootloader implementations.
715  * This is a common fixup for bogus memory tags.
716  */
717 void __init tag_fixup_mem32(struct machine_desc *mdesc, struct tag *t,
718                             char **from, struct meminfo *meminfo)
719 {
720         for (; t->hdr.size; t = tag_next(t))
721                 if (t->hdr.tag == ATAG_MEM &&
722                     (!t->u.mem.size || t->u.mem.size & ~PAGE_MASK ||
723                      t->u.mem.start & ~PAGE_MASK)) {
724                         printk(KERN_WARNING
725                                "Clearing invalid memory bank %dKB@0x%08x\n",
726                                t->u.mem.size / 1024, t->u.mem.start);
727                         t->hdr.tag = 0;
728                 }
729 }