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

Last change on this file since 31638 was 31638, checked in by brainslayer, 2 weeks ago

fix some compile bugs

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