source: trunk/target/linux/lantiq/patches-2.6.39/110-falcon_board.patch @ 27104

Last change on this file since 27104 was 27104, checked in by florian, 6 years ago

[kernel] update to 2.6.39.1

patch from Peter Wagner

File size: 48.3 KB
  • new file arch/mips/lantiq/falcon/Kconfig

    - +  
     1if SOC_FALCON 
     2 
     3menu "Mips Machine" 
     4 
     5config LANTIQ_MACH_EASY98000 
     6        bool "Easy98000" 
     7        default y 
     8 
     9endmenu 
     10 
     11endif 
  • new file arch/mips/lantiq/falcon/Makefile

    - +  
     1obj-y := clk-falcon.o devices.o gpio.o prom.o sysctrl.o reset.o 
     2obj-y += softdog_vpe.o 
     3obj-$(CONFIG_LANTIQ_MACH_EASY98000) += mach-easy98000.o 
  • new file arch/mips/lantiq/falcon/clk-falcon.c

    - +  
     1/* 
     2 * This program is free software; you can redistribute it and/or modify 
     3 * it under the terms of the GNU General Public License as published by 
     4 * the Free Software Foundation; either version 2 of the License, or 
     5 * (at your option) any later version. 
     6 * 
     7 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     8 */ 
     9 
     10#include <linux/io.h> 
     11#include <linux/module.h> 
     12#include <linux/init.h> 
     13 
     14#include <asm/time.h> 
     15#include <asm/irq.h> 
     16#include <asm/div64.h> 
     17 
     18#include <lantiq_soc.h> 
     19 
     20#include <falcon.h> 
     21#include <gpon_reg_base.h> 
     22#include <sys1_reg.h> 
     23 
     24static struct gpon_reg_sys1 * const pSYS1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE; 
     25 
     26unsigned int 
     27ltq_get_io_region_clock(void) 
     28{ 
     29        return 200000000; /* 200 MHz */ 
     30} 
     31EXPORT_SYMBOL(ltq_get_io_region_clock); 
     32 
     33unsigned int 
     34ltq_get_cpu_hz(void) 
     35{ 
     36        if ((ltq_r32(&pSYS1->cpu0cc) & CPU0CC_CPUDIV) == CPU0CC_CPUDIV_SELFHALF) 
     37                return 200000000; /* 200 MHz */ 
     38        else 
     39                return 400000000; /* 400 MHz */ 
     40} 
     41EXPORT_SYMBOL(ltq_get_cpu_hz); 
     42 
     43unsigned int 
     44ltq_get_fpi_hz(void) 
     45{ 
     46        return 100000000; 
     47} 
     48EXPORT_SYMBOL(ltq_get_fpi_hz); 
  • new file arch/mips/lantiq/falcon/devices.c

    - +  
     1#include <linux/init.h> 
     2#include <linux/module.h> 
     3#include <linux/types.h> 
     4#include <linux/string.h> 
     5#include <linux/mtd/physmap.h> 
     6#include <linux/kernel.h> 
     7#include <linux/reboot.h> 
     8#include <linux/platform_device.h> 
     9#include <linux/leds.h> 
     10#include <linux/etherdevice.h> 
     11#include <linux/reboot.h> 
     12#include <linux/time.h> 
     13#include <linux/io.h> 
     14#include <linux/gpio.h> 
     15#include <linux/leds.h> 
     16#include <linux/spi/spi.h> 
     17 
     18#include <asm/bootinfo.h> 
     19#include <asm/irq.h> 
     20 
     21#include <lantiq.h> 
     22 
     23#include <falcon/falcon_irq.h> 
     24#include <falcon/gpon_reg_base.h> 
     25#include <falcon/sys1_reg.h> 
     26#include <falcon/sys_eth_reg.h> 
     27 
     28#include <falcon/sysctrl.h> 
     29 
     30#include "devices.h" 
     31 
     32unsigned char ltq_ethaddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
     33EXPORT_SYMBOL(ltq_ethaddr); 
     34 
     35static int __init 
     36falcon_set_ethaddr(char *str) 
     37{ 
     38        sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", 
     39                &ltq_ethaddr[0], &ltq_ethaddr[1], &ltq_ethaddr[2], 
     40                &ltq_ethaddr[3], &ltq_ethaddr[4], &ltq_ethaddr[5]); 
     41        return 0; 
     42} 
     43__setup("ethaddr=", falcon_set_ethaddr); 
     44 
     45/* asc ports */ 
     46static struct resource falcon_asc0_resources[] = 
     47{ 
     48        MEM_RES("asc0",GPON_ASC0_BASE,GPON_ASC0_END), 
     49        IRQ_RES("tx",INT_NUM_IM3_IRL0), 
     50        IRQ_RES("rx",INT_NUM_IM3_IRL0+1), 
     51        IRQ_RES("err",INT_NUM_IM3_IRL0+2), 
     52}; 
     53 
     54static struct resource falcon_asc1_resources[] = 
     55{ 
     56        MEM_RES("asc1",GPON_ASC1_BASE,GPON_ASC1_END), 
     57        IRQ_RES("tx",INT_NUM_IM3_IRL0+8), 
     58        IRQ_RES("rx",INT_NUM_IM3_IRL0+9), 
     59        IRQ_RES("err",INT_NUM_IM3_IRL0+10), 
     60}; 
     61 
     62void __init falcon_register_asc(int port) 
     63{ 
     64        switch (port) { 
     65        case 0: 
     66                platform_device_register_simple("ltq_asc", 0, 
     67                        falcon_asc0_resources, ARRAY_SIZE(falcon_asc0_resources)); 
     68                break; 
     69        case 1: 
     70                platform_device_register_simple("ltq_asc", 1, 
     71                        falcon_asc1_resources, ARRAY_SIZE(falcon_asc1_resources)); 
     72                break; 
     73        default: 
     74                break; 
     75        } 
     76} 
     77 
     78/* nor flash */ 
     79static struct resource ltq_nor_resource = 
     80        MEM_RES("nor",LTQ_FLASH_START,LTQ_FLASH_START + LTQ_FLASH_MAX - 1); 
     81 
     82static struct platform_device ltq_nor = { 
     83        .name                   = "ltq_nor", 
     84        .resource               = &ltq_nor_resource, 
     85        .num_resources  = 1, 
     86}; 
     87 
     88void __init falcon_register_nor(struct physmap_flash_data *data) 
     89{ 
     90        ltq_nor.dev.platform_data = data; 
     91        platform_device_register(&ltq_nor); 
     92} 
     93 
     94/* spi flash */ 
     95static struct resource ltq_spi_resources[] = { 
     96        MEM_RES("ebu", GPON_EBU_BASE, GPON_EBU_END), 
     97        MEM_RES("sys1", GPON_SYS1_BASE, GPON_SYS1_END) 
     98}; 
     99 
     100static struct platform_device ltq_spi = { 
     101        .name                   = "falcon_spi", 
     102        .resource               = ltq_spi_resources, 
     103        .num_resources          = ARRAY_SIZE(ltq_spi_resources) 
     104}; 
     105 
     106void __init falcon_register_spi_flash(struct spi_board_info *data) 
     107{ 
     108        spi_register_board_info(data, 1); 
     109        platform_device_register(&ltq_spi); 
     110} 
     111 
     112/* watchdog */ 
     113static struct resource falcon_wdt_resource = 
     114        MEM_RES("watchdog",GPON_WDT_BASE,GPON_WDT_END); 
     115 
     116void __init falcon_register_wdt(void) 
     117{ 
     118        platform_device_register_simple("ltq_wdt", 0, &falcon_wdt_resource, 1); 
     119} 
     120 
     121/* gpio */ 
     122#define DECLARE_GPIO_RES(port) \ 
     123static struct resource falcon_gpio ## port ## _resources[] = { \ 
     124        MEM_RES("gpio"#port,GPON_GPIO ## port ## _BASE,GPON_GPIO ## port ## _END), \ 
     125        MEM_RES("padctrl"#port,GPON_PADCTRL ## port ## _BASE,GPON_PADCTRL ## port ## _END), \ 
     126        IRQ_RES("gpio_mux"#port,FALCON_IRQ_GPIO_P ## port ) \ 
     127} 
     128DECLARE_GPIO_RES(0); 
     129DECLARE_GPIO_RES(1); 
     130DECLARE_GPIO_RES(2); 
     131#ifdef REGISTER_ALL_GPIO_PORTS 
     132#if NR_IRQS < 328 
     133#error NR_IRQS to low for all gpio irqs 
     134#endif 
     135DECLARE_GPIO_RES(3); 
     136DECLARE_GPIO_RES(4); 
     137#endif 
     138 
     139void __init falcon_register_gpio(void) 
     140{ 
     141        platform_device_register_simple("falcon_gpio", 0, 
     142                falcon_gpio0_resources, ARRAY_SIZE(falcon_gpio0_resources)); 
     143        platform_device_register_simple("falcon_gpio", 1, 
     144                falcon_gpio1_resources, ARRAY_SIZE(falcon_gpio1_resources)); 
     145        platform_device_register_simple("falcon_gpio", 2, 
     146                falcon_gpio2_resources, ARRAY_SIZE(falcon_gpio2_resources)); 
     147        sys1_hw_activate(ACTS_PADCTRL1 | ACTS_P1); 
     148        sys_eth_hw_activate(SYS_ETH_ACTS_PADCTRL0 | SYS_ETH_ACTS_PADCTRL2 | 
     149                SYS_ETH_ACTS_P0 | SYS_ETH_ACTS_P2); 
     150 
     151#ifdef REGISTER_ALL_GPIO_PORTS 
     152        /* optional gpio ports: not registered, 
     153           as the pins are EBU specific and always used by linux */ 
     154        platform_device_register_simple("falcon_gpio", 3, 
     155                falcon_gpio3_resources, ARRAY_SIZE(falcon_gpio3_resources)); 
     156        platform_device_register_simple("falcon_gpio", 4, 
     157                falcon_gpio4_resources, ARRAY_SIZE(falcon_gpio4_resources)); 
     158        sys1_hw_activate(ACTS_PADCTRL3 | ACTS_PADCTRL4 | ACTS_P3 | ACTS_P4); 
     159#endif 
     160} 
     161 
     162static struct resource falcon_i2c_resources[] = { 
     163        MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END), 
     164        IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ), 
     165        IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ), 
     166        IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR), 
     167        IRQ_RES("i2c_p", FALCON_IRQ_I2C_I2C_P), 
     168}; 
     169 
     170void __init falcon_register_i2c(void) 
     171{ 
     172        platform_device_register_simple("i2c-falcon", 0, 
     173                falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources)); 
     174        sys1_hw_activate(ACTS_I2C_ACT); 
     175} 
     176 
     177void __init falcon_register_crypto(void) 
     178{ 
     179        platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0); 
     180} 
  • new file arch/mips/lantiq/falcon/devices.h

    - +  
     1#ifndef _FALCON_DEVICES_H__ 
     2#define _FALCON_DEVICES_H__ 
     3 
     4#include <linux/mtd/physmap.h> 
     5#include <linux/spi/spi.h> 
     6#include <linux/spi/flash.h> 
     7 
     8extern void __init falcon_register_asc(int port); 
     9extern void __init falcon_register_i2c(void); 
     10extern void __init falcon_register_spi_flash(struct spi_board_info *data); 
     11extern void __init falcon_register_gpio(void); 
     12extern void __init falcon_register_nor(struct physmap_flash_data *data); 
     13extern void __init falcon_register_wdt(void); 
     14extern void __init falcon_register_crypto(void); 
     15 
     16#define IRQ_RES(resname,irq) {.name=resname,.start=(irq),.flags=IORESOURCE_IRQ} 
     17#define MEM_RES(resname,adr_start,adr_end) \ 
     18        { .name=resname, .flags=IORESOURCE_MEM, \ 
     19          .start=((adr_start)&~KSEG1),.end=((adr_end)&~KSEG1) } 
     20 
     21#endif 
  • new file arch/mips/lantiq/falcon/prom.c

    - +  
     1/* 
     2 * This program is free software; you can redistribute it and/or modify 
     3 * it under the terms of the GNU General Public License as published by 
     4 * the Free Software Foundation; either version 2 of the License, or 
     5 * (at your option) any later version. 
     6 * 
     7 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     8 */ 
     9 
     10#include <linux/module.h> 
     11#include <linux/clk.h> 
     12#include <asm/bootinfo.h> 
     13#include <asm/time.h> 
     14 
     15#include <lantiq_soc.h> 
     16 
     17#include <falcon.h> 
     18 
     19#include <falcon/gpon_reg_base.h> 
     20#include <falcon/status_reg.h> 
     21#include <falcon/sys1_reg.h> 
     22 
     23#include "../prom.h" 
     24 
     25static struct gpon_reg_status * const pSTATUS = (struct gpon_reg_status *)GPON_STATUS_BASE; 
     26 
     27#define SOC_FALCON              "Falcon" 
     28 
     29void __init 
     30ltq_soc_setup(void) 
     31{ 
     32        /* not used */ 
     33} 
     34 
     35void __init 
     36ltq_soc_detect(struct ltq_soc_info *i) 
     37{ 
     38        i->partnum = (ltq_r32(&pSTATUS->chipid) & STATUS_CHIPID_PARTNR_MASK) >> STATUS_CHIPID_PARTNR_OFFSET; 
     39        i->rev = (ltq_r32(&pSTATUS->chipid) & STATUS_CHIPID_VERSION_MASK) >> STATUS_CHIPID_VERSION_OFFSET; 
     40        switch (i->partnum) 
     41        { 
     42        case SOC_ID_FALCON: 
     43                i->name = SOC_FALCON; 
     44                i->type = SOC_TYPE_FALCON; 
     45                break; 
     46 
     47        default: 
     48                printk(KERN_ERR "unknown partnum : 0x%08X\n", i->partnum); 
     49                while(1) {      }; 
     50                break; 
     51        } 
     52} 
  • new file arch/mips/lantiq/falcon/sysctrl.c

    - +  
     1/* 
     2 * This program is free software; you can redistribute it and/or 
     3 * modify it under the terms of the GNU General Public License as 
     4 * published by the Free Software Foundation; either version 2 of 
     5 * the License, or (at your option) any later version. 
     6 * 
     7 * This program is distributed in the hope that it will be useful, 
     8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     10 * GNU General Public License for more details. 
     11 * 
     12 * You should have received a copy of the GNU General Public License 
     13 * along with this program; if not, write to the Free Software 
     14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
     15 * MA 02111-1307 USA 
     16 * 
     17 * Copyright (C) 2010 Thomas Langer, Lantiq Deutschland 
     18 */ 
     19 
     20#include <linux/cpu.h> 
     21#include <linux/init.h> 
     22#include <linux/kernel.h> 
     23#include <linux/pm.h> 
     24#include <linux/io.h> 
     25#include <linux/ioport.h> 
     26#include <linux/clk.h> 
     27#include <asm/reboot.h> 
     28 
     29#include <falcon/gpon_reg_base.h> 
     30#include <falcon/status_reg.h> 
     31#include <falcon/sys1_reg.h> 
     32#include <falcon/sys_eth_reg.h> 
     33#include <falcon/sys_gpe_reg.h> 
     34 
     35#include <falcon/sysctrl.h> 
     36 
     37/* mapping to linux hw-accessor routines */ 
     38#define reg_r32(reg)                    __raw_readl(reg) 
     39#define reg_w32(val, reg)               __raw_writel(val, reg) 
     40#define reg_w32_mask(clear, set, reg)   reg_w32((reg_r32(reg) & ~(clear)) | (set), reg) 
     41 
     42static struct gpon_reg_sys1 * const sys1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE; 
     43static struct gpon_reg_sys_eth * const sys_eth = (struct gpon_reg_sys_eth *)GPON_SYS_ETH_BASE; 
     44static struct gpon_reg_sys_gpe * const sys_gpe = (struct gpon_reg_sys_gpe *)GPON_SYS_GPE_BASE; 
     45static struct gpon_reg_status * const status = (struct gpon_reg_status *)GPON_STATUS_BASE; 
     46 
     47/** 
     48 * Activate the selected module(s) 
     49 * Enables the clock of the module and activates the module itself. 
     50 * 
     51 * \param[in]   mask    bitmask of module(s), as for registers SYS1.ACT 
     52 * \return void 
     53 */ 
     54void sys1_hw_activate(u32 mask) 
     55{ 
     56        sys1_w32(mask, clken); 
     57        sys1_w32(mask, act); 
     58 
     59        while ( (sys1_r32(acts) & mask) != mask) { 
     60                /*NOP;*/ 
     61        }; 
     62} 
     63EXPORT_SYMBOL(sys1_hw_activate); 
     64 
     65/** 
     66 * Deactivate the selected module(s) 
     67 * Disables the clock of the module and deactivates the module itself. 
     68 * 
     69 * \param[in]   mask    bitmask of module(s), as for registers SYS1.DEACT 
     70 * \return void 
     71 */ 
     72void sys1_hw_deactivate(u32 mask) 
     73{ 
     74        sys1_w32(mask, clkclr); 
     75        sys1_w32(mask, deact); 
     76 
     77        while ( (sys1_r32(acts) & mask) != 0) { 
     78                /*NOP;*/ 
     79        }; 
     80} 
     81EXPORT_SYMBOL(sys1_hw_deactivate); 
     82 
     83/** 
     84 * Clock enable for the selected module(s) 
     85 * Enables the clock of the module. 
     86 * 
     87 * \param[in]   mask    bitmask of module(s), as for registers SYS1.CLKEN 
     88 * \return void 
     89 */ 
     90void sys1_hw_clk_enable(u32 mask) 
     91{ 
     92        sys1_w32(mask, clken); 
     93 
     94        while ( (sys1_r32(clks) & mask) != mask) { 
     95                /*NOP;*/ 
     96        }; 
     97} 
     98EXPORT_SYMBOL(sys1_hw_clk_enable); 
     99 
     100/** 
     101 * Clock disable for the selected module(s) 
     102 * disables the clock of the module. 
     103 * 
     104 * \param[in]   mask    bitmask of module(s), as for registers SYS1.CLKCLR 
     105 * \return void 
     106 */ 
     107void sys1_hw_clk_disable(u32 mask) 
     108{ 
     109        sys1_w32(mask, clkclr); 
     110 
     111        while ( (sys1_r32(clks) & mask) != 0) { 
     112                /*NOP;*/ 
     113        }; 
     114} 
     115EXPORT_SYMBOL(sys1_hw_clk_disable); 
     116 
     117/** 
     118 * Reboots the selected module(s) 
     119 * Triggers the reboot of the module. 
     120 * 
     121 * \param[in]   mask    bitmask of module(s), as for registers SYS1.RBT 
     122 * \return void 
     123 */ 
     124void sys1_hw_activate_or_reboot(u32 mask) 
     125{ 
     126        u32 acts = sys1_r32(acts); 
     127        /* is not already active? */ 
     128        if ((~acts & mask) != 0) 
     129                sys1_hw_activate(~acts & mask); 
     130        sys1_w32(acts & mask, rbt); 
     131        while ( (sys1_r32(acts) & mask) != mask) { 
     132                /*NOP;*/ 
     133        }; 
     134} 
     135EXPORT_SYMBOL(sys1_hw_activate_or_reboot); 
     136 
     137/** 
     138 * Activate the selected module(s) 
     139 * Enables the clock of the module and activates the module itself. 
     140 * 
     141 * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.ACT 
     142 * \return void 
     143 */ 
     144void sys_eth_hw_activate(u32 mask) 
     145{ 
     146        sys_eth_w32(mask, clken); 
     147        sys_eth_w32(mask, act); 
     148 
     149        while ( (sys_eth_r32(acts) & mask) != mask) { 
     150                /*NOP;*/ 
     151        }; 
     152} 
     153EXPORT_SYMBOL(sys_eth_hw_activate); 
     154 
     155/** 
     156 * Deactivate the selected module(s) 
     157 * Disables the clock of the module and deactivates the module itself. 
     158 * 
     159 * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.DEACT 
     160 * \return void 
     161 */ 
     162void sys_eth_hw_deactivate(u32 mask) 
     163{ 
     164        sys_eth_w32(mask, clkclr); 
     165        sys_eth_w32(mask, deact); 
     166 
     167        while ( (sys_eth_r32(acts) & mask) != 0) { 
     168                /*NOP;*/ 
     169        }; 
     170} 
     171EXPORT_SYMBOL(sys_eth_hw_deactivate); 
     172 
     173/** 
     174 * Clock enable for the selected module(s) 
     175 * Enables the clock of the module. 
     176 * 
     177 * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.CLKEN 
     178 * \return void 
     179 */ 
     180void sys_eth_hw_clk_enable(u32 mask) 
     181{ 
     182        sys_eth_w32(mask, clken); 
     183 
     184        while ( (sys_eth_r32(clks) & mask) != mask) { 
     185                /*NOP;*/ 
     186        }; 
     187} 
     188EXPORT_SYMBOL(sys_eth_hw_clk_enable); 
     189 
     190/** 
     191 * Clock disable for the selected module(s) 
     192 * disables the clock of the module. 
     193 * 
     194 * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.CLKCLR 
     195 * \return void 
     196 */ 
     197void sys_eth_hw_clk_disable(u32 mask) 
     198{ 
     199        sys_eth_w32(mask, clkclr); 
     200 
     201        while ( (sys_eth_r32(clks) & mask) != 0) { 
     202                /*NOP;*/ 
     203        }; 
     204} 
     205EXPORT_SYMBOL(sys_eth_hw_clk_disable); 
     206 
     207/** 
     208 * Reboots the selected module(s) 
     209 * Triggers the reboot of the module. 
     210 * 
     211 * \param[in]   mask    bitmask of module(s), as for registers SYS_ETH.RBT 
     212 * \return void 
     213 */ 
     214void sys_eth_hw_activate_or_reboot(u32 mask) 
     215{ 
     216        u32 acts = sys_eth_r32(acts); 
     217        /* is not already active? */ 
     218        if ((~acts & mask) != 0) 
     219                sys_eth_hw_activate(~acts & mask); 
     220        sys_eth_w32(acts & mask, rbt); 
     221        while ( (sys_eth_r32(acts) & mask) != mask) { 
     222                /*NOP;*/ 
     223        }; 
     224} 
     225EXPORT_SYMBOL(sys_eth_hw_activate_or_reboot); 
     226 
     227static int gpe_clk_is_enabled(void) 
     228{ 
     229        u32 rd_data; 
     230 
     231        rd_data = sys1_r32(infrac); 
     232        if (rd_data & (1<<(INFRAC_GP_OFFSET+1))) 
     233                return 1; 
     234        return 0; 
     235} 
     236 
     237static void enable_gpe_clk(void) 
     238{ 
     239        u32 aeFreq; 
     240        u32 rd_data; 
     241        u32 rd_data_to_keep; 
     242        int i; 
     243 
     244        if (gpe_clk_is_enabled()) 
     245                /* clock already active, no need to change here */ 
     246                return; 
     247 
     248        if (status_r32(config) == 0) 
     249                aeFreq = 1; /* use 625MHz on unfused chip */ 
     250        else 
     251                aeFreq = (status_r32(config) & STATUS_CONFIG_GPEFREQ_MASK) >> STATUS_CONFIG_GPEFREQ_OFFSET; 
     252        rd_data = sys1_r32(infrac); 
     253        /* clear gpe-fsel and enable bits */ 
     254        rd_data_to_keep = rd_data & ~(7<<(INFRAC_GP_OFFSET+1)); 
     255 
     256        /* set new fsel */ 
     257        sys1_w32(rd_data_to_keep | (aeFreq<<(INFRAC_GP_OFFSET+2)), infrac); 
     258 
     259        for (i = 0; i <10; i++) /* wait 10 cycles */ 
     260                {} 
     261 
     262        /* keep new fsel and enable */ 
     263        sys1_w32(rd_data_to_keep | (aeFreq<<(INFRAC_GP_OFFSET+2)) | 
     264                (1<<(INFRAC_GP_OFFSET+1)), infrac); 
     265        for (i = 0; i <100; i++) /* wait 100 cycles */ 
     266                {} 
     267} 
     268 
     269/** 
     270 * Activate the selected module(s) 
     271 * Enables the clock of the module and activates the module itself. 
     272 * 
     273 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.ACT 
     274 * \return void 
     275 */ 
     276void sys_gpe_hw_activate(u32 mask) 
     277{ 
     278        enable_gpe_clk(); 
     279        sys_gpe_w32(mask, clken); 
     280        sys_gpe_w32(mask, act); 
     281 
     282        while ( (sys_gpe_r32(acts) & mask) != mask) { 
     283                /*NOP;*/ 
     284        }; 
     285} 
     286EXPORT_SYMBOL(sys_gpe_hw_activate); 
     287 
     288/** 
     289 * Deactivate the selected module(s) 
     290 * Disables the clock of the module and deactivates the module itself. 
     291 * 
     292 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.DEACT 
     293 * \return void 
     294 */ 
     295void sys_gpe_hw_deactivate(u32 mask) 
     296{ 
     297        enable_gpe_clk(); 
     298        sys_gpe_w32(mask, clkclr); 
     299        sys_gpe_w32(mask, deact); 
     300 
     301        while ( (sys_gpe_r32(acts) & mask) != 0) { 
     302                /*NOP;*/ 
     303        }; 
     304} 
     305EXPORT_SYMBOL(sys_gpe_hw_deactivate); 
     306 
     307/** 
     308 * Clock enable for the selected module(s) 
     309 * Enables the clock of the module. 
     310 * 
     311 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.CLKEN 
     312 * \return void 
     313 */ 
     314void sys_gpe_hw_clk_enable(u32 mask) 
     315{ 
     316        enable_gpe_clk(); 
     317        sys_gpe_w32(mask, clken); 
     318 
     319        while ( (sys_gpe_r32(clks) & mask) != mask) { 
     320                /*NOP;*/ 
     321        }; 
     322} 
     323EXPORT_SYMBOL(sys_gpe_hw_clk_enable); 
     324 
     325/** 
     326 * Clock disable for the selected module(s) 
     327 * disables the clock of the module. 
     328 * 
     329 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.CLKCLR 
     330 * \return void 
     331 */ 
     332void sys_gpe_hw_clk_disable(u32 mask) 
     333{ 
     334        enable_gpe_clk(); 
     335        sys_gpe_w32(mask, clkclr); 
     336 
     337        while ( (sys_gpe_r32(clks) & mask) != 0) { 
     338                /*NOP;*/ 
     339        }; 
     340} 
     341EXPORT_SYMBOL(sys_gpe_hw_clk_disable); 
     342 
     343/** 
     344 * Reboots the selected module(s) 
     345 * Triggers the reboot of the module. 
     346 * 
     347 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.RBT 
     348 * \return void 
     349 */ 
     350void sys_gpe_hw_activate_or_reboot(u32 mask) 
     351{ 
     352        u32 acts; 
     353        enable_gpe_clk(); 
     354        acts = sys_gpe_r32(acts); 
     355        /* is not already active? */ 
     356        if ((~acts & mask) != 0) 
     357                sys_gpe_hw_activate(~acts & mask); 
     358        sys_gpe_w32(acts & mask, rbt); 
     359        while ( (sys_gpe_r32(acts) & mask) != mask) { 
     360                /*NOP;*/ 
     361        }; 
     362} 
     363EXPORT_SYMBOL(sys_gpe_hw_activate_or_reboot); 
     364 
     365/** 
     366 * Retrieve activation status of the selected hardware module(s) 
     367 * 
     368 * \param[in]   mask    bitmask of module(s), as for registers SYS_GPE.RBT 
     369 * \return int 1 - if hardware module(s) is activated (including clock) 
     370 */ 
     371 int sys_gpe_hw_is_activated(u32 mask) 
     372{ 
     373        if (gpe_clk_is_enabled() == 0) 
     374                return 0; 
     375 
     376        if ((sys_gpe_r32(clks) & mask) != mask) 
     377                return 0; 
     378 
     379        return ((sys_gpe_r32(acts) & mask) == mask); 
     380} 
     381EXPORT_SYMBOL(sys_gpe_hw_is_activated); 
  • new file arch/mips/lantiq/falcon/gpio.c

    - +  
     1/* 
     2 *   This program is free software; you can redistribute it and/or modify 
     3 *   it under the terms of the GNU General Public License as published by 
     4 *   the Free Software Foundation; either version 2 of the License, or 
     5 *   (at your option) any later version. 
     6 * 
     7 *   This program is distributed in the hope that it will be useful, 
     8 *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     9 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     10 *   GNU General Public License for more details. 
     11 * 
     12 *   You should have received a copy of the GNU General Public License 
     13 *   along with this program; if not, write to the Free Software 
     14 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     15 * 
     16 *   Copyright (C) 2010 Thomas Langer, Lantiq Deutschland 
     17 */ 
     18 
     19/** 
     20        TODO: 
     21                - add locking? 
     22                - provide mask of available pins per platform_data 
     23*/ 
     24 
     25#include <linux/module.h> 
     26#include <linux/types.h> 
     27#include <linux/errno.h> 
     28#include <linux/init.h> 
     29#include <linux/seq_file.h> 
     30#include <linux/platform_device.h> 
     31#include <linux/uaccess.h> 
     32#include <linux/gpio.h> 
     33#include <linux/irq.h> 
     34#include <linux/interrupt.h> 
     35#include <linux/slab.h> 
     36 
     37#include <falcon.h> 
     38#include <falcon/falcon_irq.h> 
     39 
     40#include <linux/version.h> 
     41#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)) 
     42#define for_each_set_bit for_each_bit 
     43#endif 
     44 
     45#define gpio_r32(reg)                   __raw_readl(reg) 
     46#define gpio_w32(val, reg)                      __raw_writel(val, reg) 
     47#define gpio_w32_mask(clear, set, reg)  gpio_w32((gpio_r32(reg) & ~(clear)) | (set), reg) 
     48 
     49 
     50/** register structure for padctrl 
     51    (mainly needed for mux control) */ 
     52typedef struct gpon_padctrl_s 
     53{ 
     54        /** Multiplexer Control Register 
     55            The value 0 (the reset-value) is always the default function corresponding to the pad's name. The value 1 selects always the GPIO functionality (if available). */ 
     56        unsigned int muxc[32]; 
     57        /** Pull Up Enable Register */ 
     58        unsigned int puen; /* 0x00000080 */ 
     59        /** Pull Down Enable Register */ 
     60        unsigned int pden; /* 0x00000084 */ 
     61        /** Slew Rate Control Register */ 
     62        unsigned int src; /* 0x00000088 */ 
     63        /** Drive Current Control Register */ 
     64        unsigned int dcc; /* 0x0000008C */ 
     65        /** Reserved */ 
     66        unsigned int res_0[24]; /* 0x00000090 */ 
     67        /** Pad Control Availability Register */ 
     68        unsigned int avail; /* 0x000000F0 */ 
     69} gpon_padctrl0_t; 
     70 
     71/** register structure for gpio port */ 
     72typedef struct gpon_gpio_s 
     73{ 
     74        /** Data Output Register 
     75            Via this register the output values of the different bits can be set if they are switched as outputs. */ 
     76        unsigned int out; /* 0x00000000 */ 
     77        /** Data Input Register 
     78            Via this register the input values of the different bits can be observed. */ 
     79        unsigned int in; /* 0x00000004 */ 
     80        /** Direction Register 
     81            Via this register the input direction of the different bits can be determined. */ 
     82        unsigned int dir; /* 0x00000008 */ 
     83        /** Reserved */ 
     84        unsigned int res_0[3]; /* 0x0000000C */ 
     85        /** External Interrupt Control Register 0 */ 
     86        unsigned int exintcr0; /* 0x00000018 */ 
     87        /** External Interrupt Control Register 1 */ 
     88        unsigned int exintcr1; /* 0x0000001C */ 
     89        /** IRN Capture Register 
     90            This register shows the currently active interrupt events masked with the corresponding enable bits of the IRNEN register. The interrupts can be acknowledged by a write operation. */ 
     91        unsigned int irncr; /* 0x00000020 */ 
     92        /** IRN Interrupt Control Register 
     93            A write operation directly effects the interrupts. This can be used to trigger events under software control for testing purposes. A read operation returns the unmasked interrupt events. */ 
     94        unsigned int irnicr; /* 0x00000024 */ 
     95        /** IRN Interrupt Enable Register 
     96            This register contains the enable (or mask) bits for the interrupts. Disabled interrupts are not visible in the IRNCR register and are not signalled via the interrupt line towards the controller. */ 
     97        unsigned int irnen; /* 0x00000028 */ 
     98        /** IRN Interrupt Configuration Register 
     99            Configures the interrupts bitwise to be edge-senstivie or level-sensitive. */ 
     100        unsigned int irncfg; /* 0x0000002C */ 
     101        /** IRN Interrupt Enable Set Register 
     102            The corresponding bit in the IRNEN register can be set with an atomic access. */ 
     103        unsigned int irnenset; /* 0x00000030 */ 
     104        /** IRN Interrupt Enable Clear Register 
     105            The corresponding bit in the IRNEN register can be cleared with an atomic access. */ 
     106        unsigned int irnenclr; /* 0x00000034 */ 
     107        /** Reserved */ 
     108        unsigned int res_1[2]; /* 0x00000038 */ 
     109        /** Output Set Register 
     110            This register can be used to set certain bits within the OUT register without touching the other bits. */ 
     111        unsigned int outset; /* 0x00000040 */ 
     112        /** Output Clear Register 
     113            This register can be used to clear certain bits within the OUT register without touching the other bits. */ 
     114        unsigned int outclr; /* 0x00000044 */ 
     115        /** Direction Set Register 
     116            This register can be used to set certain bits within the DIR register without touching the other bits. */ 
     117        unsigned int dirset; /* 0x00000048 */ 
     118        /** Direction Clear Register 
     119            This register can be used to clear certain bits within the DIR register without touching the other bits. */ 
     120        unsigned int dirclr; /* 0x0000004C */ 
     121} gpon_gpio_t; 
     122 
     123struct falcon_gpio_port { 
     124        struct gpio_chip gpio_chip; 
     125        gpon_padctrl0_t __iomem *pad; 
     126        gpon_gpio_t __iomem *port; 
     127        struct resource *pad_req;   /* resources requested */ 
     128        struct resource *port_req; 
     129        unsigned int irq_base; 
     130        unsigned int chained_irq; 
     131}; 
     132 
     133static int gpio_exported = 0; 
     134static int __init gpio_export_setup(char *str) 
     135{ 
     136        get_option(&str, &gpio_exported); 
     137        return 1; 
     138} 
     139__setup("gpio_exported=", gpio_export_setup); 
     140 
     141static inline struct falcon_gpio_port *to_falcon_gpio_port(struct gpio_chip *chip) 
     142{ 
     143        return container_of(chip, struct falcon_gpio_port, gpio_chip); 
     144} 
     145 
     146static int falcon_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 
     147{ 
     148        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     149        gpio_w32(1<<offset, &gpio_port->port->dirclr); 
     150        return 0; 
     151} 
     152 
     153static int falcon_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value) 
     154{ 
     155        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     156        gpio_w32(1<<offset, &gpio_port->port->dirset); 
     157        return 0; 
     158} 
     159 
     160static void falcon_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 
     161{ 
     162        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     163        if (value) 
     164                gpio_w32(1<<offset, &gpio_port->port->outset); 
     165        else 
     166                gpio_w32(1<<offset, &gpio_port->port->outclr); 
     167} 
     168 
     169static int falcon_gpio_get(struct gpio_chip *chip, unsigned int offset) 
     170{ 
     171        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     172        if ((gpio_r32(&gpio_port->port->dir) >> offset) & 1) 
     173                return (gpio_r32(&gpio_port->port->out) >> offset) & 1; 
     174        else 
     175                return (gpio_r32(&gpio_port->port->in) >> offset) & 1; 
     176} 
     177 
     178static int falcon_gpio_request(struct gpio_chip *chip, unsigned offset) 
     179{ 
     180        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     181        if ( (gpio_r32(&gpio_port->pad->avail) >> offset) & 1) { 
     182                if (gpio_r32(&gpio_port->pad->muxc[offset]) > 1) 
     183                        return -EBUSY; 
     184                /* switch on gpio function */ 
     185                gpio_w32(1, &gpio_port->pad->muxc[offset]); 
     186                return 0; 
     187        } 
     188 
     189        return -ENODEV; 
     190} 
     191 
     192static void falcon_gpio_free(struct gpio_chip *chip, unsigned offset) 
     193{ 
     194        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     195        if ( (gpio_r32(&gpio_port->pad->avail) >> offset) & 1) { 
     196                if (gpio_r32(&gpio_port->pad->muxc[offset]) > 1) 
     197                        return; 
     198                /* switch off gpio function */ 
     199                gpio_w32(0, &gpio_port->pad->muxc[offset]); 
     200        } 
     201} 
     202 
     203static int falcon_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 
     204{ 
     205        struct falcon_gpio_port *gpio_port = to_falcon_gpio_port(chip); 
     206        /* no checks: this functions is only registered with valid irq_base */ 
     207        return gpio_port->irq_base + offset; 
     208} 
     209 
     210static void falcon_gpio_disable_irq(struct irq_data *d) 
     211{ 
     212        struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq); 
     213        unsigned int offset = d->irq-gpio_port->irq_base; 
     214        gpio_w32(1<<offset, &gpio_port->port->irnenclr); 
     215} 
     216 
     217static void falcon_gpio_enable_irq(struct irq_data *d) 
     218{ 
     219        struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq); 
     220        unsigned int offset = d->irq-gpio_port->irq_base; 
     221 
     222        if (gpio_r32(&gpio_port->pad->muxc[offset]) < 1) { 
     223                /* switch on gpio function */ 
     224                gpio_w32(1, &gpio_port->pad->muxc[offset]); 
     225        } 
     226 
     227        gpio_w32(1<<offset, &gpio_port->port->irnenset); 
     228} 
     229 
     230static void falcon_gpio_ack_irq(struct irq_data *d) 
     231{ 
     232        struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq); 
     233        unsigned int offset = d->irq-gpio_port->irq_base; 
     234        gpio_w32(1<<offset, &gpio_port->port->irncr); 
     235} 
     236 
     237static void falcon_gpio_mask_and_ack_irq(struct irq_data *d) 
     238{ 
     239        struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq); 
     240        unsigned int offset = d->irq-gpio_port->irq_base; 
     241        gpio_w32(1<<offset, &gpio_port->port->irnenclr); 
     242        gpio_w32(1<<offset, &gpio_port->port->irncr); 
     243} 
     244 
     245static struct irq_chip falcon_gpio_irq_chip; 
     246static int falcon_gpio_irq_type(struct irq_data *d, unsigned int type) 
     247{ 
     248        struct falcon_gpio_port *gpio_port = irq_get_chip_data(d->irq); 
     249        unsigned int offset = d->irq-gpio_port->irq_base; 
     250        unsigned int mask = 1 << offset; 
     251 
     252        if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_NONE) 
     253                return 0; 
     254 
     255        if ((type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) != 0) { 
     256                /* level triggered */ 
     257                gpio_w32_mask(0, mask, &gpio_port->port->irncfg); 
     258                irq_set_chip_and_handler_name(d->irq, 
     259                                &falcon_gpio_irq_chip, handle_level_irq, "mux"); 
     260        } else { 
     261                /* edge triggered */ 
     262                gpio_w32_mask(mask, 0, &gpio_port->port->irncfg); 
     263                irq_set_chip_and_handler_name(d->irq, 
     264                                &falcon_gpio_irq_chip, handle_simple_irq, "mux"); 
     265        } 
     266 
     267        if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) { 
     268                gpio_w32_mask(mask, 0, &gpio_port->port->exintcr0); 
     269                gpio_w32_mask(0, mask, &gpio_port->port->exintcr1); 
     270        } else { 
     271                if ((type & (IRQ_TYPE_EDGE_RISING |IRQ_TYPE_LEVEL_HIGH)) != 0) { 
     272                        /* positive logic: rising edge, high level */ 
     273                        gpio_w32_mask(mask, 0, &gpio_port->port->exintcr0); 
     274                } else { 
     275                        /* negative logic: falling edge, low level */ 
     276                        gpio_w32_mask(0, mask, &gpio_port->port->exintcr0); 
     277                } 
     278                gpio_w32_mask(mask, 0, &gpio_port->port->exintcr1); 
     279        } 
     280 
     281        return gpio_direction_input(gpio_port->gpio_chip.base + offset); 
     282} 
     283 
     284static void falcon_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 
     285{ 
     286        struct falcon_gpio_port *gpio_port = irq_desc_get_handler_data(desc); 
     287        unsigned long irncr; 
     288        int offset; 
     289 
     290        irncr = gpio_r32(&gpio_port->port->irncr); 
     291        /* acknowledge interrupt */ 
     292        gpio_w32(irncr, &gpio_port->port->irncr); 
     293 
     294        desc->irq_data.chip->irq_ack(&desc->irq_data); 
     295 
     296        for_each_set_bit(offset, &irncr, gpio_port->gpio_chip.ngpio) 
     297                generic_handle_irq(gpio_port->irq_base + offset); 
     298} 
     299 
     300static struct irq_chip falcon_gpio_irq_chip = { 
     301        .name = "gpio_irq_mux", 
     302        .irq_mask = falcon_gpio_disable_irq, 
     303        .irq_unmask = falcon_gpio_enable_irq, 
     304        .irq_ack = falcon_gpio_ack_irq, 
     305        .irq_mask_ack = falcon_gpio_mask_and_ack_irq, 
     306        .irq_set_type = falcon_gpio_irq_type, 
     307}; 
     308 
     309static struct irqaction gpio_cascade = { 
     310        .handler = no_action, 
     311        .flags = IRQF_DISABLED, 
     312        .name = "gpio_cascade", 
     313}; 
     314 
     315static int falcon_gpio_probe(struct platform_device *pdev) 
     316{ 
     317        struct falcon_gpio_port *gpio_port; 
     318        int ret, i; 
     319        struct resource *gpiores, *padres; 
     320        int irq; 
     321 
     322        gpiores = platform_get_resource(pdev, IORESOURCE_MEM, 0); 
     323        padres = platform_get_resource(pdev, IORESOURCE_MEM, 1); 
     324        irq = platform_get_irq(pdev, 0); 
     325        if (!gpiores || !padres) 
     326                return -ENODEV; 
     327 
     328        gpio_port = kzalloc(sizeof(*gpio_port), GFP_KERNEL); 
     329        if (gpio_port == NULL) 
     330                return -ENOMEM; 
     331 
     332        gpio_port->gpio_chip.label = "falcon-gpio"; 
     333        gpio_port->gpio_chip.direction_input = falcon_gpio_direction_input; 
     334        gpio_port->gpio_chip.direction_output = falcon_gpio_direction_output; 
     335        gpio_port->gpio_chip.get = falcon_gpio_get; 
     336        gpio_port->gpio_chip.set = falcon_gpio_set; 
     337        gpio_port->gpio_chip.request = falcon_gpio_request; 
     338        gpio_port->gpio_chip.free = falcon_gpio_free; 
     339        gpio_port->gpio_chip.base = 100 * pdev->id; 
     340        gpio_port->gpio_chip.ngpio = 32; 
     341        gpio_port->gpio_chip.dev = &pdev->dev; 
     342        gpio_port->gpio_chip.exported = gpio_exported; 
     343 
     344        gpio_port->port_req = request_mem_region(gpiores->start, 
     345                resource_size(gpiores), pdev->name); 
     346        gpio_port->pad_req = request_mem_region(padres->start, 
     347                resource_size(padres), pdev->name); 
     348        if (!gpio_port->port_req || !gpio_port->pad_req) { 
     349                dev_err(&pdev->dev, "cannot claim register area\n"); 
     350                ret = -EIO; 
     351                goto err; 
     352        } 
     353 
     354        gpio_port->port = ioremap_nocache(gpiores->start, 
     355                resource_size(gpiores)); 
     356        gpio_port->pad = ioremap_nocache(padres->start, 
     357                resource_size(padres)); 
     358        if (!gpio_port->port || !gpio_port->pad) { 
     359                dev_err(&pdev->dev, "Could not map io ranges\n"); 
     360                ret = -ENOMEM; 
     361                goto err; 
     362        } 
     363 
     364        if (irq>0) { 
     365                /* 
     366                 * irq_chip support 
     367                 */ 
     368                gpio_port->gpio_chip.to_irq = falcon_gpio_to_irq; 
     369                gpio_port->irq_base = INT_NUM_EXTRA_START + 32 * pdev->id; 
     370 
     371                for (i = 0; i < 32; i++) { 
     372                        irq_set_chip_and_handler_name(gpio_port->irq_base + i, 
     373                                &falcon_gpio_irq_chip, handle_simple_irq, "mux"); 
     374                        irq_set_chip_data(gpio_port->irq_base + i, gpio_port); 
     375                        /* FIXME: set default cfg to level triggered */ 
     376                        //gpio_w32_mask(0, 1<<i, &gpio_port->port->irncfg); 
     377                        /* set to negative logic (falling edge, low level) */ 
     378                        gpio_w32_mask(0, 1<<i, &gpio_port->port->exintcr0); 
     379                } 
     380 
     381                gpio_port->chained_irq = irq; 
     382                setup_irq(irq, &gpio_cascade); 
     383                irq_set_handler_data(irq, gpio_port); 
     384                irq_set_chained_handler(irq, falcon_gpio_irq_handler); 
     385        } 
     386 
     387        ret = gpiochip_add(&gpio_port->gpio_chip); 
     388        if (ret < 0) { 
     389                dev_err(&pdev->dev, "Could not register gpiochip %d, %d\n", 
     390                        pdev->id, ret); 
     391                goto err; 
     392        } 
     393        platform_set_drvdata(pdev, gpio_port); 
     394        return ret; 
     395 
     396err: 
     397        dev_err(&pdev->dev, "Error in gpio_probe %d, %d\n", pdev->id, ret); 
     398        if (gpio_port->port_req) 
     399                release_resource(gpio_port->port_req); 
     400        if (gpio_port->pad_req) 
     401                release_resource(gpio_port->pad_req); 
     402 
     403        if (gpio_port->port) 
     404                iounmap(gpio_port->port); 
     405        if (gpio_port->pad) 
     406                iounmap(gpio_port->pad); 
     407        kfree(gpio_port); 
     408        return ret; 
     409} 
     410 
     411static int falcon_gpio_remove(struct platform_device *pdev) 
     412{ 
     413        struct falcon_gpio_port *gpio_port = platform_get_drvdata(pdev); 
     414        int ret; 
     415 
     416        ret = gpiochip_remove(&gpio_port->gpio_chip); 
     417        if (gpio_port->port_req) 
     418                release_resource(gpio_port->port_req); 
     419        if (gpio_port->pad_req) 
     420                release_resource(gpio_port->pad_req); 
     421        if (gpio_port->port) 
     422                iounmap(gpio_port->port); 
     423        if (gpio_port->pad) 
     424                iounmap(gpio_port->pad); 
     425        if (ret == 0) 
     426                kfree(gpio_port); 
     427 
     428        return ret; 
     429} 
     430 
     431static struct platform_driver falcon_gpio_driver = { 
     432        .probe = falcon_gpio_probe, 
     433        .remove = __devexit_p(falcon_gpio_remove), 
     434        .driver = { 
     435                .name = "falcon_gpio", 
     436                .owner = THIS_MODULE, 
     437        }, 
     438}; 
     439 
     440int __init falcon_gpio_init(void) 
     441{ 
     442        int ret; 
     443 
     444        printk(KERN_INFO "FALC(tm) ON GPIO Driver, (C) 2011 Lantiq Deutschland Gmbh\n"); 
     445        ret = platform_driver_register(&falcon_gpio_driver); 
     446        if (ret) 
     447                pr_err( "falcon_gpio: Error registering platform driver!"); 
     448        return ret; 
     449} 
     450 
     451void __exit falcon_gpio_exit(void) 
     452{ 
     453        platform_driver_unregister(&falcon_gpio_driver); 
     454} 
     455 
     456int gpio_to_irq(unsigned int gpio) 
     457{ 
     458        return __gpio_to_irq(gpio); 
     459} 
     460EXPORT_SYMBOL(gpio_to_irq); 
     461 
     462module_init(falcon_gpio_init); 
     463module_exit(falcon_gpio_exit); 
  • new file arch/mips/include/asm/mach-lantiq/falcon/falcon.h

    - +  
     1/* 
     2 *   This program is free software; you can redistribute it and/or modify 
     3 *   it under the terms of the GNU General Public License as published by 
     4 *   the Free Software Foundation; either version 2 of the License, or 
     5 *   (at your option) any later version. 
     6 * 
     7 *   Copyright (C) 2005 infineon 
     8 *   Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     9 */ 
     10 
     11#ifdef CONFIG_SOC_FALCON 
     12 
     13#include <lantiq_soc.h> 
     14#include <falcon/gpon_reg_base.h> 
     15 
     16#endif 
  • new file arch/mips/lantiq/falcon/reset.c

    - +  
     1/* 
     2 * This program is free software; you can redistribute it and/or modify 
     3 * it under the terms of the GNU General Public License as published by 
     4 * the Free Software Foundation; either version 2 of the License, or 
     5 * (at your option) any later version. 
     6 * 
     7 * Copyright (C) 2010 John Crispin <blogic@openwrt.org> 
     8 */ 
     9 
     10#include <linux/init.h> 
     11#include <linux/io.h> 
     12#include <linux/pm.h> 
     13#include <asm/reboot.h> 
     14#include <linux/module.h> 
     15 
     16#include <falcon.h> 
     17#include <falcon/gpon_reg_base.h> 
     18#include <falcon/status_reg.h> 
     19#include <falcon/sys1_reg.h> 
     20 
     21static struct gpon_reg_sys1 * const pSYS1 = (struct gpon_reg_sys1 *)GPON_SYS1_BASE; 
     22 
     23#define WDT_PW1                 0x00BE0000 
     24#define WDT_PW2                 0x00DC0000 
     25#define WDT_REG_BASE            (KSEG1 | 0x1F8803F0) 
     26 
     27/* This function is used by the watchdog driver */ 
     28int ltq_reset_cause(void) 
     29{ 
     30        return 0; 
     31} 
     32EXPORT_SYMBOL_GPL(ltq_reset_cause); 
     33 
     34static void 
     35ltq_machine_restart(char *command) 
     36{ 
     37        printk(KERN_NOTICE "System restart\n"); 
     38        local_irq_disable(); 
     39        ltq_w32(0, (void*)0xBF200000); /* reset Bootreg RVEC */ 
     40#if 0 
     41        ltq_w32(RBT_CPU_TRIG, &pSYS1->rbt); 
     42#else 
     43        /* use workaround via watchdog timer */ 
     44        ltq_w32(WDT_PW1, (void*)WDT_REG_BASE); 
     45        ltq_w32(WDT_PW2 | 
     46                (0x3 << 26) | /* PWL */ 
     47                (0x2 << 24) | /* CLKDIV */ 
     48                (0x1 << 31) | /* enable */ 
     49                (1), /* reload */ 
     50                (void*)WDT_REG_BASE); 
     51#endif 
     52        for(;;); 
     53} 
     54 
     55static void 
     56ltq_machine_halt(void) 
     57{ 
     58        printk(KERN_NOTICE "System halted.\n"); 
     59        local_irq_disable(); 
     60        for(;;); 
     61} 
     62 
     63static void 
     64ltq_machine_power_off(void) 
     65{ 
     66        printk(KERN_NOTICE "Please turn off the power now.\n"); 
     67        local_irq_disable(); 
     68        for(;;); 
     69} 
     70 
     71static int __init 
     72mips_reboot_setup(void) 
     73{ 
     74        _machine_restart = ltq_machine_restart; 
     75        _machine_halt = ltq_machine_halt; 
     76        pm_power_off = ltq_machine_power_off; 
     77        return 0; 
     78} 
     79 
     80arch_initcall(mips_reboot_setup); 
  • new file arch/mips/lantiq/falcon/mach-easy98000.c

    - +  
     1#include <linux/init.h> 
     2#include <linux/platform_device.h> 
     3#include <linux/leds.h> 
     4#include <linux/gpio.h> 
     5#include <linux/gpio_buttons.h> 
     6#include <linux/etherdevice.h> 
     7#include <linux/mtd/mtd.h> 
     8#include <linux/mtd/partitions.h> 
     9#include <linux/mtd/physmap.h> 
     10#include <linux/input.h> 
     11#include <linux/interrupt.h> 
     12#include <linux/dm9000.h> 
     13#include <linux/i2c.h> 
     14#include <linux/i2c-gpio.h> 
     15#include <linux/spi/spi.h> 
     16#include <linux/spi/spi_gpio.h> 
     17#include <linux/spi/eeprom.h> 
     18 
     19#include "../machtypes.h" 
     20 
     21#include "devices.h" 
     22#include "dev-leds-gpio.h" 
     23 
     24#define EASY98000_GPIO_LED_0 9 
     25#define EASY98000_GPIO_LED_1 10 
     26#define EASY98000_GPIO_LED_2 11 
     27#define EASY98000_GPIO_LED_3 12 
     28#define EASY98000_GPIO_LED_4 13 
     29#define EASY98000_GPIO_LED_5 14 
     30 
     31extern unsigned char ltq_ethaddr[6]; 
     32 
     33#ifdef CONFIG_MTD_PARTITIONS 
     34static struct mtd_partition easy98000_nor_partitions[] = 
     35{ 
     36        { 
     37                .name   = "uboot", 
     38                .offset = 0x0, 
     39                .size   = 0x40000, 
     40        }, 
     41        { 
     42                .name   = "uboot_env", 
     43                .offset = 0x40000, 
     44                .size   = 0x40000,      /* 2 sectors for redundant env. */ 
     45        }, 
     46        { 
     47                .name   = "linux", 
     48                .offset = 0x80000, 
     49                .size   = 0xF80000,     /* map only 16 MiB */ 
     50        }, 
     51}; 
     52#endif 
     53 
     54static struct physmap_flash_data easy98000_nor_flash_data = { 
     55#ifdef CONFIG_MTD_PARTITIONS 
     56        .nr_parts       = ARRAY_SIZE(easy98000_nor_partitions), 
     57        .parts          = easy98000_nor_partitions, 
     58#endif 
     59}; 
     60 
     61#ifdef CONFIG_MTD_PARTITIONS 
     62static struct flash_platform_data easy98000_spi_flash_platform_data = { 
     63        .name = "sflash", 
     64        .parts = easy98000_nor_partitions, 
     65        .nr_parts = ARRAY_SIZE(easy98000_nor_partitions) 
     66}; 
     67#endif 
     68 
     69static struct spi_board_info easy98000_spi_flash_data __initdata = { 
     70        .modalias               = "m25p80", 
     71        .bus_num                = 0, 
     72        .chip_select            = 0, 
     73        .max_speed_hz           = 10 * 1000 * 1000, 
     74        .mode                   = SPI_MODE_3, 
     75#ifdef CONFIG_MTD_PARTITIONS 
     76        .platform_data          = &easy98000_spi_flash_platform_data 
     77#endif 
     78}; 
     79 
     80static struct gpio_led easy98000_leds_gpio[] __initdata = { 
     81        { 
     82                .name           = "easy98000:green:0", 
     83                .gpio           = EASY98000_GPIO_LED_0, 
     84                .active_low     = 0, 
     85        }, { 
     86                .name           = "easy98000:green:1", 
     87                .gpio           = EASY98000_GPIO_LED_1, 
     88                .active_low     = 0, 
     89        }, { 
     90                .name           = "easy98000:green:2", 
     91                .gpio           = EASY98000_GPIO_LED_2, 
     92                .active_low     = 0, 
     93        }, { 
     94                .name           = "easy98000:green:3", 
     95                .gpio           = EASY98000_GPIO_LED_3, 
     96                .active_low     = 0, 
     97        }, { 
     98                .name           = "easy98000:green:4", 
     99                .gpio           = EASY98000_GPIO_LED_4, 
     100                .active_low     = 0, 
     101        }, { 
     102                .name           = "easy98000:green:5", 
     103                .gpio           = EASY98000_GPIO_LED_5, 
     104                .active_low     = 0, 
     105        } 
     106}; 
     107 
     108#define CONFIG_DM9000_BASE              0x14000000 
     109#define DM9000_IO                       (CONFIG_DM9000_BASE + 3) 
     110#define DM9000_DATA                     (CONFIG_DM9000_BASE + 1) 
     111 
     112static struct dm9000_plat_data dm9000_plat_data = { 
     113        .flags = DM9000_PLATF_8BITONLY, 
     114        //.dev_addr = { }, /* possibility to provide an ethernet address for the chip */ 
     115}; 
     116 
     117static struct resource dm9000_resources[] = { 
     118        MEM_RES("dm9000_io", DM9000_IO, DM9000_IO), 
     119        MEM_RES("dm9000_data", DM9000_DATA, DM9000_DATA), 
     120        [2] = { 
     121                /* with irq (210 -> gpio 110) the driver is very unreliable */ 
     122                .start  = -1,           /* use polling */ 
     123                .end    = -1, 
     124                .flags  = IORESOURCE_IRQ | IRQF_TRIGGER_LOW, 
     125        }, 
     126}; 
     127 
     128static struct platform_device dm9000_platform = { 
     129        .name = "dm9000", 
     130        .id = 0, 
     131        .num_resources  = ARRAY_SIZE(dm9000_resources), 
     132        .resource       = dm9000_resources, 
     133        .dev = { 
     134                .platform_data = (void *) &dm9000_plat_data, 
     135        } 
     136}; 
     137 
     138static void __init register_davicom(void) 
     139{ 
     140        if (!is_valid_ether_addr(ltq_ethaddr)) 
     141                random_ether_addr(dm9000_plat_data.dev_addr); 
     142        else { 
     143                memcpy(dm9000_plat_data.dev_addr, ltq_ethaddr, 6); 
     144                /* change to "Locally Administered Address" */ 
     145                dm9000_plat_data.dev_addr[0] |= 0x2; 
     146        } 
     147        platform_device_register(&dm9000_platform); 
     148} 
     149 
     150static struct i2c_gpio_platform_data easy98000_i2c_gpio_data = { 
     151        .sda_pin        = 107, 
     152        .scl_pin        = 108, 
     153}; 
     154 
     155static struct platform_device easy98000_i2c_gpio_device = { 
     156        .name           = "i2c-gpio", 
     157        .id             = 0, 
     158        .dev = { 
     159                .platform_data  = &easy98000_i2c_gpio_data, 
     160        } 
     161}; 
     162 
     163void __init register_easy98000_cpld_led(void) 
     164{ 
     165        platform_device_register_simple("easy98000_cpld_led", 0, NULL, 0); 
     166} 
     167 
     168/* setup gpio based spi bus/device for access to the eeprom on the board */ 
     169#define SPI_GPIO_MRST   102 
     170#define SPI_GPIO_MTSR   103 
     171#define SPI_GPIO_CLK    104 
     172#define SPI_GPIO_CS0    105 
     173#define SPI_GPIO_CS1    106 
     174#define SPI_GPIO_BUS_NUM        1 
     175 
     176static struct spi_gpio_platform_data easy98000_spi_gpio_data = { 
     177        .sck            = SPI_GPIO_CLK, 
     178        .mosi           = SPI_GPIO_MTSR, 
     179        .miso           = SPI_GPIO_MRST, 
     180        .num_chipselect = 2, 
     181}; 
     182 
     183static struct platform_device easy98000_spi_gpio_device = { 
     184        .name                   = "spi_gpio", 
     185        .id                     = SPI_GPIO_BUS_NUM, 
     186        .dev.platform_data      = &easy98000_spi_gpio_data, 
     187}; 
     188 
     189static struct spi_eeprom at25160n = { 
     190        .byte_len       = 16 * 1024 / 8, 
     191        .name           = "at25160n", 
     192        .page_size      = 32, 
     193        .flags          = EE_ADDR2, 
     194}; 
     195 
     196static struct spi_board_info easy98000_spi_gpio_devices __initdata = { 
     197        .modalias               = "at25", 
     198        .bus_num                = SPI_GPIO_BUS_NUM, 
     199        .max_speed_hz           = 1000 * 1000, 
     200        .mode                   = SPI_MODE_3, 
     201        .chip_select            = 1, 
     202        .controller_data        = (void *) SPI_GPIO_CS1, 
     203        .platform_data          = &at25160n, 
     204}; 
     205 
     206static void __init easy98000_spi_gpio_init(void) 
     207{ 
     208        spi_register_board_info(&easy98000_spi_gpio_devices, 1); 
     209        platform_device_register(&easy98000_spi_gpio_device); 
     210} 
     211 
     212static void __init easy98000_init_common(void) 
     213{ 
     214        falcon_register_asc(0); 
     215        falcon_register_gpio(); 
     216        falcon_register_wdt(); 
     217        falcon_register_i2c(); 
     218        platform_device_register(&easy98000_i2c_gpio_device); 
     219        register_davicom(); 
     220        ltq_add_device_leds_gpio(-1, ARRAY_SIZE(easy98000_leds_gpio), 
     221                                        easy98000_leds_gpio); 
     222        register_easy98000_cpld_led(); 
     223        falcon_register_crypto(); 
     224        easy98000_spi_gpio_init(); 
     225} 
     226 
     227static void __init easy98000_init(void) 
     228{ 
     229        easy98000_init_common(); 
     230        falcon_register_nor(&easy98000_nor_flash_data); 
     231} 
     232 
     233static void __init easy98000sf_init(void) 
     234{ 
     235        easy98000_init_common(); 
     236        falcon_register_spi_flash(&easy98000_spi_flash_data); 
     237} 
     238 
     239MIPS_MACHINE(LANTIQ_MACH_EASY98000, 
     240                        "EASY98000", 
     241                        "EASY98000 Eval Board", 
     242                        easy98000_init); 
     243 
     244MIPS_MACHINE(LANTIQ_MACH_EASY98000SF, 
     245                        "EASY98000SF", 
     246                        "EASY98000 Eval Board (Serial Flash)", 
     247                        easy98000sf_init); 
  • new file arch/mips/lantiq/falcon/softdog_vpe.c

    - +  
     1/* 
     2** ============================================================================= 
     3** FILE NAME     : softdog_vpe.c 
     4** MODULES       : LXDB 
     5** DATE          : 24-03-2008 
     6** AUTHOR        : LXDB Team 
     7** DESCRIPTION   : This header file contains the code for the watchdog 
     8**                 implentation on vpe1 side. 
     9** REFERENCES    : 
     10** COPYRIGHT     : Copyright (c) 2008 
     11**                 Am Campeon 1-12, 85579 Neubiberg, Germany 
     12** Any use of this software is subject to the conclusion of a respective 
     13** License agreement. Without such a License agreement no rights to the 
     14** software are granted 
     15** 
     16** HISTORY       : 
     17** $Date   $Author    $Comment 
     18** 24-03-2008   LXDB    Initial version 
     19** ============================================================================ 
     20*/ 
     21 
     22#include <linux/module.h> 
     23#include <linux/moduleparam.h> 
     24#include <linux/types.h> 
     25#include <linux/timer.h> 
     26#include <linux/reboot.h> 
     27#include <linux/init.h> 
     28#include <linux/jiffies.h> 
     29 
     30#include <falcon/vpe.h> 
     31 
     32static unsigned long last_wdog_value; 
     33static unsigned long vpe1_wdog_cleared; 
     34 
     35static unsigned long vpe1_wdog_dead; 
     36static void watchdog_vpe0_fire(unsigned long); /* Called when vpe0 timer expires */ 
     37static void keep_alive_vpe0(unsigned long); 
     38VPE_SW_WDOG_RESET reset_local_fn; 
     39 
     40 
     41static struct timer_list watchdog_vpe0_ticktock = 
     42                TIMER_INITIALIZER(watchdog_vpe0_fire, 0, 0); 
     43 
     44static void watchdog_vpe0_fire (unsigned long flags) 
     45{ 
     46        volatile unsigned long *wdog_ctr_value; 
     47        wdog_ctr_value = (void*)vpe1_wdog_ctr; 
     48        if (*wdog_ctr_value == last_wdog_value) { /* VPE1 watchdog expiry handling */ 
     49                vpe1_sw_wdog_stop(flags); 
     50                vpe1_wdog_dead++; 
     51                printk(KERN_DEBUG "VPE1 watchdog reset handler called\n"); 
     52        /* Call the reset handler function */ 
     53                reset_local_fn(flags); 
     54        } else { /* Everything is OK on vpe1 side. Continue. */ 
     55                last_wdog_value = *wdog_ctr_value; 
     56                vpe1_wdog_cleared++; 
     57                keep_alive_vpe0(flags); 
     58        } 
     59} 
     60 
     61int32_t vpe1_sw_wdog_register_reset_handler (VPE_SW_WDOG_RESET reset_fn) 
     62{ 
     63        reset_local_fn = (VPE_SW_WDOG_RESET)reset_fn; 
     64        return 0; 
     65} 
     66 
     67static void keep_alive_vpe0(unsigned long flags) 
     68{ 
     69        mod_timer(&watchdog_vpe0_ticktock, jiffies+ vpe1_wdog_timeout ); 
     70} 
     71 
     72unsigned long vpe1_sw_wdog_start(unsigned long flags) 
     73{ 
     74        volatile unsigned long *wdog_ctr_value; 
     75        wdog_ctr_value = (void*)vpe1_wdog_ctr; 
     76        *wdog_ctr_value = 0; 
     77        last_wdog_value = 0; 
     78        keep_alive_vpe0(flags); 
     79        return 0; 
     80} 
     81 
     82unsigned long vpe1_sw_wdog_stop(unsigned long flags) 
     83{ 
     84        del_timer(&watchdog_vpe0_ticktock); 
     85        return 0; 
     86} 
     87 
     88static int __init watchdog_vpe1_init(void) 
     89{ 
     90        /* Nothing to be done here */ 
     91        return 0; 
     92} 
     93 
     94static void __exit watchdog_vpe1_exit(void) 
     95{ 
     96        unsigned long flags=0; 
     97        vpe1_sw_wdog_stop(flags); 
     98} 
     99 
     100module_init(watchdog_vpe1_init); 
     101module_exit(watchdog_vpe1_exit); 
     102 
     103EXPORT_SYMBOL(vpe1_sw_wdog_register_reset_handler); 
     104EXPORT_SYMBOL(vpe1_sw_wdog_start); 
     105EXPORT_SYMBOL(vpe1_sw_wdog_stop); 
     106 
     107MODULE_AUTHOR("LXDB"); 
     108MODULE_DESCRIPTION("Software Watchdog For VPE1"); 
     109MODULE_LICENSE("GPL"); 
  • new file arch/mips/include/asm/mach-lantiq/falcon/vpe.h

    - +  
     1/* 
     2 *   This program is free software; you can redistribute it and/or modify 
     3 *   it under the terms of the GNU General Public License as published by 
     4 *   the Free Software Foundation; either version 2 of the License, or 
     5 *   (at your option) any later version. 
     6 * 
     7 *   This program is distributed in the hope that it will be useful, 
     8 *   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     9 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     10 *   GNU General Public License for more details. 
     11 * 
     12 *   You should have received a copy of the GNU General Public License 
     13 *   along with this program; if not, write to the Free Software 
     14 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
     15 * 
     16 *   Copyright (C) 2005 infineon 
     17 *   Copyright (C) 2007 John Crispin <blogic@openwrt.org> 
     18 * 
     19 */ 
     20#ifndef _IFXMIPS_VPE_H__ 
     21#define _IFXMIPS_VPE_H__ 
     22 
     23/* For the explanation of the APIs please refer the section "MT APRP Kernel 
     24 * Programming" in AR9 SW Architecture Specification 
     25 */ 
     26int32_t vpe1_sw_start(void* sw_start_addr, uint32_t tcmask, uint32_t flags); 
     27int32_t vpe1_sw_stop(uint32_t flags); 
     28uint32_t vpe1_get_load_addr (uint32_t flags); 
     29uint32_t vpe1_get_max_mem (uint32_t flags); 
     30 
     31int32_t vpe1_set_boot_param(char *field, char *value, char flags); 
     32int32_t vpe1_get_boot_param(char *field, char **value, char flags); 
     33 
     34/* Watchdog APIs */ 
     35extern unsigned long vpe1_wdog_ctr; 
     36extern unsigned long vpe1_wdog_timeout; 
     37 
     38unsigned long vpe1_sw_wdog_start(unsigned long); 
     39unsigned long vpe1_sw_wdog_stop(unsigned long); 
     40 
     41typedef int (*VPE_SW_WDOG_RESET)(unsigned long wdog_cleared_ok_count); 
     42int32_t vpe1_sw_wdog_register_reset_handler(VPE_SW_WDOG_RESET reset_fn); 
     43 
     44#endif 
  • arch/mips/lantiq/Kconfig

    a b config SOC_XWAY 
    1616        bool "XWAY" 
    1717        select SOC_TYPE_XWAY 
    1818        select HW_HAS_PCI 
     19 
     20config SOC_FALCON 
     21        bool "FALCON" 
    1922endchoice 
    2023 
    2124source "arch/mips/lantiq/xway/Kconfig" 
     25source "arch/mips/lantiq/falcon/Kconfig" 
    2226 
    2327endif 
  • arch/mips/lantiq/Makefile

    a b obj-y := irq.o setup.o clk.o prom.o devi 
    99obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 
    1010 
    1111obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ 
     12obj-$(CONFIG_SOC_FALCON) += falcon/ 
  • arch/mips/lantiq/Platform

    a b platform-$(CONFIG_LANTIQ) += lantiq/ 
    66cflags-$(CONFIG_LANTIQ)         += -I$(srctree)/arch/mips/include/asm/mach-lantiq 
    77load-$(CONFIG_LANTIQ)           = 0xffffffff80002000 
    88cflags-$(CONFIG_SOC_TYPE_XWAY)  += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway 
     9cflags-$(CONFIG_SOC_FALCON)     += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon 
  • arch/mips/lantiq/machtypes.h

    a b enum lantiq_mach_type { 
    1515        LTQ_MACH_GENERIC = 0, 
    1616        LTQ_MACH_EASY50712,     /* Danube evaluation board */ 
    1717        LTQ_MACH_EASY50601,     /* Amazon SE evaluation board */ 
     18 
     19        /* FALCON */ 
     20        LANTIQ_MACH_EASY98000,          /* Falcon Eval Board, NOR Flash */ 
     21        LANTIQ_MACH_EASY98000SF,        /* Falcon Eval Board, Serial Flash */ 
     22        LANTIQ_MACH_EASY98020,          /* Falcon Reference Board */ 
    1823}; 
    1924 
    2025#endif 
Note: See TracBrowser for help on using the repository browser.