diff options
Diffstat (limited to 'target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch')
-rw-r--r-- | target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch | 659 |
1 files changed, 659 insertions, 0 deletions
diff --git a/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch b/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch new file mode 100644 index 0000000..ddc624f --- /dev/null +++ b/target/linux/lantiq/patches-3.0/0013-MIPS-lantiq-adds-FALC-ON-spi-driver.patch @@ -0,0 +1,659 @@ +From 2bd534c30688bcb3f70f1816fbcff813fc746103 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Aug 2011 18:12:26 +0200 +Subject: [PATCH 13/24] MIPS: lantiq: adds FALC-ON spi driver + +The external bus unit (EBU) found on the FALC-ON SoC has spi emulation that is +designed for serial flash access. + +Signed-off-by: Thomas Langer <thomas.langer@lantiq.com> +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/mips/lantiq/falcon/devices.c | 12 +- + arch/mips/lantiq/falcon/devices.h | 4 + + arch/mips/lantiq/falcon/mach-easy98000.c | 27 ++ + drivers/spi/Kconfig | 4 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-falcon.c | 477 ++++++++++++++++++++++++++++++ + 6 files changed, 523 insertions(+), 2 deletions(-) + create mode 100644 drivers/spi/spi-falcon.c + +Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.c +=================================================================== +--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:30:34.584838403 +0200 ++++ linux-3.0.3/arch/mips/lantiq/falcon/devices.c 2011-10-05 12:42:58.696870214 +0200 +@@ -129,7 +129,7 @@ + + /* i2c */ + static struct resource falcon_i2c_resources[] = { +- MEM_RES("i2c", GPON_I2C_BASE,GPON_I2C_END), ++ MEM_RES("i2c", LTQ_I2C_BASE_ADDR, LTQ_I2C_SIZE), + IRQ_RES("i2c_lb", FALCON_IRQ_I2C_LBREQ), + IRQ_RES("i2c_b", FALCON_IRQ_I2C_BREQ), + IRQ_RES("i2c_err", FALCON_IRQ_I2C_I2C_ERR), +@@ -140,10 +140,18 @@ + { + platform_device_register_simple("i2c-falcon", 0, + falcon_i2c_resources, ARRAY_SIZE(falcon_i2c_resources)); +- sys1_hw_activate(ACTS_I2C_ACT); ++ ltq_sysctl_activate(SYSCTL_SYS1, ACTS_I2C_ACT); + } + +-void __init falcon_register_crypto(void) ++/* spi flash */ ++static struct platform_device ltq_spi = { ++ .name = "falcon_spi", ++ .num_resources = 0, ++}; ++ ++void __init ++falcon_register_spi_flash(struct spi_board_info *data) + { +- platform_device_register_simple("ltq_falcon_deu", 0, NULL, 0); ++ spi_register_board_info(data, 1); ++ platform_device_register(<q_spi); + } +Index: linux-3.0.3/arch/mips/lantiq/falcon/devices.h +=================================================================== +--- linux-3.0.3.orig/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.584838403 +0200 ++++ linux-3.0.3/arch/mips/lantiq/falcon/devices.h 2011-10-05 12:30:34.600838405 +0200 +@@ -11,11 +11,15 @@ + #ifndef _FALCON_DEVICES_H__ + #define _FALCON_DEVICES_H__ + ++#include <linux/spi/spi.h> ++#include <linux/spi/flash.h> ++ + #include "../devices.h" + + extern void falcon_register_nand(void); + extern void falcon_register_gpio(void); + extern void falcon_register_gpio_extra(void); + extern void falcon_register_i2c(void); ++extern void falcon_register_spi_flash(struct spi_board_info *data); + + #endif +Index: linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c +=================================================================== +--- linux-3.0.3.orig/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.552838402 +0200 ++++ linux-3.0.3/arch/mips/lantiq/falcon/mach-easy98000.c 2011-10-05 12:30:34.600838405 +0200 +@@ -40,6 +40,21 @@ + .parts = easy98000_nor_partitions, + }; + ++static struct flash_platform_data easy98000_spi_flash_platform_data = { ++ .name = "sflash", ++ .parts = easy98000_nor_partitions, ++ .nr_parts = ARRAY_SIZE(easy98000_nor_partitions) ++}; ++ ++static struct spi_board_info easy98000_spi_flash_data __initdata = { ++ .modalias = "m25p80", ++ .bus_num = 0, ++ .chip_select = 0, ++ .max_speed_hz = 10 * 1000 * 1000, ++ .mode = SPI_MODE_3, ++ .platform_data = &easy98000_spi_flash_platform_data ++}; ++ + /* setup gpio based spi bus/device for access to the eeprom on the board */ + #define SPI_GPIO_MRST 102 + #define SPI_GPIO_MTSR 103 +@@ -93,6 +108,13 @@ + } + + static void __init ++easy98000sf_init(void) ++{ ++ easy98000_init_common(); ++ falcon_register_spi_flash(&easy98000_spi_flash_data); ++} ++ ++static void __init + easy98000nand_init(void) + { + easy98000_init_common(); +@@ -104,6 +126,11 @@ + "EASY98000 Eval Board", + easy98000_init); + ++MIPS_MACHINE(LANTIQ_MACH_EASY98000SF, ++ "EASY98000SF", ++ "EASY98000 Eval Board (Serial Flash)", ++ easy98000sf_init); ++ + MIPS_MACHINE(LANTIQ_MACH_EASY98000NAND, + "EASY98000NAND", + "EASY98000 Eval Board (NAND Flash)", +Index: linux-3.0.3/drivers/spi/Kconfig +=================================================================== +--- linux-3.0.3.orig/drivers/spi/Kconfig 2011-10-05 12:30:33.608838362 +0200 ++++ linux-3.0.3/drivers/spi/Kconfig 2011-10-05 12:41:56.864867570 +0200 +@@ -219,6 +219,10 @@ + This drivers supports the MPC52xx SPI controller in master SPI + mode. + ++config SPI_FALCON ++ tristate "Falcon SPI controller support" ++ depends on SOC_FALCON ++ + config SPI_MPC52xx_PSC + tristate "Freescale MPC52xx PSC SPI controller" + depends on PPC_MPC52xx && EXPERIMENTAL +Index: linux-3.0.3/drivers/spi/Makefile +=================================================================== +--- linux-3.0.3.orig/drivers/spi/Makefile 2011-10-05 12:30:33.608838362 +0200 ++++ linux-3.0.3/drivers/spi/Makefile 2011-10-05 12:41:56.884867571 +0200 +@@ -56,6 +56,7 @@ + obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o + obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o + obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o ++obj-$(CONFIG_SPI_FALCON) += spi-falcon.o + + # special build for s3c24xx spi driver with fiq support + spi_s3c24xx_hw-y := spi_s3c24xx.o +Index: linux-3.0.3/drivers/spi/spi-falcon.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ linux-3.0.3/drivers/spi/spi-falcon.c 2011-10-05 12:30:34.600838405 +0200 +@@ -0,0 +1,477 @@ ++/* ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ * ++ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> ++ */ ++ ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/spi/spi.h> ++#include <linux/delay.h> ++#include <linux/workqueue.h> ++ ++#include <lantiq_soc.h> ++ ++#define DRV_NAME "falcon_spi" ++ ++#define FALCON_SPI_XFER_BEGIN (1 << 0) ++#define FALCON_SPI_XFER_END (1 << 1) ++ ++/* Bus Read Configuration Register0 */ ++#define LTQ_BUSRCON0 0x00000010 ++/* Bus Write Configuration Register0 */ ++#define LTQ_BUSWCON0 0x00000018 ++/* Serial Flash Configuration Register */ ++#define LTQ_SFCON 0x00000080 ++/* Serial Flash Time Register */ ++#define LTQ_SFTIME 0x00000084 ++/* Serial Flash Status Register */ ++#define LTQ_SFSTAT 0x00000088 ++/* Serial Flash Command Register */ ++#define LTQ_SFCMD 0x0000008C ++/* Serial Flash Address Register */ ++#define LTQ_SFADDR 0x00000090 ++/* Serial Flash Data Register */ ++#define LTQ_SFDATA 0x00000094 ++/* Serial Flash I/O Control Register */ ++#define LTQ_SFIO 0x00000098 ++/* EBU Clock Control Register */ ++#define LTQ_EBUCC 0x000000C4 ++ ++/* Dummy Phase Length */ ++#define SFCMD_DUMLEN_OFFSET 16 ++#define SFCMD_DUMLEN_MASK 0x000F0000 ++/* Chip Select */ ++#define SFCMD_CS_OFFSET 24 ++#define SFCMD_CS_MASK 0x07000000 ++/* field offset */ ++#define SFCMD_ALEN_OFFSET 20 ++#define SFCMD_ALEN_MASK 0x00700000 ++/* SCK Rise-edge Position */ ++#define SFTIME_SCKR_POS_OFFSET 8 ++#define SFTIME_SCKR_POS_MASK 0x00000F00 ++/* SCK Period */ ++#define SFTIME_SCK_PER_OFFSET 0 ++#define SFTIME_SCK_PER_MASK 0x0000000F ++/* SCK Fall-edge Position */ ++#define SFTIME_SCKF_POS_OFFSET 12 ++#define SFTIME_SCKF_POS_MASK 0x0000F000 ++/* Device Size */ ++#define SFCON_DEV_SIZE_A23_0 0x03000000 ++#define SFCON_DEV_SIZE_MASK 0x0F000000 ++/* Read Data Position */ ++#define SFTIME_RD_POS_MASK 0x000F0000 ++/* Data Output */ ++#define SFIO_UNUSED_WD_MASK 0x0000000F ++/* Command Opcode mask */ ++#define SFCMD_OPC_MASK 0x000000FF ++/* dlen bytes of data to write */ ++#define SFCMD_DIR_WRITE 0x00000100 ++/* Data Length offset */ ++#define SFCMD_DLEN_OFFSET 9 ++/* Command Error */ ++#define SFSTAT_CMD_ERR 0x20000000 ++/* Access Command Pending */ ++#define SFSTAT_CMD_PEND 0x00400000 ++/* Frequency set to 100MHz. */ ++#define EBUCC_EBUDIV_SELF100 0x00000001 ++/* Serial Flash */ ++#define BUSRCON0_AGEN_SERIAL_FLASH 0xF0000000 ++/* 8-bit multiplexed */ ++#define BUSRCON0_PORTW_8_BIT_MUX 0x00000000 ++/* Serial Flash */ ++#define BUSWCON0_AGEN_SERIAL_FLASH 0xF0000000 ++/* Chip Select after opcode */ ++#define SFCMD_KEEP_CS_KEEP_SELECTED 0x00008000 ++ ++struct falcon_spi { ++ u32 sfcmd; /* for caching of opcode, direction, ... */ ++ struct spi_master *master; ++}; ++ ++int ++falcon_spi_xfer(struct spi_device *spi, ++ struct spi_transfer *t, ++ unsigned long flags) ++{ ++ struct device *dev = &spi->dev; ++ struct falcon_spi *priv = spi_master_get_devdata(spi->master); ++ const u8 *txp = t->tx_buf; ++ u8 *rxp = t->rx_buf; ++ unsigned int bytelen = ((8 * t->len + 7) / 8); ++ unsigned int len, alen, dumlen; ++ u32 val; ++ enum { ++ state_init, ++ state_command_prepare, ++ state_write, ++ state_read, ++ state_disable_cs, ++ state_end ++ } state = state_init; ++ ++ do { ++ switch (state) { ++ case state_init: /* detect phase of upper layer sequence */ ++ { ++ /* initial write ? */ ++ if (flags & FALCON_SPI_XFER_BEGIN) { ++ if (!txp) { ++ dev_err(dev, ++ "BEGIN without tx data!\n"); ++ return -1; ++ } ++ /* ++ * Prepare the parts of the sfcmd register, ++ * which should not ++ * change during a sequence! ++ * Only exception are the length fields, ++ * especially alen and dumlen. ++ */ ++ ++ priv->sfcmd = ((spi->chip_select ++ << SFCMD_CS_OFFSET) ++ & SFCMD_CS_MASK); ++ priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED; ++ priv->sfcmd |= *txp; ++ txp++; ++ bytelen--; ++ if (bytelen) { ++ /* more data: ++ * maybe address and/or dummy */ ++ state = state_command_prepare; ++ break; ++ } else { ++ dev_dbg(dev, "write cmd %02X\n", ++ priv->sfcmd & SFCMD_OPC_MASK); ++ } ++ } ++ /* continued write ? */ ++ if (txp && bytelen) { ++ state = state_write; ++ break; ++ } ++ /* read data? */ ++ if (rxp && bytelen) { ++ state = state_read; ++ break; ++ } ++ /* end of sequence? */ ++ if (flags & FALCON_SPI_XFER_END) ++ state = state_disable_cs; ++ else ++ state = state_end; ++ break; ++ } ++ case state_command_prepare: /* collect tx data for ++ address and dummy phase */ ++ { ++ /* txp is valid, already checked */ ++ val = 0; ++ alen = 0; ++ dumlen = 0; ++ while (bytelen > 0) { ++ if (alen < 3) { ++ val = (val<<8)|(*txp++); ++ alen++; ++ } else if ((dumlen < 15) && (*txp == 0)) { ++ /* ++ * assume dummy bytes are set to 0 ++ * from upper layer ++ */ ++ dumlen++; ++ txp++; ++ } else ++ break; ++ bytelen--; ++ } ++ priv->sfcmd &= ~(SFCMD_ALEN_MASK | SFCMD_DUMLEN_MASK); ++ priv->sfcmd |= (alen << SFCMD_ALEN_OFFSET) | ++ (dumlen << SFCMD_DUMLEN_OFFSET); ++ if (alen > 0) ++ ltq_ebu_w32(val, LTQ_SFADDR); ++ ++ dev_dbg(dev, "write cmd %02X, alen=%d " ++ "(addr=%06X) dumlen=%d\n", ++ priv->sfcmd & SFCMD_OPC_MASK, ++ alen, val, dumlen); ++ ++ if (bytelen > 0) { ++ /* continue with write */ ++ state = state_write; ++ } else if (flags & FALCON_SPI_XFER_END) { ++ /* end of sequence? */ ++ state = state_disable_cs; ++ } else { ++ /* go to end and expect another ++ * call (read or write) */ ++ state = state_end; ++ } ++ break; ++ } ++ case state_write: ++ { ++ /* txp still valid */ ++ priv->sfcmd |= SFCMD_DIR_WRITE; ++ len = 0; ++ val = 0; ++ do { ++ if (bytelen--) ++ val |= (*txp++) << (8 * len++); ++ if ((flags & FALCON_SPI_XFER_END) ++ && (bytelen == 0)) { ++ priv->sfcmd &= ++ ~SFCMD_KEEP_CS_KEEP_SELECTED; ++ } ++ if ((len == 4) || (bytelen == 0)) { ++ ltq_ebu_w32(val, LTQ_SFDATA); ++ ltq_ebu_w32(priv->sfcmd ++ | (len<<SFCMD_DLEN_OFFSET), ++ LTQ_SFCMD); ++ len = 0; ++ val = 0; ++ priv->sfcmd &= ~(SFCMD_ALEN_MASK ++ | SFCMD_DUMLEN_MASK); ++ } ++ } while (bytelen); ++ state = state_end; ++ break; ++ } ++ case state_read: ++ { ++ /* read data */ ++ priv->sfcmd &= ~SFCMD_DIR_WRITE; ++ do { ++ if ((flags & FALCON_SPI_XFER_END) ++ && (bytelen <= 4)) { ++ priv->sfcmd &= ++ ~SFCMD_KEEP_CS_KEEP_SELECTED; ++ } ++ len = (bytelen > 4) ? 4 : bytelen; ++ bytelen -= len; ++ ltq_ebu_w32(priv->sfcmd ++ |(len<<SFCMD_DLEN_OFFSET), LTQ_SFCMD); ++ priv->sfcmd &= ~(SFCMD_ALEN_MASK ++ | SFCMD_DUMLEN_MASK); ++ do { ++ val = ltq_ebu_r32(LTQ_SFSTAT); ++ if (val & SFSTAT_CMD_ERR) { ++ /* reset error status */ ++ dev_err(dev, "SFSTAT: CMD_ERR " ++ "(%x)\n", val); ++ ltq_ebu_w32(SFSTAT_CMD_ERR, ++ LTQ_SFSTAT); ++ return -1; ++ } ++ } while (val & SFSTAT_CMD_PEND); ++ val = ltq_ebu_r32(LTQ_SFDATA); ++ do { ++ *rxp = (val & 0xFF); ++ rxp++; ++ val >>= 8; ++ len--; ++ } while (len); ++ } while (bytelen); ++ state = state_end; ++ break; ++ } ++ case state_disable_cs: ++ { ++ priv->sfcmd &= ~SFCMD_KEEP_CS_KEEP_SELECTED; ++ ltq_ebu_w32(priv->sfcmd | (0 << SFCMD_DLEN_OFFSET), ++ LTQ_SFCMD); ++ val = ltq_ebu_r32(LTQ_SFSTAT); ++ if (val & SFSTAT_CMD_ERR) { ++ /* reset error status */ ++ dev_err(dev, "SFSTAT: CMD_ERR (%x)\n", val); ++ ltq_ebu_w32(SFSTAT_CMD_ERR, LTQ_SFSTAT); ++ return -1; ++ } ++ state = state_end; ++ break; ++ } ++ case state_end: ++ break; ++ } ++ } while (state != state_end); ++ ++ return 0; ++} ++ ++static int ++falcon_spi_setup(struct spi_device *spi) ++{ ++ struct device *dev = &spi->dev; ++ const u32 ebuclk = CLOCK_100M; ++ unsigned int i; ++ unsigned long flags; ++ ++ dev_dbg(dev, "setup\n"); ++ ++ if (spi->master->bus_num > 0 || spi->chip_select > 0) ++ return -ENODEV; ++ ++ spin_lock_irqsave(&ebu_lock, flags); ++ ++ if (ebuclk < spi->max_speed_hz) { ++ /* set EBU clock to 100 MHz */ ++ ltq_sys1_w32_mask(0, EBUCC_EBUDIV_SELF100, LTQ_EBUCC); ++ i = 1; /* divider */ ++ } else { ++ /* set EBU clock to 50 MHz */ ++ ltq_sys1_w32_mask(EBUCC_EBUDIV_SELF100, 0, LTQ_EBUCC); ++ ++ /* search for suitable divider */ ++ for (i = 1; i < 7; i++) { ++ if (ebuclk / i <= spi->max_speed_hz) ++ break; ++ } ++ } ++ ++ /* setup period of serial clock */ ++ ltq_ebu_w32_mask(SFTIME_SCKF_POS_MASK ++ | SFTIME_SCKR_POS_MASK ++ | SFTIME_SCK_PER_MASK, ++ (i << SFTIME_SCKR_POS_OFFSET) ++ | (i << (SFTIME_SCK_PER_OFFSET + 1)), ++ LTQ_SFTIME); ++ ++ /* set some bits of unused_wd, to not trigger HOLD/WP ++ * signals on non QUAD flashes */ ++ ltq_ebu_w32((SFIO_UNUSED_WD_MASK & (0x8 | 0x4)), LTQ_SFIO); ++ ++ ltq_ebu_w32(BUSRCON0_AGEN_SERIAL_FLASH | BUSRCON0_PORTW_8_BIT_MUX, ++ LTQ_BUSRCON0); ++ ltq_ebu_w32(BUSWCON0_AGEN_SERIAL_FLASH, LTQ_BUSWCON0); ++ /* set address wrap around to maximum for 24-bit addresses */ ++ ltq_ebu_w32_mask(SFCON_DEV_SIZE_MASK, SFCON_DEV_SIZE_A23_0, LTQ_SFCON); ++ ++ spin_unlock_irqrestore(&ebu_lock, flags); ++ ++ return 0; ++} ++ ++static int ++falcon_spi_transfer(struct spi_device *spi, struct spi_message *m) ++{ ++ struct falcon_spi *priv = spi_master_get_devdata(spi->master); ++ struct spi_transfer *t; ++ unsigned long spi_flags; ++ unsigned long flags; ++ int ret = 0; ++ ++ priv->sfcmd = 0; ++ m->actual_length = 0; ++ ++ spi_flags = FALCON_SPI_XFER_BEGIN; ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ if (list_is_last(&t->transfer_list, &m->transfers)) ++ spi_flags |= FALCON_SPI_XFER_END; ++ ++ spin_lock_irqsave(&ebu_lock, flags); ++ ret = falcon_spi_xfer(spi, t, spi_flags); ++ spin_unlock_irqrestore(&ebu_lock, flags); ++ ++ if (ret) ++ break; ++ ++ m->actual_length += t->len; ++ ++ if (t->delay_usecs || t->cs_change) ++ BUG(); ++ ++ spi_flags = 0; ++ } ++ ++ m->status = ret; ++ m->complete(m->context); ++ ++ return 0; ++} ++ ++static void ++falcon_spi_cleanup(struct spi_device *spi) ++{ ++ struct device *dev = &spi->dev; ++ ++ dev_dbg(dev, "cleanup\n"); ++} ++ ++static int __devinit ++falcon_spi_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct falcon_spi *priv; ++ struct spi_master *master; ++ int ret; ++ ++ dev_dbg(dev, "probing\n"); ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*priv)); ++ if (!master) { ++ dev_err(dev, "no memory for spi_master\n"); ++ return -ENOMEM; ++ } ++ ++ priv = spi_master_get_devdata(master); ++ priv->master = master; ++ ++ master->mode_bits = SPI_MODE_3; ++ master->num_chipselect = 1; ++ master->bus_num = 0; ++ ++ master->setup = falcon_spi_setup; ++ master->transfer = falcon_spi_transfer; ++ master->cleanup = falcon_spi_cleanup; ++ ++ platform_set_drvdata(pdev, priv); ++ ++ ret = spi_register_master(master); ++ if (ret) ++ spi_master_put(master); ++ ++ return ret; ++} ++ ++static int __devexit ++falcon_spi_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct falcon_spi *priv = platform_get_drvdata(pdev); ++ ++ dev_dbg(dev, "removed\n"); ++ ++ spi_unregister_master(priv->master); ++ ++ return 0; ++} ++ ++static struct platform_driver falcon_spi_driver = { ++ .probe = falcon_spi_probe, ++ .remove = __devexit_p(falcon_spi_remove), ++ .driver = { ++ .name = DRV_NAME, ++ .owner = THIS_MODULE ++ } ++}; ++ ++static int __init ++falcon_spi_init(void) ++{ ++ return platform_driver_register(&falcon_spi_driver); ++} ++ ++static void __exit ++falcon_spi_exit(void) ++{ ++ platform_driver_unregister(&falcon_spi_driver); ++} ++ ++module_init(falcon_spi_init); ++module_exit(falcon_spi_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("Lantiq Falcon SPI controller driver"); +Index: linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h +=================================================================== +--- linux-3.0.3.orig/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:38:16.176858136 +0200 ++++ linux-3.0.3/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h 2011-10-05 12:39:54.936862358 +0200 +@@ -48,6 +48,10 @@ + + #define LTQ_EBU_MODCON 0x000C + ++/* I2C */ ++#define LTQ_I2C_BASE_ADDR 0x1E200000 ++#define LTQ_I2C_SIZE 0x00010000 ++ + /* GPIO */ + #define LTQ_GPIO0_BASE_ADDR 0x1D810000 + #define LTQ_GPIO0_SIZE 0x0080 +@@ -92,6 +96,7 @@ + + /* Activation Status Register */ + #define ACTS_ASC1_ACT 0x00000800 ++#define ACTS_I2C_ACT 0x00004000 + #define ACTS_P0 0x00010000 + #define ACTS_P1 0x00010000 + #define ACTS_P2 0x00020000 |