source: src/linux/universal/linux-4.9/arch/arm/mach-cns3xxx/laguna.c @ 31630

Last change on this file since 31630 was 31630, checked in by brainslayer, 5 months ago

new fs is compatible with standard squashfs, just smaller

File size: 37.6 KB
Line 
1/*
2 * Gateworks Corporation Laguna Platform
3 *
4 * Copyright 2000 Deep Blue Solutions Ltd
5 * Copyright 2008 ARM Limited
6 * Copyright 2008 Cavium Networks
7 *                Scott Shu
8 * Copyright 2010 MontaVista Software, LLC.
9 *                Anton Vorontsov <avorontsov@mvista.com>
10 * Copyright 2011 Gateworks Corporation
11 *                Chris Lang <clang@gateworks.com>
12 *
13 * This file is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License, Version 2, as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/compiler.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/gpio.h>
24#include <linux/vmalloc.h>
25#include <linux/dma-mapping.h>
26#include <linux/serial_core.h>
27#include <linux/serial_8250.h>
28#include <linux/platform_device.h>
29#include <linux/mtd/mtd.h>
30#include <linux/mtd/physmap.h>
31#include <linux/mtd/partitions.h>
32#include <linux/usb/ehci_pdriver.h>
33#include <linux/usb/ohci_pdriver.h>
34#include <linux/leds.h>
35#include <linux/i2c.h>
36#include <linux/platform_data/at24.h>
37#include <linux/i2c/pca953x.h>
38#include <linux/spi/spi.h>
39#include <linux/spi/flash.h>
40#include <linux/if_ether.h>
41#include <linux/pps-gpio.h>
42#include <linux/export.h>
43#include <linux/module.h>
44#include <asm/setup.h>
45#include <asm/mach-types.h>
46#include <asm/mach/arch.h>
47#include <asm/mach/map.h>
48#include <asm/mach/time.h>
49#include <mach/cns3xxx.h>
50#include <mach/platform.h>
51#include <mach/irqs.h>
52#include <linux/magic.h>
53#ifdef CONFIG_CPU_FREQ
54#include <linux/cpufreq.h>
55extern struct cpufreq_driver cns_cpu_freq_driver;
56#endif
57#include <mach/pm.h>
58#include <mach/gpio.h>
59#include "core.h"
60#include "devices.h"
61
62#define ARRAY_AND_SIZE(x)       (x), ARRAY_SIZE(x)
63
64unsigned int numcpucores=1;
65EXPORT_SYMBOL(numcpucores);
66
67// Config 1 Bitmap
68#define ETH0_LOAD           BIT(0)
69#define ETH1_LOAD           BIT(1)
70#define ETH2_LOAD           BIT(2)
71#define SATA0_LOAD          BIT(3)
72#define SATA1_LOAD          BIT(4)
73#define PCM_LOAD            BIT(5)
74#define I2S_LOAD            BIT(6)
75#define SPI0_LOAD           BIT(7)
76#define SPI1_LOAD           BIT(8)
77#define PCIE0_LOAD          BIT(9)
78#define PCIE1_LOAD          BIT(10)
79#define USB0_LOAD           BIT(11)
80#define USB1_LOAD           BIT(12)
81#define USB1_ROUTE          BIT(13)
82#define SD_LOAD             BIT(14)
83#define UART0_LOAD          BIT(15)
84#define UART1_LOAD          BIT(16)
85#define UART2_LOAD          BIT(17)
86#define MPCI0_LOAD          BIT(18)
87#define MPCI1_LOAD          BIT(19)
88#define MPCI2_LOAD          BIT(20)
89#define MPCI3_LOAD          BIT(21)
90#define FP_BUT_LOAD         BIT(22)
91#define FP_BUT_HEADER_LOAD  BIT(23)
92#define FP_LED_LOAD         BIT(24)
93#define FP_LED_HEADER_LOAD  BIT(25)
94#define FP_TAMPER_LOAD      BIT(26)
95#define HEADER_33V_LOAD     BIT(27)
96#define SATA_POWER_LOAD     BIT(28)
97#define FP_POWER_LOAD       BIT(29)
98#define GPIO_HEADER_LOAD    BIT(30)
99#define GSP_BAT_LOAD        BIT(31)
100
101// Config 2 Bitmap
102#define FAN_LOAD            BIT(0)
103#define SPI_FLASH_LOAD      BIT(1)
104#define NOR_FLASH_LOAD      BIT(2)
105#define GPS_LOAD            BIT(3)
106#define SUPPLY_5V_LOAD      BIT(6)
107#define SUPPLY_33V_LOAD     BIT(7)
108
109struct laguna_board_info {
110        char model[16];
111        u32 config_bitmap;
112        u32 config2_bitmap;
113        u8 nor_flash_size;
114        u8 spi_flash_size;
115};
116
117struct laguna_board_info laguna_info __initdata;
118
119EXPORT_SYMBOL(laguna_info);
120/*
121 * NOR Flash
122 */
123static struct mtd_partition laguna_norflash_partitions[] = {
124        /* Bootloader */
125        {
126                .name = "bootloader",
127                .offset = 0,
128                .size = SZ_256K,
129                .mask_flags = 0, /* force read-only */
130        },
131        /* Bootloader params */
132        {
133                .name = "params",
134                .offset = SZ_256K,
135                .size = SZ_128K,
136                .mask_flags = 0,
137        },
138        /* linux */
139        {
140                .name = "linux",
141                .offset = SZ_256K + SZ_128K,
142                .size = SZ_2M,
143                .mask_flags = 0,
144        },
145        /* Root FS */
146        {
147                .name = "rootfs",
148                .offset = SZ_256K + SZ_128K + SZ_2M,
149                .size = SZ_16M - SZ_256K - SZ_128K - SZ_2M,
150                .mask_flags = 0,
151        },
152        /* ddwrt */
153        {
154                .name = "ddwrt",
155                .offset = SZ_256K + SZ_128K + SZ_2M,
156                .size = SZ_128K,
157                .mask_flags = 0,
158        },
159        /* NVRAM */
160        {
161                .name = "nvram",
162                .offset = SZ_256K + SZ_128K + SZ_2M,
163                .size = SZ_128K,
164                .mask_flags = 0,
165        }
166};
167
168static struct physmap_flash_data laguna_nor_pdata = {
169        .width = 2,
170        .parts = laguna_norflash_partitions,
171        .nr_parts = ARRAY_SIZE(laguna_norflash_partitions),
172};
173
174static struct resource laguna_norflash_resource = {
175        .start = CNS3XXX_FLASH_BASE,
176        .end = CNS3XXX_FLASH_BASE + SZ_128M - 1,
177        .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
178};
179
180static struct platform_device laguna_norflash_device = {
181        .name = "physmap-flash",
182        .id = 0,
183        .resource = &laguna_norflash_resource,
184        .num_resources = 1,
185        .dev = {
186                .platform_data = &laguna_nor_pdata,
187        },
188};
189
190/*
191 * SPI
192 */
193/* SPI Flash */
194static struct mtd_partition laguna_spiflash_partitions[] = {
195        /* Bootloader */
196        {
197                .name           = "bootloader",
198                .offset         = 0,
199                .size           = SZ_256K,
200        },
201        /* Bootloader params */
202        {
203                .name           = "params",
204                .offset         = SZ_256K,
205                .size           = SZ_256K,
206        },
207        /* linux */
208        {
209                .name = "linux",
210                .offset = SZ_512K,
211                .size = SZ_2M,
212                .mask_flags = 0,
213        },
214        /* FileSystem */
215        {
216                .name           = "rootfs",
217                .offset         = SZ_512K + SZ_2M ,
218                .size           = SZ_16M - SZ_512K - SZ_2M,
219        },
220        /* ddwrt */
221        {
222                .name = "ddwrt",
223                .offset = SZ_512K + SZ_2M,
224                .size = SZ_128K,
225                .mask_flags = 0,
226        },
227        /* NVRAM */
228        {
229                .name = "nvram",
230                .offset = SZ_512K + SZ_2M,
231                .size = SZ_128K,
232                .mask_flags = 0,
233        }
234};
235
236static struct flash_platform_data laguna_spi_pdata = {
237        .parts = laguna_spiflash_partitions,
238        .nr_parts = ARRAY_SIZE(laguna_spiflash_partitions),
239};
240
241static struct spi_board_info __initdata laguna_spi_devices[] = {
242        {
243                .modalias = "m25p80",
244                .platform_data = &laguna_spi_pdata,
245                .max_speed_hz = 50000000,
246                .bus_num = 1,
247                .chip_select = 0,
248        },
249};
250
251static struct platform_device laguna_spi_controller_device = {
252        .name = "cns3xxx_spi",
253};
254
255/*
256 * LED's
257 */
258static struct gpio_led laguna_gpio_leds[] = {
259        {
260                .name = "user1", /* Green Led */
261                .gpio = 115,
262                .active_low = 1,
263        },{
264                .name = "user2", /* Red Led */
265                .gpio = 114,
266                .active_low = 1,
267        },{
268                .name = "pwr1", /* Green Led */
269                .gpio = 116,
270                .active_low = 1,
271        },{
272                .name = "pwr2", /* Yellow Led */
273                .gpio = 117,
274                .active_low = 1,
275        },{
276                .name = "txd1", /* Green Led */
277                .gpio = 118,
278                .active_low = 1,
279        },{
280                .name = "txd2", /* Yellow Led */
281                .gpio = 119,
282                .active_low = 1,
283        },{
284                .name = "rxd1", /* Green Led */
285                .gpio = 120,
286                .active_low = 1,
287        },{
288                .name = "rxd2", /* Yellow Led */
289                .gpio = 121,
290                .active_low = 1,
291        },{
292                .name = "ser1", /* Green Led */
293                .gpio = 122,
294                .active_low = 1,
295        },{
296                .name = "ser2", /* Yellow Led */
297                .gpio = 123,
298                .active_low = 1,
299        },{
300                .name = "enet1", /* Green Led */
301                .gpio = 124,
302                .active_low = 1,
303        },{
304                .name = "enet2", /* Yellow Led */
305                .gpio = 125,
306                .active_low = 1,
307        },{
308                .name = "sig1_1", /* Green Led */
309                .gpio = 126,
310                .active_low = 1,
311        },{
312                .name = "sig1_2", /* Yellow Led */
313                .gpio = 127,
314                .active_low = 1,
315        },{
316                .name = "sig2_1", /* Green Led */
317                .gpio = 128,
318                .active_low = 1,
319        },{
320                .name = "sig2_2", /* Yellow Led */
321                .gpio = 129,
322                .active_low = 1,
323        },{
324                .name = "sig3_1", /* Green Led */
325                .gpio = 130,
326                .active_low = 1,
327        },{
328                .name = "sig3_2", /* Yellow Led */
329                .gpio = 131,
330                .active_low = 1,
331        },{
332                .name = "net1", /*Green Led */
333                .gpio = 109,
334                .active_low = 1,
335        },{
336                .name = "net2", /* Red Led */
337                .gpio = 110,
338                .active_low = 1,
339        },{
340                .name = "mod1", /* Green Led */
341                .gpio = 111,
342                .active_low = 1,
343        },{
344                .name = "mod2", /* Red Led */
345                .gpio = 112,
346                .active_low = 1,
347        },
348};
349
350static struct gpio_led_platform_data laguna_gpio_leds_data = {
351        .num_leds = 22,
352        .leds = laguna_gpio_leds,
353};
354
355static struct platform_device laguna_gpio_leds_device = {
356        .name = "leds-gpio",
357        .id = -1,
358        .dev.platform_data = &laguna_gpio_leds_data,
359};
360
361/*
362 * Ethernet
363 */
364static struct cns3xxx_plat_info laguna_net_data = {
365        .ports = 0,
366        .phy = {
367                0,
368                1,
369                2,
370        },
371};
372
373static struct resource laguna_net_resource[] = {
374        {
375                .name = "eth0_mem",
376                .start = CNS3XXX_SWITCH_BASE,
377                .end = CNS3XXX_SWITCH_BASE + SZ_4K - 1,
378                .flags = IORESOURCE_MEM
379        }, {
380                .name = "eth_rx",
381                .start = IRQ_CNS3XXX_SW_R0RXC,
382                .end = IRQ_CNS3XXX_SW_R0RXC,
383                .flags = IORESOURCE_IRQ
384        }, {
385                .name = "eth_stat",
386                .start = IRQ_CNS3XXX_SW_STATUS,
387                .end = IRQ_CNS3XXX_SW_STATUS,
388                .flags = IORESOURCE_IRQ
389        }
390};
391
392static u64 laguna_net_dmamask = DMA_BIT_MASK(32);
393
394static struct platform_device laguna_net_device = {
395        .name = "cns3xxx_eth",
396        .id = 0,
397        .resource = laguna_net_resource,
398        .num_resources = ARRAY_SIZE(laguna_net_resource),
399        .dev = {
400                .dma_mask = &laguna_net_dmamask,
401                .coherent_dma_mask = DMA_BIT_MASK(32),
402                .platform_data = &laguna_net_data,
403        }
404};
405
406
407
408/*
409 * UART
410 */
411static void __init laguna_early_serial_setup(void)
412{
413#ifdef CONFIG_SERIAL_8250_CONSOLE
414        static struct uart_port laguna_serial_port = {
415                .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
416                .mapbase        = CNS3XXX_UART0_BASE,
417                .irq            = IRQ_CNS3XXX_UART0,
418                .iotype         = UPIO_MEM,
419                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
420                .regshift       = 2,
421                .uartclk        = 24000000,
422                .line           = 0,
423                .type           = PORT_16550A,
424                .fifosize       = 16,
425        };
426
427        early_serial_setup(&laguna_serial_port);
428#endif
429}
430
431static struct resource laguna_uart_resources[] = {
432        {
433                .start = CNS3XXX_UART0_BASE,
434                .end   = CNS3XXX_UART0_BASE + SZ_4K - 1,
435                .flags    = IORESOURCE_MEM
436        },{
437                .start = CNS3XXX_UART1_BASE,
438                .end   = CNS3XXX_UART1_BASE + SZ_4K - 1,
439                .flags    = IORESOURCE_MEM
440        },{
441                .start = CNS3XXX_UART2_BASE,
442                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
443                .flags    = IORESOURCE_MEM
444        },
445};
446
447static struct plat_serial8250_port laguna_uart_data[] = {
448        {
449                .mapbase        = (CNS3XXX_UART0_BASE),
450                .irq            = IRQ_CNS3XXX_UART0,
451                .iotype         = UPIO_MEM,
452                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
453                .regshift       = 2,
454                .uartclk        = 24000000,
455                .type           = PORT_16550A,
456        },{
457                .mapbase        = (CNS3XXX_UART1_BASE),
458                .irq            = IRQ_CNS3XXX_UART1,
459                .iotype         = UPIO_MEM,
460                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
461                .regshift       = 2,
462                .uartclk        = 24000000,
463                .type           = PORT_16550A,
464        },{
465                .mapbase        = (CNS3XXX_UART2_BASE),
466                .irq            = IRQ_CNS3XXX_UART2,
467                .iotype         = UPIO_MEM,
468                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST | UPF_IOREMAP,
469                .regshift       = 2,
470                .uartclk        = 24000000,
471                .type           = PORT_16550A,
472        },
473        { },
474};
475
476static struct platform_device laguna_uart = {
477        .name     = "serial8250",
478        .id     = PLAT8250_DEV_PLATFORM,
479        .dev.platform_data  = laguna_uart_data,
480        .num_resources    = 3,
481        .resource   = laguna_uart_resources
482};
483
484/*
485 * USB
486 */
487static struct resource cns3xxx_usb_ehci_resources[] = {
488        [0] = {
489                .start = CNS3XXX_USB_BASE,
490                .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
491                .flags = IORESOURCE_MEM,
492        },
493        [1] = {
494                .start = IRQ_CNS3XXX_USB_EHCI,
495                .flags = IORESOURCE_IRQ,
496        },
497};
498
499static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
500
501static int csn3xxx_usb_power_on(struct platform_device *pdev)
502{
503        /*
504         * EHCI and OHCI share the same clock and power,
505         * resetting twice would cause the 1st controller been reset.
506         * Therefore only do power up  at the first up device, and
507         * power down at the last down device.
508         *
509         * Set USB AHB INCR length to 16
510         */
511        if (atomic_inc_return(&usb_pwr_ref) == 1) {
512                cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
513                cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
514                cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
515                __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
516                        MISC_CHIP_CONFIG_REG);
517        }
518
519        return 0;
520}
521
522static void csn3xxx_usb_power_off(struct platform_device *pdev)
523{
524        /*
525         * EHCI and OHCI share the same clock and power,
526         * resetting twice would cause the 1st controller been reset.
527         * Therefore only do power up  at the first up device, and
528         * power down at the last down device.
529         */
530        if (atomic_dec_return(&usb_pwr_ref) == 0)
531                cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
532}
533
534static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
535        .power_on       = csn3xxx_usb_power_on,
536        .power_off      = csn3xxx_usb_power_off,
537};
538
539
540static struct platform_device cns3xxx_usb_ehci_device = {
541        .name          = "ehci-platform",
542        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
543        .resource      = cns3xxx_usb_ehci_resources,
544        .dev           = {
545                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
546                .coherent_dma_mask = DMA_BIT_MASK(32),
547                .platform_data     = &cns3xxx_usb_ehci_pdata,
548        },
549};
550
551
552static struct resource cns3xxx_usb_ohci_resources[] = {
553        [0] = {
554                .start = CNS3XXX_USB_OHCI_BASE,
555                .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
556                .flags = IORESOURCE_MEM,
557        },
558        [1] = {
559                .start = IRQ_CNS3XXX_USB_OHCI,
560                .flags = IORESOURCE_IRQ,
561        },
562};
563
564static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
565
566static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
567        .num_ports      = 1,
568        .power_on       = csn3xxx_usb_power_on,
569        .power_off      = csn3xxx_usb_power_off,
570};
571
572static struct platform_device cns3xxx_usb_ohci_device = {
573        .name          = "ohci-platform",
574        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
575        .resource      = cns3xxx_usb_ohci_resources,
576        .dev           = {
577                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
578                .coherent_dma_mask = DMA_BIT_MASK(32),
579                .platform_data     = &cns3xxx_usb_ohci_pdata,
580        },
581};
582
583static struct resource cns3xxx_usb_otg_resources[] = {
584        [0] = {
585                .start = CNS3XXX_USBOTG_BASE,
586                .end   = CNS3XXX_USBOTG_BASE + SZ_16M - 1,
587                .flags = IORESOURCE_MEM,
588        },
589        [1] = {
590                .start = IRQ_CNS3XXX_USB_OTG,
591                .flags = IORESOURCE_IRQ,
592        },
593};
594
595static u64 cns3xxx_usb_otg_dma_mask = DMA_BIT_MASK(32);
596
597static struct platform_device cns3xxx_usb_otg_device = {
598        .name          = "dwc_otg",
599        .num_resources = ARRAY_SIZE(cns3xxx_usb_otg_resources),
600        .resource      = cns3xxx_usb_otg_resources,
601        .dev           = {
602                .dma_mask          = &cns3xxx_usb_otg_dma_mask,
603                .coherent_dma_mask = DMA_BIT_MASK(32),
604        },
605};
606
607/*
608 * I2C
609 */
610static struct resource laguna_i2c_resource[] = {
611        {
612                .start    = CNS3XXX_SSP_BASE + 0x20,
613                .end      = 0x7100003f,
614                .flags    = IORESOURCE_MEM,
615        },{
616                .start    = IRQ_CNS3XXX_I2C,
617                .flags    = IORESOURCE_IRQ,
618        },
619};
620
621static struct platform_device laguna_i2c_controller = {
622        .name   = "cns3xxx-i2c",
623        .num_resources  = 2,
624        .resource = laguna_i2c_resource,
625};
626
627static struct memory_accessor *at24_mem_acc;
628
629static void at24_setup(struct memory_accessor *mem_acc, void *context)
630{
631        char buf[16];
632
633        at24_mem_acc = mem_acc;
634
635        /* Read MAC addresses */
636        if (at24_mem_acc->read(at24_mem_acc, buf, 0x100, 6) == 6)
637                memcpy(&laguna_net_data.hwaddr[0], buf, ETH_ALEN);
638        if (at24_mem_acc->read(at24_mem_acc, buf, 0x106, 6) == 6)
639                memcpy(&laguna_net_data.hwaddr[1], buf, ETH_ALEN);
640        if (at24_mem_acc->read(at24_mem_acc, buf, 0x10C, 6) == 6)
641                memcpy(&laguna_net_data.hwaddr[2], buf, ETH_ALEN);
642        if (at24_mem_acc->read(at24_mem_acc, buf, 0x112, 6) == 6)
643                memcpy(&laguna_net_data.hwaddr[3], buf, ETH_ALEN);
644
645        /* Read out Model Information */
646        if (at24_mem_acc->read(at24_mem_acc, buf, 0x130, 16) == 16)
647                memcpy(&laguna_info.model, buf, 16);
648        if (at24_mem_acc->read(at24_mem_acc, buf, 0x140, 1) == 1)
649                memcpy(&laguna_info.nor_flash_size, buf, 1);
650        if (at24_mem_acc->read(at24_mem_acc, buf, 0x141, 1) == 1)
651                memcpy(&laguna_info.spi_flash_size, buf, 1);
652        if (at24_mem_acc->read(at24_mem_acc, buf, 0x142, 4) == 4)
653                memcpy(&laguna_info.config_bitmap, buf, 4);
654        if (at24_mem_acc->read(at24_mem_acc, buf, 0x146, 4) == 4)
655                memcpy(&laguna_info.config2_bitmap, buf, 4);
656};
657
658static struct at24_platform_data laguna_eeprom_info = {
659        .byte_len = 1024,
660        .page_size = 16,
661        .flags = AT24_FLAG_READONLY,
662        .setup = at24_setup,
663};
664
665static struct pca953x_platform_data laguna_pca_data = {
666        .gpio_base = 100,
667};
668
669static struct pca953x_platform_data laguna_pca2_data = {
670        .gpio_base = 116,
671        .irq_base = -1,
672};
673
674static struct i2c_board_info __initdata laguna_i2c_devices[] = {
675        {
676                I2C_BOARD_INFO("pca9555", 0x23),
677                .platform_data = &laguna_pca_data,
678        },{
679                I2C_BOARD_INFO("pca9555", 0x27),
680                .platform_data = &laguna_pca2_data,
681        },{
682                I2C_BOARD_INFO("gsp", 0x29),
683        },{
684                I2C_BOARD_INFO ("24c08",0x50),
685                .platform_data = &laguna_eeprom_info,
686        },{
687                I2C_BOARD_INFO("ds1672", 0x68),
688        },
689};
690
691/*
692 * Watchdog
693 */
694
695static struct resource laguna_watchdog_resources[] = {
696        [0] = {
697                .start  = CNS3XXX_TC11MP_TWD_BASE + 0x100, // CPU0 watchdog
698                .end    = CNS3XXX_TC11MP_TWD_BASE + SZ_4K - 1,
699                .flags  = IORESOURCE_MEM,
700        },
701};
702
703static struct platform_device laguna_watchdog = {
704        .name           = "mpcore_wdt",
705        .id             = -1,
706        .num_resources  = ARRAY_SIZE(laguna_watchdog_resources),
707        .resource       = laguna_watchdog_resources,
708};
709
710
711
712/*
713 * GPS PPS
714 */
715static struct pps_gpio_platform_data laguna_pps_data = {
716        .gpio_pin = 0,
717        .gpio_label = "GPS_PPS",
718        .assert_falling_edge = 0,
719        .capture_clear = 0,
720};
721
722static struct platform_device laguna_pps_device = {
723        .name = "pps-gpio",
724        .id = -1,
725        .dev.platform_data = &laguna_pps_data,
726};
727
728
729static struct platform_device laguna_gpio_dev = {
730        .name = "GPIODEV",
731        .id = -1,
732};
733/*
734 * GPIO
735 */
736
737static struct gpio laguna_gpio_gw2391[] = {
738        {   0, GPIOF_IN           , "*GPS_PPS" },
739        {   1, GPIOF_IN           , "*GSC_IRQ#" },
740        {   2, GPIOF_IN           , "*USB_FAULT#" },
741        {   5, GPIOF_OUT_INIT_LOW , "*USB0_PCI_SEL" },
742        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
743        {   7, GPIOF_OUT_INIT_LOW , "*USB1_PCI_SEL" },
744        {   8, GPIOF_OUT_INIT_HIGH, "*PERST#" },
745        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN#" },
746        { 100, GPIOF_IN           , "*USER_PB#" },
747        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
748        { 108, GPIOF_IN           , "DIO0" },
749        { 109, GPIOF_IN           , "DIO1" },
750        { 110, GPIOF_IN           , "DIO2" },
751        { 111, GPIOF_IN           , "DIO3" },
752        { 112, GPIOF_IN           , "DIO4" },
753};
754
755static struct gpio laguna_gpio_gw2388[] = {
756        {   0, GPIOF_IN           , "*GPS_PPS" },
757        {   1, GPIOF_IN           , "*GSC_IRQ#" },
758        {   3, GPIOF_IN           , "*USB_FAULT#" },
759        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
760        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
761        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
762        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
763        { 100, GPIOF_OUT_INIT_HIGH, "*USER_PB#" },
764        { 108, GPIOF_IN           , "DIO0" },
765        { 109, GPIOF_IN           , "DIO1" },
766        { 110, GPIOF_IN           , "DIO2" },
767        { 111, GPIOF_IN           , "DIO3" },
768        { 112, GPIOF_IN           , "DIO4" },
769};
770
771static struct gpio laguna_gpio_gw2387[] = {
772        {   0, GPIOF_IN           , "*GPS_PPS" },
773        {   1, GPIOF_IN           , "*GSC_IRQ#" },
774        {   2, GPIOF_IN           , "*USB_FAULT#" },
775        {   5, GPIOF_OUT_INIT_LOW , "*USB_PCI_SEL" },
776        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
777        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
778        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
779        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
780        { 100, GPIOF_IN           , "*USER_PB#" },
781        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
782        { 108, GPIOF_IN           , "DIO0" },
783        { 109, GPIOF_IN           , "DIO1" },
784        { 110, GPIOF_IN           , "DIO2" },
785        { 111, GPIOF_IN           , "DIO3" },
786        { 112, GPIOF_IN           , "DIO4" },
787        { 113, GPIOF_IN           , "DIO5" },
788};
789
790static struct gpio laguna_gpio_gw2386[] = {
791        {   0, GPIOF_IN           , "*GPS_PPS" },
792        {   2, GPIOF_IN           , "*USB_FAULT#" },
793        {   6, GPIOF_OUT_INIT_LOW , "*USB_PCI_SEL" },
794        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
795        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
796        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
797        { 108, GPIOF_IN           , "DIO0" },
798        { 109, GPIOF_IN           , "DIO1" },
799        { 110, GPIOF_IN           , "DIO2" },
800        { 111, GPIOF_IN           , "DIO3" },
801        { 112, GPIOF_IN           , "DIO4" },
802        { 113, GPIOF_IN           , "DIO5" },
803};
804
805static struct gpio laguna_gpio_gw2385[] = {
806        {   0, GPIOF_IN           , "*GSC_IRQ#" },
807        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
808        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
809        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
810        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_PCI_SEL" },
811        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
812        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
813        {   9, GPIOF_OUT_INIT_LOW , "*SER_EN" },
814        {  10, GPIOF_IN,            "*USER_PB#" },
815        {  11, GPIOF_OUT_INIT_HIGH, "*PERST#" },
816        { 100, GPIOF_IN           , "*USER_PB#" },
817        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
818};
819
820static struct gpio laguna_gpio_gw2384[] = {
821        {   0, GPIOF_IN           , "*GSC_IRQ#" },
822        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
823        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
824        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
825        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_PCI_SEL" },
826        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
827        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
828        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
829        {  12, GPIOF_OUT_INIT_LOW , "J10_DIOLED0" },
830        {  13, GPIOF_OUT_INIT_HIGH, "*I2CMUX_RST#" },
831        {  14, GPIOF_OUT_INIT_LOW , "J10_DIOLED1" },
832        {  15, GPIOF_OUT_INIT_LOW , "J10_DIOLED2" },
833        { 100, GPIOF_IN           , "*USER_PB#" },
834        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
835        { 108, GPIOF_IN           , "J9_DIOGSC0" },
836};
837
838static struct gpio laguna_gpio_gw2383[] = {
839        {   0, GPIOF_IN           , "*GPS_PPS" },
840        {   1, GPIOF_IN           , "*GSC_IRQ#" },
841        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
842        {   3, GPIOF_IN           , "GPIO0" },
843        {   8, GPIOF_IN           , "GPIO1" },
844        { 100, GPIOF_IN           , "DIO0" },
845        { 101, GPIOF_IN           , "DIO1" },
846        { 108, GPIOF_IN           , "*USER_PB#" },
847};
848
849static struct gpio laguna_gpio_gw2382[] = {
850        {   0, GPIOF_IN           , "*GPS_PPS" },
851        {   1, GPIOF_IN           , "*GSC_IRQ#" },
852        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
853        {   3, GPIOF_IN           , "GPIO0" },
854        {   4, GPIOF_IN           , "GPIO1" },
855        {   9, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
856        {  10, GPIOF_OUT_INIT_HIGH, "*USB_PCI_SEL#" },
857        { 100, GPIOF_IN           , "DIO0" },
858        { 101, GPIOF_IN           , "DIO1" },
859        { 108, GPIOF_IN           , "*USER_PB#" },
860};
861
862static struct gpio laguna_gpio_gw2380[] = {
863        {   0, GPIOF_IN           , "*GPS_PPS" },
864        {   1, GPIOF_IN           , "*GSC_IRQ#" },
865        {   3, GPIOF_IN           , "GPIO0" },
866        {   8, GPIOF_IN           , "GPIO1" },
867        { 100, GPIOF_IN           , "DIO0" },
868        { 101, GPIOF_IN           , "DIO1" },
869        { 102, GPIOF_IN           , "DIO2" },
870        { 103, GPIOF_IN           , "DIO3" },
871        { 108, GPIOF_IN           , "*USER_PB#" },
872};
873
874
875/*
876 * Initialization
877 */
878
879static void __init laguna_init(void)
880{
881        platform_device_register(&laguna_watchdog);
882
883        platform_device_register(&laguna_i2c_controller);
884
885        i2c_register_board_info(0, laguna_i2c_devices,
886                        ARRAY_SIZE(laguna_i2c_devices));
887
888
889        pm_power_off = cns3xxx_power_off;
890}
891
892static struct map_desc laguna_io_desc[] __initdata = {
893        {
894                .virtual        = CNS3XXX_UART0_BASE_VIRT,
895                .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
896                .length         = SZ_4K,
897                .type           = MT_DEVICE,
898        },
899};
900
901
902static int laguna_register_gpio(struct gpio *array, size_t num)
903{
904
905        int i, err, ret;
906
907        ret = 0;
908        for (i = 0; i < num; i++, array++) {
909                const char *label = array->label;
910                if (label[0] == '*')
911                        label++;
912                err = gpio_request_one(array->gpio, array->flags, label);
913                if (err)
914                        ret = err;
915                else {
916                        err = gpio_export(array->gpio, array->label[0] != '*');
917                }
918        }
919        return ret;
920}
921
922 
923#define SPI_MEM_MAP_VALUE(reg_offset)           (*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset)))
924
925#define SPI_CONFIGURATION_REG                   SPI_MEM_MAP_VALUE(0x40)
926#define SPI_SERVICE_STATUS_REG                  SPI_MEM_MAP_VALUE(0x44)
927#define SPI_BIT_RATE_CONTROL_REG                SPI_MEM_MAP_VALUE(0x48)
928#define SPI_TRANSMIT_CONTROL_REG                SPI_MEM_MAP_VALUE(0x4C)
929#define SPI_TRANSMIT_BUFFER_REG                 SPI_MEM_MAP_VALUE(0x50)
930#define SPI_RECEIVE_CONTROL_REG                 SPI_MEM_MAP_VALUE(0x54)
931#define SPI_RECEIVE_BUFFER_REG                  SPI_MEM_MAP_VALUE(0x58)
932#define SPI_FIFO_TRANSMIT_CONFIG_REG            SPI_MEM_MAP_VALUE(0x5C)
933#define SPI_FIFO_TRANSMIT_CONTROL_REG           SPI_MEM_MAP_VALUE(0x60)
934#define SPI_FIFO_RECEIVE_CONFIG_REG             SPI_MEM_MAP_VALUE(0x64)
935#define SPI_INTERRUPT_STATUS_REG                SPI_MEM_MAP_VALUE(0x68)
936#define SPI_INTERRUPT_ENABLE_REG                SPI_MEM_MAP_VALUE(0x6C)
937
938#define SPI_TRANSMIT_BUFFER_REG_ADDR            (CNS3XXX_SSP_BASE +0x50)
939#define SPI_RECEIVE_BUFFER_REG_ADDR             (CNS3XXX_SSP_BASE +0x58)
940
941
942/* allow disabling of external isolated PCIe IRQs */
943static int cns3xxx_pciextirq = 1;
944static int __init cns3xxx_pciextirq_disable(char *s)
945{
946      cns3xxx_pciextirq = 0;
947      return 1;
948}
949__setup("noextirq", cns3xxx_pciextirq_disable);
950
951static int __init laguna_pcie_init_irq(void)
952{
953        int irqs[] = {
954                IRQ_CNS3XXX_EXTERNAL_PIN0,
955                IRQ_CNS3XXX_EXTERNAL_PIN1,
956                IRQ_CNS3XXX_EXTERNAL_PIN2,
957                154,
958        };
959
960        if (!machine_is_gw2388())
961                return 0;
962
963        /* Verify GPIOB[26:29] == 0001b indicating support for ext irqs */
964        if (cns3xxx_pciextirq) {
965        u32 __iomem *mem = (void __iomem *)(CNS3XXX_GPIOB_BASE_VIRT + 0x0004);
966        u32 reg = __raw_readl(mem);
967        reg >>=16;
968        switch (reg & 0x3c00) {
969        case 0x0400: /* GW2388-4-G (mod) */
970                printk(KERN_INFO "laguna: using isolated PCI interrupts:"
971                       " irq%d/irq%d/irq%d/irq%d\n",
972                       irqs[0], irqs[1], irqs[2], irqs[3]);
973                cns3xxx_pcie_set_irqs(0, irqs);
974                break;
975        case 0x0408: /* GW2388-4-H */
976        case 0x3c00: /* GW2388-4-G */
977        default:
978                printk(KERN_INFO "laguna: using shared PCI interrupts:"
979                       " irq%d/irq%d/irq%d/irq%d\n",
980                       IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE, IRQ_CNS3XXX_PCIE0_DEVICE);
981                break; 
982        }
983       
984        }
985        return 0;
986}
987subsys_initcall(laguna_pcie_init_irq);
988
989
990static void __init laguna_map_io(void)
991{
992        cns3xxx_common_init();
993        iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
994        laguna_early_serial_setup();
995}
996
997extern void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
998        u32 base, int irq, int secondary_irq_base);
999
1000static int __init laguna_model_setup(void)
1001{
1002        u32 __iomem *mem;
1003        u32 reg;
1004
1005        printk("Running on Gateworks Laguna %s\n", laguna_info.model);
1006
1007        cns3xxx_gpio_init( 0, 32, CNS3XXX_GPIOA_BASE_VIRT, IRQ_CNS3XXX_GPIOA,
1008                NR_IRQS_CNS3XXX);
1009        /*
1010         * If pcie external interrupts are supported and desired
1011         * configure IRQ types and configure pin function.
1012         * Note that cns3xxx_pciextirq is enabled by default, but can be
1013         * unset via the 'noextirq' kernel param or by laguna_pcie_init() if
1014         * the baseboard model does not support this hardware feature.
1015         */
1016        if (cns3xxx_pciextirq) {
1017                mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0018);
1018                reg = __raw_readl(mem);
1019                /* GPIO26 is gpio, EXT_INT[0:2] not gpio func */
1020                reg &= ~0x3c000000;
1021                reg |= 0x38000000;
1022                __raw_writel(reg, mem);
1023
1024                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1025                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1026
1027                irq_set_irq_type(154, IRQ_TYPE_LEVEL_LOW);
1028                irq_set_irq_type(93, IRQ_TYPE_LEVEL_HIGH);
1029                irq_set_irq_type(94, IRQ_TYPE_LEVEL_HIGH);
1030                irq_set_irq_type(95, IRQ_TYPE_LEVEL_HIGH);
1031        } else {
1032                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1033                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1034        }
1035
1036
1037        if (strncmp(laguna_info.model, "GW", 2) == 0) {
1038                printk("CONFIG BITMAP = 0x%08X\n",laguna_info.config_bitmap);
1039                if (laguna_info.config_bitmap & ETH0_LOAD)
1040                        laguna_net_data.ports |= BIT(0);
1041                printk(KERN_INFO "detecting ETH\n");
1042                if (strncmp(laguna_info.model, "GW2388", 6) == 0 || strncmp(laguna_info.model, "GW2389", 6) == 0)
1043                {
1044                if (laguna_info.config_bitmap & ETH1_LOAD)
1045                        laguna_net_data.ports |= BIT(1);
1046                if (laguna_info.config_bitmap & ETH2_LOAD)
1047                        laguna_net_data.ports |= BIT(2);
1048                }
1049                printk(KERN_INFO "registering ETH\n");
1050                if (laguna_net_data.ports)
1051                        platform_device_register(&laguna_net_device);
1052
1053                printk(KERN_INFO "registering AHCI\n");
1054                if (laguna_info.config_bitmap & (SATA0_LOAD | SATA1_LOAD))
1055                        cns3xxx_ahci_init();
1056
1057
1058                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1059                {
1060                printk(KERN_INFO "check USB0\n");
1061                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1062                        printk(KERN_INFO "register USB0\n");
1063                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1064
1065                        /* DRVVBUS pins share with GPIOA */
1066                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1067                        reg = __raw_readl(mem);
1068                        reg |= 0x8;
1069                        __raw_writel(reg, mem);
1070
1071                        /* Enable OTG */
1072                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1073                        reg = __raw_readl(mem);
1074                        reg &= ~(1 << 10);
1075                        __raw_writel(reg, mem);
1076
1077                        platform_device_register(&cns3xxx_usb_otg_device);
1078                }
1079
1080                printk(KERN_INFO "check USB1\n");
1081                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1082                        printk(KERN_INFO "register USB1\n");
1083                        platform_device_register(&cns3xxx_usb_ehci_device);
1084                        platform_device_register(&cns3xxx_usb_ohci_device);
1085                }
1086                }else{
1087                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1088
1089                        printk(KERN_EMERG "power up USB0\n");
1090                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1091
1092                        /* DRVVBUS pins share with GPIOA */
1093                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1094                        reg = __raw_readl(mem);
1095                        reg |= 0x8;
1096                        __raw_writel(reg, mem);
1097
1098                        /* Enable OTG */
1099                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1100                        reg = __raw_readl(mem);
1101                        reg &= ~(1 << 10);
1102                        __raw_writel(reg, mem);
1103
1104                        platform_device_register(&cns3xxx_usb_otg_device);
1105                }
1106
1107                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1108                        printk(KERN_EMERG "power up ehci/ohci\n");
1109                        platform_device_register(&cns3xxx_usb_ehci_device);
1110                        platform_device_register(&cns3xxx_usb_ohci_device);
1111                }
1112                }
1113
1114
1115                if (laguna_info.config_bitmap & (SD_LOAD))
1116                {
1117                        printk(KERN_EMERG "init sdhci\n");
1118                        cns3xxx_sdhci_init();
1119                }
1120                printk(KERN_INFO "check UART\n");
1121                if (laguna_info.config_bitmap & (UART0_LOAD))
1122                        laguna_uart.num_resources = 1;
1123                if (laguna_info.config_bitmap & (UART1_LOAD))
1124                        laguna_uart.num_resources = 2;
1125                if (laguna_info.config_bitmap & (UART2_LOAD))
1126                        laguna_uart.num_resources = 3;
1127                printk(KERN_INFO "register %d UART(s) \n",laguna_uart.num_resources);
1128                platform_device_register(&laguna_uart);
1129
1130                printk(KERN_EMERG "notflash size %d\n",laguna_info.nor_flash_size);
1131                if ((laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) && (
1132                strncmp(laguna_info.model, "GW2388", 6) == 0 ||
1133                strncmp(laguna_info.model, "GW2387", 6) == 0 ||
1134                strncmp(laguna_info.model, "GW2389", 6) == 0 ||
1135                strncmp(laguna_info.model, "GW2391", 6) == 0 ||
1136                strncmp(laguna_info.model, "GW2393", 6) == 0)) {
1137                        printk(KERN_EMERG "detecting NOR FLASH\n");
1138//                      if (laguna_info.nor_flash_size < 1 || laguna_info.nor_flash_size > 5)
1139//                          laguna_info.nor_flash_size = 2; //guess default for wrong config
1140                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1141                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1142                        switch (laguna_info.nor_flash_size) {
1143                                case 1:
1144                                        laguna_norflash_partitions[2].size = SZ_8M - SZ_256K - SZ_128K  - SZ_128K;
1145                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
1146                                break;
1147                                case 2:
1148                                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1149                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1150                                break;
1151                                case 3:
1152                                        laguna_norflash_partitions[2].size = SZ_32M - SZ_256K - SZ_128K  - SZ_128K;
1153                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
1154                                break;
1155                                case 4:
1156                                        laguna_norflash_partitions[2].size = SZ_64M - SZ_256K - SZ_128K  - SZ_128K;
1157                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
1158                                break;
1159                                case 5:
1160                                        laguna_norflash_partitions[2].size = SZ_128M - SZ_256K - SZ_128K  - SZ_128K;
1161                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
1162                                break;
1163                        }
1164                        unsigned int flashsize = laguna_norflash_partitions[2].size + SZ_256K + SZ_128K + SZ_128K;
1165                        unsigned char *buf = (unsigned char *)ioremap(laguna_norflash_resource.start,laguna_norflash_resource.end - laguna_norflash_resource.start + 1);
1166                        unsigned int offset=0;
1167                        int tmplen;
1168                        int filesyssize=0;
1169                        int erasesize=0x20000;
1170                        while(offset<laguna_norflash_resource.end)
1171                        {
1172                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1173                        {
1174                        printk(KERN_EMERG "found squashfs on %X\n",offset);
1175                        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
1176                        filesyssize = sb->bytes_used;
1177                        tmplen = offset + filesyssize;
1178                        tmplen +=  (erasesize - 1);
1179                        tmplen &= ~(erasesize - 1);
1180                        filesyssize = tmplen - offset;
1181                        laguna_norflash_partitions[3].offset = offset;
1182                        laguna_norflash_partitions[3].size = filesyssize;
1183                        laguna_norflash_partitions[4].offset = offset + filesyssize;
1184                        laguna_norflash_partitions[4].size = (flashsize- SZ_128K) - laguna_norflash_partitions[4].offset;
1185                        laguna_norflash_partitions[5].offset = (flashsize - SZ_128K);
1186                        laguna_norflash_partitions[5].size = SZ_128K;
1187                        break;
1188                        }
1189                        buf+=0x1000;
1190                        offset+=0x1000;
1191                        }
1192                        iounmap(buf);
1193                        platform_device_register(&laguna_norflash_device);
1194                }
1195
1196                if ((laguna_info.config2_bitmap & (SPI_FLASH_LOAD)) && (strncmp(laguna_info.model, "GW2380", 6) == 0 || strncmp(laguna_info.model, "GW2382", 6) == 0 || strncmp(laguna_info.model, "GW2384", 6) == 0)) {
1197                //      printk(KERN_EMERG "detecting SPI FLASH\n");
1198                        SPI_CONFIGURATION_REG = 0x40000000;
1199                        HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1200                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1201#if 0
1202                        switch (laguna_info.spi_flash_size) {
1203                                case 1:
1204                                        laguna_spiflash_partitions[2].size              = SZ_4M - SZ_512K;
1205                                break;
1206                                case 2:
1207                                        laguna_spiflash_partitions[2].size              = SZ_8M - SZ_512K;
1208                                break;
1209                                case 3:
1210                                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1211                                break;
1212                                case 4:
1213                                        laguna_spiflash_partitions[2].size              = SZ_32M - SZ_512K;
1214                                break;
1215                                case 5:
1216                                        laguna_spiflash_partitions[2].size              = SZ_64M - SZ_512K;
1217                                break;
1218                        }
1219#endif
1220                        unsigned int flashsize = laguna_spiflash_partitions[2].size + SZ_512K;
1221                        unsigned char *buf = (unsigned char *)ioremap(CNS3XXX_SPI_FLASH_BASE,SZ_16M-1);
1222                //      unsigned char *buf = (unsigned char *)CNS3XXX_SPI_FLASH_BASE;
1223                        unsigned int offset=0;
1224                        int tmplen;
1225                        int filesyssize=0;
1226                        int erasesize=0x40000;
1227                        while(offset<SZ_8M)
1228                        {
1229                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1230                        {
1231                        struct squashfs_super_block *sb;
1232                        char *block = vmalloc(0x40000);
1233                        memcpy(block,buf,0x40000);
1234                        sb = (struct squashfs_super_block*)block;
1235                        printk(KERN_EMERG "found squashfs @0x%08X magic=0x%08X\n",offset,*((__u32 *) buf));
1236                        filesyssize = sb->bytes_used;
1237                        vfree(block);
1238                        tmplen = offset + filesyssize;
1239                        tmplen +=  (erasesize - 1);
1240                        tmplen &= ~(erasesize - 1);
1241                        filesyssize = tmplen - offset;
1242                        laguna_spiflash_partitions[3].offset = offset;
1243                        laguna_spiflash_partitions[3].size = filesyssize;
1244                        laguna_spiflash_partitions[4].offset = offset + filesyssize;
1245                        laguna_spiflash_partitions[4].size = (flashsize- SZ_256K) - laguna_spiflash_partitions[4].offset;
1246                        laguna_spiflash_partitions[5].offset = (flashsize - SZ_256K);
1247                        laguna_spiflash_partitions[5].size = SZ_256K;
1248                        break;
1249                        }
1250                        buf+=0x1000;
1251                        offset+=0x1000;
1252                        }
1253                        iounmap(buf);
1254                        HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1255
1256                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1257                        spi_register_board_info(laguna_spi_devices, ARRAY_SIZE(laguna_spi_devices));
1258
1259                }
1260
1261                if (laguna_info.config_bitmap & (SPI0_LOAD | SPI1_LOAD))
1262                {
1263                        platform_device_register(&laguna_spi_controller_device);
1264                }
1265
1266                if (laguna_info.config2_bitmap & GPS_LOAD)
1267                        platform_device_register(&laguna_pps_device);
1268
1269                /*
1270                 *      Do any model specific setup not known by the bitmap by matching
1271                 *  the first 6 characters of the model name
1272                 */
1273
1274
1275                if ( (strncmp(laguna_info.model, "GW2388", 6) == 0)
1276                  || (strncmp(laguna_info.model, "GW2389", 6) == 0) )
1277                {
1278                        // configure GPIO's
1279                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2388));
1280                        // configure LED's
1281                        laguna_gpio_leds_data.num_leds = 2;
1282                } else if (strncmp(laguna_info.model, "GW2387", 6) == 0) {
1283                        // configure GPIO's
1284                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2387));
1285                        // configure LED's
1286                        laguna_gpio_leds_data.num_leds = 2;
1287                } else if (strncmp(laguna_info.model, "GW2386", 6) == 0) {
1288                        // configure GPIO's
1289                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2386));
1290                        // configure LED's
1291                        laguna_gpio_leds_data.num_leds = 2;
1292                } else if (strncmp(laguna_info.model, "GW2385", 6) == 0) {
1293                        // configure GPIO's
1294                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2385));
1295                        // configure LED's
1296                        laguna_gpio_leds[0].gpio = 115;
1297                        laguna_gpio_leds[1].gpio = 12;
1298                        laguna_gpio_leds[1].name = "red";
1299                        laguna_gpio_leds[1].active_low = 0,
1300                        laguna_gpio_leds[2].gpio = 14;
1301                        laguna_gpio_leds[2].name = "green";
1302                        laguna_gpio_leds[2].active_low = 0,
1303                        laguna_gpio_leds[3].gpio = 15;
1304                        laguna_gpio_leds[3].name = "blue";
1305                        laguna_gpio_leds[3].active_low = 0,
1306                        laguna_gpio_leds_data.num_leds = 4;
1307                } else if (strncmp(laguna_info.model, "GW2384", 6) == 0 || strncmp(laguna_info.model, "GW2394", 6) == 0) {
1308                        // configure GPIO's
1309                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2384));
1310                        // configure LED's
1311                        laguna_gpio_leds_data.num_leds = 1;
1312                } else if (strncmp(laguna_info.model, "GW2383", 6) == 0) {
1313                        // configure GPIO's
1314                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2383));
1315                        // configure LED's
1316                        laguna_gpio_leds[0].gpio = 107;
1317                        laguna_gpio_leds_data.num_leds = 1;
1318                } else if (strncmp(laguna_info.model, "GW2382", 6) == 0) {
1319                        // configure GPIO's
1320                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2382));
1321                        // configure LED's
1322                        laguna_gpio_leds[0].gpio = 107;
1323                        laguna_gpio_leds_data.num_leds = 1;
1324                } else if (strncmp(laguna_info.model, "GW2380", 6) == 0) {
1325                        // configure GPIO's
1326                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2380));
1327                        // configure LED's
1328                        laguna_gpio_leds[0].gpio = 107;
1329                        laguna_gpio_leds[1].gpio = 106;
1330                        laguna_gpio_leds_data.num_leds = 2;
1331                } else if (strncmp(laguna_info.model, "GW2391", 6) == 0 || strncmp(laguna_info.model, "GW2393", 6) == 0) {
1332                        // configure GPIO's
1333                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2391));
1334                        // configure LED's
1335                        laguna_gpio_leds_data.num_leds = 2;
1336                }
1337                platform_device_register(&laguna_gpio_leds_device);
1338                platform_device_register(&laguna_gpio_dev);
1339        } else {
1340                // Do some defaults here, not sure what yet
1341        }
1342        return 0;
1343}
1344
1345late_initcall(laguna_model_setup);
1346
1347MACHINE_START(GW2388, "Gateworks Corporation Laguna Platform")
1348        .atag_offset    = 0x100,
1349        .smp            = smp_ops(cns3xxx_smp_ops),
1350//      .nr_irqs        = NR_IRQS_CNS3XXX,
1351        .map_io         = laguna_map_io,
1352        .init_irq       = cns3xxx_init_irq,
1353        .init_time      = cns3xxx_timer_init,
1354        .init_machine   = laguna_init,
1355        .init_late      = cns3xxx_pcie_init_late,
1356        .restart        = cns3xxx_restart,
1357MACHINE_END
Note: See TracBrowser for help on using the repository browser.