add 2.6.28 patches and kernel config

SVN-Revision: 14884
v19.07.3_mercusys_ac12_duma
Florian Fainelli 15 years ago
parent a54018aa87
commit 499fa7f7a1

@ -0,0 +1,237 @@
CONFIG_32BIT=y
# CONFIG_64BIT is not set
# CONFIG_8139TOO is not set
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
# CONFIG_ATA_PIIX is not set
CONFIG_ATA_SFF=y
CONFIG_BASE_SMALL=0
# CONFIG_BCM47XX is not set
CONFIG_BITREVERSE=y
CONFIG_BOOT_RAW=y
CONFIG_CEVT_R4K=y
CONFIG_CLASSIC_RCU=y
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_LITTLE_ENDIAN=y
# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
CONFIG_CPU_MIPSR1=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_VR41XX is not set
CONFIG_CSRC_R4K=y
# CONFIG_DEBUG_FS is not set
CONFIG_DEVPORT=y
# CONFIG_DM9000 is not set
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_DMA_NONCOHERENT=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
CONFIG_EXT2_FS=y
# CONFIG_FREEZER is not set
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_SYSFS=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
# CONFIG_HAVE_AOUT is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_HAVE_IDE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_HW_HAS_PCI=y
CONFIG_HW_RANDOM=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
# CONFIG_I2C is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IDE is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IRQ_CPU=y
CONFIG_KEXEC=y
CONFIG_KMOD=y
CONFIG_KORINA=y
# CONFIG_LEDS_ALIX is not set
# CONFIG_LEDS_GPIO is not set
# CONFIG_LEMOTE_FULONG is not set
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_EMMA is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_TMIO is not set
CONFIG_MIKROTIK_RB532=y
CONFIG_MIPS=y
# CONFIG_MIPS_COBALT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=4
# CONFIG_MIPS_MACHINE is not set
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM is not set
CONFIG_MTD=y
# CONFIG_MTD_ABSENT is not set
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
# CONFIG_MTD_CFI_AMDSTD is not set
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_CHAR=y
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
CONFIG_MTD_MAP_BANK_WIDTH_2=y
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MTDRAM is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_NANDSIM is not set
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_ONENAND is not set
# CONFIG_MTD_OTP is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_PHRAM is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
CONFIG_MTD_PHYSMAP_LEN=0
CONFIG_MTD_PHYSMAP_START=0x8000000
# CONFIG_MTD_PLATRAM is not set
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_NATSEMI is not set
CONFIG_NF_CONNTRACK=y
CONFIG_NF_CT_ACCT=y
# CONFIG_NF_DEFRAG_IPV4 is not set
# CONFIG_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
CONFIG_PAGEFLAGS_EXTENDED=y
# CONFIG_PAGE_SIZE_16KB is not set
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_64KB is not set
# CONFIG_PAGE_SIZE_8KB is not set
CONFIG_PATA_PLATFORM=y
CONFIG_PATA_RB532=y
# CONFIG_PATA_SCH is not set
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCSPKR_PLATFORM=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_PROBE_INITRD_HEADER is not set
# CONFIG_PROM_EMU is not set
# CONFIG_R6040 is not set
CONFIG_RC32434_WDT=y
CONFIG_RTC_LIB=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
CONFIG_SCSI=y
CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
# CONFIG_TC35815 is not set
CONFIG_TRAD_SIGNALS=y
# CONFIG_VGASTATE is not set
CONFIG_VIA_RHINE=y
CONFIG_VIA_RHINE_MMIO=y
CONFIG_YAFFS_9BYTE_TAGS=y
# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
CONFIG_YAFFS_AUTO_YAFFS2=y
# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
CONFIG_YAFFS_FS=y
CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
CONFIG_YAFFS_YAFFS1=y
CONFIG_YAFFS_YAFFS2=y
CONFIG_ZONE_DMA_FLAG=0

@ -0,0 +1,42 @@
The code is rather based on trial-and-error than knowledge. Verified Via
Rhine functionality in PIO as well as MMIO mode.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
Tested-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/pci/pci-rc32434.c | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
index 1c2821e..71f7d27 100644
--- a/arch/mips/pci/pci-rc32434.c
+++ b/arch/mips/pci/pci-rc32434.c
@@ -205,6 +205,8 @@ static int __init rc32434_pcibridge_init(void)
static int __init rc32434_pci_init(void)
{
+ void __iomem *io_map_base;
+
pr_info("PCI: Initializing PCI\n");
ioport_resource.start = rc32434_res_pci_io1.start;
@@ -212,6 +214,15 @@ static int __init rc32434_pci_init(void)
rc32434_pcibridge_init();
+ io_map_base = ioremap(rc32434_res_pci_io1.start,
+ rc32434_res_pci_io1.end - rc32434_res_pci_io1.start + 1);
+
+ if (!io_map_base)
+ return -ENOMEM;
+
+ rc32434_controller.io_map_base =
+ (unsigned long)io_map_base - rc32434_res_pci_io1.start;
+
register_pci_controller(&rc32434_controller);
rc32434_sync();
--
1.5.6.4

@ -0,0 +1,35 @@
The algorithm works unconditionally. If bitval is one, the first line is
a no op and the second line sets the bit at offset position. Vice versa,
if bitval is zero, the first line clears the bit at offset position and
the second line is a no op.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
arch/mips/rb532/gpio.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index 0e84c8a..e35cb75 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -119,13 +119,11 @@ static inline void rb532_set_bit(unsigned bitval,
unsigned long flags;
u32 val;
- bitval = !!bitval; /* map parameter to {0,1} */
-
local_irq_save(flags);
val = readl(ioaddr);
- val &= ~( ~bitval << offset ); /* unset bit if bitval == 0 */
- val |= ( bitval << offset ); /* set bit if bitval == 1 */
+ val &= ~(!bitval << offset); /* unset bit if bitval == 0 */
+ val |= (!!bitval << offset); /* set bit if bitval == 1 */
writel(val, ioaddr);
local_irq_restore(flags);
--
1.5.6.4

@ -0,0 +1,52 @@
After applying the following changes I could verify functionality by
mounting a filesystem on the cfdisk and reading/writing files in it.
The set_irq_type() function must be wrong, as there is no set_type()
function defined for the rb532 IRQ chip. But as the used IRQ actually is
being triggered by a GPIO, setting it's interrupt level should be the
right alternative. Also to clear a GPIO triggered IRQ, the source has to
be cleared. This is being done at the end of rb532_pata_irq_handler.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
Acked-by: Florian Fainelli <florian@openwrt.org>
---
diff -urN linux-2.6.28.7/drivers/ata/pata_rb532_cf.c linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c
--- linux-2.6.28.7/drivers/ata/pata_rb532_cf.c 2009-02-20 23:41:27.000000000 +0100
+++ linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c 2009-03-15 13:21:06.000000000 +0100
@@ -31,6 +31,7 @@
#include <scsi/scsi_host.h>
#include <asm/gpio.h>
+#include <asm/mach-rc32434/gpio.h>
#define DRV_NAME "pata-rb532-cf"
#define DRV_VERSION "0.1.0"
@@ -63,8 +64,8 @@
ata_sff_sync might be sufficient. */
ata_sff_dma_pause(ap);
ndelay(RB500_CF_IO_DELAY);
-
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
+
+ rb532_gpio_set_ilevel(1, info->gpio_line);
}
static void rb532_pata_exec_command(struct ata_port *ap,
@@ -113,13 +114,15 @@
struct rb532_cf_info *info = ah->private_data;
if (gpio_get_value(info->gpio_line)) {
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
+ rb532_gpio_set_ilevel(0, info->gpio_line);
if (!info->frozen)
ata_sff_interrupt(info->irq, dev_instance);
} else {
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
+ rb532_gpio_set_ilevel(1, info->gpio_line);
}
+ rb532_gpio_set_istat(0, info->gpio_line);
+
return IRQ_HANDLED;
}

@ -0,0 +1,33 @@
* rename the offset definition to avoid abiguity with the standard ATA
IO address
* read and write four bytes at once like the original driver does
* use writesl() and readsl() which implicitly iterate over the data
This patch assumes buflen to be a multiple of four, which is true for
ATA devices. ATAPI support is not known, though unlikely, as the
original driver always transfers 512 Bytes at once.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
Acked-by: Sergei Shtyltov <sshtylyov@ru.mvista.com>
---
diff -urN linux-2.6.28.7/drivers/ata/pata_rb532_cf.c linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c
--- linux-2.6.28.7/drivers/ata/pata_rb532_cf.c 2009-03-15 13:24:24.000000000 +0100
+++ linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c 2009-03-15 13:26:19.000000000 +0100
@@ -82,13 +82,10 @@
void __iomem *ioaddr = ap->ioaddr.data_addr;
int retlen = buflen;
- if (write_data) {
- for (; buflen > 0; buflen--, buf++)
- writeb(*buf, ioaddr);
- } else {
- for (; buflen > 0; buflen--, buf++)
- *buf = readb(ioaddr);
- }
+ if (write_data)
+ writesl(ioaddr, buf, buflen / sizeof(u32));
+ else
+ readsl(ioaddr, buf, buflen / sizeof(u32));
rb532_pata_finish_io(adev->link->ap);
return retlen;

@ -0,0 +1,19 @@
Per definition, this function should return the number of bytes
consumed. Also take care of the unlikely case when buflen is not a
multiple of four; while transferring, the division cuts the remaining
bytes, so alter the return value accordingly.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
diff -urN linux-2.6.28.7/drivers/ata/pata_rb532_cf.c linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c
--- linux-2.6.28.7/drivers/ata/pata_rb532_cf.c 2009-03-15 13:29:09.000000000 +0100
+++ linux-2.6.28.7.new/drivers/ata/pata_rb532_cf.c 2009-03-15 13:29:46.000000000 +0100
@@ -88,7 +88,7 @@
readsl(ioaddr, buf, buflen / sizeof(u32));
rb532_pata_finish_io(adev->link->ap);
- return retlen;
+ return buflen - (buflen % sizeof(u32));;
}
static void rb532_pata_freeze(struct ata_port *ap)

@ -0,0 +1,15 @@
diff -urN linux-2.6.27.5/arch/mips/kernel/head.S linux-2.6.27.5.new/arch/mips/kernel/head.S
--- linux-2.6.27.5/arch/mips/kernel/head.S 2008-11-15 19:24:03.000000000 +0100
+++ linux-2.6.27.5.new/arch/mips/kernel/head.S 2008-11-15 19:24:55.000000000 +0100
@@ -123,6 +123,11 @@
j kernel_entry
nop
+
+
+EXPORT(_image_cmdline)
+ .ascii "CMDLINE:"
+
#ifndef CONFIG_NO_EXCEPT_FILL
/*
* Reserved space for exception handlers.

@ -0,0 +1,31 @@
The new value is the one used in the external patch before and allows at
least a standard MTU of 1500 to be handled correctly. Impact of this
change gets visible when bigger packets are to be received, issuing:
| ping -s 492 <IP>
and bigger payload sized led to 100% packet loss.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index fefb33d..e30c2f4 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -84,7 +84,10 @@
#define KORINA_NUM_RDS 64 /* number of receive descriptors */
#define KORINA_NUM_TDS 64 /* number of transmit descriptors */
-#define KORINA_RBSIZE 536 /* size of one resource buffer = Ether MTU */
+/* KORINA_RBSIZE is the hardware's default maximum receive
+ * frame size in bytes. Having this hardcoded means that there
+ * is no support for MTU sizes greater than 1500. */
+#define KORINA_RBSIZE 1536 /* size of one resource buffer = Ether MTU */
#define KORINA_RDS_MASK (KORINA_NUM_RDS - 1)
#define KORINA_TDS_MASK (KORINA_NUM_TDS - 1)
#define RD_RING_SIZE (KORINA_NUM_RDS * sizeof(struct dma_desc))
--
1.5.6.4

@ -0,0 +1,33 @@
Without this the driver will crash when the NIC is being restarted.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index e30c2f4..65b8487 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -904,6 +904,8 @@ static int korina_restart(struct net_device *dev)
korina_free_ring(dev);
+ napi_disable(&lp->napi);
+
ret = korina_init(dev);
if (ret < 0) {
printk(KERN_ERR DRV_NAME "%s: cannot restart device\n",
@@ -1070,6 +1072,8 @@ static int korina_close(struct net_device *dev)
korina_free_ring(dev);
+ napi_disable(&lp->napi);
+
free_irq(lp->rx_irq, dev);
free_irq(lp->tx_irq, dev);
free_irq(lp->ovr_irq, dev);
--
1.5.6.4

@ -0,0 +1,138 @@
This function needs an early exit condition to function properly, or
else caller assumes napi workload wasn't enough to handle all received
packets and korina_rx is called again (and again and again and ...).
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
--- a/drivers/net/korina.c 2009-01-19 23:19:10.000000000 +0100
+++ b/drivers/net/korina.c 2009-01-19 23:25:31.000000000 +0100
@@ -353,15 +353,20 @@
struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done];
struct sk_buff *skb, *skb_new;
u8 *pkt_buf;
- u32 devcs, pkt_len, dmas, rx_free_desc;
+ u32 devcs, pkt_len, dmas;
int count;
dma_cache_inv((u32)rd, sizeof(*rd));
for (count = 0; count < limit; count++) {
+ skb = lp->rx_skb[lp->rx_next_done];
+ skb_new = NULL;
devcs = rd->devcs;
+ if ((KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) == 0)
+ break;
+
/* Update statistics counters */
if (devcs & ETH_RX_CRC)
dev->stats.rx_crc_errors++;
@@ -384,64 +389,53 @@
* in Rc32434 (errata ref #077) */
dev->stats.rx_errors++;
dev->stats.rx_dropped++;
- }
-
- while ((rx_free_desc = KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) {
- /* init the var. used for the later
- * operations within the while loop */
- skb_new = NULL;
+ } else if ((devcs & ETH_RX_ROK)) {
pkt_len = RCVPKT_LENGTH(devcs);
- skb = lp->rx_skb[lp->rx_next_done];
+ /* must be the (first and) last
+ * descriptor then */
+ pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
+
+ /* invalidate the cache */
+ dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4);
+
+ /* Malloc up new buffer. */
+ skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2);
+
+ if (!skb_new)
+ break;
+ /* Do not count the CRC */
+ skb_put(skb, pkt_len - 4);
+ skb->protocol = eth_type_trans(skb, dev);
+
+ /* Pass the packet to upper layers */
+ netif_receive_skb(skb);
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+
+ /* Update the mcast stats */
+ if (devcs & ETH_RX_MP)
+ dev->stats.multicast++;
- if ((devcs & ETH_RX_ROK)) {
- /* must be the (first and) last
- * descriptor then */
- pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
-
- /* invalidate the cache */
- dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4);
-
- /* Malloc up new buffer. */
- skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2);
-
- if (!skb_new)
- break;
- /* Do not count the CRC */
- skb_put(skb, pkt_len - 4);
- skb->protocol = eth_type_trans(skb, dev);
-
- /* Pass the packet to upper layers */
- netif_receive_skb(skb);
- dev->last_rx = jiffies;
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pkt_len;
-
- /* Update the mcast stats */
- if (devcs & ETH_RX_MP)
- dev->stats.multicast++;
-
- lp->rx_skb[lp->rx_next_done] = skb_new;
- }
-
- rd->devcs = 0;
-
- /* Restore descriptor's curr_addr */
- if (skb_new)
- rd->ca = CPHYSADDR(skb_new->data);
- else
- rd->ca = CPHYSADDR(skb->data);
+ lp->rx_skb[lp->rx_next_done] = skb_new;
+ }
+ rd->devcs = 0;
+
+ /* Restore descriptor's curr_addr */
+ if (skb_new)
+ rd->ca = CPHYSADDR(skb_new->data);
+ else
+ rd->ca = CPHYSADDR(skb->data);
- rd->control = DMA_COUNT(KORINA_RBSIZE) |
+ rd->control = DMA_COUNT(KORINA_RBSIZE) |
DMA_DESC_COD | DMA_DESC_IOD;
- lp->rd_ring[(lp->rx_next_done - 1) &
- KORINA_RDS_MASK].control &=
- ~DMA_DESC_COD;
-
- lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
- dma_cache_wback((u32)rd, sizeof(*rd));
- rd = &lp->rd_ring[lp->rx_next_done];
- writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas);
- }
+ lp->rd_ring[(lp->rx_next_done - 1) &
+ KORINA_RDS_MASK].control &=
+ ~DMA_DESC_COD;
+
+ lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK;
+ dma_cache_wback((u32)rd, sizeof(*rd));
+ rd = &lp->rd_ring[lp->rx_next_done];
+ writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas);
}
dmas = readl(&lp->rx_dma_regs->dmas);

@ -0,0 +1,18 @@
The called netif_rx_schedule() does all the work for us:
- it checks the return value of netif_rx_schedule_prep() and
- if everything is ok calls __netif_rx_schedule().
Before this change, the driver received absolutely nothing.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
--- a/drivers/net/korina.c 2009-01-19 23:26:19.000000000 +0100
+++ b/drivers/net/korina.c 2009-01-19 23:27:06.000000000 +0100
@@ -330,7 +330,7 @@
dmas = readl(&lp->rx_dma_regs->dmas);
if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
- netif_rx_schedule_prep(dev, &lp->napi);
+ netif_rx_schedule(dev, &lp->napi);
dmasm = readl(&lp->rx_dma_regs->dmasm);
writel(dmasm | (DMA_STAT_DONE |

@ -0,0 +1,40 @@
Triggering TX before the write to the DMA status mask register leads to
transferring packets with maximum payload no matter what the actual
packet size is.
While here, also trigger RX scheduling after writing the DMA status mask
register, like it was in the original driver before it was sent
upstream.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
--- a/drivers/net/korina.c 2009-01-19 23:27:41.000000000 +0100
+++ b/drivers/net/korina.c 2009-01-19 23:29:08.000000000 +0100
@@ -330,12 +330,12 @@
dmas = readl(&lp->rx_dma_regs->dmas);
if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
- netif_rx_schedule(dev, &lp->napi);
-
dmasm = readl(&lp->rx_dma_regs->dmasm);
writel(dmasm | (DMA_STAT_DONE |
DMA_STAT_HALT | DMA_STAT_ERR),
&lp->rx_dma_regs->dmasm);
+
+ netif_rx_schedule(dev, &lp->napi);
if (dmas & DMA_STAT_ERR)
printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
@@ -621,11 +621,11 @@
dmas = readl(&lp->tx_dma_regs->dmas);
if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
- korina_tx(dev);
-
dmasm = readl(&lp->tx_dma_regs->dmasm);
writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR),
&lp->tx_dma_regs->dmasm);
+
+ korina_tx(dev);
if (lp->tx_chain_status == desc_filled &&
(readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {

@ -0,0 +1,87 @@
Originally this must have been a rewrite error when introducing
'chain_index'. But the original driver did not use the previous chain
item everywhere: when altering the address tx_chain_tail points to, it
should move forward, not backwards.
Also this is not an "index" but rather the penultimate element in the
chain, so rename it accordingly.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index dced5e7..f200175 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -199,7 +199,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
struct korina_private *lp = netdev_priv(dev);
unsigned long flags;
u32 length;
- u32 chain_index;
+ u32 chain_prev, chain_next;
struct dma_desc *td;
spin_lock_irqsave(&lp->lock, flags);
@@ -231,8 +231,8 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
/* Setup the transmit descriptor. */
dma_cache_inv((u32) td, sizeof(*td));
td->ca = CPHYSADDR(skb->data);
- chain_index = (lp->tx_chain_tail - 1) &
- KORINA_TDS_MASK;
+ chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK;
+ chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK;
if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) {
if (lp->tx_chain_status == desc_empty) {
@@ -240,7 +240,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
td->control = DMA_COUNT(length) |
DMA_DESC_COF | DMA_DESC_IOF;
/* Move tail */
- lp->tx_chain_tail = chain_index;
+ lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
&lp->tx_dma_regs->dmandptr);
@@ -251,12 +251,12 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
td->control = DMA_COUNT(length) |
DMA_DESC_COF | DMA_DESC_IOF;
/* Link to prev */
- lp->td_ring[chain_index].control &=
+ lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
/* Link to prev */
- lp->td_ring[chain_index].link = CPHYSADDR(td);
+ lp->td_ring[chain_prev].link = CPHYSADDR(td);
/* Move tail */
- lp->tx_chain_tail = chain_index;
+ lp->tx_chain_tail = chain_next;
/* Write to NDPTR */
writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]),
&(lp->tx_dma_regs->dmandptr));
@@ -270,17 +270,17 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
td->control = DMA_COUNT(length) |
DMA_DESC_COF | DMA_DESC_IOF;
/* Move tail */
- lp->tx_chain_tail = chain_index;
+ lp->tx_chain_tail = chain_next;
lp->tx_chain_status = desc_filled;
netif_stop_queue(dev);
} else {
/* Update tail */
td->control = DMA_COUNT(length) |
DMA_DESC_COF | DMA_DESC_IOF;
- lp->td_ring[chain_index].control &=
+ lp->td_ring[chain_prev].control &=
~DMA_DESC_COF;
- lp->td_ring[chain_index].link = CPHYSADDR(td);
- lp->tx_chain_tail = chain_index;
+ lp->td_ring[chain_prev].link = CPHYSADDR(td);
+ lp->tx_chain_tail = chain_next;
}
}
dma_cache_wback((u32) td, sizeof(*td));
--
1.5.6.4

@ -0,0 +1,25 @@
Apparently this doesn't make sense. Otherwise the queue gets disabled as
soon as it's getting empty and can only be resurrected by a driver
restart.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index f200175..bd33fa9 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -272,7 +272,6 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
/* Move tail */
lp->tx_chain_tail = chain_next;
lp->tx_chain_status = desc_filled;
- netif_stop_queue(dev);
} else {
/* Update tail */
td->control = DMA_COUNT(length) |
--
1.5.6.4

@ -0,0 +1,53 @@
As the kernel warning states: "IRQF_DISABLED is not guaranteed on shared
IRQs". Since these IRQs' values are hardcoded and my test system doesn't
show any shared use of IRQs at all, rather make them non-shared than
non-disabled.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index bd33fa9..1d6e48e 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -1000,14 +1000,14 @@ static int korina_open(struct net_device *dev)
* that handles the Done Finished
* Ovr and Und Events */
ret = request_irq(lp->rx_irq, &korina_rx_dma_interrupt,
- IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Rx", dev);
+ IRQF_DISABLED, "Korina ethernet Rx", dev);
if (ret < 0) {
printk(KERN_ERR DRV_NAME "%s: unable to get Rx DMA IRQ %d\n",
dev->name, lp->rx_irq);
goto err_release;
}
ret = request_irq(lp->tx_irq, &korina_tx_dma_interrupt,
- IRQF_SHARED | IRQF_DISABLED, "Korina ethernet Tx", dev);
+ IRQF_DISABLED, "Korina ethernet Tx", dev);
if (ret < 0) {
printk(KERN_ERR DRV_NAME "%s: unable to get Tx DMA IRQ %d\n",
dev->name, lp->tx_irq);
@@ -1016,7 +1016,7 @@ static int korina_open(struct net_device *dev)
/* Install handler for overrun error. */
ret = request_irq(lp->ovr_irq, &korina_ovr_interrupt,
- IRQF_SHARED | IRQF_DISABLED, "Ethernet Overflow", dev);
+ IRQF_DISABLED, "Ethernet Overflow", dev);
if (ret < 0) {
printk(KERN_ERR DRV_NAME"%s: unable to get OVR IRQ %d\n",
dev->name, lp->ovr_irq);
@@ -1025,7 +1025,7 @@ static int korina_open(struct net_device *dev)
/* Install handler for underflow error. */
ret = request_irq(lp->und_irq, &korina_und_interrupt,
- IRQF_SHARED | IRQF_DISABLED, "Ethernet Underflow", dev);
+ IRQF_DISABLED, "Ethernet Underflow", dev);
if (ret < 0) {
printk(KERN_ERR DRV_NAME "%s: unable to get UND IRQ %d\n",
dev->name, lp->und_irq);
--
1.5.6.4

@ -0,0 +1,34 @@
As the assigned value is being overwritten shortly after, it can be
dropped and so the whole variable definition moved to the start of the
function.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 60ae7bf..75010ca 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -743,6 +743,7 @@ static struct ethtool_ops netdev_ethtool_ops = {
static void korina_alloc_ring(struct net_device *dev)
{
struct korina_private *lp = netdev_priv(dev);
+ struct sk_buff *skb;
int i;
/* Initialize the transmit descriptors */
@@ -758,8 +759,6 @@ static void korina_alloc_ring(struct net_device *dev)
/* Initialize the receive descriptors */
for (i = 0; i < KORINA_NUM_RDS; i++) {
- struct sk_buff *skb = lp->rx_skb[i];
-
skb = dev_alloc_skb(KORINA_RBSIZE + 2);
if (!skb)
break;
--
1.5.6.4

@ -0,0 +1,36 @@
After the last loop iteration, i has the value RC32434_NUM_RDS and
therefore leads to an index overflow when used afterwards to address the
last element. This is yet another another bug introduced when rewriting
parts of the driver for upstream preparation, as the original driver
used 'RC32434_NUM_RDS - 1' instead.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 1d6e48e..67fbdf4 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -769,11 +769,12 @@ static void korina_alloc_ring(struct net_device *dev)
lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[i+1]);
}
- /* loop back */
- lp->rd_ring[i].link = CPHYSADDR(&lp->rd_ring[0]);
- lp->rx_next_done = 0;
+ /* loop back receive descriptors, so the last
+ * descriptor points to the first one */
+ lp->rd_ring[i - 1].link = CPHYSADDR(&lp->rd_ring[0]);
+ lp->rd_ring[i - 1].control |= DMA_DESC_COD;
- lp->rd_ring[i].control |= DMA_DESC_COD;
+ lp->rx_next_done = 0;
lp->rx_chain_head = 0;
lp->rx_chain_tail = 0;
lp->rx_chain_status = desc_empty;
--
1.5.6.4

@ -0,0 +1,28 @@
This is copy and paste from the original driver. As skb_reserve() is
also called within korina_alloc_ring() when initially allocating the
receive descriptors, the same should be done when allocating new space
after passing an skb to upper layers.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 67fbdf4..60ae7bf 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -416,6 +416,9 @@ static int korina_rx(struct net_device *dev, int limit)
if (devcs & ETH_RX_MP)
dev->stats.multicast++;
+ /* 16 bit align */
+ skb_reserve(skb_new, 2);
+
lp->rx_skb[lp->rx_next_done] = skb_new;
}
--
1.5.6.4

@ -0,0 +1,33 @@
I'm not sure if this is necessary, but the original driver did it and
apparently also many other drivers do it, so it should not be completely
wrong to do it.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
drivers/net/korina.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 75010ca..56b4db2 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -419,6 +419,7 @@ static int korina_rx(struct net_device *dev, int limit)
/* 16 bit align */
skb_reserve(skb_new, 2);
+ skb_new->dev = dev;
lp->rx_skb[lp->rx_next_done] = skb_new;
}
@@ -763,6 +764,7 @@ static void korina_alloc_ring(struct net_device *dev)
if (!skb)
break;
skb_reserve(skb, 2);
+ skb->dev = dev;
lp->rx_skb[i] = skb;
lp->rd_ring[i].control = DMA_DESC_IOD |
DMA_COUNT(KORINA_RBSIZE);
--
1.5.6.4

@ -0,0 +1,12 @@
diff -urN linux-2.6.27.5/drivers/watchdog/rc32434_wdt.c linux-2.6.27.5.new/drivers/watchdog/rc32434_wdt.c
--- linux-2.6.27.5/drivers/watchdog/rc32434_wdt.c 2008-11-07 18:55:34.000000000 +0100
+++ linux-2.6.27.5.new/drivers/watchdog/rc32434_wdt.c 2008-11-15 22:06:28.000000000 +0100
@@ -261,7 +261,7 @@
int ret;
struct resource *r;
- r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb500_wdt_res");
+ r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rb532_wdt_res");
if (!r) {
printk(KERN_ERR KBUILD_MODNAME
"failed to retrieve resources\n");

@ -0,0 +1,26 @@
As the korina ethernet driver uses platform_get_drvdata() to extract the
driver specific data from the platform device, driver_data has to be
used here.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
arch/mips/rb532/devices.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index 9b6b744..3c74561 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -89,7 +89,7 @@ static struct korina_device korina_dev0_data = {
static struct platform_device korina_dev0 = {
.id = -1,
.name = "korina",
- .dev.platform_data = &korina_dev0_data,
+ .dev.driver_data = &korina_dev0_data,
.resource = korina_dev0_res,
.num_resources = ARRAY_SIZE(korina_dev0_res),
};
--
1.5.6.4

@ -0,0 +1,91 @@
Auto-detection works just fine, so use it instead of specifying the type
manually. Also define a platform device for the uart, as suggested by
David Daney.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
arch/mips/rb532/devices.c | 26 ++++++++++++++++++++++++++
arch/mips/rb532/serial.c | 2 +-
2 files changed, 27 insertions(+), 1 deletions(-)
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c
index c1c2918..9b6b744 100644
--- a/arch/mips/rb532/devices.c
+++ b/arch/mips/rb532/devices.c
@@ -24,6 +24,7 @@
#include <linux/mtd/partitions.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/serial_8250.h>
#include <asm/bootinfo.h>
@@ -39,6 +40,8 @@
#define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
#define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
+extern unsigned int idt_cpu_freq;
+
static struct resource korina_dev0_res[] = {
{
.name = "korina_regs",
@@ -214,12 +217,32 @@ static struct platform_device rb532_wdt = {
.num_resources = ARRAY_SIZE(rb532_wdt_res),
};
+static struct plat_serial8250_port rb532_uart_res[] = {
+ {
+ .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE),
+ .irq = UART0_IRQ,
+ .regshift = 2,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF,
+ },
+ {
+ .flags = 0,
+ }
+};
+
+static struct platform_device rb532_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = &rb532_uart_res,
+};
+
static struct platform_device *rb532_devs[] = {
&korina_dev0,
&nand_slot0,
&cf_slot0,
&rb532_led,
&rb532_button,
+ &rb532_uart,
&rb532_wdt
};
@@ -294,6 +317,9 @@ static int __init plat_setup_devices(void)
/* Initialise the NAND device */
rb532_nand_setup();
+ /* set the uart clock to the current cpu frequency */
+ rb532_uart_res[0].uartclk = idt_cpu_freq;
+
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
}
diff --git a/arch/mips/rb532/serial.c b/arch/mips/rb532/serial.c
index 3e0d7ec..00ed19f 100644
--- a/arch/mips/rb532/serial.c
+++ b/arch/mips/rb532/serial.c
@@ -36,7 +36,7 @@
extern unsigned int idt_cpu_freq;
static struct uart_port rb532_uart = {
- .type = PORT_16550A,
+ .flags = UPF_BOOT_AUTOCONF,
.line = 0,
.irq = UART0_IRQ,
.iotype = UPIO_MEM,
--
1.5.6.4

@ -0,0 +1,32 @@
This register just contains the address of the actual resource, so
initialisation has to be the same as cf_slot0_res and nand_slot0_res.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index d75eb19..40deb11 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -55,8 +55,6 @@ static struct resource rb532_gpio_reg0_res[] = {
static struct resource rb532_dev3_ctl_res[] = {
{
.name = "dev3_ctl",
- .start = REGBASE + DEV3BASE,
- .end = REGBASE + DEV3BASE + sizeof(struct dev_reg) - 1,
.flags = IORESOURCE_MEM,
}
};
@@ -243,6 +241,9 @@ int __init rb532_gpio_init(void)
/* Register our GPIO chip */
gpiochip_add(&rb532_gpio_chip->chip);
+ rb532_dev3_ctl_res[0].start = readl(IDT434_REG_BASE + DEV3BASE);
+ rb532_dev3_ctl_res[0].end = rb532_dev3_ctl_res[0].start + 0x1000;
+
r = rb532_dev3_ctl_res;
dev3.base = ioremap_nocache(r->start, r->end - r->start);
--
1.5.6.4

@ -0,0 +1,23 @@
The data to be written is just a byte, so use writeb instead of writel.
Also, dev3.base contains the address, not the data so referencing here
is wrong.
Signed-off-by: Phil Sutter <n0-1@freewrt.org>
---
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c
index 40deb11..7e0cb4f 100644
--- a/arch/mips/rb532/gpio.c
+++ b/arch/mips/rb532/gpio.c
@@ -93,7 +93,7 @@ void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
spin_lock_irqsave(&dev3.lock, flags);
dev3.state = (dev3.state | or_mask) & ~nand_mask;
- writel(dev3.state, &dev3.base);
+ writeb(dev3.state, dev3.base);
spin_unlock_irqrestore(&dev3.lock, flags);
}
--
1.5.6.4

@ -0,0 +1,48 @@
--- a/arch/mips/rb532/devices.c 2009-01-25 13:36:15.000000000 +0100
+++ b/arch/mips/rb532/devices.c 2009-01-25 14:00:56.000000000 +0100
@@ -119,6 +119,19 @@
};
/* Resources and device for NAND */
+
+/*
+ * We need to use the OLD Yaffs-1 OOB layout, otherwise the RB bootloader
+ * will not be able to find the kernel that we load. So set the oobinfo
+ * when creating the partitions
+ */
+static struct nand_ecclayout rb532_nand_ecclayout = {
+ .eccbytes = 6,
+ .eccpos = { 8, 9, 10, 13, 14, 15 },
+ .oobavail = 9,
+ .oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
+};
+
static int rb532_dev_ready(struct mtd_info *mtd)
{
return gpio_get_value(GPIO_RDY);
@@ -277,6 +290,16 @@
/* NAND definitions */
#define NAND_CHIP_DELAY 25
+static int rb532_nand_fixup(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if (mtd->writesize == 512)
+ chip->ecc.layout = &rb532_nand_ecclayout;
+
+ return 0;
+}
+
static void __init rb532_nand_setup(void)
{
switch (mips_machtype) {
@@ -296,6 +319,8 @@
rb532_nand_data.chip.partitions = rb532_partition_info;
rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
rb532_nand_data.chip.options = NAND_NO_AUTOINCR;
+
+ rb532_nand_data.chip.chip_fixup = &rb532_nand_fixup;
}
Loading…
Cancel
Save