source: src/linux/universal/linux-3.10/arch/arm/mach-cns3xxx/laguna.c @ 29547

Last change on this file since 29547 was 29547, checked in by BrainSlayer, 13 months ago

generic irq chip

File size: 36.9 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/i2c/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/squashfs_fs.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 struct platform_device laguna_net_device = {
393        .name = "cns3xxx_eth",
394        .id = 0,
395        .resource = laguna_net_resource,
396        .num_resources = ARRAY_SIZE(laguna_net_resource),
397        .dev.platform_data = &laguna_net_data,
398};
399
400
401
402/*
403 * UART
404 */
405static void __init laguna_early_serial_setup(void)
406{
407#ifdef CONFIG_SERIAL_8250_CONSOLE
408        static struct uart_port laguna_serial_port = {
409                .membase        = (void __iomem *)CNS3XXX_UART0_BASE_VIRT,
410                .mapbase        = CNS3XXX_UART0_BASE,
411                .irq            = IRQ_CNS3XXX_UART0,
412                .iotype         = UPIO_MEM,
413                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE,
414                .regshift       = 2,
415                .uartclk        = 24000000,
416                .line           = 0,
417                .type           = PORT_16550A,
418                .fifosize       = 16,
419        };
420
421        early_serial_setup(&laguna_serial_port);
422#endif
423}
424
425static struct resource laguna_uart_resources[] = {
426        {
427                .start = CNS3XXX_UART0_BASE,
428                .end   = CNS3XXX_UART0_BASE + SZ_4K - 1,
429                .flags    = IORESOURCE_MEM
430        },{
431                .start = CNS3XXX_UART2_BASE,
432                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
433                .flags    = IORESOURCE_MEM
434        },{
435                .start = CNS3XXX_UART2_BASE,
436                .end   = CNS3XXX_UART2_BASE + SZ_4K - 1,
437                .flags    = IORESOURCE_MEM
438        },
439};
440
441static struct plat_serial8250_port laguna_uart_data[] = {
442        {
443                .membase        = (char*) (CNS3XXX_UART0_BASE_VIRT),
444                .mapbase        = (CNS3XXX_UART0_BASE),
445                .irq            = IRQ_CNS3XXX_UART0,
446                .iotype         = UPIO_MEM,
447                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
448                .regshift       = 2,
449                .uartclk        = 24000000,
450                .type           = PORT_16550A,
451        },{
452                .membase        = (char*) (CNS3XXX_UART1_BASE_VIRT),
453                .mapbase        = (CNS3XXX_UART1_BASE),
454                .irq            = IRQ_CNS3XXX_UART1,
455                .iotype         = UPIO_MEM,
456                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
457                .regshift       = 2,
458                .uartclk        = 24000000,
459                .type           = PORT_16550A,
460        },{
461                .membase        = (char*) (CNS3XXX_UART2_BASE_VIRT),
462                .mapbase        = (CNS3XXX_UART2_BASE),
463                .irq            = IRQ_CNS3XXX_UART2,
464                .iotype         = UPIO_MEM,
465                .flags          = UPF_BOOT_AUTOCONF | UPF_FIXED_TYPE | UPF_NO_TXEN_TEST,
466                .regshift       = 2,
467                .uartclk        = 24000000,
468                .type           = PORT_16550A,
469        },
470};
471
472static struct platform_device laguna_uart = {
473        .name     = "serial8250",
474        .id     = PLAT8250_DEV_PLATFORM,
475        .dev.platform_data  = laguna_uart_data,
476        .num_resources    = 3,
477        .resource   = laguna_uart_resources
478};
479
480/*
481 * USB
482 */
483static struct resource cns3xxx_usb_ehci_resources[] = {
484        [0] = {
485                .start = CNS3XXX_USB_BASE,
486                .end   = CNS3XXX_USB_BASE + SZ_16M - 1,
487                .flags = IORESOURCE_MEM,
488        },
489        [1] = {
490                .start = IRQ_CNS3XXX_USB_EHCI,
491                .flags = IORESOURCE_IRQ,
492        },
493};
494
495static u64 cns3xxx_usb_ehci_dma_mask = DMA_BIT_MASK(32);
496
497static int csn3xxx_usb_power_on(struct platform_device *pdev)
498{
499        /*
500         * EHCI and OHCI share the same clock and power,
501         * resetting twice would cause the 1st controller been reset.
502         * Therefore only do power up  at the first up device, and
503         * power down at the last down device.
504         *
505         * Set USB AHB INCR length to 16
506         */
507        if (atomic_inc_return(&usb_pwr_ref) == 1) {
508                cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
509                cns3xxx_pwr_clk_en(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
510                cns3xxx_pwr_soft_rst(1 << PM_SOFT_RST_REG_OFFST_USB_HOST);
511                __raw_writel((__raw_readl(MISC_CHIP_CONFIG_REG) | (0X2 << 24)),
512                        MISC_CHIP_CONFIG_REG);
513        }
514
515        return 0;
516}
517
518static void csn3xxx_usb_power_off(struct platform_device *pdev)
519{
520        /*
521         * EHCI and OHCI share the same clock and power,
522         * resetting twice would cause the 1st controller been reset.
523         * Therefore only do power up  at the first up device, and
524         * power down at the last down device.
525         */
526        if (atomic_dec_return(&usb_pwr_ref) == 0)
527                cns3xxx_pwr_clk_dis(1 << PM_CLK_GATE_REG_OFFSET_USB_HOST);
528}
529
530static struct usb_ehci_pdata cns3xxx_usb_ehci_pdata = {
531        .power_on       = csn3xxx_usb_power_on,
532        .power_off      = csn3xxx_usb_power_off,
533};
534
535
536static struct platform_device cns3xxx_usb_ehci_device = {
537        .name          = "ehci-platform",
538        .num_resources = ARRAY_SIZE(cns3xxx_usb_ehci_resources),
539        .resource      = cns3xxx_usb_ehci_resources,
540        .dev           = {
541                .dma_mask          = &cns3xxx_usb_ehci_dma_mask,
542                .coherent_dma_mask = DMA_BIT_MASK(32),
543                .platform_data     = &cns3xxx_usb_ehci_pdata,
544        },
545};
546
547
548static struct resource cns3xxx_usb_ohci_resources[] = {
549        [0] = {
550                .start = CNS3XXX_USB_OHCI_BASE,
551                .end   = CNS3XXX_USB_OHCI_BASE + SZ_16M - 1,
552                .flags = IORESOURCE_MEM,
553        },
554        [1] = {
555                .start = IRQ_CNS3XXX_USB_OHCI,
556                .flags = IORESOURCE_IRQ,
557        },
558};
559
560static u64 cns3xxx_usb_ohci_dma_mask = DMA_BIT_MASK(32);
561
562static struct usb_ohci_pdata cns3xxx_usb_ohci_pdata = {
563        .num_ports      = 1,
564        .power_on       = csn3xxx_usb_power_on,
565        .power_off      = csn3xxx_usb_power_off,
566};
567
568static struct platform_device cns3xxx_usb_ohci_device = {
569        .name          = "ohci-platform",
570        .num_resources = ARRAY_SIZE(cns3xxx_usb_ohci_resources),
571        .resource      = cns3xxx_usb_ohci_resources,
572        .dev           = {
573                .dma_mask          = &cns3xxx_usb_ohci_dma_mask,
574                .coherent_dma_mask = DMA_BIT_MASK(32),
575                .platform_data     = &cns3xxx_usb_ohci_pdata,
576        },
577};
578
579static struct resource cns3xxx_usb_otg_resources[] = {
580        [0] = {
581                .start = CNS3XXX_USBOTG_BASE,
582                .end   = CNS3XXX_USBOTG_BASE + SZ_16M - 1,
583                .flags = IORESOURCE_MEM,
584        },
585        [1] = {
586                .start = IRQ_CNS3XXX_USB_OTG,
587                .flags = IORESOURCE_IRQ,
588        },
589};
590
591static u64 cns3xxx_usb_otg_dma_mask = DMA_BIT_MASK(32);
592
593static struct platform_device cns3xxx_usb_otg_device = {
594        .name          = "dwc_otg",
595        .num_resources = ARRAY_SIZE(cns3xxx_usb_otg_resources),
596        .resource      = cns3xxx_usb_otg_resources,
597        .dev           = {
598                .dma_mask          = &cns3xxx_usb_otg_dma_mask,
599                .coherent_dma_mask = DMA_BIT_MASK(32),
600        },
601};
602
603/*
604 * I2C
605 */
606static struct resource laguna_i2c_resource[] = {
607        {
608                .start    = CNS3XXX_SSP_BASE + 0x20,
609                .end      = 0x7100003f,
610                .flags    = IORESOURCE_MEM,
611        },{
612                .start    = IRQ_CNS3XXX_I2C,
613                .flags    = IORESOURCE_IRQ,
614        },
615};
616
617static struct platform_device laguna_i2c_controller = {
618        .name   = "cns3xxx-i2c",
619        .num_resources  = 2,
620        .resource = laguna_i2c_resource,
621};
622
623static struct memory_accessor *at24_mem_acc;
624
625static void at24_setup(struct memory_accessor *mem_acc, void *context)
626{
627        char buf[16];
628
629        at24_mem_acc = mem_acc;
630
631        /* Read MAC addresses */
632        if (at24_mem_acc->read(at24_mem_acc, buf, 0x100, 6) == 6)
633                memcpy(&laguna_net_data.hwaddr[0], buf, ETH_ALEN);
634        if (at24_mem_acc->read(at24_mem_acc, buf, 0x106, 6) == 6)
635                memcpy(&laguna_net_data.hwaddr[1], buf, ETH_ALEN);
636        if (at24_mem_acc->read(at24_mem_acc, buf, 0x10C, 6) == 6)
637                memcpy(&laguna_net_data.hwaddr[2], buf, ETH_ALEN);
638        if (at24_mem_acc->read(at24_mem_acc, buf, 0x112, 6) == 6)
639                memcpy(&laguna_net_data.hwaddr[3], buf, ETH_ALEN);
640
641        /* Read out Model Information */
642        if (at24_mem_acc->read(at24_mem_acc, buf, 0x130, 16) == 16)
643                memcpy(&laguna_info.model, buf, 16);
644        if (at24_mem_acc->read(at24_mem_acc, buf, 0x140, 1) == 1)
645                memcpy(&laguna_info.nor_flash_size, buf, 1);
646        if (at24_mem_acc->read(at24_mem_acc, buf, 0x141, 1) == 1)
647                memcpy(&laguna_info.spi_flash_size, buf, 1);
648        if (at24_mem_acc->read(at24_mem_acc, buf, 0x142, 4) == 4)
649                memcpy(&laguna_info.config_bitmap, buf, 4);
650        if (at24_mem_acc->read(at24_mem_acc, buf, 0x146, 4) == 4)
651                memcpy(&laguna_info.config2_bitmap, buf, 4);
652};
653
654static struct at24_platform_data laguna_eeprom_info = {
655        .byte_len = 1024,
656        .page_size = 16,
657        .flags = AT24_FLAG_READONLY,
658        .setup = at24_setup,
659};
660
661static struct pca953x_platform_data laguna_pca_data = {
662        .gpio_base = 100,
663};
664
665static struct pca953x_platform_data laguna_pca2_data = {
666        .gpio_base = 116,
667        .irq_base = -1,
668};
669
670static struct i2c_board_info __initdata laguna_i2c_devices[] = {
671        {
672                I2C_BOARD_INFO("pca9555", 0x23),
673                .platform_data = &laguna_pca_data,
674        },{
675                I2C_BOARD_INFO("pca9555", 0x27),
676                .platform_data = &laguna_pca2_data,
677        },{
678                I2C_BOARD_INFO("gsp", 0x29),
679        },{
680                I2C_BOARD_INFO ("24c08",0x50),
681                .platform_data = &laguna_eeprom_info,
682        },{
683                I2C_BOARD_INFO("ds1672", 0x68),
684        },
685};
686
687/*
688 * Watchdog
689 */
690
691static struct resource laguna_watchdog_resource[] = {
692        {
693                .start = CNS3XXX_TC11MP_TWD_BASE,
694                .end = CNS3XXX_TC11MP_TWD_BASE + 0x100 - 1,
695                .flags = IORESOURCE_MEM,
696        },{
697                .start = IRQ_LOCALWDOG,
698                .end = IRQ_LOCALWDOG,
699                .flags = IORESOURCE_IRQ,
700        }
701};
702
703
704static struct platform_device laguna_watchdog = {
705        .name = "mpcore_wdt",
706        .id = -1,
707        .num_resources = ARRAY_SIZE(laguna_watchdog_resource),
708        .resource = laguna_watchdog_resource,
709};
710
711static struct platform_device cns3xxx_watchdog_device = {
712        .name           = "cns3xxx-wdt",
713        .id             = -1,
714        .num_resources  = ARRAY_SIZE(laguna_watchdog_resource),
715        .resource       = laguna_watchdog_resource,
716};
717
718
719/*
720 * GPS PPS
721 */
722static struct pps_gpio_platform_data laguna_pps_data = {
723        .gpio_pin = 0,
724        .gpio_label = "GPS_PPS",
725        .assert_falling_edge = 0,
726        .capture_clear = 0,
727};
728
729static struct platform_device laguna_pps_device = {
730        .name = "pps-gpio",
731        .id = -1,
732        .dev.platform_data = &laguna_pps_data,
733};
734
735
736static struct platform_device laguna_gpio_dev = {
737        .name = "GPIODEV",
738        .id = -1,
739};
740/*
741 * GPIO
742 */
743
744static struct gpio laguna_gpio_gw2391[] = {
745        {   0, GPIOF_IN           , "*GPS_PPS" },
746        {   1, GPIOF_IN           , "*GSC_IRQ#" },
747        {   2, GPIOF_IN           , "*USB_FAULT#" },
748        {   5, GPIOF_OUT_INIT_LOW , "*USB0_PCI_SEL" },
749        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
750        {   7, GPIOF_OUT_INIT_LOW , "*USB1_PCI_SEL" },
751        {   8, GPIOF_OUT_INIT_HIGH, "*PERST#" },
752        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN#" },
753        { 100, GPIOF_IN           , "*USER_PB#" },
754        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
755        { 108, GPIOF_IN           , "DIO0" },
756        { 109, GPIOF_IN           , "DIO1" },
757        { 110, GPIOF_IN           , "DIO2" },
758        { 111, GPIOF_IN           , "DIO3" },
759        { 112, GPIOF_IN           , "DIO4" },
760};
761
762static struct gpio laguna_gpio_gw2388[] = {
763        {   0, GPIOF_IN           , "*GPS_PPS" },
764        {   1, GPIOF_IN           , "*GSC_IRQ#" },
765        {   3, GPIOF_IN           , "*USB_FAULT#" },
766        {   6, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
767        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
768        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
769        {   9, GPIOF_OUT_INIT_LOW , "*FP_SER_EN" },
770        { 100, GPIOF_OUT_INIT_HIGH, "*USER_PB#" },
771        { 108, GPIOF_IN           , "DIO0" },
772        { 109, GPIOF_IN           , "DIO1" },
773        { 110, GPIOF_IN           , "DIO2" },
774        { 111, GPIOF_IN           , "DIO3" },
775        { 112, GPIOF_IN           , "DIO4" },
776};
777
778static struct gpio laguna_gpio_gw2387[] = {
779        {   0, GPIOF_IN           , "*GPS_PPS" },
780        {   1, GPIOF_IN           , "*GSC_IRQ#" },
781        {   2, GPIOF_IN           , "*USB_FAULT#" },
782        {   5, GPIOF_OUT_INIT_LOW , "*USB_PCI_SEL" },
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_IN           , "*USER_PB#" },
788        { 103, GPIOF_OUT_INIT_HIGH, "*V5_EN" },
789        { 108, GPIOF_IN           , "DIO0" },
790        { 109, GPIOF_IN           , "DIO1" },
791        { 110, GPIOF_IN           , "DIO2" },
792        { 111, GPIOF_IN           , "DIO3" },
793        { 112, GPIOF_IN           , "DIO4" },
794        { 113, GPIOF_IN           , "DIO5" },
795};
796
797static struct gpio laguna_gpio_gw2385[] = {
798        {   0, GPIOF_IN           , "*GSC_IRQ#" },
799        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
800        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
801        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
802        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_PCI_SEL" },
803        {   7, GPIOF_OUT_INIT_LOW , "*GSM_SEL0" },
804        {   8, GPIOF_OUT_INIT_LOW , "*GSM_SEL1" },
805        {   9, GPIOF_OUT_INIT_LOW , "*SER_EN" },
806        {  10, GPIOF_IN,            "*USER_PB#" },
807        {  11, GPIOF_OUT_INIT_HIGH, "*PERST#" },
808        { 100, GPIOF_IN           , "*USER_PB#" },
809        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
810};
811
812static struct gpio laguna_gpio_gw2384[] = {
813        {   0, GPIOF_IN           , "*GSC_IRQ#" },
814        {   1, GPIOF_OUT_INIT_HIGH, "*USB_HST_VBUS_EN" },
815        {   2, GPIOF_IN           , "*USB_HST_FAULT#" },
816        {   5, GPIOF_IN           , "*USB_OTG_FAULT#" },
817        {   6, GPIOF_OUT_INIT_LOW , "*USB_HST_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        {  12, GPIOF_OUT_INIT_LOW , "J10_DIOLED0" },
822        {  13, GPIOF_OUT_INIT_HIGH, "*I2CMUX_RST#" },
823        {  14, GPIOF_OUT_INIT_LOW , "J10_DIOLED1" },
824        {  15, GPIOF_OUT_INIT_LOW , "J10_DIOLED2" },
825        { 100, GPIOF_IN           , "*USER_PB#" },
826        { 103, GPIOF_OUT_INIT_HIGH, "V5_EN" },
827        { 108, GPIOF_IN           , "J9_DIOGSC0" },
828};
829
830static struct gpio laguna_gpio_gw2383[] = {
831        {   0, GPIOF_IN           , "*GPS_PPS" },
832        {   1, GPIOF_IN           , "*GSC_IRQ#" },
833        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
834        {   3, GPIOF_IN           , "GPIO0" },
835        {   8, GPIOF_IN           , "GPIO1" },
836        { 100, GPIOF_IN           , "DIO0" },
837        { 101, GPIOF_IN           , "DIO1" },
838        { 108, GPIOF_IN           , "*USER_PB#" },
839};
840
841static struct gpio laguna_gpio_gw2382[] = {
842        {   0, GPIOF_IN           , "*GPS_PPS" },
843        {   1, GPIOF_IN           , "*GSC_IRQ#" },
844        {   2, GPIOF_OUT_INIT_HIGH, "*PCIE_RST#" },
845        {   3, GPIOF_IN           , "GPIO0" },
846        {   4, GPIOF_IN           , "GPIO1" },
847        {   9, GPIOF_OUT_INIT_HIGH, "*USB_VBUS_EN" },
848        {  10, GPIOF_OUT_INIT_HIGH, "*USB_PCI_SEL#" },
849        { 100, GPIOF_IN           , "DIO0" },
850        { 101, GPIOF_IN           , "DIO1" },
851        { 108, GPIOF_IN           , "*USER_PB#" },
852};
853
854static struct gpio laguna_gpio_gw2380[] = {
855        {   0, GPIOF_IN           , "*GPS_PPS" },
856        {   1, GPIOF_IN           , "*GSC_IRQ#" },
857        {   3, GPIOF_IN           , "GPIO0" },
858        {   8, GPIOF_IN           , "GPIO1" },
859        { 100, GPIOF_IN           , "DIO0" },
860        { 101, GPIOF_IN           , "DIO1" },
861        { 102, GPIOF_IN           , "DIO2" },
862        { 103, GPIOF_IN           , "DIO3" },
863        { 108, GPIOF_IN           , "*USER_PB#" },
864};
865
866
867/*
868 * Initialization
869 */
870
871static void __init laguna_init(void)
872{
873        platform_device_register(&laguna_watchdog);
874        platform_device_register(&cns3xxx_watchdog_device);
875
876        platform_device_register(&laguna_i2c_controller);
877
878        i2c_register_board_info(0, laguna_i2c_devices,
879                        ARRAY_SIZE(laguna_i2c_devices));
880
881
882        pm_power_off = cns3xxx_power_off;
883}
884
885static struct map_desc laguna_io_desc[] __initdata = {
886        {
887                .virtual        = CNS3XXX_UART0_BASE_VIRT,
888                .pfn            = __phys_to_pfn(CNS3XXX_UART0_BASE),
889                .length         = SZ_4K,
890                .type           = MT_DEVICE,
891        },{
892                .virtual        = CNS3XXX_UART1_BASE_VIRT,
893                .pfn            = __phys_to_pfn(CNS3XXX_UART1_BASE),
894                .length         = SZ_4K,
895                .type           = MT_DEVICE,
896        },{
897                .virtual        = CNS3XXX_UART2_BASE_VIRT,
898                .pfn            = __phys_to_pfn(CNS3XXX_UART2_BASE),
899                .length         = SZ_4K,
900                .type           = MT_DEVICE,
901        },
902};
903
904static void __init laguna_map_io(void)
905{
906        cns3xxx_common_init();
907        iotable_init(laguna_io_desc, ARRAY_SIZE(laguna_io_desc));
908
909        laguna_early_serial_setup();
910}
911
912static int laguna_register_gpio(struct gpio *array, size_t num)
913{
914
915        int i, err, ret;
916
917        ret = 0;
918        for (i = 0; i < num; i++, array++) {
919                const char *label = array->label;
920                if (label[0] == '*')
921                        label++;
922                err = gpio_request_one(array->gpio, array->flags, label);
923                if (err)
924                        ret = err;
925                else {
926                        err = gpio_export(array->gpio, array->label[0] != '*');
927                }
928        }
929        return ret;
930}
931
932 
933#define SPI_MEM_MAP_VALUE(reg_offset)           (*((u32 volatile *)(CNS3XXX_SSP_BASE_VIRT + reg_offset)))
934
935#define SPI_CONFIGURATION_REG                   SPI_MEM_MAP_VALUE(0x40)
936#define SPI_SERVICE_STATUS_REG                  SPI_MEM_MAP_VALUE(0x44)
937#define SPI_BIT_RATE_CONTROL_REG                SPI_MEM_MAP_VALUE(0x48)
938#define SPI_TRANSMIT_CONTROL_REG                SPI_MEM_MAP_VALUE(0x4C)
939#define SPI_TRANSMIT_BUFFER_REG                 SPI_MEM_MAP_VALUE(0x50)
940#define SPI_RECEIVE_CONTROL_REG                 SPI_MEM_MAP_VALUE(0x54)
941#define SPI_RECEIVE_BUFFER_REG                  SPI_MEM_MAP_VALUE(0x58)
942#define SPI_FIFO_TRANSMIT_CONFIG_REG            SPI_MEM_MAP_VALUE(0x5C)
943#define SPI_FIFO_TRANSMIT_CONTROL_REG           SPI_MEM_MAP_VALUE(0x60)
944#define SPI_FIFO_RECEIVE_CONFIG_REG             SPI_MEM_MAP_VALUE(0x64)
945#define SPI_INTERRUPT_STATUS_REG                SPI_MEM_MAP_VALUE(0x68)
946#define SPI_INTERRUPT_ENABLE_REG                SPI_MEM_MAP_VALUE(0x6C)
947
948#define SPI_TRANSMIT_BUFFER_REG_ADDR            (CNS3XXX_SSP_BASE +0x50)
949#define SPI_RECEIVE_BUFFER_REG_ADDR             (CNS3XXX_SSP_BASE +0x58)
950
951/* allow disabling of external isolated PCIe IRQs */
952static int cns3xxx_pciextirq = 1;
953static int __init cns3xxx_pciextirq_disable(char *s)
954{
955        cns3xxx_pciextirq = 0;
956        return 1;
957}
958__setup("noextirq", cns3xxx_pciextirq_disable);
959
960
961static int __init laguna_pcie_init(void)
962{
963        u32 __iomem *mem = (void __iomem *)(CNS3XXX_GPIOB_BASE_VIRT + 0x0004);
964        u32 reg = (__raw_readl(mem) >> 26) & 0xf;
965        int irqs[] = {
966                IRQ_CNS3XXX_EXTERNAL_PIN0,
967                IRQ_CNS3XXX_EXTERNAL_PIN1,
968                IRQ_CNS3XXX_EXTERNAL_PIN2,
969                154,
970        };
971
972        if (!machine_is_gw2388())
973                return 0;
974
975        /* Verify GPIOB[26:29] == 0001b indicating support for ext irqs */
976        if (cns3xxx_pciextirq && reg != 1)
977                cns3xxx_pciextirq = 0;
978
979        if (cns3xxx_pciextirq) {
980                printk("laguna: using isolated PCI interrupts:"
981                       " irq%d/irq%d/irq%d/irq%d\n",
982                       irqs[0], irqs[1], irqs[2], irqs[3]);
983                return cns3xxx_pcie_init(irqs, NULL);
984        }
985        printk("laguna: using shared PCI interrupts: irq%d\n",
986               IRQ_CNS3XXX_PCIE0_DEVICE);
987        return cns3xxx_pcie_init(NULL, NULL);
988}
989
990subsys_initcall(laguna_pcie_init);
991
992extern void __init cns3xxx_gpio_init(int gpio_base, int ngpio,
993        u32 base, int irq, int secondary_irq_base);
994
995static int __init laguna_model_setup(void)
996{
997        u32 __iomem *mem;
998        u32 reg;
999
1000        printk("Running on Gateworks Laguna %s\n", laguna_info.model);
1001
1002        cns3xxx_gpio_init( 0, 32, CNS3XXX_GPIOA_BASE_VIRT, IRQ_CNS3XXX_GPIOA,
1003                NR_IRQS_CNS3XXX);
1004        /*
1005         * If pcie external interrupts are supported and desired
1006         * configure IRQ types and configure pin function.
1007         * Note that cns3xxx_pciextirq is enabled by default, but can be
1008         * unset via the 'noextirq' kernel param or by laguna_pcie_init() if
1009         * the baseboard model does not support this hardware feature.
1010         */
1011        if (cns3xxx_pciextirq) {
1012                mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0018);
1013                reg = __raw_readl(mem);
1014                /* GPIO26 is gpio, EXT_INT[0:2] not gpio func */
1015                reg &= ~0x3c000000;
1016                reg |= 0x38000000;
1017                __raw_writel(reg, mem);
1018
1019                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1020                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1021
1022                irq_set_irq_type(154, IRQ_TYPE_LEVEL_LOW);
1023                irq_set_irq_type(93, IRQ_TYPE_LEVEL_HIGH);
1024                irq_set_irq_type(94, IRQ_TYPE_LEVEL_HIGH);
1025                irq_set_irq_type(95, IRQ_TYPE_LEVEL_HIGH);
1026        } else {
1027                cns3xxx_gpio_init(32, 32, CNS3XXX_GPIOB_BASE_VIRT,
1028                                  IRQ_CNS3XXX_GPIOB, NR_IRQS_CNS3XXX + 32);
1029        }
1030
1031
1032        if (strncmp(laguna_info.model, "GW", 2) == 0) {
1033                printk("CONFIG BITMAP = 0x%08X\n",laguna_info.config_bitmap);
1034                if (laguna_info.config_bitmap & ETH0_LOAD)
1035                        laguna_net_data.ports |= BIT(0);
1036                printk(KERN_INFO "detecting ETH\n");
1037                if (strncmp(laguna_info.model, "GW2388", 6) == 0 || strncmp(laguna_info.model, "GW2389", 6) == 0)
1038                {
1039                if (laguna_info.config_bitmap & ETH1_LOAD)
1040                        laguna_net_data.ports |= BIT(1);
1041                if (laguna_info.config_bitmap & ETH2_LOAD)
1042                        laguna_net_data.ports |= BIT(2);
1043                }
1044                printk(KERN_INFO "registering ETH\n");
1045                if (laguna_net_data.ports)
1046                        platform_device_register(&laguna_net_device);
1047
1048                printk(KERN_INFO "registering AHCI\n");
1049                if (laguna_info.config_bitmap & (SATA0_LOAD | SATA1_LOAD))
1050                        cns3xxx_ahci_init();
1051
1052                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1053                {
1054                printk(KERN_INFO "check USB0\n");
1055                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1056                        printk(KERN_INFO "register USB0\n");
1057                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1058
1059                        /* DRVVBUS pins share with GPIOA */
1060                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1061                        reg = __raw_readl(mem);
1062                        reg |= 0x8;
1063                        __raw_writel(reg, mem);
1064
1065                        /* Enable OTG */
1066                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1067                        reg = __raw_readl(mem);
1068                        reg &= ~(1 << 10);
1069                        __raw_writel(reg, mem);
1070
1071                        platform_device_register(&cns3xxx_usb_otg_device);
1072                }
1073
1074                printk(KERN_INFO "check USB1\n");
1075                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1076                        printk(KERN_INFO "register USB1\n");
1077                        platform_device_register(&cns3xxx_usb_ehci_device);
1078                        platform_device_register(&cns3xxx_usb_ohci_device);
1079                }
1080                }else{
1081                if (laguna_info.config_bitmap & (USB0_LOAD)) {
1082
1083                        printk(KERN_EMERG "power up USB0\n");
1084                        cns3xxx_pwr_power_up(1 << PM_PLL_HM_PD_CTRL_REG_OFFSET_PLL_USB);
1085
1086                        /* DRVVBUS pins share with GPIOA */
1087                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0014);
1088                        reg = __raw_readl(mem);
1089                        reg |= 0x8;
1090                        __raw_writel(reg, mem);
1091
1092                        /* Enable OTG */
1093                        mem = (void __iomem *)(CNS3XXX_MISC_BASE_VIRT + 0x0808);
1094                        reg = __raw_readl(mem);
1095                        reg &= ~(1 << 10);
1096                        __raw_writel(reg, mem);
1097
1098                        platform_device_register(&cns3xxx_usb_otg_device);
1099                }
1100
1101                if (laguna_info.config_bitmap & (USB1_LOAD)) {
1102                        printk(KERN_EMERG "power up ehci/ohci\n");
1103                        platform_device_register(&cns3xxx_usb_ehci_device);
1104                        platform_device_register(&cns3xxx_usb_ohci_device);
1105                }
1106                }
1107
1108
1109                if (laguna_info.config_bitmap & (SD_LOAD))
1110                {
1111                        printk(KERN_EMERG "init sdhci\n");
1112                        cns3xxx_sdhci_init();
1113                }
1114                printk(KERN_INFO "check UART\n");
1115                if (laguna_info.config_bitmap & (UART0_LOAD))
1116                        laguna_uart.num_resources = 1;
1117                if (laguna_info.config_bitmap & (UART1_LOAD))
1118                        laguna_uart.num_resources = 2;
1119                if (laguna_info.config_bitmap & (UART2_LOAD))
1120                        laguna_uart.num_resources = 3;
1121                printk(KERN_INFO "register %d UART(s) \n",laguna_uart.num_resources);
1122                platform_device_register(&laguna_uart);
1123
1124                printk(KERN_EMERG "notflash size %d\n",laguna_info.nor_flash_size);
1125                if ((laguna_info.config2_bitmap & (NOR_FLASH_LOAD)) && (strncmp(laguna_info.model, "GW2388", 6) == 0 || strncmp(laguna_info.model, "GW2387", 6) == 0 || strncmp(laguna_info.model, "GW2389", 6) == 0 || strncmp(laguna_info.model, "GW2391", 6) == 0)) {
1126                        printk(KERN_EMERG "detecting NOR FLASH\n");
1127//                      if (laguna_info.nor_flash_size < 1 || laguna_info.nor_flash_size > 5)
1128//                          laguna_info.nor_flash_size = 2; //guess default for wrong config
1129                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1130                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1131                        switch (laguna_info.nor_flash_size) {
1132                                case 1:
1133                                        laguna_norflash_partitions[2].size = SZ_8M - SZ_256K - SZ_128K  - SZ_128K;
1134                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_8M - 1;
1135                                break;
1136                                case 2:
1137                                        laguna_norflash_partitions[2].size = SZ_16M - SZ_256K - SZ_128K  - SZ_128K;
1138                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_16M - 1;
1139                                break;
1140                                case 3:
1141                                        laguna_norflash_partitions[2].size = SZ_32M - SZ_256K - SZ_128K  - SZ_128K;
1142                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_32M - 1;
1143                                break;
1144                                case 4:
1145                                        laguna_norflash_partitions[2].size = SZ_64M - SZ_256K - SZ_128K  - SZ_128K;
1146                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_64M - 1;
1147                                break;
1148                                case 5:
1149                                        laguna_norflash_partitions[2].size = SZ_128M - SZ_256K - SZ_128K  - SZ_128K;
1150                                        laguna_norflash_resource.end = CNS3XXX_FLASH_BASE + SZ_128M - 1;
1151                                break;
1152                        }
1153                        unsigned int flashsize = laguna_norflash_partitions[2].size + SZ_256K + SZ_128K + SZ_128K;
1154                        unsigned char *buf = (unsigned char *)ioremap(laguna_norflash_resource.start,laguna_norflash_resource.end - laguna_norflash_resource.start + 1);
1155                        unsigned int offset=0;
1156                        int tmplen;
1157                        int filesyssize=0;
1158                        int erasesize=0x20000;
1159                        while(offset<laguna_norflash_resource.end)
1160                        {
1161                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1162                        {
1163                //      printk(KERN_EMERG "found squashfs\n");
1164                        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
1165                        filesyssize = sb->bytes_used;
1166                        tmplen = offset + filesyssize;
1167                        tmplen +=  (erasesize - 1);
1168                        tmplen &= ~(erasesize - 1);
1169                        filesyssize = tmplen - offset;
1170                        laguna_norflash_partitions[3].offset = offset;
1171                        laguna_norflash_partitions[3].size = filesyssize;
1172                        laguna_norflash_partitions[4].offset = offset + filesyssize;
1173                        laguna_norflash_partitions[4].size = (flashsize- SZ_128K) - laguna_norflash_partitions[4].offset;
1174                        laguna_norflash_partitions[5].offset = (flashsize - SZ_128K);
1175                        laguna_norflash_partitions[5].size = SZ_128K;
1176                        break;
1177                        }
1178                        buf+=0x1000;
1179                        offset+=0x1000;
1180                        }
1181
1182                        platform_device_register(&laguna_norflash_device);
1183                }
1184
1185                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)) {
1186                //      printk(KERN_EMERG "detecting SPI FLASH\n");
1187                        SPI_CONFIGURATION_REG = 0x40000000;
1188                        HAL_MISC_ENABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1189                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1190#if 0
1191                        switch (laguna_info.spi_flash_size) {
1192                                case 1:
1193                                        laguna_spiflash_partitions[2].size              = SZ_4M - SZ_512K;
1194                                break;
1195                                case 2:
1196                                        laguna_spiflash_partitions[2].size              = SZ_8M - SZ_512K;
1197                                break;
1198                                case 3:
1199                                        laguna_spiflash_partitions[2].size              = SZ_16M - SZ_512K;
1200                                break;
1201                                case 4:
1202                                        laguna_spiflash_partitions[2].size              = SZ_32M - SZ_512K;
1203                                break;
1204                                case 5:
1205                                        laguna_spiflash_partitions[2].size              = SZ_64M - SZ_512K;
1206                                break;
1207                        }
1208#endif
1209                        unsigned int flashsize = laguna_spiflash_partitions[2].size + SZ_512K;
1210                        unsigned char *buf = (unsigned char *)ioremap(CNS3XXX_SPI_FLASH_BASE,SZ_16M-1);
1211                //      unsigned char *buf = (unsigned char *)CNS3XXX_SPI_FLASH_BASE;
1212                        unsigned int offset=0;
1213                        int tmplen;
1214                        int filesyssize=0;
1215                        int erasesize=0x40000;
1216                        while(offset<SZ_8M)
1217                        {
1218                        if (*((__u32 *) buf) == SQUASHFS_MAGIC)
1219                        {
1220                        struct squashfs_super_block *sb;
1221                        char *block = vmalloc(0x40000);
1222                        memcpy(block,buf,0x40000);
1223                        sb = (struct squashfs_super_block*)block;
1224                        printk(KERN_EMERG "found squashfs @0x%08X magic=0x%08X\n",offset,*((__u32 *) buf));
1225                        filesyssize = sb->bytes_used;
1226                        vfree(block);
1227                        tmplen = offset + filesyssize;
1228                        tmplen +=  (erasesize - 1);
1229                        tmplen &= ~(erasesize - 1);
1230                        filesyssize = tmplen - offset;
1231                        laguna_spiflash_partitions[3].offset = offset;
1232                        laguna_spiflash_partitions[3].size = filesyssize;
1233                        laguna_spiflash_partitions[4].offset = offset + filesyssize;
1234                        laguna_spiflash_partitions[4].size = (flashsize- SZ_256K) - laguna_spiflash_partitions[4].offset;
1235                        laguna_spiflash_partitions[5].offset = (flashsize - SZ_256K);
1236                        laguna_spiflash_partitions[5].size = SZ_256K;
1237                        break;
1238                        }
1239                        buf+=0x1000;
1240                        offset+=0x1000;
1241                        }
1242                        HAL_MISC_DISABLE_SPI_SERIAL_FLASH_BANK_ACCESS();
1243
1244                if (strncmp(laguna_info.model, "GW2380", 6) == 0)
1245                        spi_register_board_info(laguna_spi_devices, ARRAY_SIZE(laguna_spi_devices));
1246
1247                }
1248
1249                if (laguna_info.config_bitmap & (SPI0_LOAD | SPI1_LOAD))
1250                {
1251                        platform_device_register(&laguna_spi_controller_device);
1252                }
1253
1254                if (laguna_info.config2_bitmap & GPS_LOAD)
1255                        platform_device_register(&laguna_pps_device);
1256
1257                /*
1258                 *      Do any model specific setup not known by the bitmap by matching
1259                 *  the first 6 characters of the model name
1260                 */
1261
1262
1263                if ( (strncmp(laguna_info.model, "GW2388", 6) == 0)
1264                  || (strncmp(laguna_info.model, "GW2389", 6) == 0) )
1265                {
1266                        // configure GPIO's
1267                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2388));
1268                        // configure LED's
1269                        laguna_gpio_leds_data.num_leds = 2;
1270                } else if (strncmp(laguna_info.model, "GW2387", 6) == 0) {
1271                        // configure GPIO's
1272                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2387));
1273                        // configure LED's
1274                        laguna_gpio_leds_data.num_leds = 2;
1275                } else if (strncmp(laguna_info.model, "GW2385", 6) == 0) {
1276                        // configure GPIO's
1277                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2385));
1278                        // configure LED's
1279                        laguna_gpio_leds[0].gpio = 115;
1280                        laguna_gpio_leds[1].gpio = 12;
1281                        laguna_gpio_leds[1].name = "red";
1282                        laguna_gpio_leds[1].active_low = 0,
1283                        laguna_gpio_leds[2].gpio = 14;
1284                        laguna_gpio_leds[2].name = "green";
1285                        laguna_gpio_leds[2].active_low = 0,
1286                        laguna_gpio_leds[3].gpio = 15;
1287                        laguna_gpio_leds[3].name = "blue";
1288                        laguna_gpio_leds[3].active_low = 0,
1289                        laguna_gpio_leds_data.num_leds = 4;
1290                } else if (strncmp(laguna_info.model, "GW2384", 6) == 0) {
1291                        // configure GPIO's
1292                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2384));
1293                        // configure LED's
1294                        laguna_gpio_leds_data.num_leds = 1;
1295                } else if (strncmp(laguna_info.model, "GW2383", 6) == 0) {
1296                        // configure GPIO's
1297                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2383));
1298                        // configure LED's
1299                        laguna_gpio_leds[0].gpio = 107;
1300                        laguna_gpio_leds_data.num_leds = 1;
1301                } else if (strncmp(laguna_info.model, "GW2382", 6) == 0) {
1302                        // configure GPIO's
1303                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2382));
1304                        // configure LED's
1305                        laguna_gpio_leds[0].gpio = 107;
1306                        laguna_gpio_leds_data.num_leds = 1;
1307                } else if (strncmp(laguna_info.model, "GW2380", 6) == 0) {
1308                        // configure GPIO's
1309                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2380));
1310                        // configure LED's
1311                        laguna_gpio_leds[0].gpio = 107;
1312                        laguna_gpio_leds[1].gpio = 106;
1313                        laguna_gpio_leds_data.num_leds = 2;
1314                } else if (strncmp(laguna_info.model, "GW2391", 6) == 0) {
1315                        // configure GPIO's
1316                        laguna_register_gpio(ARRAY_AND_SIZE(laguna_gpio_gw2391));
1317                        // configure LED's
1318                        laguna_gpio_leds_data.num_leds = 2;
1319                }
1320                platform_device_register(&laguna_gpio_leds_device);
1321                platform_device_register(&laguna_gpio_dev);
1322        } else {
1323                // Do some defaults here, not sure what yet
1324        }
1325        return 0;
1326}
1327
1328late_initcall(laguna_model_setup);
1329
1330MACHINE_START(GW2388, "Gateworks Corporation Laguna Platform")
1331        .atag_offset    = 0x100,
1332        .nr_irqs        = NR_IRQS_CNS3XXX,
1333        .smp            = smp_ops(cns3xxx_smp_ops),
1334        .map_io         = laguna_map_io,
1335        .init_irq       = cns3xxx_init_irq,
1336        .init_time      = cns3xxx_timer_init,
1337        .init_machine   = laguna_init,
1338        .restart        = cns3xxx_restart,
1339MACHINE_END
Note: See TracBrowser for help on using the repository browser.