[leon] move patches to patches-2.6.36
authorflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 16 Nov 2012 16:32:55 +0000 (16:32 +0000)
committerflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Fri, 16 Nov 2012 16:32:55 +0000 (16:32 +0000)
Signed-off-by: Florian Fainelli <florian@openwrt.org>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34220 3c298f89-4303-0410-b956-a3cf2f4a3e73

54 files changed:
target/linux/leon/patches-2.6.36/001-find_irq_and_timer_via_of.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/002-sparc_uimage_target.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/003-smp_cpu_stuck_fix.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/004-extended_irq_controller.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/005-avoid_openprom_duplicates.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/006-amp_support.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/007-amp_timer.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/008-hz_specific_timer_init.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/009-remove_second_timer.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/010-apbuart_ampopts.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/011-greth_fix_unhandled_irq.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/012-greth_amba_vendor_device.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/013-apbuart_amba_vendor_device.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/014-timer_irqctrl_amba_vendor_device.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/015-dma_ops.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/016-ioport_update.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/017-greth_no_gbit.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/018-greth_compat_mode.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/019-greth_fix_open_close.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/020-greth_optimize_gbit_tx_descriptor_handling.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/021-greth_fix_memory_leak.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/022-greth_avoid_bad_speed_duplex.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/023-greth_handle_frame_error_interrupts.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/024-greth_resolve_smp_and_other_issues.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/025-greth_bootloader_disable_device_node.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/026-greth_gbit_mac_set_ee_when_edcl.patch [new file with mode: 0644]
target/linux/leon/patches-2.6.36/027-sparc_v8_assembler.patch [new file with mode: 0644]
target/linux/leon/patches/001-find_irq_and_timer_via_of.patch [deleted file]
target/linux/leon/patches/002-sparc_uimage_target.patch [deleted file]
target/linux/leon/patches/003-smp_cpu_stuck_fix.patch [deleted file]
target/linux/leon/patches/004-extended_irq_controller.patch [deleted file]
target/linux/leon/patches/005-avoid_openprom_duplicates.patch [deleted file]
target/linux/leon/patches/006-amp_support.patch [deleted file]
target/linux/leon/patches/007-amp_timer.patch [deleted file]
target/linux/leon/patches/008-hz_specific_timer_init.patch [deleted file]
target/linux/leon/patches/009-remove_second_timer.patch [deleted file]
target/linux/leon/patches/010-apbuart_ampopts.patch [deleted file]
target/linux/leon/patches/011-greth_fix_unhandled_irq.patch [deleted file]
target/linux/leon/patches/012-greth_amba_vendor_device.patch [deleted file]
target/linux/leon/patches/013-apbuart_amba_vendor_device.patch [deleted file]
target/linux/leon/patches/014-timer_irqctrl_amba_vendor_device.patch [deleted file]
target/linux/leon/patches/015-dma_ops.patch [deleted file]
target/linux/leon/patches/016-ioport_update.patch [deleted file]
target/linux/leon/patches/017-greth_no_gbit.patch [deleted file]
target/linux/leon/patches/018-greth_compat_mode.patch [deleted file]
target/linux/leon/patches/019-greth_fix_open_close.patch [deleted file]
target/linux/leon/patches/020-greth_optimize_gbit_tx_descriptor_handling.patch [deleted file]
target/linux/leon/patches/021-greth_fix_memory_leak.patch [deleted file]
target/linux/leon/patches/022-greth_avoid_bad_speed_duplex.patch [deleted file]
target/linux/leon/patches/023-greth_handle_frame_error_interrupts.patch [deleted file]
target/linux/leon/patches/024-greth_resolve_smp_and_other_issues.patch [deleted file]
target/linux/leon/patches/025-greth_bootloader_disable_device_node.patch [deleted file]
target/linux/leon/patches/026-greth_gbit_mac_set_ee_when_edcl.patch [deleted file]
target/linux/leon/patches/027-sparc_v8_assembler.patch [deleted file]

diff --git a/target/linux/leon/patches-2.6.36/001-find_irq_and_timer_via_of.patch b/target/linux/leon/patches-2.6.36/001-find_irq_and_timer_via_of.patch
new file mode 100644 (file)
index 0000000..18d7f8b
--- /dev/null
@@ -0,0 +1,48 @@
+From af1da1d5a8701f39cdbae4a0ab8e04b450eef298 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 8 Sep 2010 18:05:38 +0200
+Subject: [PATCH] SPARC/LEON: find IRQ and Timer via OF-Tree, instead of hardcoded.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/leon_kernel.c |   23 ++++++++++++++++++++++-
+ 1 files changed, 22 insertions(+), 1 deletions(-)
+
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -105,13 +105,34 @@ static void leon_disable_irq(unsigned in
+ void __init leon_init_timers(irq_handler_t counter_fn)
+ {
+       int irq;
++      struct device_node *rootnp, *np;
++      struct property *pp;
++      int len;
+       leondebug_irq_disable = 0;
+       leon_debug_irqout = 0;
+       master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
+       dummy_master_l10_counter = 0;
+-      if (leon3_gptimer_regs && leon3_irqctrl_regs) {
++      /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
++      rootnp = of_find_node_by_path("/ambapp0");
++      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_IRQMP"))) {
++              pp = of_find_property(np, "reg", &len);
++              if (pp)
++                      leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
++      }
++
++      /* Find GPTIMER Timer Registers base address otherwise bail out. */
++      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_GPTIMER"))) {
++              pp = of_find_property(np, "reg", &len);
++              if (pp)
++                      leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value;
++              pp = of_find_property(np, "interrupts", &len);
++              if (pp)
++                      leon3_gptimer_irq = *(unsigned int *)pp->value;
++      }
++
++      if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
+                                     (((1000000 / HZ) - 1)));
diff --git a/target/linux/leon/patches-2.6.36/002-sparc_uimage_target.patch b/target/linux/leon/patches-2.6.36/002-sparc_uimage_target.patch
new file mode 100644 (file)
index 0000000..6e25ff2
--- /dev/null
@@ -0,0 +1,79 @@
+From 234ef25344b567b3b8dad62c0863ebe16377528f Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Tue, 14 Sep 2010 11:26:55 +0200
+Subject: [PATCH] SPARC: added U-Boot build target: uImage
+
+---
+ arch/sparc/Makefile      |    3 ++-
+ arch/sparc/boot/Makefile |   35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 37 insertions(+), 1 deletions(-)
+
+--- a/arch/sparc/Makefile
++++ b/arch/sparc/Makefile
+@@ -88,7 +88,7 @@ boot := arch/sparc/boot
+ # Default target
+ all: zImage
+-image zImage tftpboot.img vmlinux.aout: vmlinux
++image zImage uImage tftpboot.img vmlinux.aout: vmlinux
+       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+ archclean:
+@@ -102,6 +102,7 @@ ifeq ($(ARCH),sparc)
+ define archhelp
+   echo  '* image        - kernel image ($(boot)/image)'
+   echo  '* zImage       - stripped kernel image ($(boot)/zImage)'
++  echo  '  uImage       - U-Boot SPARC32/LEON Image'
+   echo  '  tftpboot.img - image prepared for tftp'
+ endef
+ else
+--- a/arch/sparc/boot/Makefile
++++ b/arch/sparc/boot/Makefile
+@@ -5,6 +5,7 @@
+ ROOT_IMG      := /usr/src/root.img
+ ELFTOAOUT     := elftoaout
++MKIMAGE       := $(srctree)/scripts/mkuboot.sh
+ hostprogs-y   := piggyback_32 piggyback_64 btfixupprep
+ targets               := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
+@@ -90,5 +91,39 @@ $(obj)/tftpboot.img: $(obj)/image $(obj)
+ $(obj)/vmlinux.aout: vmlinux FORCE
+       $(call if_changed,elftoaout)
+       @echo '  kernel: $@ is ready'
++else
++
++# The following lines make a readable image for U-Boot.
++#  uImage   - Binary file read by U-boot
++#  uImage.o - object file of uImage for loading with a
++#             flash programmer understanding ELF.
++
++OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment
++$(obj)/image.bin: $(obj)/image FORCE
++      $(call if_changed,objcopy)
++
++$(obj)/image.gz: $(obj)/image.bin
++      $(call if_changed,gzip)
++
++# Start of Main memory
++ifndef UIMAGE_LOADADDR
++UIMAGE_LOADADDR=0x40004000
+ endif
++# The first sector after the U-Boot image (256k)
++ifndef UIMAGE_FLASHADDR
++UIMAGE_FLASHADDR=0x00040000
++endif
++
++quiet_cmd_uimage = UIMAGE  $@
++      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sparc -O linux -T kernel \
++               -C gzip -a $(UIMAGE_LOADADDR) -e 0xf0004000 -n 'Linux-$(KERNELRELEASE)' \
++               -d $< $@
++
++targets += uImage
++$(obj)/uImage: $(obj)/image.gz
++      $(call if_changed,uimage)
++      $(LD) -Tdata $(UIMAGE_FLASHADDR) -r -b binary arch/sparc/boot/uImage -o arch/sparc/boot/uImage.o
++      @echo '  Image $@ is ready'
++
++endif
diff --git a/target/linux/leon/patches-2.6.36/003-smp_cpu_stuck_fix.patch b/target/linux/leon/patches-2.6.36/003-smp_cpu_stuck_fix.patch
new file mode 100644 (file)
index 0000000..3d572f5
--- /dev/null
@@ -0,0 +1,23 @@
+From 417bc6751fdd3c24df274f25e020ec3decd09280 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Thu, 16 Sep 2010 11:00:46 +0200
+Subject: [PATCH] Fixed SPARC/LEON SMP CPU Stuck problem.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/leon_smp.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/kernel/leon_smp.c
++++ b/arch/sparc/kernel/leon_smp.c
+@@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(voi
+ static inline unsigned long do_swap(volatile unsigned long *ptr,
+                                   unsigned long val)
+ {
+-      __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
+-                           : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
++      __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val)
++                           : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
+                            : "memory");
+       return val;
+ }
diff --git a/target/linux/leon/patches-2.6.36/004-extended_irq_controller.patch b/target/linux/leon/patches-2.6.36/004-extended_irq_controller.patch
new file mode 100644 (file)
index 0000000..b660b64
--- /dev/null
@@ -0,0 +1,119 @@
+From a729672f117df3602b6d3171d8ab7a84bf53b053 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Thu, 16 Sep 2010 11:12:41 +0200
+Subject: [PATCH] SPARC/LEON: added support for Extended IRQ controller, partial patches are already in git tree.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/include/asm/irq_32.h |    4 ++++
+ arch/sparc/kernel/irq_32.c      |   32 ++++++++++++++++++++++++++------
+ arch/sparc/kernel/leon_kernel.c |    8 +++++++-
+ 3 files changed, 37 insertions(+), 7 deletions(-)
+
+--- a/arch/sparc/include/asm/irq_32.h
++++ b/arch/sparc/include/asm/irq_32.h
+@@ -6,7 +6,11 @@
+ #ifndef _SPARC_IRQ_H
+ #define _SPARC_IRQ_H
++#ifdef CONFIG_SPARC_LEON
++#define NR_IRQS    32
++#else
+ #define NR_IRQS    16
++#endif
+ #include <linux/interrupt.h>
+--- a/arch/sparc/kernel/irq_32.c
++++ b/arch/sparc/kernel/irq_32.c
+@@ -110,6 +110,11 @@ EXPORT_SYMBOL(__raw_local_irq_save);
+ EXPORT_SYMBOL(raw_local_irq_enable);
+ EXPORT_SYMBOL(raw_local_irq_restore);
++#ifdef CONFIG_SPARC_LEON
++extern unsigned int sparc_leon_eirq;
++extern int sparc_leon_eirq_get(int eirq, int cpu);
++#endif
++
+ /*
+  * Dave Redman (djhr@tadpole.co.uk)
+  *
+@@ -222,10 +227,11 @@ void free_irq(unsigned int irq, void *de
+               return;
+       }
+       cpu_irq = irq & (NR_IRQS - 1);
+-        if (cpu_irq > 14) {  /* 14 irq levels on the sparc */
+-                printk("Trying to free bogus IRQ %d\n", irq);
+-                return;
+-        }
++      /* 14 irq levels on the sparc, however some LEON systems have 31 IRQs */
++      if ((cpu_irq == 15) || (cpu_irq >= NR_IRQS)) {  
++              printk("Trying to free bogus IRQ %d\n", irq);
++              return;
++      }
+       spin_lock_irqsave(&irq_action_lock, flags);
+@@ -303,7 +309,14 @@ void unexpected_irq(int irq, void *dev_i
+         int i;
+       struct irqaction * action;
+       unsigned int cpu_irq;
+-      
++
++#ifdef CONFIG_SPARC_LEON
++      /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
++      if ( sparc_leon_eirq == irq ) {
++              irq = sparc_leon_eirq_get(irq, smp_processor_id());
++      }
++#endif
++
+       cpu_irq = irq & (NR_IRQS - 1);
+       action = sparc_irq[cpu_irq].action;
+@@ -330,6 +343,13 @@ void handler_irq(int irq, struct pt_regs
+       extern void smp4m_irq_rotate(int cpu);
+ #endif
++#ifdef CONFIG_SPARC_LEON
++      /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
++      if ( sparc_leon_eirq == irq ) {
++              irq = sparc_leon_eirq_get(irq, cpu);
++      }
++#endif
++
+       old_regs = set_irq_regs(regs);
+       irq_enter();
+       disable_pil_irq(irq);
+@@ -526,7 +546,7 @@ int request_irq(unsigned int irq,
+               return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
+       }
+       cpu_irq = irq & (NR_IRQS - 1);
+-      if(cpu_irq > 14) {
++      if(cpu_irq == 15) {
+               ret = -EINVAL;
+               goto out;
+       }
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -104,7 +104,7 @@ static void leon_disable_irq(unsigned in
+ void __init leon_init_timers(irq_handler_t counter_fn)
+ {
+-      int irq;
++      int irq, eirq;
+       struct device_node *rootnp, *np;
+       struct property *pp;
+       int len;
+@@ -153,6 +153,12 @@ void __init leon_init_timers(irq_handler
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
+ # endif
++              LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
++              eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf;
++              if ( eirq != 0 ) {
++                      /* Extended IRQ controller available */
++                      sparc_leon_eirq_register(eirq);
++              }
+       } else {
+               printk(KERN_ERR "No Timer/irqctrl found\n");
+               BUG();
diff --git a/target/linux/leon/patches-2.6.36/005-avoid_openprom_duplicates.patch b/target/linux/leon/patches-2.6.36/005-avoid_openprom_duplicates.patch
new file mode 100644 (file)
index 0000000..54bfd27
--- /dev/null
@@ -0,0 +1,58 @@
+From 486a578298b7ab45c3edfdce8d4feaef93c3229b Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Thu, 16 Sep 2010 11:15:37 +0200
+Subject: [PATCH] SPARC/LEON: to avoid name duplicates in openprom fs when REG is not available the NAME now includes NODE ID when REG not present
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/prom_32.c |   27 +++++++++++++++++++--------
+ 1 files changed, 19 insertions(+), 8 deletions(-)
+
+--- a/arch/sparc/kernel/prom_32.c
++++ b/arch/sparc/kernel/prom_32.c
+@@ -136,18 +136,29 @@ static void __init ebus_path_component(s
+ /* "name:vendor:device@irq,addrlo" */
+ static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
+ {
+-      struct amba_prom_registers *regs; unsigned int *intr;
+-      unsigned int *device, *vendor;
++      struct amba_prom_registers *regs;
++      unsigned int *intr, *device, *vendor, reg0;
+       struct property *prop;
++      int interrupt = 0;
++      /* In order to get a unique ID in the device tree (multiple AMBA devices 
++       * may have the same name) the node number is printed
++       */
+       prop = of_find_property(dp, "reg", NULL);
+-      if (!prop)
+-              return;
+-      regs = prop->value;
++      if (!prop) {
++              reg0 = (unsigned int)dp->phandle;
++      } else {
++              regs = prop->value;
++              reg0 = regs->phys_addr;
++      }
++
++      /* Not all cores have Interrupt */
+       prop = of_find_property(dp, "interrupts", NULL);
+       if (!prop)
+-              return;
+-      intr = prop->value;
++              intr = &interrupt; /* IRQ0 does not exist */
++      else
++              intr = prop->value;
++
+       prop = of_find_property(dp, "vendor", NULL);
+       if (!prop)
+               return;
+@@ -159,7 +170,7 @@ static void __init ambapp_path_component
+       sprintf(tmp_buf, "%s:%d:%d@%x,%x",
+               dp->name, *vendor, *device,
+-              *intr, regs->phys_addr);
++              *intr, reg0);
+ }
+ static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
diff --git a/target/linux/leon/patches-2.6.36/006-amp_support.patch b/target/linux/leon/patches-2.6.36/006-amp_support.patch
new file mode 100644 (file)
index 0000000..98d1c9f
--- /dev/null
@@ -0,0 +1,85 @@
+From 25a68b8cd8ea1553f8b56278418d6c1ecc12e247 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 22 Sep 2010 10:19:34 +0200
+Subject: [PATCH] SPARC/LEON: added support for AMP systems with IRQAMP IRQ Controller.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/include/asm/leon.h      |   12 ++++++++++++
+ arch/sparc/include/asm/leon_amba.h |    6 +++---
+ arch/sparc/kernel/leon_kernel.c    |   14 ++++++++++++++
+ 3 files changed, 29 insertions(+), 3 deletions(-)
+
+--- a/arch/sparc/include/asm/leon.h
++++ b/arch/sparc/include/asm/leon.h
+@@ -224,6 +224,18 @@ static inline void sparc_leon3_disable_c
+                         "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
+ };
++static inline unsigned long sparc_leon3_asr17(void)
++{
++      u32 asr17;
++      __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17));
++      return asr17;
++};
++
++static inline int sparc_leon3_cpuid(void)
++{
++      return sparc_leon3_asr17() >> 28;
++}
++
+ #endif /*!__ASSEMBLY__*/
+ #ifdef CONFIG_SMP
+--- a/arch/sparc/include/asm/leon_amba.h
++++ b/arch/sparc/include/asm/leon_amba.h
+@@ -100,9 +100,8 @@ struct leon3_irqctrl_regs_map {
+       u32 mpbroadcast;
+       u32 notused02;
+       u32 notused03;
+-      u32 notused10;
+-      u32 notused11;
+-      u32 notused12;
++      u32 ampctrl;
++      u32 icsel[2];
+       u32 notused13;
+       u32 notused20;
+       u32 notused21;
+@@ -112,6 +111,7 @@ struct leon3_irqctrl_regs_map {
+       u32 force[16];
+       /* Extended IRQ registers */
+       u32 intid[16];  /* 0xc0 */
++      u32 unused[(0x1000-0x100)/4];
+ };
+ struct leon3_apbuart_regs_map {
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -108,6 +108,7 @@ void __init leon_init_timers(irq_handler
+       struct device_node *rootnp, *np;
+       struct property *pp;
+       int len;
++      int cpu, icsel;
+       leondebug_irq_disable = 0;
+       leon_debug_irqout = 0;
+@@ -153,6 +154,19 @@ void __init leon_init_timers(irq_handler
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
+ # endif
++              /* The IRQ controller may (if implemented) consist of multiple
++               * IRQ controllers, each mapped on a 4Kb boundary.
++               * Each CPU may be routed to different IRQCTRLs, however
++               * we assume that all CPUs (in SMP system) is routed to the
++               * same IRQ Controller, and for non-SMP only one IRQCTRL is
++               * accessed anyway.
++               * In AMP systems, Linux may not be run on CPU0.
++               */
++              cpu = sparc_leon3_cpuid();
++              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
++              icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
++              leon3_irqctrl_regs += icsel;
++
+               LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
+               eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf;
+               if ( eirq != 0 ) {
diff --git a/target/linux/leon/patches-2.6.36/007-amp_timer.patch b/target/linux/leon/patches-2.6.36/007-amp_timer.patch
new file mode 100644 (file)
index 0000000..d8d4363
--- /dev/null
@@ -0,0 +1,120 @@
+From 1dffe06838c26b7c3fc99f9ddb7db78e378f6908 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 22 Sep 2010 13:21:13 +0200
+Subject: [PATCH] SPARC/LEON: added support for selecting Timer Core and Timer within core, useful for AMP systems.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/leon_kernel.c |   41 +++++++++++++++++++++++++-------------
+ 1 files changed, 27 insertions(+), 14 deletions(-)
+
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -23,15 +23,16 @@
+ #include "prom.h"
+ #include "irq.h"
+-struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */
+-struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */
++struct leon3_irqctrl_regs_map *leon3_irqctrl_regs = NULL; /* interrupt controller base address, initialized by amba_init() */
++struct leon3_gptimer_regs_map *leon3_gptimer_regs = NULL; /* timer controller base address, initialized by amba_init() */
+ struct amba_apb_device leon_percpu_timer_dev[16];
+ int leondebug_irq_disable;
+ int leon_debug_irqout;
+ static int dummy_master_l10_counter;
+-unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */
++unsigned long leon3_gptimer_irq = 0; /* interrupt controller irq number, initialized by amba_init() */
++unsigned long leon3_gptimer_idx = 0; /* Timer Index (starting at 0) with Timer Core */
+ unsigned int sparc_leon_eirq;
+ #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
+@@ -109,6 +110,7 @@ void __init leon_init_timers(irq_handler
+       struct property *pp;
+       int len;
+       int cpu, icsel;
++      int ampopts;
+       leondebug_irq_disable = 0;
+       leon_debug_irqout = 0;
+@@ -124,24 +126,35 @@ void __init leon_init_timers(irq_handler
+       }
+       /* Find GPTIMER Timer Registers base address otherwise bail out. */
+-      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_GPTIMER"))) {
++      np = rootnp;
++      while (np && (np=of_find_node_by_name(np, "GAISLER_GPTIMER"))) {
++              ampopts = 0;
++              pp = of_find_property(np, "ampopts", &len);
++              if ( pp && ((ampopts = *(int *)pp->value) == 0) ) {
++                      /* Skip this instance, resource already allocated by other OS */
++                      continue;
++              }
++              /* Select Timer-Instance on Timer Core. Default is zero */
++              leon3_gptimer_idx = ampopts & 0x7;
++
+               pp = of_find_property(np, "reg", &len);
+               if (pp)
+                       leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value;
+               pp = of_find_property(np, "interrupts", &len);
+               if (pp)
+                       leon3_gptimer_irq = *(unsigned int *)pp->value;
++              break;
+       }
+       if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
+-                                    (((1000000 / HZ) - 1)));
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
++                                    (((1000000 / 100) - 1)));
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
+ #ifdef CONFIG_SMP
+               leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
+-              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1;
++              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1+leon3_gptimer_idx;
+               if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
+                     (1<<LEON3_GPTIMER_SEPIRQ))) {
+@@ -149,9 +162,9 @@ void __init leon_init_timers(irq_handler
+                       BUG();
+               }
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000/100) - 1)));
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
+ # endif
+               /* The IRQ controller may (if implemented) consist of multiple
+@@ -178,7 +191,7 @@ void __init leon_init_timers(irq_handler
+               BUG();
+       }
+-      irq = request_irq(leon3_gptimer_irq,
++      irq = request_irq(leon3_gptimer_irq+leon3_gptimer_idx,
+                         counter_fn,
+                         (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
+@@ -210,13 +223,13 @@ void __init leon_init_timers(irq_handler
+ # endif
+       if (leon3_gptimer_regs) {
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
+                                     LEON3_GPTIMER_EN |
+                                     LEON3_GPTIMER_RL |
+                                     LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+ #ifdef CONFIG_SMP
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl,
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
+                                     LEON3_GPTIMER_EN |
+                                     LEON3_GPTIMER_RL |
+                                     LEON3_GPTIMER_LD |
diff --git a/target/linux/leon/patches-2.6.36/008-hz_specific_timer_init.patch b/target/linux/leon/patches-2.6.36/008-hz_specific_timer_init.patch
new file mode 100644 (file)
index 0000000..aae3d29
--- /dev/null
@@ -0,0 +1,30 @@
+From e4d697dad4d43109f045a4f25cb1d706122045c0 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 22 Sep 2010 13:24:36 +0200
+Subject: [PATCH] SPARC/LEON: removed constant timer initialization as if HZ=100, now it reflects the value of HZ
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/leon_kernel.c |    4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -149,7 +149,7 @@ void __init leon_init_timers(irq_handler
+       if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
+-                                    (((1000000 / 100) - 1)));
++                                    (((1000000 / HZ) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
+ #ifdef CONFIG_SMP
+@@ -163,7 +163,7 @@ void __init leon_init_timers(irq_handler
+               }
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000/100) - 1)));
++              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000 / HZ) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
+ # endif
diff --git a/target/linux/leon/patches-2.6.36/009-remove_second_timer.patch b/target/linux/leon/patches-2.6.36/009-remove_second_timer.patch
new file mode 100644 (file)
index 0000000..b0b1346
--- /dev/null
@@ -0,0 +1,187 @@
+From 300f3ee36c3019ee36f81befd91cd1b32544cefe Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 22 Sep 2010 15:39:05 +0200
+Subject: [PATCH] SPARC/LEON: Removed the need for two timers, per-cpu ticker is shared with system clock timer.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/include/asm/leon.h      |    2 +-
+ arch/sparc/include/asm/leon_amba.h |    3 +-
+ arch/sparc/kernel/entry.S          |    3 +-
+ arch/sparc/kernel/leon_kernel.c    |   37 ++++++++---------------------------
+ arch/sparc/kernel/leon_smp.c       |    8 ++++++-
+ 5 files changed, 21 insertions(+), 32 deletions(-)
+
+--- a/arch/sparc/include/asm/leon.h
++++ b/arch/sparc/include/asm/leon.h
+@@ -240,7 +240,7 @@ static inline int sparc_leon3_cpuid(void
+ #ifdef CONFIG_SMP
+ # define LEON3_IRQ_RESCHEDULE         13
+-# define LEON3_IRQ_TICKER             (leon_percpu_timer_dev[0].irq)
++# define LEON3_IRQ_TICKER             (leon3_gptimer_irq + leon3_gptimer_idx)
+ # define LEON3_IRQ_CROSS_CALL         15
+ #endif
+--- a/arch/sparc/include/asm/leon_amba.h
++++ b/arch/sparc/include/asm/leon_amba.h
+@@ -182,11 +182,12 @@ void _amba_init(struct device_node *dp,
+ extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs;
+ extern struct leon3_gptimer_regs_map *leon3_gptimer_regs;
+-extern struct amba_apb_device leon_percpu_timer_dev[16];
+ extern int leondebug_irq_disable;
+ extern int leon_debug_irqout;
+ extern unsigned long leon3_gptimer_irq;
++extern unsigned long leon3_gptimer_idx; /* Timer Index (starting at 0) with Timer Core */
+ extern unsigned int sparc_leon_eirq;
++extern unsigned long leon3_cpu_idx;
+ #endif /* __ASSEMBLY__ */
+--- a/arch/sparc/kernel/entry.S
++++ b/arch/sparc/kernel/entry.S
+@@ -411,8 +411,9 @@ smpleon_ticker:
+       WRITE_PAUSE
+       wr      %g2, PSR_ET, %psr
+       WRITE_PAUSE
++      mov     %l7, %o0                ! irq level
+       call    leon_percpu_timer_interrupt
+-       add    %sp, STACKFRAME_SZ, %o0
++       add    %sp, STACKFRAME_SZ, %o1 ! pt_regs
+       wr      %l0, PSR_ET, %psr
+       WRITE_PAUSE
+       RESTORE_ALL
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -25,7 +25,6 @@
+ struct leon3_irqctrl_regs_map *leon3_irqctrl_regs = NULL; /* interrupt controller base address, initialized by amba_init() */
+ struct leon3_gptimer_regs_map *leon3_gptimer_regs = NULL; /* timer controller base address, initialized by amba_init() */
+-struct amba_apb_device leon_percpu_timer_dev[16];
+ int leondebug_irq_disable;
+ int leon_debug_irqout;
+@@ -34,6 +33,7 @@ static int dummy_master_l10_counter;
+ unsigned long leon3_gptimer_irq = 0; /* interrupt controller irq number, initialized by amba_init() */
+ unsigned long leon3_gptimer_idx = 0; /* Timer Index (starting at 0) with Timer Core */
+ unsigned int sparc_leon_eirq;
++unsigned long leon3_cpu_idx = 0; /* Boot CPU Index */
+ #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
+ /* Return the IRQ of the pending IRQ on the extended IRQ controller */
+@@ -109,13 +109,14 @@ void __init leon_init_timers(irq_handler
+       struct device_node *rootnp, *np;
+       struct property *pp;
+       int len;
+-      int cpu, icsel;
++      int icsel;
+       int ampopts;
+       leondebug_irq_disable = 0;
+       leon_debug_irqout = 0;
+       master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
+       dummy_master_l10_counter = 0;
++      leon3_cpu_idx = sparc_leon3_cpuid();
+       /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
+       rootnp = of_find_node_by_path("/ambapp0");
+@@ -152,21 +153,11 @@ void __init leon_init_timers(irq_handler
+                                     (((1000000 / HZ) - 1)));
+               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
+-#ifdef CONFIG_SMP
+-              leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
+-              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1+leon3_gptimer_idx;
+-
+               if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
+                     (1<<LEON3_GPTIMER_SEPIRQ))) {
+-                      prom_printf("irq timer not configured with separate irqs\n");
+-                      BUG();
++                      prom_printf("LEON-SMP: GPTIMER use shared irqs, using other timers will fail.\n");
+               }
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000 / HZ) - 1)));
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
+-# endif
+-
+               /* The IRQ controller may (if implemented) consist of multiple
+                * IRQ controllers, each mapped on a 4Kb boundary.
+                * Each CPU may be routed to different IRQCTRLs, however
+@@ -175,9 +166,8 @@ void __init leon_init_timers(irq_handler
+                * accessed anyway.
+                * In AMP systems, Linux may not be run on CPU0.
+                */
+-              cpu = sparc_leon3_cpuid();
+-              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
+-              icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
++              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[leon3_cpu_idx/8]);
++              icsel = (icsel >> ((7 - (leon3_cpu_idx & 0x7)) * 4)) & 0xf;
+               leon3_irqctrl_regs += icsel;
+               LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
+@@ -204,7 +194,8 @@ void __init leon_init_timers(irq_handler
+ # ifdef CONFIG_SMP
+       {
+               unsigned long flags;
+-              struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)];
++              struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + 
++                                              (leon3_gptimer_irq + leon3_gptimer_idx - 1)];
+               /* For SMP we use the level 14 ticker, however the bootup code
+                * has copied the firmwares level 14 vector into boot cpu's
+@@ -222,21 +213,11 @@ void __init leon_init_timers(irq_handler
+       }
+ # endif
+-      if (leon3_gptimer_regs) {
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
++      LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
+                                     LEON3_GPTIMER_EN |
+                                     LEON3_GPTIMER_RL |
+                                     LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+-#ifdef CONFIG_SMP
+-              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
+-                                    LEON3_GPTIMER_EN |
+-                                    LEON3_GPTIMER_RL |
+-                                    LEON3_GPTIMER_LD |
+-                                    LEON3_GPTIMER_IRQEN);
+-#endif
+-
+-      }
+ }
+ void leon_clear_clock_irq(void)
+--- a/arch/sparc/kernel/leon_smp.c
++++ b/arch/sparc/kernel/leon_smp.c
+@@ -52,6 +52,7 @@ extern volatile unsigned long cpu_callin
+ extern unsigned char boot_cpu_id;
+ extern cpumask_t smp_commenced_mask;
+ void __init leon_configure_cache_smp(void);
++extern void handler_irq(int irq, struct pt_regs * regs);
+ static inline unsigned long do_swap(volatile unsigned long *ptr,
+                                   unsigned long val)
+@@ -385,7 +386,7 @@ void leon_cross_call_irq(void)
+       ccall_info.processors_out[i] = 1;
+ }
+-void leon_percpu_timer_interrupt(struct pt_regs *regs)
++void leon_percpu_timer_interrupt(int irq, struct pt_regs *regs)
+ {
+       struct pt_regs *old_regs;
+       int cpu = smp_processor_id();
+@@ -406,6 +407,11 @@ void leon_percpu_timer_interrupt(struct
+               prof_counter(cpu) = prof_multiplier(cpu);
+       }
+       set_irq_regs(old_regs);
++
++      if ( cpu == leon3_cpu_idx ) {
++              /* Ticker Clock is shared with the System Clock */
++              handler_irq(irq, regs);
++      }
+ }
+ static void __init smp_setup_percpu_timer(void)
diff --git a/target/linux/leon/patches-2.6.36/010-apbuart_ampopts.patch b/target/linux/leon/patches-2.6.36/010-apbuart_ampopts.patch
new file mode 100644 (file)
index 0000000..f47c54a
--- /dev/null
@@ -0,0 +1,41 @@
+From 8129fa5437f3fe5f95bac180a43cd5a856cebdf3 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 20 Oct 2010 17:00:41 +0200
+Subject: [PATCH] Added support for ampopts in APBUART driver. Used in AMP systems.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/serial/apbuart.c |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+--- a/drivers/serial/apbuart.c
++++ b/drivers/serial/apbuart.c
+@@ -26,6 +26,7 @@
+ #include <linux/of.h>
+ #include <linux/of_device.h>
+ #include <linux/of_platform.h>
++#include <linux/of_irq.h>
+ #include <linux/platform_device.h>
+ #include <linux/io.h>
+ #include <linux/serial_core.h>
+@@ -573,7 +574,6 @@ static int __devinit apbuart_probe(struc
+       printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
+              (unsigned long long) port->mapbase, port->irq);
+       return 0;
+-
+ }
+ static struct of_device_id __initdata apbuart_match[] = {
+@@ -620,9 +620,12 @@ static void grlib_apbuart_configure(void
+               int *vendor = (int *) of_get_property(np, "vendor", NULL);
+               int *device = (int *) of_get_property(np, "device", NULL);
+               int *irqs = (int *) of_get_property(np, "interrupts", NULL);
++              int *ampopts = (int *) of_get_property(np, "ampopts", NULL);
+               regs = (struct amba_prom_registers *)
+                   of_get_property(np, "reg", NULL);
++              if (ampopts && (*ampopts == 0))
++                      continue; /* Ignore if used by another OS instance */
+               if (vendor)
+                       v = *vendor;
+               if (device)
diff --git a/target/linux/leon/patches-2.6.36/011-greth_fix_unhandled_irq.patch b/target/linux/leon/patches-2.6.36/011-greth_fix_unhandled_irq.patch
new file mode 100644 (file)
index 0000000..55e6185
--- /dev/null
@@ -0,0 +1,21 @@
+From 3d7788e8f5ae3d44e48f9b7476528acf3d9c8b32 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 20 Oct 2010 17:07:12 +0200
+Subject: [PATCH] GRETH: Fixed potential future problem where unhandled IRQ is cleared.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -584,7 +584,7 @@ static irqreturn_t greth_interrupt(int i
+       if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
+               /* Clear interrupt status */
+-              GRETH_REGORIN(greth->regs->status,
++              GRETH_REGSAVE(greth->regs->status,
+                             status & (GRETH_INT_RX | GRETH_INT_TX));
+               retval = IRQ_HANDLED;
diff --git a/target/linux/leon/patches-2.6.36/012-greth_amba_vendor_device.patch b/target/linux/leon/patches-2.6.36/012-greth_amba_vendor_device.patch
new file mode 100644 (file)
index 0000000..78b526c
--- /dev/null
@@ -0,0 +1,22 @@
+From ff5f2ee8b37f2278dd86946761313c3664c51836 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Thu, 21 Oct 2010 14:34:48 +0200
+Subject: [PATCH] GRETH: added raw AMBA vendor/device number to match against.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -1600,6 +1600,9 @@ static struct of_device_id greth_of_matc
+       {
+        .name = "GAISLER_ETHMAC",
+        },
++      {
++       .name = "01_01d",
++       },
+       {},
+ };
diff --git a/target/linux/leon/patches-2.6.36/013-apbuart_amba_vendor_device.patch b/target/linux/leon/patches-2.6.36/013-apbuart_amba_vendor_device.patch
new file mode 100644 (file)
index 0000000..7675f10
--- /dev/null
@@ -0,0 +1,22 @@
+From 1c14b8995c1b8212180b5009dc04ac222a449ecb Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Thu, 21 Oct 2010 14:35:09 +0200
+Subject: [PATCH] APBUART: added raw AMBA vendor/device number to match against.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/serial/apbuart.c |    3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+--- a/drivers/serial/apbuart.c
++++ b/drivers/serial/apbuart.c
+@@ -580,6 +580,9 @@ static struct of_device_id __initdata ap
+       {
+        .name = "GAISLER_APBUART",
+        },
++      {
++       .name = "01_00c",
++       },
+       {},
+ };
diff --git a/target/linux/leon/patches-2.6.36/014-timer_irqctrl_amba_vendor_device.patch b/target/linux/leon/patches-2.6.36/014-timer_irqctrl_amba_vendor_device.patch
new file mode 100644 (file)
index 0000000..58f7657
--- /dev/null
@@ -0,0 +1,32 @@
+From 12782c44d0c687b5b0400a8224a9b1bf9eb9a428 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Tue, 26 Oct 2010 09:59:05 +0200
+Subject: [PATCH] TIMER,IRQCTRL: added raw AMBA vendor/device number to match against.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/kernel/leon_kernel.c |    6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/kernel/leon_kernel.c
++++ b/arch/sparc/kernel/leon_kernel.c
+@@ -120,7 +120,8 @@ void __init leon_init_timers(irq_handler
+       /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
+       rootnp = of_find_node_by_path("/ambapp0");
+-      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_IRQMP"))) {
++      if (rootnp && ((np=of_find_node_by_name(rootnp, "GAISLER_IRQMP")) ||
++                      (np=of_find_node_by_name(rootnp, "01_00d")))) {
+               pp = of_find_property(np, "reg", &len);
+               if (pp)
+                       leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
+@@ -128,7 +129,8 @@ void __init leon_init_timers(irq_handler
+       /* Find GPTIMER Timer Registers base address otherwise bail out. */
+       np = rootnp;
+-      while (np && (np=of_find_node_by_name(np, "GAISLER_GPTIMER"))) {
++      while (np && ((np=of_find_node_by_name(np, "GAISLER_GPTIMER")) ||
++                      (np=of_find_node_by_name(np, "01_011")))) {
+               ampopts = 0;
+               pp = of_find_property(np, "ampopts", &len);
+               if ( pp && ((ampopts = *(int *)pp->value) == 0) ) {
diff --git a/target/linux/leon/patches-2.6.36/015-dma_ops.patch b/target/linux/leon/patches-2.6.36/015-dma_ops.patch
new file mode 100644 (file)
index 0000000..7f488e0
--- /dev/null
@@ -0,0 +1,296 @@
+From c6d8f92cfd7f4f19eb3b16545b3b68c561978fe8 Mon Sep 17 00:00:00 2001
+From: Kristoffer Glembo <kristoffer@gaisler.com>
+Date: Mon, 7 Jun 2010 14:00:30 +0200
+Subject: [PATCH] sparc32: Added LEON dma_ops.
+
+Added leon3_dma_ops and mmu_inval_dma_area.
+---
+ arch/sparc/kernel/ioport.c |  139 +++++++++++++++++++++++++++++++------------
+ 1 files changed, 100 insertions(+), 39 deletions(-)
+
+--- a/arch/sparc/kernel/ioport.c
++++ b/arch/sparc/kernel/ioport.c
+@@ -50,10 +50,15 @@
+ #include <asm/io-unit.h>
+ #include <asm/leon.h>
+-#ifdef CONFIG_SPARC_LEON
+-#define mmu_inval_dma_area(p, l) leon_flush_dcache_all()
+-#else
++#ifndef CONFIG_SPARC_LEON
+ #define mmu_inval_dma_area(p, l)      /* Anton pulled it out for 2.4.0-xx */
++#else
++static inline void mmu_inval_dma_area(unsigned long va, unsigned long len)
++{
++      if (!sparc_leon3_snooping_enabled()) {
++              leon_flush_dcache_all();
++      }
++}
+ #endif
+ static struct resource *_sparc_find_resource(struct resource *r,
+@@ -254,7 +259,7 @@ static void *sbus_alloc_coherent(struct
+                                dma_addr_t *dma_addrp, gfp_t gfp)
+ {
+       struct platform_device *op = to_platform_device(dev);
+-      unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
++      unsigned long len_total = PAGE_ALIGN(len);
+       unsigned long va;
+       struct resource *res;
+       int order;
+@@ -287,15 +292,19 @@ static void *sbus_alloc_coherent(struct
+        * XXX That's where sdev would be used. Currently we load
+        * all iommu tables with the same translations.
+        */
+-      if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
+-              goto err_noiommu;
+-
+-      res->name = op->dev.of_node->name;
++#ifdef CONFIG_SPARC_LEON
++      sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);   
++      *dma_addrp = virt_to_phys(va);
++#else
++      if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) {
++              release_resource(res);
++              goto err_nova;
++      }
++#endif
++      res->name = op->node->name;
+       return (void *)(unsigned long)res->start;
+-err_noiommu:
+-      release_resource(res);
+ err_nova:
+       free_pages(va, order);
+ err_nomem:
+@@ -321,7 +330,7 @@ static void sbus_free_coherent(struct de
+               return;
+       }
+-      n = (n + PAGE_SIZE-1) & PAGE_MASK;
++      n = PAGE_ALIGN(n);
+       if ((res->end-res->start)+1 != n) {
+               printk("sbus_free_consistent: region 0x%lx asked 0x%zx\n",
+                   (long)((res->end-res->start)+1), n);
+@@ -333,7 +342,12 @@ static void sbus_free_coherent(struct de
+       /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
+       pgv = virt_to_page(p);
+-      mmu_unmap_dma_area(dev, ba, n);
++
++#ifdef CONFIG_SPARC_LEON
++      sparc_unmapiorange((unsigned long)p, n);
++#else
++      mmu_unmap_dma_area(dev, ba, n);
++#endif
+       __free_pages(pgv, get_order(n));
+ }
+@@ -408,9 +422,6 @@ struct dma_map_ops sbus_dma_ops = {
+       .sync_sg_for_device     = sbus_sync_sg_for_device,
+ };
+-struct dma_map_ops *dma_ops = &sbus_dma_ops;
+-EXPORT_SYMBOL(dma_ops);
+-
+ static int __init sparc_register_ioport(void)
+ {
+       register_proc_sparc_ioport();
+@@ -422,7 +433,7 @@ arch_initcall(sparc_register_ioport);
+ #endif /* CONFIG_SBUS */
+-#ifdef CONFIG_PCI
++#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON)
+ /* Allocate and map kernel buffer using consistent mode DMA for a device.
+  * hwdev should be valid struct pci_dev pointer for PCI devices.
+@@ -430,7 +441,7 @@ arch_initcall(sparc_register_ioport);
+ static void *pci32_alloc_coherent(struct device *dev, size_t len,
+                                 dma_addr_t *pba, gfp_t gfp)
+ {
+-      unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
++      unsigned long len_total = PAGE_ALIGN(len);
+       unsigned long va;
+       struct resource *res;
+       int order;
+@@ -463,10 +474,6 @@ static void *pci32_alloc_coherent(struct
+               return NULL;
+       }
+       mmu_inval_dma_area(va, len_total);
+-#if 0
+-/* P3 */ printk("pci_alloc_consistent: kva %lx uncva %lx phys %lx size %lx\n",
+-  (long)va, (long)res->start, (long)virt_to_phys(va), len_total);
+-#endif
+       sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
+       *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
+@@ -498,7 +505,7 @@ static void pci32_free_coherent(struct d
+               return;
+       }
+-      n = (n + PAGE_SIZE-1) & PAGE_MASK;
++      n = PAGE_ALIGN(n);
+       if ((res->end-res->start)+1 != n) {
+               printk("pci_free_consistent: region 0x%lx asked 0x%lx\n",
+                   (long)((res->end-res->start)+1), (long)n);
+@@ -515,6 +522,14 @@ static void pci32_free_coherent(struct d
+       free_pages(pgp, get_order(n));
+ }
++static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
++                           enum dma_data_direction dir, struct dma_attrs *attrs)
++{
++      if (dir != PCI_DMA_TODEVICE) {
++              mmu_inval_dma_area((unsigned long)phys_to_virt(ba), PAGE_ALIGN(size));
++      }
++}
++
+ /*
+  * Same as pci_map_single, but with pages.
+  */
+@@ -551,8 +566,7 @@ static int pci32_map_sg(struct device *d
+       /* IIep is write-through, not flushing. */
+       for_each_sg(sgl, sg, nents, n) {
+-              BUG_ON(page_address(sg_page(sg)) == NULL);
+-              sg->dma_address = virt_to_phys(sg_virt(sg));
++              sg->dma_address = sg_phys(sg);
+               sg->dma_length = sg->length;
+       }
+       return nents;
+@@ -571,10 +585,7 @@ static void pci32_unmap_sg(struct device
+       if (dir != PCI_DMA_TODEVICE) {
+               for_each_sg(sgl, sg, nents, n) {
+-                      BUG_ON(page_address(sg_page(sg)) == NULL);
+-                      mmu_inval_dma_area(
+-                          (unsigned long) page_address(sg_page(sg)),
+-                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
++                      mmu_inval_dma_area((unsigned long)sg_virt(sg), PAGE_ALIGN(sg->length));
+               }
+       }
+ }
+@@ -594,7 +605,7 @@ static void pci32_sync_single_for_cpu(st
+ {
+       if (dir != PCI_DMA_TODEVICE) {
+               mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
+-                  (size + PAGE_SIZE-1) & PAGE_MASK);
++                                 PAGE_ALIGN(size));
+       }
+ }
+@@ -621,10 +632,7 @@ static void pci32_sync_sg_for_cpu(struct
+       if (dir != PCI_DMA_TODEVICE) {
+               for_each_sg(sgl, sg, nents, n) {
+-                      BUG_ON(page_address(sg_page(sg)) == NULL);
+-                      mmu_inval_dma_area(
+-                          (unsigned long) page_address(sg_page(sg)),
+-                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
++                      mmu_inval_dma_area((unsigned long)sg_virt(sg), PAGE_ALIGN(sg->length));
+               }
+       }
+ }
+@@ -637,18 +645,38 @@ static void pci32_sync_sg_for_device(str
+       if (dir != PCI_DMA_TODEVICE) {
+               for_each_sg(sgl, sg, nents, n) {
+-                      BUG_ON(page_address(sg_page(sg)) == NULL);
+-                      mmu_inval_dma_area(
+-                          (unsigned long) page_address(sg_page(sg)),
+-                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
++                      mmu_inval_dma_area((unsigned long)sg_virt(sg),  PAGE_ALIGN(sg->length));
+               }
+       }
+ }
++/* LEON3 unmapping functions 
++ * 
++ * We can only invalidate the whole cache so unmap_page and unmap_sg do the same thing
++ */
++static void leon3_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
++                           enum dma_data_direction dir, struct dma_attrs *attrs)
++{
++      if (dir != PCI_DMA_TODEVICE) {
++              mmu_inval_dma_area(0, 0);
++      }
++}
++
++static void leon3_unmap_sg(struct device *dev, struct scatterlist *sgl,
++                         int nents, enum dma_data_direction dir,
++                         struct dma_attrs *attrs)
++{
++
++      if (dir != PCI_DMA_TODEVICE) {
++              mmu_inval_dma_area(0, 0);
++      }
++}
++
+ struct dma_map_ops pci32_dma_ops = {
+       .alloc_coherent         = pci32_alloc_coherent,
+       .free_coherent          = pci32_free_coherent,
+       .map_page               = pci32_map_page,
++      .unmap_page             = pci32_unmap_page,
+       .map_sg                 = pci32_map_sg,
+       .unmap_sg               = pci32_unmap_sg,
+       .sync_single_for_cpu    = pci32_sync_single_for_cpu,
+@@ -658,7 +686,30 @@ struct dma_map_ops pci32_dma_ops = {
+ };
+ EXPORT_SYMBOL(pci32_dma_ops);
+-#endif /* CONFIG_PCI */
++struct dma_map_ops leon3_dma_ops = {
++      .alloc_coherent         = sbus_alloc_coherent,
++      .free_coherent          = sbus_free_coherent,
++      .map_page               = pci32_map_page,
++      .unmap_page             = leon3_unmap_page,
++      .map_sg                 = pci32_map_sg,
++      .unmap_sg               = leon3_unmap_sg,
++      .sync_single_for_cpu    = pci32_sync_single_for_cpu,
++      .sync_single_for_device = pci32_sync_single_for_device,
++      .sync_sg_for_cpu        = pci32_sync_sg_for_cpu,
++      .sync_sg_for_device     = pci32_sync_sg_for_device,
++};
++
++#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */
++
++#ifdef CONFIG_SPARC_LEON
++struct dma_map_ops *dma_ops = &leon3_dma_ops;
++#else
++struct dma_map_ops *dma_ops = &sbus_dma_ops;
++#endif
++
++#ifdef CONFIG_SBUS
++EXPORT_SYMBOL(dma_ops);
++#endif
+ /*
+  * Return whether the given PCI device DMA address mask can be
+@@ -676,6 +727,16 @@ int dma_supported(struct device *dev, u6
+ }
+ EXPORT_SYMBOL(dma_supported);
++int dma_set_mask(struct device *dev, u64 dma_mask)
++{
++#ifdef CONFIG_PCI
++      if (dev->bus == &pci_bus_type)
++              return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
++#endif
++      return -EOPNOTSUPP;
++}
++EXPORT_SYMBOL(dma_set_mask);
++
+ #ifdef CONFIG_PROC_FS
+ static int sparc_io_proc_show(struct seq_file *m, void *v)
+@@ -717,7 +778,7 @@ static const struct file_operations spar
+ static struct resource *_sparc_find_resource(struct resource *root,
+                                            unsigned long hit)
+ {
+-        struct resource *tmp;
++      struct resource *tmp;
+       for (tmp = root->child; tmp != 0; tmp = tmp->sibling) {
+               if (tmp->start <= hit && tmp->end >= hit)
diff --git a/target/linux/leon/patches-2.6.36/016-ioport_update.patch b/target/linux/leon/patches-2.6.36/016-ioport_update.patch
new file mode 100644 (file)
index 0000000..130b36e
--- /dev/null
@@ -0,0 +1,51 @@
+From 36cad96a50eb877d0c5cb3d8d93c1807ad9c774c Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 09:37:23 +0100
+Subject: [PATCH] Fix kristoffers ioport.c patch for more recent kernel.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ arch/sparc/include/asm/dma-mapping.h |   13 +------------
+ arch/sparc/kernel/ioport.c           |    3 ++-
+ 2 files changed, 3 insertions(+), 13 deletions(-)
+
+--- a/arch/sparc/include/asm/dma-mapping.h
++++ b/arch/sparc/include/asm/dma-mapping.h
+@@ -51,17 +51,6 @@ static inline int dma_mapping_error(stru
+       return (dma_addr == DMA_ERROR_CODE);
+ }
+-static inline int dma_set_mask(struct device *dev, u64 mask)
+-{
+-#ifdef CONFIG_PCI
+-      if (dev->bus == &pci_bus_type) {
+-              if (!dev->dma_mask || !dma_supported(dev, mask))
+-                      return -EINVAL;
+-              *dev->dma_mask = mask;
+-              return 0;
+-      }
+-#endif
+-      return -EINVAL;
+-}
++extern int dma_set_mask(struct device *dev, u64 dma_mask);
+ #endif
+--- a/arch/sparc/kernel/ioport.c
++++ b/arch/sparc/kernel/ioport.c
+@@ -301,7 +301,7 @@ static void *sbus_alloc_coherent(struct
+               goto err_nova;
+       }
+ #endif
+-      res->name = op->node->name;
++      res->name = op->dev.of_node->name;
+       return (void *)(unsigned long)res->start;
+@@ -737,6 +737,7 @@ int dma_set_mask(struct device *dev, u64
+ }
+ EXPORT_SYMBOL(dma_set_mask);
++
+ #ifdef CONFIG_PROC_FS
+ static int sparc_io_proc_show(struct seq_file *m, void *v)
diff --git a/target/linux/leon/patches-2.6.36/017-greth_no_gbit.patch b/target/linux/leon/patches-2.6.36/017-greth_no_gbit.patch
new file mode 100644 (file)
index 0000000..5e3ee3d
--- /dev/null
@@ -0,0 +1,66 @@
+From 2e864d18c31d4e0255269f9e9cfccc09512676c6 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 16:51:38 +0100
+Subject: [PATCH] GRETH: added greth_no_gbit option
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |   15 +++++++++++++--
+ drivers/net/greth.h |    1 +
+ 2 files changed, 14 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -66,6 +66,10 @@ static int greth_edcl = 1;
+ module_param(greth_edcl, int, 0);
+ MODULE_PARM_DESC(greth_edcl, "GRETH EDCL usage indicator. Set to 1 if EDCL is used.");
++static int no_gbit = 0;
++module_param(no_gbit, int, S_IRUGO);
++MODULE_PARM_DESC(no_gbit, "GRETH report GBit not supported by MAC enable. Only affects GRETH GBit MAC, default 0 (off).");
++
+ static int greth_open(struct net_device *dev);
+ static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
+          struct net_device *dev);
+@@ -1284,7 +1288,7 @@ static int greth_mdio_probe(struct net_d
+       }
+       ret = phy_connect_direct(dev, phy, &greth_link_change,
+-                      0, greth->gbit_mac ?
++                      0, greth->gbit_phy_support ?
+                       PHY_INTERFACE_MODE_GMII :
+                       PHY_INTERFACE_MODE_MII);
+       if (ret) {
+@@ -1293,7 +1297,7 @@ static int greth_mdio_probe(struct net_d
+               return ret;
+       }
+-      if (greth->gbit_mac)
++      if (greth->gbit_phy_support)
+               phy->supported &= PHY_GBIT_FEATURES;
+       else
+               phy->supported &= PHY_BASIC_FEATURES;
+@@ -1441,6 +1445,13 @@ static int __devinit greth_of_probe(stru
+       tmp = GRETH_REGLOAD(regs->control);
+       greth->gbit_mac = (tmp >> 27) & 1;
++      /* Let user skip GBit link mode by telling MDIO layer that MAC does
++       * not support GBIT (for debug) */
++      if (greth->gbit_mac && !no_gbit)
++              greth->gbit_phy_support = 1;
++      else
++              greth->gbit_phy_support = 0;
++
+       /* Check for multicast capability */
+       greth->multicast = (tmp >> 25) & 1;
+--- a/drivers/net/greth.h
++++ b/drivers/net/greth.h
+@@ -138,6 +138,7 @@ struct greth_private {
+       u8 gbit_mac;
+       u8 mdio_int_en;
+       u8 edcl;
++      u8 gbit_phy_support;
+ };
+ #endif
diff --git a/target/linux/leon/patches-2.6.36/018-greth_compat_mode.patch b/target/linux/leon/patches-2.6.36/018-greth_compat_mode.patch
new file mode 100644 (file)
index 0000000..4afe89e
--- /dev/null
@@ -0,0 +1,41 @@
+From a498d7076ee0f82ec3f508293a9cf1ccba15829e Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 16:52:19 +0100
+Subject: [PATCH] GRETH: added greth_compat_mode module parameter
+
+The greth_compat_mode option can be used to set a GRETH GBit capable MAC
+in operate as if the GRETH 10/100 device was found. The GRETH GBit supports
+TCP/UDP checksum offloading, unaligned frame buffers, scatter gather etc.
+Enabling this mode allows the developer to test the GRETH 10/100 device
+without all features mentioned above on a GBit MAC capable of the above.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -70,6 +70,11 @@ static int no_gbit = 0;
+ module_param(no_gbit, int, S_IRUGO);
+ MODULE_PARM_DESC(no_gbit, "GRETH report GBit not supported by MAC enable. Only affects GRETH GBit MAC, default 0 (off).");
++/* Use this option to enable GRETH 10/100 code on GRETH_GBIT hardware (debug legacy code option) */
++static int compat_mode = 0;
++module_param(compat_mode, int, S_IRUGO);
++MODULE_PARM_DESC(compat_mode, "GRETH 10/100 legacy mode enable. Only affects GRETH GBit MAC, default 0 (off).");
++
+ static int greth_open(struct net_device *dev);
+ static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
+          struct net_device *dev);
+@@ -1452,6 +1457,10 @@ static int __devinit greth_of_probe(stru
+       else
+               greth->gbit_phy_support = 0;
++      /* Force GBit MAC in legacy 10/100 mode (no offloading etc.) */
++      if (compat_mode == 1)
++              greth->gbit_mac = 0;
++
+       /* Check for multicast capability */
+       greth->multicast = (tmp >> 25) & 1;
diff --git a/target/linux/leon/patches-2.6.36/019-greth_fix_open_close.patch b/target/linux/leon/patches-2.6.36/019-greth_fix_open_close.patch
new file mode 100644 (file)
index 0000000..fffb391
--- /dev/null
@@ -0,0 +1,34 @@
+From 6216bc809c5bdd586b14d096fbaf6dc25574b928 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 09:59:14 +0100
+Subject: [PATCH] GRETH: fix opening/closing
+
+When NAPI is disabled there is no point in having IRQs enabled, TX/RX
+should be off before clearing the TX/RX descriptor rings.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -365,6 +365,8 @@ static int greth_open(struct net_device
+               dev_dbg(&dev->dev, " starting queue\n");
+       netif_start_queue(dev);
++      GRETH_REGSAVE(greth->regs->status, 0xFF);
++
+       napi_enable(&greth->napi);
+       greth_enable_irqs(greth);
+@@ -380,7 +382,9 @@ static int greth_close(struct net_device
+       napi_disable(&greth->napi);
++      greth_disable_irqs(greth);
+       greth_disable_tx(greth);
++      greth_disable_rx(greth);
+       netif_stop_queue(dev);
diff --git a/target/linux/leon/patches-2.6.36/020-greth_optimize_gbit_tx_descriptor_handling.patch b/target/linux/leon/patches-2.6.36/020-greth_optimize_gbit_tx_descriptor_handling.patch
new file mode 100644 (file)
index 0000000..3a14eb7
--- /dev/null
@@ -0,0 +1,61 @@
+From 544631281bed5cc37b8f2d3a99f44c9d4b97f9a8 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 10:07:12 +0100
+Subject: [PATCH] GRETH: GBit transmit descriptor handling optimization
+
+It is safe to enable all fragments before enabling the first descriptor,
+this way all descriptors don't have to be processed twice, added extra
+memory barrier.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |   19 ++++++++++---------
+ 1 files changed, 10 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -512,7 +512,7 @@ greth_start_xmit_gbit(struct sk_buff *sk
+               greth->tx_skbuff[curr_tx] = NULL;
+               bdp = greth->tx_bd_base + curr_tx;
+-              status = GRETH_TXBD_CSALL;
++              status = GRETH_TXBD_CSALL | GRETH_BD_EN;
+               status |= frag->size & GRETH_BD_LEN;
+               /* Wrap around descriptor ring */
+@@ -549,26 +549,27 @@ greth_start_xmit_gbit(struct sk_buff *sk
+       wmb();
+-      /* Enable the descriptors that we configured ...  */
+-      for (i = 0; i < nr_frags + 1; i++) {
+-              bdp = greth->tx_bd_base + greth->tx_next;
+-              greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
+-              greth->tx_next = NEXT_TX(greth->tx_next);
+-              greth->tx_free--;
+-      }
++      /* Enable the descriptor chain by enabling the first descriptor */
++      bdp = greth->tx_bd_base + greth->tx_next;
++      greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
++      greth->tx_next = curr_tx;
++      greth->tx_free -= nr_frags + 1;
++
++      wmb();
+       greth_enable_tx(greth);
+       return NETDEV_TX_OK;
+ frag_map_error:
+-      /* Unmap SKB mappings that succeeded */
++      /* Unmap SKB mappings that succeeded and disable descriptor */
+       for (i = 0; greth->tx_next + i != curr_tx; i++) {
+               bdp = greth->tx_bd_base + greth->tx_next + i;
+               dma_unmap_single(greth->dev,
+                                greth_read_bd(&bdp->addr),
+                                greth_read_bd(&bdp->stat) & GRETH_BD_LEN,
+                                DMA_TO_DEVICE);
++              greth_write_bd(&bdp->stat, 0);
+       }
+ map_error:
+       if (net_ratelimit())
diff --git a/target/linux/leon/patches-2.6.36/021-greth_fix_memory_leak.patch b/target/linux/leon/patches-2.6.36/021-greth_fix_memory_leak.patch
new file mode 100644 (file)
index 0000000..1d05af1
--- /dev/null
@@ -0,0 +1,49 @@
+From 54789a03adf9c924d0cf7b890323c9c1ca7ab042 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 10:26:09 +0100
+Subject: [PATCH] GRETH: fixed skb buffer memory leak on frame errors
+
+A new SKB buffer should not be allocated when the old SKB is reused.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |   17 +++++++++++------
+ 1 files changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -879,10 +879,8 @@ static int greth_rx_gbit(struct net_devi
+                       }
+               }
+-              /* Allocate new skb to replace current */
+-              newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN);
+-
+-              if (!bad && newskb) {
++              /* Allocate new skb to replace current, not needed if the current skb can be reused */
++              if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) {
+                       skb_reserve(newskb, NET_IP_ALIGN);
+                       dma_addr = dma_map_single(greth->dev,
+@@ -919,12 +917,19 @@ static int greth_rx_gbit(struct net_devi
+                               if (net_ratelimit())
+                                       dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
+                               dev_kfree_skb(newskb);
+-                              dev->stats.rx_dropped++;
++                              dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */
+                       }
++              } else if ( bad ) {
++                      /* Bad Frame transfer, the skb is reused */
++                      dev->stats.rx_dropped++;
+               } else {
++                      /* Failed Allocating a new skb. This is rather stupid but the current "filled" 
++                       * skb is reused, as if transfer failure. One could argue that RX descriptor table
++                       * handling should be divided into cleaning and filling as the TX part of the driver
++                       */
+                       if (net_ratelimit())
+                               dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
+-                      dev->stats.rx_dropped++;
++                      dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */
+               }
+               status = GRETH_BD_EN | GRETH_BD_IE;
diff --git a/target/linux/leon/patches-2.6.36/022-greth_avoid_bad_speed_duplex.patch b/target/linux/leon/patches-2.6.36/022-greth_avoid_bad_speed_duplex.patch
new file mode 100644 (file)
index 0000000..e825364
--- /dev/null
@@ -0,0 +1,50 @@
+From c2e963057ca5635d6e5387623c3ad0c0b3123754 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 10:28:37 +0100
+Subject: [PATCH] GRETH: avoid writing bad speed/duplex when setting transfer mode
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |   19 ++++++++-----------
+ 1 files changed, 8 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -1236,29 +1236,26 @@ static void greth_link_change(struct net
+       struct greth_private *greth = netdev_priv(dev);
+       struct phy_device *phydev = greth->phy;
+       unsigned long flags;
+-
+       int status_change = 0;
++      u32 ctrl;
+       spin_lock_irqsave(&greth->devlock, flags);
+       if (phydev->link) {
+               if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) {
+-
+-                      GRETH_REGANDIN(greth->regs->control,
+-                                     ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB));
++                      ctrl = GRETH_REGLOAD(greth->regs->control) & 
++                             ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB);
+                       if (phydev->duplex)
+-                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_FD);
+-
+-                      if (phydev->speed == SPEED_100) {
+-
+-                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_SP);
+-                      }
++                              ctrl |= GRETH_CTRL_FD;
++                      if (phydev->speed == SPEED_100)
++                              ctrl |= GRETH_CTRL_SP;
+                       else if (phydev->speed == SPEED_1000)
+-                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_GB);
++                              ctrl |= GRETH_CTRL_GB;
++                      GRETH_REGSAVE(greth->regs->control, ctrl);
+                       greth->speed = phydev->speed;
+                       greth->duplex = phydev->duplex;
+                       status_change = 1;
diff --git a/target/linux/leon/patches-2.6.36/023-greth_handle_frame_error_interrupts.patch b/target/linux/leon/patches-2.6.36/023-greth_handle_frame_error_interrupts.patch
new file mode 100644 (file)
index 0000000..12bfb1c
--- /dev/null
@@ -0,0 +1,49 @@
+From f62c047af910c9c9696db7b47472a3728b8100e8 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 11:56:22 +0100
+Subject: [PATCH] GRETH: handle frame error interrupts
+
+Not handling frame error interrupts are unlikly but may lead to dead
+lock if 128 error frames are recieved in a row.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    5 +++--
+ drivers/net/greth.h |    2 ++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -595,11 +595,12 @@ static irqreturn_t greth_interrupt(int i
+       status = GRETH_REGLOAD(greth->regs->status);
+       /* Handle rx and tx interrupts through poll */
+-      if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
++      if (status & (GRETH_INT_RE | GRETH_INT_RX | GRETH_INT_TE | GRETH_INT_TX)) {
+               /* Clear interrupt status */
+               GRETH_REGSAVE(greth->regs->status,
+-                            status & (GRETH_INT_RX | GRETH_INT_TX));
++                            status & (GRETH_INT_RE | GRETH_INT_RX | 
++                                      GRETH_INT_TE | GRETH_INT_TX));
+               retval = IRQ_HANDLED;
+--- a/drivers/net/greth.h
++++ b/drivers/net/greth.h
+@@ -23,6 +23,7 @@
+ #define GRETH_BD_LEN 0x7FF
+ #define GRETH_TXEN 0x1
++#define GRETH_INT_TE 0x2
+ #define GRETH_INT_TX 0x8
+ #define GRETH_TXI 0x4
+ #define GRETH_TXBD_STATUS 0x0001C000
+@@ -35,6 +36,7 @@
+ #define GRETH_TXBD_ERR_UE 0x4000
+ #define GRETH_TXBD_ERR_AL 0x8000
++#define GRETH_INT_RE         0x1
+ #define GRETH_INT_RX         0x4
+ #define GRETH_RXEN           0x2
+ #define GRETH_RXI            0x8
diff --git a/target/linux/leon/patches-2.6.36/024-greth_resolve_smp_and_other_issues.patch b/target/linux/leon/patches-2.6.36/024-greth_resolve_smp_and_other_issues.patch
new file mode 100644 (file)
index 0000000..c2293ca
--- /dev/null
@@ -0,0 +1,399 @@
+From 4439d933884ee3c7e320b8d33bd2e268dd5b6fa5 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 11:40:19 +0100
+Subject: [PATCH] GRETH: resolve SMP issues and other problems
+
+Fixes the following:
+1. POLL should not enable IRQ when work is not completed
+2. No locking between TX descriptor cleaning and XMIT descriptor handling
+3. No locking between RX POLL and XMIT modifying control register
+4. Since TX cleaning (called from POLL) is running in parallel with XMIT
+   unnecessary locking is needed.
+5. IRQ handler looks at RX frame status solely, this is wrong when IRQ is
+   temporarily disabled (in POLL), and when IRQ is shared.
+6. IRQ handler clears IRQ status, which is unnecessary
+7. TX queue was stopped in preventing cause when not MAX_SKB_FRAGS+1 descriptors
+   were available after a SKB been scheduled by XMIT. Instead the TX queue is
+   stopped first when not enough descriptors are available upon entering XMIT.
+
+It was hard to split up this patch in smaller pieces since all are tied
+together somehow.
+
+Note the RX flag used in the interrupt handler does not signal that interrtupt
+was asserted, but that a frame was received. Same goes for TX. Also, IRQ is not
+asserted when the RX flag is set before enabling IRQ enable until a new frame is
+received. So extra care must be taken to avoid enabling IRQ and all descriptors
+are already used, hence dead lock will upon us. See new POLL implementation that
+enableds IRQ then look at the RX flag to determine if one or more IRQs may have
+been missed. TX/RX flags are cleared before handling previously enabled
+descriptors, this ensures that the RX/TX flags are valid when determining if IRQ
+should be turned on again.
+
+By moving TX cleaning from POLL to XMIT in the standard case, removes some
+locking trouble. Enabling TX cleaning from poll only when not enough TX
+descriptors are available is safe because the TX queue is at the same time
+stopped, thus XMIT will not be called. The TX queue is woken up again when
+enough descriptrs are available.
+
+TX Frames are always enabled with IRQ, however the TX IRQ Enable flag will not
+be enabled until XMIT must wait for free descriptors.
+
+Locking RX and XMIT parts of the driver from each other is needed because the
+RX/TX enable bits share the same register.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |  158 ++++++++++++++++++++++++++++++---------------------
+ 1 files changed, 93 insertions(+), 65 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -1,7 +1,7 @@
+ /*
+  * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC.
+  *
+- * 2005-2009 (c) Aeroflex Gaisler AB
++ * 2005-2010 (c) Aeroflex Gaisler AB
+  *
+  * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs
+  * available in the GRLIB VHDL IP core library.
+@@ -401,12 +401,20 @@ greth_start_xmit(struct sk_buff *skb, st
+       struct greth_private *greth = netdev_priv(dev);
+       struct greth_bd *bdp;
+       int err = NETDEV_TX_OK;
+-      u32 status, dma_addr;
++      u32 status, dma_addr, ctrl;
++      unsigned long flags;
+-      bdp = greth->tx_bd_base + greth->tx_next;
++      /* Clean TX Ring */
++      greth_clean_tx(greth->netdev);
+       if (unlikely(greth->tx_free <= 0)) {
++              spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
++              ctrl = GRETH_REGLOAD(greth->regs->control);
++              /* Enable TX IRQ only if not already in poll() routine */
++              if ( ctrl & GRETH_RXI )
++                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
+               netif_stop_queue(dev);
++              spin_unlock_irqrestore(&greth->devlock, flags);
+               return NETDEV_TX_BUSY;
+       }
+@@ -419,13 +427,14 @@ greth_start_xmit(struct sk_buff *skb, st
+               goto out;
+       }
++      bdp = greth->tx_bd_base + greth->tx_next;
+       dma_addr = greth_read_bd(&bdp->addr);
+       memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
+       dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
+-      status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN);
++      status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN);
+       /* Wrap around descriptor ring */
+       if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
+@@ -435,22 +444,11 @@ greth_start_xmit(struct sk_buff *skb, st
+       greth->tx_next = NEXT_TX(greth->tx_next);
+       greth->tx_free--;
+-      /* No more descriptors */
+-      if (unlikely(greth->tx_free == 0)) {
+-
+-              /* Free transmitted descriptors */
+-              greth_clean_tx(dev);
+-
+-              /* If nothing was cleaned, stop queue & wait for irq */
+-              if (unlikely(greth->tx_free == 0)) {
+-                      status |= GRETH_BD_IE;
+-                      netif_stop_queue(dev);
+-              }
+-      }
+-
+       /* Write descriptor control word and enable transmission */
+       greth_write_bd(&bdp->stat, status);
++      spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
+       greth_enable_tx(greth);
++      spin_unlock_irqrestore(&greth->devlock, flags);
+ out:
+       dev_kfree_skb(skb);
+@@ -463,13 +461,24 @@ greth_start_xmit_gbit(struct sk_buff *sk
+ {
+       struct greth_private *greth = netdev_priv(dev);
+       struct greth_bd *bdp;
+-      u32 status = 0, dma_addr;
++      u32 status = 0, dma_addr, ctrl;
+       int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
++      unsigned long flags;
+       nr_frags = skb_shinfo(skb)->nr_frags;
++      /* Clean TX Ring */
++      greth_clean_tx_gbit(dev);
++
+       if (greth->tx_free < nr_frags + 1) {
++              spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
++              ctrl = GRETH_REGLOAD(greth->regs->control);
++              /* Enable TX IRQ only if not already in poll() routine */
++              if ( ctrl & GRETH_RXI ) {
++                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
++              }
+               netif_stop_queue(dev);
++              spin_unlock_irqrestore(&greth->devlock, flags);
+               err = NETDEV_TX_BUSY;
+               goto out;
+       }
+@@ -522,14 +531,8 @@ greth_start_xmit_gbit(struct sk_buff *sk
+               /* More fragments left */
+               if (i < nr_frags - 1)
+                       status |= GRETH_TXBD_MORE;
+-
+-              /* ... last fragment, check if out of descriptors  */
+-              else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) {
+-
+-                      /* Enable interrupts and stop queue */
+-                      status |= GRETH_BD_IE;
+-                      netif_stop_queue(dev);
+-              }
++              else
++                      status |= GRETH_BD_IE; /* enable IRQ on last fragment */
+               greth_write_bd(&bdp->stat, status);
+@@ -557,7 +560,9 @@ greth_start_xmit_gbit(struct sk_buff *sk
+       wmb();
++      spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
+       greth_enable_tx(greth);
++      spin_unlock_irqrestore(&greth->devlock, flags);
+       return NETDEV_TX_OK;
+@@ -579,12 +584,11 @@ out:
+       return err;
+ }
+-
+ static irqreturn_t greth_interrupt(int irq, void *dev_id)
+ {
+       struct net_device *dev = dev_id;
+       struct greth_private *greth;
+-      u32 status;
++      u32 status, ctrl;
+       irqreturn_t retval = IRQ_NONE;
+       greth = netdev_priv(dev);
+@@ -594,13 +598,14 @@ static irqreturn_t greth_interrupt(int i
+       /* Get the interrupt events that caused us to be here. */
+       status = GRETH_REGLOAD(greth->regs->status);
+-      /* Handle rx and tx interrupts through poll */
+-      if (status & (GRETH_INT_RE | GRETH_INT_RX | GRETH_INT_TE | GRETH_INT_TX)) {
++      /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be set regardless
++       * of whether IRQ is enabled or not. Especially important when shared IRQ.
++       */
++      ctrl = GRETH_REGLOAD(greth->regs->control);
+-              /* Clear interrupt status */
+-              GRETH_REGSAVE(greth->regs->status,
+-                            status & (GRETH_INT_RE | GRETH_INT_RX | 
+-                                      GRETH_INT_TE | GRETH_INT_TX));
++      /* Handle rx and tx interrupts through poll */
++      if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) ||
++          ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) {
+               retval = IRQ_HANDLED;
+@@ -625,6 +630,8 @@ static void greth_clean_tx(struct net_de
+       while (1) {
+               bdp = greth->tx_bd_base + greth->tx_last;
++              GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
++              mb();
+               stat = greth_read_bd(&bdp->stat);
+               if (unlikely(stat & GRETH_BD_EN))
+@@ -685,7 +692,10 @@ static void greth_clean_tx_gbit(struct n
+               /* We only clean fully completed SKBs */
+               bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
+-              stat = bdp_last_frag->stat;
++
++              GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
++              mb();
++              stat = greth_read_bd(&bdp_last_frag->stat);
+               if (stat & GRETH_BD_EN)
+                       break;
+@@ -717,23 +727,12 @@ static void greth_clean_tx_gbit(struct n
+               greth->tx_free += nr_frags+1;
+               dev_kfree_skb(skb);
+       }
+-      if (greth->tx_free > (MAX_SKB_FRAGS + 1)) {
++
++      if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS + 1))) {
+               netif_wake_queue(dev);
+       }
+ }
+-static int greth_pending_packets(struct greth_private *greth)
+-{
+-      struct greth_bd *bdp;
+-      u32 status;
+-      bdp = greth->rx_bd_base + greth->rx_cur;
+-      status = greth_read_bd(&bdp->stat);
+-      if (status & GRETH_BD_EN)
+-              return 0;
+-      else
+-              return 1;
+-}
+-
+ static int greth_rx(struct net_device *dev, int limit)
+ {
+       struct greth_private *greth;
+@@ -742,20 +741,24 @@ static int greth_rx(struct net_device *d
+       int pkt_len;
+       int bad, count;
+       u32 status, dma_addr;
++      unsigned long flags;
+       greth = netdev_priv(dev);
+       for (count = 0; count < limit; ++count) {
+               bdp = greth->rx_bd_base + greth->rx_cur;
++              GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
++              mb();
+               status = greth_read_bd(&bdp->stat);
+-              dma_addr = greth_read_bd(&bdp->addr);
+-              bad = 0;
+               if (unlikely(status & GRETH_BD_EN)) {
+                       break;
+               }
++              dma_addr = greth_read_bd(&bdp->addr);
++              bad = 0;
++
+               /* Check status for errors. */
+               if (unlikely(status & GRETH_RXBD_STATUS)) {
+                       if (status & GRETH_RXBD_ERR_FT) {
+@@ -817,7 +820,9 @@ static int greth_rx(struct net_device *d
+               dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
++              spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */
+               greth_enable_rx(greth);
++              spin_unlock_irqrestore(&greth->devlock, flags);
+               greth->rx_cur = NEXT_RX(greth->rx_cur);
+       }
+@@ -851,6 +856,7 @@ static int greth_rx_gbit(struct net_devi
+       int pkt_len;
+       int bad, count = 0;
+       u32 status, dma_addr;
++      unsigned long flags;
+       greth = netdev_priv(dev);
+@@ -858,6 +864,8 @@ static int greth_rx_gbit(struct net_devi
+               bdp = greth->rx_bd_base + greth->rx_cur;
+               skb = greth->rx_skbuff[greth->rx_cur];
++              GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
++              mb();
+               status = greth_read_bd(&bdp->stat);
+               bad = 0;
+@@ -940,7 +948,9 @@ static int greth_rx_gbit(struct net_devi
+               wmb();
+               greth_write_bd(&bdp->stat, status);
++              spin_lock_irqsave(&greth->devlock, flags);
+               greth_enable_rx(greth);
++              spin_unlock_irqrestore(&greth->devlock, flags);
+               greth->rx_cur = NEXT_RX(greth->rx_cur);
+       }
+@@ -952,15 +962,19 @@ static int greth_poll(struct napi_struct
+ {
+       struct greth_private *greth;
+       int work_done = 0;
++      unsigned long flags;
++      u32 mask, ctrl;
+       greth = container_of(napi, struct greth_private, napi);
+-      if (greth->gbit_mac) {
+-              greth_clean_tx_gbit(greth->netdev);
+-      } else {
+-              greth_clean_tx(greth->netdev);
++restart_txrx_poll:
++      if ( netif_queue_stopped(greth->netdev) ) {
++              if (greth->gbit_mac) {
++                      greth_clean_tx_gbit(greth->netdev);
++              } else {
++                      greth_clean_tx(greth->netdev);
++              }
+       }
+-restart_poll:
+       if (greth->gbit_mac) {
+               work_done += greth_rx_gbit(greth->netdev, budget - work_done);
+       } else {
+@@ -969,15 +983,29 @@ restart_poll:
+       if (work_done < budget) {
+-              napi_complete(napi);
++              spin_lock_irqsave(&greth->devlock, flags);
+-              if (greth_pending_packets(greth)) {
+-                      napi_reschedule(napi);
+-                      goto restart_poll;
++              ctrl = GRETH_REGLOAD(greth->regs->control);
++              if (netif_queue_stopped(greth->netdev)) {
++                      GRETH_REGSAVE(greth->regs->control,
++                                      ctrl | GRETH_TXI | GRETH_RXI);
++                      mask = GRETH_INT_RX | GRETH_INT_RE |
++                             GRETH_INT_TX | GRETH_INT_TE;
++              } else {
++                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI);
++                      mask = GRETH_INT_RX | GRETH_INT_RE;
++              }
++
++              if (GRETH_REGLOAD(greth->regs->status) & mask) {
++                      GRETH_REGSAVE(greth->regs->control, ctrl);
++                      spin_unlock_irqrestore(&greth->devlock, flags);
++                      goto restart_txrx_poll;
++              } else {
++                      __napi_complete(napi);
++                      spin_unlock_irqrestore(&greth->devlock, flags);
+               }
+       }
+-      greth_enable_irqs(greth);
+       return work_done;
+ }
+@@ -1172,11 +1200,11 @@ static const struct ethtool_ops greth_et
+ };
+ static struct net_device_ops greth_netdev_ops = {
+-      .ndo_open = greth_open,
+-      .ndo_stop = greth_close,
+-      .ndo_start_xmit = greth_start_xmit,
+-      .ndo_set_mac_address = greth_set_mac_add,
+-      .ndo_validate_addr      = eth_validate_addr,
++      .ndo_open               = greth_open,
++      .ndo_stop               = greth_close,
++      .ndo_start_xmit         = greth_start_xmit,
++      .ndo_set_mac_address    = greth_set_mac_add,
++      .ndo_validate_addr      = eth_validate_addr,
+ };
+ static inline int wait_for_mdio(struct greth_private *greth)
diff --git a/target/linux/leon/patches-2.6.36/025-greth_bootloader_disable_device_node.patch b/target/linux/leon/patches-2.6.36/025-greth_bootloader_disable_device_node.patch
new file mode 100644 (file)
index 0000000..836bab1
--- /dev/null
@@ -0,0 +1,25 @@
+From 66d5b37cc6d32291419bf99161e83e2946ea5f25 Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 12:11:03 +0100
+Subject: [PATCH] GRETH: added option to disable a device node from bootloader.
+
+Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
+---
+ drivers/net/greth.c |    6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -1428,6 +1428,12 @@ static int __devinit greth_of_probe(stru
+       int err;
+       int tmp;
+       unsigned long timeout;
++      int *ampopts;
++
++      /* Skip device if used by another OS instance */
++      ampopts = (int *) of_get_property(ofdev->dev.of_node, "ampopts", NULL);
++      if (ampopts && (*ampopts == 0))
++              return -EIO;
+       dev = alloc_etherdev(sizeof(struct greth_private));
diff --git a/target/linux/leon/patches-2.6.36/026-greth_gbit_mac_set_ee_when_edcl.patch b/target/linux/leon/patches-2.6.36/026-greth_gbit_mac_set_ee_when_edcl.patch
new file mode 100644 (file)
index 0000000..94fa0bd
--- /dev/null
@@ -0,0 +1,31 @@
+From 50fcb51c42bc721f18f1bfa10f705519cd344a2a Mon Sep 17 00:00:00 2001
+From: Daniel Hellstrom <daniel@gaisler.com>
+Date: Wed, 1 Dec 2010 16:20:01 +0100
+Subject: [PATCH] GRETH: Newer GBit MACs need setting EE bit when EDCL should be enabled
+
+---
+ drivers/net/greth.c |    2 +-
+ drivers/net/greth.h |    1 +
+ 2 files changed, 2 insertions(+), 1 deletions(-)
+
+--- a/drivers/net/greth.c
++++ b/drivers/net/greth.c
+@@ -1511,7 +1511,7 @@ static int __devinit greth_of_probe(stru
+       /* If we have EDCL we disable the EDCL speed-duplex FSM so
+        * it doesn't interfere with the software */
+       if (greth->edcl != 0)
+-              GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX);
++              GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX|GRETH_CTRL_EE);
+       /* Check if MAC can handle MDIO interrupts */
+       greth->mdio_int_en = (tmp >> 26) & 1;
+--- a/drivers/net/greth.h
++++ b/drivers/net/greth.h
+@@ -15,6 +15,7 @@
+ #define GRETH_CTRL_PSTATIEN   0x400
+ #define GRETH_CTRL_MCEN       0x800
+ #define GRETH_CTRL_DISDUPLEX  0x1000
++#define GRETH_CTRL_EE         0x4000
+ #define GRETH_STATUS_PHYSTAT  0x100
+ #define GRETH_BD_EN 0x800
diff --git a/target/linux/leon/patches-2.6.36/027-sparc_v8_assembler.patch b/target/linux/leon/patches-2.6.36/027-sparc_v8_assembler.patch
new file mode 100644 (file)
index 0000000..5baea94
--- /dev/null
@@ -0,0 +1,31 @@
+[PATCH] sparc32: Add -Av8 to assembler command line.
+
+Newer version of binutils are more strict about specifying the
+correct options to enable certain classes of instructions.
+
+The sparc32 build is done for v7 in order to support sun4c systems
+which lack hardware integer multiply and divide instructions.
+
+So we have to pass -Av8 when building the assembler routines that
+use these instructions and get patched into the kernel when we find
+out that we have a v8 capable cpu.
+
+Reported-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
+Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
+---
+ arch/sparc/Makefile |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
+index ad1fb5d..eddcfb3 100644
+--- a/arch/sparc/Makefile
++++ b/arch/sparc/Makefile
+@@ -31,7 +31,7 @@ UTS_MACHINE    := sparc
+ #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
+ KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+-KBUILD_AFLAGS += -m32
++KBUILD_AFLAGS += -m32 -Wa,-Av8
+ #LDFLAGS_vmlinux = -N -Ttext 0xf0004000
+ #  Since 2.5.40, the first stage is left not btfix-ed.
diff --git a/target/linux/leon/patches/001-find_irq_and_timer_via_of.patch b/target/linux/leon/patches/001-find_irq_and_timer_via_of.patch
deleted file mode 100644 (file)
index 18d7f8b..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-From af1da1d5a8701f39cdbae4a0ab8e04b450eef298 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 8 Sep 2010 18:05:38 +0200
-Subject: [PATCH] SPARC/LEON: find IRQ and Timer via OF-Tree, instead of hardcoded.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/leon_kernel.c |   23 ++++++++++++++++++++++-
- 1 files changed, 22 insertions(+), 1 deletions(-)
-
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -105,13 +105,34 @@ static void leon_disable_irq(unsigned in
- void __init leon_init_timers(irq_handler_t counter_fn)
- {
-       int irq;
-+      struct device_node *rootnp, *np;
-+      struct property *pp;
-+      int len;
-       leondebug_irq_disable = 0;
-       leon_debug_irqout = 0;
-       master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
-       dummy_master_l10_counter = 0;
--      if (leon3_gptimer_regs && leon3_irqctrl_regs) {
-+      /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
-+      rootnp = of_find_node_by_path("/ambapp0");
-+      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_IRQMP"))) {
-+              pp = of_find_property(np, "reg", &len);
-+              if (pp)
-+                      leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
-+      }
-+
-+      /* Find GPTIMER Timer Registers base address otherwise bail out. */
-+      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_GPTIMER"))) {
-+              pp = of_find_property(np, "reg", &len);
-+              if (pp)
-+                      leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value;
-+              pp = of_find_property(np, "interrupts", &len);
-+              if (pp)
-+                      leon3_gptimer_irq = *(unsigned int *)pp->value;
-+      }
-+
-+      if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
-                                     (((1000000 / HZ) - 1)));
diff --git a/target/linux/leon/patches/002-sparc_uimage_target.patch b/target/linux/leon/patches/002-sparc_uimage_target.patch
deleted file mode 100644 (file)
index 6e25ff2..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 234ef25344b567b3b8dad62c0863ebe16377528f Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Tue, 14 Sep 2010 11:26:55 +0200
-Subject: [PATCH] SPARC: added U-Boot build target: uImage
-
----
- arch/sparc/Makefile      |    3 ++-
- arch/sparc/boot/Makefile |   35 +++++++++++++++++++++++++++++++++++
- 2 files changed, 37 insertions(+), 1 deletions(-)
-
---- a/arch/sparc/Makefile
-+++ b/arch/sparc/Makefile
-@@ -88,7 +88,7 @@ boot := arch/sparc/boot
- # Default target
- all: zImage
--image zImage tftpboot.img vmlinux.aout: vmlinux
-+image zImage uImage tftpboot.img vmlinux.aout: vmlinux
-       $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
- archclean:
-@@ -102,6 +102,7 @@ ifeq ($(ARCH),sparc)
- define archhelp
-   echo  '* image        - kernel image ($(boot)/image)'
-   echo  '* zImage       - stripped kernel image ($(boot)/zImage)'
-+  echo  '  uImage       - U-Boot SPARC32/LEON Image'
-   echo  '  tftpboot.img - image prepared for tftp'
- endef
- else
---- a/arch/sparc/boot/Makefile
-+++ b/arch/sparc/boot/Makefile
-@@ -5,6 +5,7 @@
- ROOT_IMG      := /usr/src/root.img
- ELFTOAOUT     := elftoaout
-+MKIMAGE       := $(srctree)/scripts/mkuboot.sh
- hostprogs-y   := piggyback_32 piggyback_64 btfixupprep
- targets               := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout
-@@ -90,5 +91,39 @@ $(obj)/tftpboot.img: $(obj)/image $(obj)
- $(obj)/vmlinux.aout: vmlinux FORCE
-       $(call if_changed,elftoaout)
-       @echo '  kernel: $@ is ready'
-+else
-+
-+# The following lines make a readable image for U-Boot.
-+#  uImage   - Binary file read by U-boot
-+#  uImage.o - object file of uImage for loading with a
-+#             flash programmer understanding ELF.
-+
-+OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment
-+$(obj)/image.bin: $(obj)/image FORCE
-+      $(call if_changed,objcopy)
-+
-+$(obj)/image.gz: $(obj)/image.bin
-+      $(call if_changed,gzip)
-+
-+# Start of Main memory
-+ifndef UIMAGE_LOADADDR
-+UIMAGE_LOADADDR=0x40004000
- endif
-+# The first sector after the U-Boot image (256k)
-+ifndef UIMAGE_FLASHADDR
-+UIMAGE_FLASHADDR=0x00040000
-+endif
-+
-+quiet_cmd_uimage = UIMAGE  $@
-+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sparc -O linux -T kernel \
-+               -C gzip -a $(UIMAGE_LOADADDR) -e 0xf0004000 -n 'Linux-$(KERNELRELEASE)' \
-+               -d $< $@
-+
-+targets += uImage
-+$(obj)/uImage: $(obj)/image.gz
-+      $(call if_changed,uimage)
-+      $(LD) -Tdata $(UIMAGE_FLASHADDR) -r -b binary arch/sparc/boot/uImage -o arch/sparc/boot/uImage.o
-+      @echo '  Image $@ is ready'
-+
-+endif
diff --git a/target/linux/leon/patches/003-smp_cpu_stuck_fix.patch b/target/linux/leon/patches/003-smp_cpu_stuck_fix.patch
deleted file mode 100644 (file)
index 3d572f5..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-From 417bc6751fdd3c24df274f25e020ec3decd09280 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Thu, 16 Sep 2010 11:00:46 +0200
-Subject: [PATCH] Fixed SPARC/LEON SMP CPU Stuck problem.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/leon_smp.c |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/sparc/kernel/leon_smp.c
-+++ b/arch/sparc/kernel/leon_smp.c
-@@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(voi
- static inline unsigned long do_swap(volatile unsigned long *ptr,
-                                   unsigned long val)
- {
--      __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val)
--                           : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
-+      __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val)
-+                           : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS)
-                            : "memory");
-       return val;
- }
diff --git a/target/linux/leon/patches/004-extended_irq_controller.patch b/target/linux/leon/patches/004-extended_irq_controller.patch
deleted file mode 100644 (file)
index b660b64..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-From a729672f117df3602b6d3171d8ab7a84bf53b053 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Thu, 16 Sep 2010 11:12:41 +0200
-Subject: [PATCH] SPARC/LEON: added support for Extended IRQ controller, partial patches are already in git tree.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/include/asm/irq_32.h |    4 ++++
- arch/sparc/kernel/irq_32.c      |   32 ++++++++++++++++++++++++++------
- arch/sparc/kernel/leon_kernel.c |    8 +++++++-
- 3 files changed, 37 insertions(+), 7 deletions(-)
-
---- a/arch/sparc/include/asm/irq_32.h
-+++ b/arch/sparc/include/asm/irq_32.h
-@@ -6,7 +6,11 @@
- #ifndef _SPARC_IRQ_H
- #define _SPARC_IRQ_H
-+#ifdef CONFIG_SPARC_LEON
-+#define NR_IRQS    32
-+#else
- #define NR_IRQS    16
-+#endif
- #include <linux/interrupt.h>
---- a/arch/sparc/kernel/irq_32.c
-+++ b/arch/sparc/kernel/irq_32.c
-@@ -110,6 +110,11 @@ EXPORT_SYMBOL(__raw_local_irq_save);
- EXPORT_SYMBOL(raw_local_irq_enable);
- EXPORT_SYMBOL(raw_local_irq_restore);
-+#ifdef CONFIG_SPARC_LEON
-+extern unsigned int sparc_leon_eirq;
-+extern int sparc_leon_eirq_get(int eirq, int cpu);
-+#endif
-+
- /*
-  * Dave Redman (djhr@tadpole.co.uk)
-  *
-@@ -222,10 +227,11 @@ void free_irq(unsigned int irq, void *de
-               return;
-       }
-       cpu_irq = irq & (NR_IRQS - 1);
--        if (cpu_irq > 14) {  /* 14 irq levels on the sparc */
--                printk("Trying to free bogus IRQ %d\n", irq);
--                return;
--        }
-+      /* 14 irq levels on the sparc, however some LEON systems have 31 IRQs */
-+      if ((cpu_irq == 15) || (cpu_irq >= NR_IRQS)) {  
-+              printk("Trying to free bogus IRQ %d\n", irq);
-+              return;
-+      }
-       spin_lock_irqsave(&irq_action_lock, flags);
-@@ -303,7 +309,14 @@ void unexpected_irq(int irq, void *dev_i
-         int i;
-       struct irqaction * action;
-       unsigned int cpu_irq;
--      
-+
-+#ifdef CONFIG_SPARC_LEON
-+      /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
-+      if ( sparc_leon_eirq == irq ) {
-+              irq = sparc_leon_eirq_get(irq, smp_processor_id());
-+      }
-+#endif
-+
-       cpu_irq = irq & (NR_IRQS - 1);
-       action = sparc_irq[cpu_irq].action;
-@@ -330,6 +343,13 @@ void handler_irq(int irq, struct pt_regs
-       extern void smp4m_irq_rotate(int cpu);
- #endif
-+#ifdef CONFIG_SPARC_LEON
-+      /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
-+      if ( sparc_leon_eirq == irq ) {
-+              irq = sparc_leon_eirq_get(irq, cpu);
-+      }
-+#endif
-+
-       old_regs = set_irq_regs(regs);
-       irq_enter();
-       disable_pil_irq(irq);
-@@ -526,7 +546,7 @@ int request_irq(unsigned int irq,
-               return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
-       }
-       cpu_irq = irq & (NR_IRQS - 1);
--      if(cpu_irq > 14) {
-+      if(cpu_irq == 15) {
-               ret = -EINVAL;
-               goto out;
-       }
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -104,7 +104,7 @@ static void leon_disable_irq(unsigned in
- void __init leon_init_timers(irq_handler_t counter_fn)
- {
--      int irq;
-+      int irq, eirq;
-       struct device_node *rootnp, *np;
-       struct property *pp;
-       int len;
-@@ -153,6 +153,12 @@ void __init leon_init_timers(irq_handler
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
- # endif
-+              LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
-+              eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf;
-+              if ( eirq != 0 ) {
-+                      /* Extended IRQ controller available */
-+                      sparc_leon_eirq_register(eirq);
-+              }
-       } else {
-               printk(KERN_ERR "No Timer/irqctrl found\n");
-               BUG();
diff --git a/target/linux/leon/patches/005-avoid_openprom_duplicates.patch b/target/linux/leon/patches/005-avoid_openprom_duplicates.patch
deleted file mode 100644 (file)
index 54bfd27..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-From 486a578298b7ab45c3edfdce8d4feaef93c3229b Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Thu, 16 Sep 2010 11:15:37 +0200
-Subject: [PATCH] SPARC/LEON: to avoid name duplicates in openprom fs when REG is not available the NAME now includes NODE ID when REG not present
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/prom_32.c |   27 +++++++++++++++++++--------
- 1 files changed, 19 insertions(+), 8 deletions(-)
-
---- a/arch/sparc/kernel/prom_32.c
-+++ b/arch/sparc/kernel/prom_32.c
-@@ -136,18 +136,29 @@ static void __init ebus_path_component(s
- /* "name:vendor:device@irq,addrlo" */
- static void __init ambapp_path_component(struct device_node *dp, char *tmp_buf)
- {
--      struct amba_prom_registers *regs; unsigned int *intr;
--      unsigned int *device, *vendor;
-+      struct amba_prom_registers *regs;
-+      unsigned int *intr, *device, *vendor, reg0;
-       struct property *prop;
-+      int interrupt = 0;
-+      /* In order to get a unique ID in the device tree (multiple AMBA devices 
-+       * may have the same name) the node number is printed
-+       */
-       prop = of_find_property(dp, "reg", NULL);
--      if (!prop)
--              return;
--      regs = prop->value;
-+      if (!prop) {
-+              reg0 = (unsigned int)dp->phandle;
-+      } else {
-+              regs = prop->value;
-+              reg0 = regs->phys_addr;
-+      }
-+
-+      /* Not all cores have Interrupt */
-       prop = of_find_property(dp, "interrupts", NULL);
-       if (!prop)
--              return;
--      intr = prop->value;
-+              intr = &interrupt; /* IRQ0 does not exist */
-+      else
-+              intr = prop->value;
-+
-       prop = of_find_property(dp, "vendor", NULL);
-       if (!prop)
-               return;
-@@ -159,7 +170,7 @@ static void __init ambapp_path_component
-       sprintf(tmp_buf, "%s:%d:%d@%x,%x",
-               dp->name, *vendor, *device,
--              *intr, regs->phys_addr);
-+              *intr, reg0);
- }
- static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
diff --git a/target/linux/leon/patches/006-amp_support.patch b/target/linux/leon/patches/006-amp_support.patch
deleted file mode 100644 (file)
index 98d1c9f..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-From 25a68b8cd8ea1553f8b56278418d6c1ecc12e247 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 22 Sep 2010 10:19:34 +0200
-Subject: [PATCH] SPARC/LEON: added support for AMP systems with IRQAMP IRQ Controller.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/include/asm/leon.h      |   12 ++++++++++++
- arch/sparc/include/asm/leon_amba.h |    6 +++---
- arch/sparc/kernel/leon_kernel.c    |   14 ++++++++++++++
- 3 files changed, 29 insertions(+), 3 deletions(-)
-
---- a/arch/sparc/include/asm/leon.h
-+++ b/arch/sparc/include/asm/leon.h
-@@ -224,6 +224,18 @@ static inline void sparc_leon3_disable_c
-                         "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
- };
-+static inline unsigned long sparc_leon3_asr17(void)
-+{
-+      u32 asr17;
-+      __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17));
-+      return asr17;
-+};
-+
-+static inline int sparc_leon3_cpuid(void)
-+{
-+      return sparc_leon3_asr17() >> 28;
-+}
-+
- #endif /*!__ASSEMBLY__*/
- #ifdef CONFIG_SMP
---- a/arch/sparc/include/asm/leon_amba.h
-+++ b/arch/sparc/include/asm/leon_amba.h
-@@ -100,9 +100,8 @@ struct leon3_irqctrl_regs_map {
-       u32 mpbroadcast;
-       u32 notused02;
-       u32 notused03;
--      u32 notused10;
--      u32 notused11;
--      u32 notused12;
-+      u32 ampctrl;
-+      u32 icsel[2];
-       u32 notused13;
-       u32 notused20;
-       u32 notused21;
-@@ -112,6 +111,7 @@ struct leon3_irqctrl_regs_map {
-       u32 force[16];
-       /* Extended IRQ registers */
-       u32 intid[16];  /* 0xc0 */
-+      u32 unused[(0x1000-0x100)/4];
- };
- struct leon3_apbuart_regs_map {
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -108,6 +108,7 @@ void __init leon_init_timers(irq_handler
-       struct device_node *rootnp, *np;
-       struct property *pp;
-       int len;
-+      int cpu, icsel;
-       leondebug_irq_disable = 0;
-       leon_debug_irqout = 0;
-@@ -153,6 +154,19 @@ void __init leon_init_timers(irq_handler
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
- # endif
-+              /* The IRQ controller may (if implemented) consist of multiple
-+               * IRQ controllers, each mapped on a 4Kb boundary.
-+               * Each CPU may be routed to different IRQCTRLs, however
-+               * we assume that all CPUs (in SMP system) is routed to the
-+               * same IRQ Controller, and for non-SMP only one IRQCTRL is
-+               * accessed anyway.
-+               * In AMP systems, Linux may not be run on CPU0.
-+               */
-+              cpu = sparc_leon3_cpuid();
-+              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
-+              icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
-+              leon3_irqctrl_regs += icsel;
-+
-               LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
-               eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf;
-               if ( eirq != 0 ) {
diff --git a/target/linux/leon/patches/007-amp_timer.patch b/target/linux/leon/patches/007-amp_timer.patch
deleted file mode 100644 (file)
index d8d4363..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-From 1dffe06838c26b7c3fc99f9ddb7db78e378f6908 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 22 Sep 2010 13:21:13 +0200
-Subject: [PATCH] SPARC/LEON: added support for selecting Timer Core and Timer within core, useful for AMP systems.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/leon_kernel.c |   41 +++++++++++++++++++++++++-------------
- 1 files changed, 27 insertions(+), 14 deletions(-)
-
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -23,15 +23,16 @@
- #include "prom.h"
- #include "irq.h"
--struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address, initialized by amba_init() */
--struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address, initialized by amba_init() */
-+struct leon3_irqctrl_regs_map *leon3_irqctrl_regs = NULL; /* interrupt controller base address, initialized by amba_init() */
-+struct leon3_gptimer_regs_map *leon3_gptimer_regs = NULL; /* timer controller base address, initialized by amba_init() */
- struct amba_apb_device leon_percpu_timer_dev[16];
- int leondebug_irq_disable;
- int leon_debug_irqout;
- static int dummy_master_l10_counter;
--unsigned long leon3_gptimer_irq; /* interrupt controller irq number, initialized by amba_init() */
-+unsigned long leon3_gptimer_irq = 0; /* interrupt controller irq number, initialized by amba_init() */
-+unsigned long leon3_gptimer_idx = 0; /* Timer Index (starting at 0) with Timer Core */
- unsigned int sparc_leon_eirq;
- #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
-@@ -109,6 +110,7 @@ void __init leon_init_timers(irq_handler
-       struct property *pp;
-       int len;
-       int cpu, icsel;
-+      int ampopts;
-       leondebug_irq_disable = 0;
-       leon_debug_irqout = 0;
-@@ -124,24 +126,35 @@ void __init leon_init_timers(irq_handler
-       }
-       /* Find GPTIMER Timer Registers base address otherwise bail out. */
--      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_GPTIMER"))) {
-+      np = rootnp;
-+      while (np && (np=of_find_node_by_name(np, "GAISLER_GPTIMER"))) {
-+              ampopts = 0;
-+              pp = of_find_property(np, "ampopts", &len);
-+              if ( pp && ((ampopts = *(int *)pp->value) == 0) ) {
-+                      /* Skip this instance, resource already allocated by other OS */
-+                      continue;
-+              }
-+              /* Select Timer-Instance on Timer Core. Default is zero */
-+              leon3_gptimer_idx = ampopts & 0x7;
-+
-               pp = of_find_property(np, "reg", &len);
-               if (pp)
-                       leon3_gptimer_regs = *(struct leon3_gptimer_regs_map **)pp->value;
-               pp = of_find_property(np, "interrupts", &len);
-               if (pp)
-                       leon3_gptimer_irq = *(unsigned int *)pp->value;
-+              break;
-       }
-       if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0);
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld,
--                                    (((1000000 / HZ) - 1)));
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0);
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
-+                                    (((1000000 / 100) - 1)));
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
- #ifdef CONFIG_SMP
-               leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
--              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1;
-+              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1+leon3_gptimer_idx;
-               if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
-                     (1<<LEON3_GPTIMER_SEPIRQ))) {
-@@ -149,9 +162,9 @@ void __init leon_init_timers(irq_handler
-                       BUG();
-               }
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0);
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1)));
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000/100) - 1)));
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
- # endif
-               /* The IRQ controller may (if implemented) consist of multiple
-@@ -178,7 +191,7 @@ void __init leon_init_timers(irq_handler
-               BUG();
-       }
--      irq = request_irq(leon3_gptimer_irq,
-+      irq = request_irq(leon3_gptimer_irq+leon3_gptimer_idx,
-                         counter_fn,
-                         (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
-@@ -210,13 +223,13 @@ void __init leon_init_timers(irq_handler
- # endif
-       if (leon3_gptimer_regs) {
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl,
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
-                                     LEON3_GPTIMER_EN |
-                                     LEON3_GPTIMER_RL |
-                                     LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
- #ifdef CONFIG_SMP
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl,
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
-                                     LEON3_GPTIMER_EN |
-                                     LEON3_GPTIMER_RL |
-                                     LEON3_GPTIMER_LD |
diff --git a/target/linux/leon/patches/008-hz_specific_timer_init.patch b/target/linux/leon/patches/008-hz_specific_timer_init.patch
deleted file mode 100644 (file)
index aae3d29..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From e4d697dad4d43109f045a4f25cb1d706122045c0 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 22 Sep 2010 13:24:36 +0200
-Subject: [PATCH] SPARC/LEON: removed constant timer initialization as if HZ=100, now it reflects the value of HZ
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/leon_kernel.c |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -149,7 +149,7 @@ void __init leon_init_timers(irq_handler
-       if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
--                                    (((1000000 / 100) - 1)));
-+                                    (((1000000 / HZ) - 1)));
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
- #ifdef CONFIG_SMP
-@@ -163,7 +163,7 @@ void __init leon_init_timers(irq_handler
-               }
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000/100) - 1)));
-+              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000 / HZ) - 1)));
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
- # endif
diff --git a/target/linux/leon/patches/009-remove_second_timer.patch b/target/linux/leon/patches/009-remove_second_timer.patch
deleted file mode 100644 (file)
index b0b1346..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-From 300f3ee36c3019ee36f81befd91cd1b32544cefe Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 22 Sep 2010 15:39:05 +0200
-Subject: [PATCH] SPARC/LEON: Removed the need for two timers, per-cpu ticker is shared with system clock timer.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/include/asm/leon.h      |    2 +-
- arch/sparc/include/asm/leon_amba.h |    3 +-
- arch/sparc/kernel/entry.S          |    3 +-
- arch/sparc/kernel/leon_kernel.c    |   37 ++++++++---------------------------
- arch/sparc/kernel/leon_smp.c       |    8 ++++++-
- 5 files changed, 21 insertions(+), 32 deletions(-)
-
---- a/arch/sparc/include/asm/leon.h
-+++ b/arch/sparc/include/asm/leon.h
-@@ -240,7 +240,7 @@ static inline int sparc_leon3_cpuid(void
- #ifdef CONFIG_SMP
- # define LEON3_IRQ_RESCHEDULE         13
--# define LEON3_IRQ_TICKER             (leon_percpu_timer_dev[0].irq)
-+# define LEON3_IRQ_TICKER             (leon3_gptimer_irq + leon3_gptimer_idx)
- # define LEON3_IRQ_CROSS_CALL         15
- #endif
---- a/arch/sparc/include/asm/leon_amba.h
-+++ b/arch/sparc/include/asm/leon_amba.h
-@@ -182,11 +182,12 @@ void _amba_init(struct device_node *dp,
- extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs;
- extern struct leon3_gptimer_regs_map *leon3_gptimer_regs;
--extern struct amba_apb_device leon_percpu_timer_dev[16];
- extern int leondebug_irq_disable;
- extern int leon_debug_irqout;
- extern unsigned long leon3_gptimer_irq;
-+extern unsigned long leon3_gptimer_idx; /* Timer Index (starting at 0) with Timer Core */
- extern unsigned int sparc_leon_eirq;
-+extern unsigned long leon3_cpu_idx;
- #endif /* __ASSEMBLY__ */
---- a/arch/sparc/kernel/entry.S
-+++ b/arch/sparc/kernel/entry.S
-@@ -411,8 +411,9 @@ smpleon_ticker:
-       WRITE_PAUSE
-       wr      %g2, PSR_ET, %psr
-       WRITE_PAUSE
-+      mov     %l7, %o0                ! irq level
-       call    leon_percpu_timer_interrupt
--       add    %sp, STACKFRAME_SZ, %o0
-+       add    %sp, STACKFRAME_SZ, %o1 ! pt_regs
-       wr      %l0, PSR_ET, %psr
-       WRITE_PAUSE
-       RESTORE_ALL
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -25,7 +25,6 @@
- struct leon3_irqctrl_regs_map *leon3_irqctrl_regs = NULL; /* interrupt controller base address, initialized by amba_init() */
- struct leon3_gptimer_regs_map *leon3_gptimer_regs = NULL; /* timer controller base address, initialized by amba_init() */
--struct amba_apb_device leon_percpu_timer_dev[16];
- int leondebug_irq_disable;
- int leon_debug_irqout;
-@@ -34,6 +33,7 @@ static int dummy_master_l10_counter;
- unsigned long leon3_gptimer_irq = 0; /* interrupt controller irq number, initialized by amba_init() */
- unsigned long leon3_gptimer_idx = 0; /* Timer Index (starting at 0) with Timer Core */
- unsigned int sparc_leon_eirq;
-+unsigned long leon3_cpu_idx = 0; /* Boot CPU Index */
- #define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
- /* Return the IRQ of the pending IRQ on the extended IRQ controller */
-@@ -109,13 +109,14 @@ void __init leon_init_timers(irq_handler
-       struct device_node *rootnp, *np;
-       struct property *pp;
-       int len;
--      int cpu, icsel;
-+      int icsel;
-       int ampopts;
-       leondebug_irq_disable = 0;
-       leon_debug_irqout = 0;
-       master_l10_counter = (unsigned int *)&dummy_master_l10_counter;
-       dummy_master_l10_counter = 0;
-+      leon3_cpu_idx = sparc_leon3_cpuid();
-       /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
-       rootnp = of_find_node_by_path("/ambapp0");
-@@ -152,21 +153,11 @@ void __init leon_init_timers(irq_handler
-                                     (((1000000 / HZ) - 1)));
-               LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
--#ifdef CONFIG_SMP
--              leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
--              leon_percpu_timer_dev[0].irq = leon3_gptimer_irq+1+leon3_gptimer_idx;
--
-               if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
-                     (1<<LEON3_GPTIMER_SEPIRQ))) {
--                      prom_printf("irq timer not configured with separate irqs\n");
--                      BUG();
-+                      prom_printf("LEON-SMP: GPTIMER use shared irqs, using other timers will fail.\n");
-               }
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld, (((1000000 / HZ) - 1)));
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
--# endif
--
-               /* The IRQ controller may (if implemented) consist of multiple
-                * IRQ controllers, each mapped on a 4Kb boundary.
-                * Each CPU may be routed to different IRQCTRLs, however
-@@ -175,9 +166,8 @@ void __init leon_init_timers(irq_handler
-                * accessed anyway.
-                * In AMP systems, Linux may not be run on CPU0.
-                */
--              cpu = sparc_leon3_cpuid();
--              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
--              icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
-+              icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[leon3_cpu_idx/8]);
-+              icsel = (icsel >> ((7 - (leon3_cpu_idx & 0x7)) * 4)) & 0xf;
-               leon3_irqctrl_regs += icsel;
-               LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
-@@ -204,7 +194,8 @@ void __init leon_init_timers(irq_handler
- # ifdef CONFIG_SMP
-       {
-               unsigned long flags;
--              struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)];
-+              struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + 
-+                                              (leon3_gptimer_irq + leon3_gptimer_idx - 1)];
-               /* For SMP we use the level 14 ticker, however the bootup code
-                * has copied the firmwares level 14 vector into boot cpu's
-@@ -222,21 +213,11 @@ void __init leon_init_timers(irq_handler
-       }
- # endif
--      if (leon3_gptimer_regs) {
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
-+      LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
-                                     LEON3_GPTIMER_EN |
-                                     LEON3_GPTIMER_RL |
-                                     LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
--#ifdef CONFIG_SMP
--              LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
--                                    LEON3_GPTIMER_EN |
--                                    LEON3_GPTIMER_RL |
--                                    LEON3_GPTIMER_LD |
--                                    LEON3_GPTIMER_IRQEN);
--#endif
--
--      }
- }
- void leon_clear_clock_irq(void)
---- a/arch/sparc/kernel/leon_smp.c
-+++ b/arch/sparc/kernel/leon_smp.c
-@@ -52,6 +52,7 @@ extern volatile unsigned long cpu_callin
- extern unsigned char boot_cpu_id;
- extern cpumask_t smp_commenced_mask;
- void __init leon_configure_cache_smp(void);
-+extern void handler_irq(int irq, struct pt_regs * regs);
- static inline unsigned long do_swap(volatile unsigned long *ptr,
-                                   unsigned long val)
-@@ -385,7 +386,7 @@ void leon_cross_call_irq(void)
-       ccall_info.processors_out[i] = 1;
- }
--void leon_percpu_timer_interrupt(struct pt_regs *regs)
-+void leon_percpu_timer_interrupt(int irq, struct pt_regs *regs)
- {
-       struct pt_regs *old_regs;
-       int cpu = smp_processor_id();
-@@ -406,6 +407,11 @@ void leon_percpu_timer_interrupt(struct
-               prof_counter(cpu) = prof_multiplier(cpu);
-       }
-       set_irq_regs(old_regs);
-+
-+      if ( cpu == leon3_cpu_idx ) {
-+              /* Ticker Clock is shared with the System Clock */
-+              handler_irq(irq, regs);
-+      }
- }
- static void __init smp_setup_percpu_timer(void)
diff --git a/target/linux/leon/patches/010-apbuart_ampopts.patch b/target/linux/leon/patches/010-apbuart_ampopts.patch
deleted file mode 100644 (file)
index f47c54a..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From 8129fa5437f3fe5f95bac180a43cd5a856cebdf3 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 20 Oct 2010 17:00:41 +0200
-Subject: [PATCH] Added support for ampopts in APBUART driver. Used in AMP systems.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/serial/apbuart.c |    5 ++++-
- 1 files changed, 4 insertions(+), 1 deletions(-)
-
---- a/drivers/serial/apbuart.c
-+++ b/drivers/serial/apbuart.c
-@@ -26,6 +26,7 @@
- #include <linux/of.h>
- #include <linux/of_device.h>
- #include <linux/of_platform.h>
-+#include <linux/of_irq.h>
- #include <linux/platform_device.h>
- #include <linux/io.h>
- #include <linux/serial_core.h>
-@@ -573,7 +574,6 @@ static int __devinit apbuart_probe(struc
-       printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
-              (unsigned long long) port->mapbase, port->irq);
-       return 0;
--
- }
- static struct of_device_id __initdata apbuart_match[] = {
-@@ -620,9 +620,12 @@ static void grlib_apbuart_configure(void
-               int *vendor = (int *) of_get_property(np, "vendor", NULL);
-               int *device = (int *) of_get_property(np, "device", NULL);
-               int *irqs = (int *) of_get_property(np, "interrupts", NULL);
-+              int *ampopts = (int *) of_get_property(np, "ampopts", NULL);
-               regs = (struct amba_prom_registers *)
-                   of_get_property(np, "reg", NULL);
-+              if (ampopts && (*ampopts == 0))
-+                      continue; /* Ignore if used by another OS instance */
-               if (vendor)
-                       v = *vendor;
-               if (device)
diff --git a/target/linux/leon/patches/011-greth_fix_unhandled_irq.patch b/target/linux/leon/patches/011-greth_fix_unhandled_irq.patch
deleted file mode 100644 (file)
index 55e6185..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From 3d7788e8f5ae3d44e48f9b7476528acf3d9c8b32 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 20 Oct 2010 17:07:12 +0200
-Subject: [PATCH] GRETH: Fixed potential future problem where unhandled IRQ is cleared.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -584,7 +584,7 @@ static irqreturn_t greth_interrupt(int i
-       if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
-               /* Clear interrupt status */
--              GRETH_REGORIN(greth->regs->status,
-+              GRETH_REGSAVE(greth->regs->status,
-                             status & (GRETH_INT_RX | GRETH_INT_TX));
-               retval = IRQ_HANDLED;
diff --git a/target/linux/leon/patches/012-greth_amba_vendor_device.patch b/target/linux/leon/patches/012-greth_amba_vendor_device.patch
deleted file mode 100644 (file)
index 78b526c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From ff5f2ee8b37f2278dd86946761313c3664c51836 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Thu, 21 Oct 2010 14:34:48 +0200
-Subject: [PATCH] GRETH: added raw AMBA vendor/device number to match against.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    3 +++
- 1 files changed, 3 insertions(+), 0 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -1600,6 +1600,9 @@ static struct of_device_id greth_of_matc
-       {
-        .name = "GAISLER_ETHMAC",
-        },
-+      {
-+       .name = "01_01d",
-+       },
-       {},
- };
diff --git a/target/linux/leon/patches/013-apbuart_amba_vendor_device.patch b/target/linux/leon/patches/013-apbuart_amba_vendor_device.patch
deleted file mode 100644 (file)
index 7675f10..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-From 1c14b8995c1b8212180b5009dc04ac222a449ecb Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Thu, 21 Oct 2010 14:35:09 +0200
-Subject: [PATCH] APBUART: added raw AMBA vendor/device number to match against.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/serial/apbuart.c |    3 +++
- 1 files changed, 3 insertions(+), 0 deletions(-)
-
---- a/drivers/serial/apbuart.c
-+++ b/drivers/serial/apbuart.c
-@@ -580,6 +580,9 @@ static struct of_device_id __initdata ap
-       {
-        .name = "GAISLER_APBUART",
-        },
-+      {
-+       .name = "01_00c",
-+       },
-       {},
- };
diff --git a/target/linux/leon/patches/014-timer_irqctrl_amba_vendor_device.patch b/target/linux/leon/patches/014-timer_irqctrl_amba_vendor_device.patch
deleted file mode 100644 (file)
index 58f7657..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-From 12782c44d0c687b5b0400a8224a9b1bf9eb9a428 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Tue, 26 Oct 2010 09:59:05 +0200
-Subject: [PATCH] TIMER,IRQCTRL: added raw AMBA vendor/device number to match against.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/kernel/leon_kernel.c |    6 ++++--
- 1 files changed, 4 insertions(+), 2 deletions(-)
-
---- a/arch/sparc/kernel/leon_kernel.c
-+++ b/arch/sparc/kernel/leon_kernel.c
-@@ -120,7 +120,8 @@ void __init leon_init_timers(irq_handler
-       /* Find IRQMP IRQ Controller Registers base address otherwise bail out. */
-       rootnp = of_find_node_by_path("/ambapp0");
--      if (rootnp && (np=of_find_node_by_name(rootnp, "GAISLER_IRQMP"))) {
-+      if (rootnp && ((np=of_find_node_by_name(rootnp, "GAISLER_IRQMP")) ||
-+                      (np=of_find_node_by_name(rootnp, "01_00d")))) {
-               pp = of_find_property(np, "reg", &len);
-               if (pp)
-                       leon3_irqctrl_regs = *(struct leon3_irqctrl_regs_map **)pp->value;
-@@ -128,7 +129,8 @@ void __init leon_init_timers(irq_handler
-       /* Find GPTIMER Timer Registers base address otherwise bail out. */
-       np = rootnp;
--      while (np && (np=of_find_node_by_name(np, "GAISLER_GPTIMER"))) {
-+      while (np && ((np=of_find_node_by_name(np, "GAISLER_GPTIMER")) ||
-+                      (np=of_find_node_by_name(np, "01_011")))) {
-               ampopts = 0;
-               pp = of_find_property(np, "ampopts", &len);
-               if ( pp && ((ampopts = *(int *)pp->value) == 0) ) {
diff --git a/target/linux/leon/patches/015-dma_ops.patch b/target/linux/leon/patches/015-dma_ops.patch
deleted file mode 100644 (file)
index 7f488e0..0000000
+++ /dev/null
@@ -1,296 +0,0 @@
-From c6d8f92cfd7f4f19eb3b16545b3b68c561978fe8 Mon Sep 17 00:00:00 2001
-From: Kristoffer Glembo <kristoffer@gaisler.com>
-Date: Mon, 7 Jun 2010 14:00:30 +0200
-Subject: [PATCH] sparc32: Added LEON dma_ops.
-
-Added leon3_dma_ops and mmu_inval_dma_area.
----
- arch/sparc/kernel/ioport.c |  139 +++++++++++++++++++++++++++++++------------
- 1 files changed, 100 insertions(+), 39 deletions(-)
-
---- a/arch/sparc/kernel/ioport.c
-+++ b/arch/sparc/kernel/ioport.c
-@@ -50,10 +50,15 @@
- #include <asm/io-unit.h>
- #include <asm/leon.h>
--#ifdef CONFIG_SPARC_LEON
--#define mmu_inval_dma_area(p, l) leon_flush_dcache_all()
--#else
-+#ifndef CONFIG_SPARC_LEON
- #define mmu_inval_dma_area(p, l)      /* Anton pulled it out for 2.4.0-xx */
-+#else
-+static inline void mmu_inval_dma_area(unsigned long va, unsigned long len)
-+{
-+      if (!sparc_leon3_snooping_enabled()) {
-+              leon_flush_dcache_all();
-+      }
-+}
- #endif
- static struct resource *_sparc_find_resource(struct resource *r,
-@@ -254,7 +259,7 @@ static void *sbus_alloc_coherent(struct
-                                dma_addr_t *dma_addrp, gfp_t gfp)
- {
-       struct platform_device *op = to_platform_device(dev);
--      unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
-+      unsigned long len_total = PAGE_ALIGN(len);
-       unsigned long va;
-       struct resource *res;
-       int order;
-@@ -287,15 +292,19 @@ static void *sbus_alloc_coherent(struct
-        * XXX That's where sdev would be used. Currently we load
-        * all iommu tables with the same translations.
-        */
--      if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
--              goto err_noiommu;
--
--      res->name = op->dev.of_node->name;
-+#ifdef CONFIG_SPARC_LEON
-+      sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);   
-+      *dma_addrp = virt_to_phys(va);
-+#else
-+      if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0) {
-+              release_resource(res);
-+              goto err_nova;
-+      }
-+#endif
-+      res->name = op->node->name;
-       return (void *)(unsigned long)res->start;
--err_noiommu:
--      release_resource(res);
- err_nova:
-       free_pages(va, order);
- err_nomem:
-@@ -321,7 +330,7 @@ static void sbus_free_coherent(struct de
-               return;
-       }
--      n = (n + PAGE_SIZE-1) & PAGE_MASK;
-+      n = PAGE_ALIGN(n);
-       if ((res->end-res->start)+1 != n) {
-               printk("sbus_free_consistent: region 0x%lx asked 0x%zx\n",
-                   (long)((res->end-res->start)+1), n);
-@@ -333,7 +342,12 @@ static void sbus_free_coherent(struct de
-       /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
-       pgv = virt_to_page(p);
--      mmu_unmap_dma_area(dev, ba, n);
-+
-+#ifdef CONFIG_SPARC_LEON
-+      sparc_unmapiorange((unsigned long)p, n);
-+#else
-+      mmu_unmap_dma_area(dev, ba, n);
-+#endif
-       __free_pages(pgv, get_order(n));
- }
-@@ -408,9 +422,6 @@ struct dma_map_ops sbus_dma_ops = {
-       .sync_sg_for_device     = sbus_sync_sg_for_device,
- };
--struct dma_map_ops *dma_ops = &sbus_dma_ops;
--EXPORT_SYMBOL(dma_ops);
--
- static int __init sparc_register_ioport(void)
- {
-       register_proc_sparc_ioport();
-@@ -422,7 +433,7 @@ arch_initcall(sparc_register_ioport);
- #endif /* CONFIG_SBUS */
--#ifdef CONFIG_PCI
-+#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON)
- /* Allocate and map kernel buffer using consistent mode DMA for a device.
-  * hwdev should be valid struct pci_dev pointer for PCI devices.
-@@ -430,7 +441,7 @@ arch_initcall(sparc_register_ioport);
- static void *pci32_alloc_coherent(struct device *dev, size_t len,
-                                 dma_addr_t *pba, gfp_t gfp)
- {
--      unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
-+      unsigned long len_total = PAGE_ALIGN(len);
-       unsigned long va;
-       struct resource *res;
-       int order;
-@@ -463,10 +474,6 @@ static void *pci32_alloc_coherent(struct
-               return NULL;
-       }
-       mmu_inval_dma_area(va, len_total);
--#if 0
--/* P3 */ printk("pci_alloc_consistent: kva %lx uncva %lx phys %lx size %lx\n",
--  (long)va, (long)res->start, (long)virt_to_phys(va), len_total);
--#endif
-       sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
-       *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
-@@ -498,7 +505,7 @@ static void pci32_free_coherent(struct d
-               return;
-       }
--      n = (n + PAGE_SIZE-1) & PAGE_MASK;
-+      n = PAGE_ALIGN(n);
-       if ((res->end-res->start)+1 != n) {
-               printk("pci_free_consistent: region 0x%lx asked 0x%lx\n",
-                   (long)((res->end-res->start)+1), (long)n);
-@@ -515,6 +522,14 @@ static void pci32_free_coherent(struct d
-       free_pages(pgp, get_order(n));
- }
-+static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
-+                           enum dma_data_direction dir, struct dma_attrs *attrs)
-+{
-+      if (dir != PCI_DMA_TODEVICE) {
-+              mmu_inval_dma_area((unsigned long)phys_to_virt(ba), PAGE_ALIGN(size));
-+      }
-+}
-+
- /*
-  * Same as pci_map_single, but with pages.
-  */
-@@ -551,8 +566,7 @@ static int pci32_map_sg(struct device *d
-       /* IIep is write-through, not flushing. */
-       for_each_sg(sgl, sg, nents, n) {
--              BUG_ON(page_address(sg_page(sg)) == NULL);
--              sg->dma_address = virt_to_phys(sg_virt(sg));
-+              sg->dma_address = sg_phys(sg);
-               sg->dma_length = sg->length;
-       }
-       return nents;
-@@ -571,10 +585,7 @@ static void pci32_unmap_sg(struct device
-       if (dir != PCI_DMA_TODEVICE) {
-               for_each_sg(sgl, sg, nents, n) {
--                      BUG_ON(page_address(sg_page(sg)) == NULL);
--                      mmu_inval_dma_area(
--                          (unsigned long) page_address(sg_page(sg)),
--                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-+                      mmu_inval_dma_area((unsigned long)sg_virt(sg), PAGE_ALIGN(sg->length));
-               }
-       }
- }
-@@ -594,7 +605,7 @@ static void pci32_sync_single_for_cpu(st
- {
-       if (dir != PCI_DMA_TODEVICE) {
-               mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
--                  (size + PAGE_SIZE-1) & PAGE_MASK);
-+                                 PAGE_ALIGN(size));
-       }
- }
-@@ -621,10 +632,7 @@ static void pci32_sync_sg_for_cpu(struct
-       if (dir != PCI_DMA_TODEVICE) {
-               for_each_sg(sgl, sg, nents, n) {
--                      BUG_ON(page_address(sg_page(sg)) == NULL);
--                      mmu_inval_dma_area(
--                          (unsigned long) page_address(sg_page(sg)),
--                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-+                      mmu_inval_dma_area((unsigned long)sg_virt(sg), PAGE_ALIGN(sg->length));
-               }
-       }
- }
-@@ -637,18 +645,38 @@ static void pci32_sync_sg_for_device(str
-       if (dir != PCI_DMA_TODEVICE) {
-               for_each_sg(sgl, sg, nents, n) {
--                      BUG_ON(page_address(sg_page(sg)) == NULL);
--                      mmu_inval_dma_area(
--                          (unsigned long) page_address(sg_page(sg)),
--                          (sg->length + PAGE_SIZE-1) & PAGE_MASK);
-+                      mmu_inval_dma_area((unsigned long)sg_virt(sg),  PAGE_ALIGN(sg->length));
-               }
-       }
- }
-+/* LEON3 unmapping functions 
-+ * 
-+ * We can only invalidate the whole cache so unmap_page and unmap_sg do the same thing
-+ */
-+static void leon3_unmap_page(struct device *dev, dma_addr_t ba, size_t size,
-+                           enum dma_data_direction dir, struct dma_attrs *attrs)
-+{
-+      if (dir != PCI_DMA_TODEVICE) {
-+              mmu_inval_dma_area(0, 0);
-+      }
-+}
-+
-+static void leon3_unmap_sg(struct device *dev, struct scatterlist *sgl,
-+                         int nents, enum dma_data_direction dir,
-+                         struct dma_attrs *attrs)
-+{
-+
-+      if (dir != PCI_DMA_TODEVICE) {
-+              mmu_inval_dma_area(0, 0);
-+      }
-+}
-+
- struct dma_map_ops pci32_dma_ops = {
-       .alloc_coherent         = pci32_alloc_coherent,
-       .free_coherent          = pci32_free_coherent,
-       .map_page               = pci32_map_page,
-+      .unmap_page             = pci32_unmap_page,
-       .map_sg                 = pci32_map_sg,
-       .unmap_sg               = pci32_unmap_sg,
-       .sync_single_for_cpu    = pci32_sync_single_for_cpu,
-@@ -658,7 +686,30 @@ struct dma_map_ops pci32_dma_ops = {
- };
- EXPORT_SYMBOL(pci32_dma_ops);
--#endif /* CONFIG_PCI */
-+struct dma_map_ops leon3_dma_ops = {
-+      .alloc_coherent         = sbus_alloc_coherent,
-+      .free_coherent          = sbus_free_coherent,
-+      .map_page               = pci32_map_page,
-+      .unmap_page             = leon3_unmap_page,
-+      .map_sg                 = pci32_map_sg,
-+      .unmap_sg               = leon3_unmap_sg,
-+      .sync_single_for_cpu    = pci32_sync_single_for_cpu,
-+      .sync_single_for_device = pci32_sync_single_for_device,
-+      .sync_sg_for_cpu        = pci32_sync_sg_for_cpu,
-+      .sync_sg_for_device     = pci32_sync_sg_for_device,
-+};
-+
-+#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */
-+
-+#ifdef CONFIG_SPARC_LEON
-+struct dma_map_ops *dma_ops = &leon3_dma_ops;
-+#else
-+struct dma_map_ops *dma_ops = &sbus_dma_ops;
-+#endif
-+
-+#ifdef CONFIG_SBUS
-+EXPORT_SYMBOL(dma_ops);
-+#endif
- /*
-  * Return whether the given PCI device DMA address mask can be
-@@ -676,6 +727,16 @@ int dma_supported(struct device *dev, u6
- }
- EXPORT_SYMBOL(dma_supported);
-+int dma_set_mask(struct device *dev, u64 dma_mask)
-+{
-+#ifdef CONFIG_PCI
-+      if (dev->bus == &pci_bus_type)
-+              return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-+#endif
-+      return -EOPNOTSUPP;
-+}
-+EXPORT_SYMBOL(dma_set_mask);
-+
- #ifdef CONFIG_PROC_FS
- static int sparc_io_proc_show(struct seq_file *m, void *v)
-@@ -717,7 +778,7 @@ static const struct file_operations spar
- static struct resource *_sparc_find_resource(struct resource *root,
-                                            unsigned long hit)
- {
--        struct resource *tmp;
-+      struct resource *tmp;
-       for (tmp = root->child; tmp != 0; tmp = tmp->sibling) {
-               if (tmp->start <= hit && tmp->end >= hit)
diff --git a/target/linux/leon/patches/016-ioport_update.patch b/target/linux/leon/patches/016-ioport_update.patch
deleted file mode 100644 (file)
index 130b36e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From 36cad96a50eb877d0c5cb3d8d93c1807ad9c774c Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 09:37:23 +0100
-Subject: [PATCH] Fix kristoffers ioport.c patch for more recent kernel.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- arch/sparc/include/asm/dma-mapping.h |   13 +------------
- arch/sparc/kernel/ioport.c           |    3 ++-
- 2 files changed, 3 insertions(+), 13 deletions(-)
-
---- a/arch/sparc/include/asm/dma-mapping.h
-+++ b/arch/sparc/include/asm/dma-mapping.h
-@@ -51,17 +51,6 @@ static inline int dma_mapping_error(stru
-       return (dma_addr == DMA_ERROR_CODE);
- }
--static inline int dma_set_mask(struct device *dev, u64 mask)
--{
--#ifdef CONFIG_PCI
--      if (dev->bus == &pci_bus_type) {
--              if (!dev->dma_mask || !dma_supported(dev, mask))
--                      return -EINVAL;
--              *dev->dma_mask = mask;
--              return 0;
--      }
--#endif
--      return -EINVAL;
--}
-+extern int dma_set_mask(struct device *dev, u64 dma_mask);
- #endif
---- a/arch/sparc/kernel/ioport.c
-+++ b/arch/sparc/kernel/ioport.c
-@@ -301,7 +301,7 @@ static void *sbus_alloc_coherent(struct
-               goto err_nova;
-       }
- #endif
--      res->name = op->node->name;
-+      res->name = op->dev.of_node->name;
-       return (void *)(unsigned long)res->start;
-@@ -737,6 +737,7 @@ int dma_set_mask(struct device *dev, u64
- }
- EXPORT_SYMBOL(dma_set_mask);
-+
- #ifdef CONFIG_PROC_FS
- static int sparc_io_proc_show(struct seq_file *m, void *v)
diff --git a/target/linux/leon/patches/017-greth_no_gbit.patch b/target/linux/leon/patches/017-greth_no_gbit.patch
deleted file mode 100644 (file)
index 5e3ee3d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-From 2e864d18c31d4e0255269f9e9cfccc09512676c6 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 16:51:38 +0100
-Subject: [PATCH] GRETH: added greth_no_gbit option
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |   15 +++++++++++++--
- drivers/net/greth.h |    1 +
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -66,6 +66,10 @@ static int greth_edcl = 1;
- module_param(greth_edcl, int, 0);
- MODULE_PARM_DESC(greth_edcl, "GRETH EDCL usage indicator. Set to 1 if EDCL is used.");
-+static int no_gbit = 0;
-+module_param(no_gbit, int, S_IRUGO);
-+MODULE_PARM_DESC(no_gbit, "GRETH report GBit not supported by MAC enable. Only affects GRETH GBit MAC, default 0 (off).");
-+
- static int greth_open(struct net_device *dev);
- static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
-          struct net_device *dev);
-@@ -1284,7 +1288,7 @@ static int greth_mdio_probe(struct net_d
-       }
-       ret = phy_connect_direct(dev, phy, &greth_link_change,
--                      0, greth->gbit_mac ?
-+                      0, greth->gbit_phy_support ?
-                       PHY_INTERFACE_MODE_GMII :
-                       PHY_INTERFACE_MODE_MII);
-       if (ret) {
-@@ -1293,7 +1297,7 @@ static int greth_mdio_probe(struct net_d
-               return ret;
-       }
--      if (greth->gbit_mac)
-+      if (greth->gbit_phy_support)
-               phy->supported &= PHY_GBIT_FEATURES;
-       else
-               phy->supported &= PHY_BASIC_FEATURES;
-@@ -1441,6 +1445,13 @@ static int __devinit greth_of_probe(stru
-       tmp = GRETH_REGLOAD(regs->control);
-       greth->gbit_mac = (tmp >> 27) & 1;
-+      /* Let user skip GBit link mode by telling MDIO layer that MAC does
-+       * not support GBIT (for debug) */
-+      if (greth->gbit_mac && !no_gbit)
-+              greth->gbit_phy_support = 1;
-+      else
-+              greth->gbit_phy_support = 0;
-+
-       /* Check for multicast capability */
-       greth->multicast = (tmp >> 25) & 1;
---- a/drivers/net/greth.h
-+++ b/drivers/net/greth.h
-@@ -138,6 +138,7 @@ struct greth_private {
-       u8 gbit_mac;
-       u8 mdio_int_en;
-       u8 edcl;
-+      u8 gbit_phy_support;
- };
- #endif
diff --git a/target/linux/leon/patches/018-greth_compat_mode.patch b/target/linux/leon/patches/018-greth_compat_mode.patch
deleted file mode 100644 (file)
index 4afe89e..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-From a498d7076ee0f82ec3f508293a9cf1ccba15829e Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 16:52:19 +0100
-Subject: [PATCH] GRETH: added greth_compat_mode module parameter
-
-The greth_compat_mode option can be used to set a GRETH GBit capable MAC
-in operate as if the GRETH 10/100 device was found. The GRETH GBit supports
-TCP/UDP checksum offloading, unaligned frame buffers, scatter gather etc.
-Enabling this mode allows the developer to test the GRETH 10/100 device
-without all features mentioned above on a GBit MAC capable of the above.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    9 +++++++++
- 1 files changed, 9 insertions(+), 0 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -70,6 +70,11 @@ static int no_gbit = 0;
- module_param(no_gbit, int, S_IRUGO);
- MODULE_PARM_DESC(no_gbit, "GRETH report GBit not supported by MAC enable. Only affects GRETH GBit MAC, default 0 (off).");
-+/* Use this option to enable GRETH 10/100 code on GRETH_GBIT hardware (debug legacy code option) */
-+static int compat_mode = 0;
-+module_param(compat_mode, int, S_IRUGO);
-+MODULE_PARM_DESC(compat_mode, "GRETH 10/100 legacy mode enable. Only affects GRETH GBit MAC, default 0 (off).");
-+
- static int greth_open(struct net_device *dev);
- static netdev_tx_t greth_start_xmit(struct sk_buff *skb,
-          struct net_device *dev);
-@@ -1452,6 +1457,10 @@ static int __devinit greth_of_probe(stru
-       else
-               greth->gbit_phy_support = 0;
-+      /* Force GBit MAC in legacy 10/100 mode (no offloading etc.) */
-+      if (compat_mode == 1)
-+              greth->gbit_mac = 0;
-+
-       /* Check for multicast capability */
-       greth->multicast = (tmp >> 25) & 1;
diff --git a/target/linux/leon/patches/019-greth_fix_open_close.patch b/target/linux/leon/patches/019-greth_fix_open_close.patch
deleted file mode 100644 (file)
index fffb391..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From 6216bc809c5bdd586b14d096fbaf6dc25574b928 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 09:59:14 +0100
-Subject: [PATCH] GRETH: fix opening/closing
-
-When NAPI is disabled there is no point in having IRQs enabled, TX/RX
-should be off before clearing the TX/RX descriptor rings.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -365,6 +365,8 @@ static int greth_open(struct net_device
-               dev_dbg(&dev->dev, " starting queue\n");
-       netif_start_queue(dev);
-+      GRETH_REGSAVE(greth->regs->status, 0xFF);
-+
-       napi_enable(&greth->napi);
-       greth_enable_irqs(greth);
-@@ -380,7 +382,9 @@ static int greth_close(struct net_device
-       napi_disable(&greth->napi);
-+      greth_disable_irqs(greth);
-       greth_disable_tx(greth);
-+      greth_disable_rx(greth);
-       netif_stop_queue(dev);
diff --git a/target/linux/leon/patches/020-greth_optimize_gbit_tx_descriptor_handling.patch b/target/linux/leon/patches/020-greth_optimize_gbit_tx_descriptor_handling.patch
deleted file mode 100644 (file)
index 3a14eb7..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-From 544631281bed5cc37b8f2d3a99f44c9d4b97f9a8 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 10:07:12 +0100
-Subject: [PATCH] GRETH: GBit transmit descriptor handling optimization
-
-It is safe to enable all fragments before enabling the first descriptor,
-this way all descriptors don't have to be processed twice, added extra
-memory barrier.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |   19 ++++++++++---------
- 1 files changed, 10 insertions(+), 9 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -512,7 +512,7 @@ greth_start_xmit_gbit(struct sk_buff *sk
-               greth->tx_skbuff[curr_tx] = NULL;
-               bdp = greth->tx_bd_base + curr_tx;
--              status = GRETH_TXBD_CSALL;
-+              status = GRETH_TXBD_CSALL | GRETH_BD_EN;
-               status |= frag->size & GRETH_BD_LEN;
-               /* Wrap around descriptor ring */
-@@ -549,26 +549,27 @@ greth_start_xmit_gbit(struct sk_buff *sk
-       wmb();
--      /* Enable the descriptors that we configured ...  */
--      for (i = 0; i < nr_frags + 1; i++) {
--              bdp = greth->tx_bd_base + greth->tx_next;
--              greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
--              greth->tx_next = NEXT_TX(greth->tx_next);
--              greth->tx_free--;
--      }
-+      /* Enable the descriptor chain by enabling the first descriptor */
-+      bdp = greth->tx_bd_base + greth->tx_next;
-+      greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
-+      greth->tx_next = curr_tx;
-+      greth->tx_free -= nr_frags + 1;
-+
-+      wmb();
-       greth_enable_tx(greth);
-       return NETDEV_TX_OK;
- frag_map_error:
--      /* Unmap SKB mappings that succeeded */
-+      /* Unmap SKB mappings that succeeded and disable descriptor */
-       for (i = 0; greth->tx_next + i != curr_tx; i++) {
-               bdp = greth->tx_bd_base + greth->tx_next + i;
-               dma_unmap_single(greth->dev,
-                                greth_read_bd(&bdp->addr),
-                                greth_read_bd(&bdp->stat) & GRETH_BD_LEN,
-                                DMA_TO_DEVICE);
-+              greth_write_bd(&bdp->stat, 0);
-       }
- map_error:
-       if (net_ratelimit())
diff --git a/target/linux/leon/patches/021-greth_fix_memory_leak.patch b/target/linux/leon/patches/021-greth_fix_memory_leak.patch
deleted file mode 100644 (file)
index 1d05af1..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From 54789a03adf9c924d0cf7b890323c9c1ca7ab042 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 10:26:09 +0100
-Subject: [PATCH] GRETH: fixed skb buffer memory leak on frame errors
-
-A new SKB buffer should not be allocated when the old SKB is reused.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |   17 +++++++++++------
- 1 files changed, 11 insertions(+), 6 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -879,10 +879,8 @@ static int greth_rx_gbit(struct net_devi
-                       }
-               }
--              /* Allocate new skb to replace current */
--              newskb = netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN);
--
--              if (!bad && newskb) {
-+              /* Allocate new skb to replace current, not needed if the current skb can be reused */
-+              if (!bad && (newskb=netdev_alloc_skb(dev, MAX_FRAME_SIZE + NET_IP_ALIGN))) {
-                       skb_reserve(newskb, NET_IP_ALIGN);
-                       dma_addr = dma_map_single(greth->dev,
-@@ -919,12 +917,19 @@ static int greth_rx_gbit(struct net_devi
-                               if (net_ratelimit())
-                                       dev_warn(greth->dev, "Could not create DMA mapping, dropping packet\n");
-                               dev_kfree_skb(newskb);
--                              dev->stats.rx_dropped++;
-+                              dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */
-                       }
-+              } else if ( bad ) {
-+                      /* Bad Frame transfer, the skb is reused */
-+                      dev->stats.rx_dropped++;
-               } else {
-+                      /* Failed Allocating a new skb. This is rather stupid but the current "filled" 
-+                       * skb is reused, as if transfer failure. One could argue that RX descriptor table
-+                       * handling should be divided into cleaning and filling as the TX part of the driver
-+                       */
-                       if (net_ratelimit())
-                               dev_warn(greth->dev, "Could not allocate SKB, dropping packet\n");
--                      dev->stats.rx_dropped++;
-+                      dev->stats.rx_dropped++; /* reusing current skb, so it is a drop */
-               }
-               status = GRETH_BD_EN | GRETH_BD_IE;
diff --git a/target/linux/leon/patches/022-greth_avoid_bad_speed_duplex.patch b/target/linux/leon/patches/022-greth_avoid_bad_speed_duplex.patch
deleted file mode 100644 (file)
index e825364..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-From c2e963057ca5635d6e5387623c3ad0c0b3123754 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 10:28:37 +0100
-Subject: [PATCH] GRETH: avoid writing bad speed/duplex when setting transfer mode
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |   19 ++++++++-----------
- 1 files changed, 8 insertions(+), 11 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -1236,29 +1236,26 @@ static void greth_link_change(struct net
-       struct greth_private *greth = netdev_priv(dev);
-       struct phy_device *phydev = greth->phy;
-       unsigned long flags;
--
-       int status_change = 0;
-+      u32 ctrl;
-       spin_lock_irqsave(&greth->devlock, flags);
-       if (phydev->link) {
-               if ((greth->speed != phydev->speed) || (greth->duplex != phydev->duplex)) {
--
--                      GRETH_REGANDIN(greth->regs->control,
--                                     ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB));
-+                      ctrl = GRETH_REGLOAD(greth->regs->control) & 
-+                             ~(GRETH_CTRL_FD | GRETH_CTRL_SP | GRETH_CTRL_GB);
-                       if (phydev->duplex)
--                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_FD);
--
--                      if (phydev->speed == SPEED_100) {
--
--                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_SP);
--                      }
-+                              ctrl |= GRETH_CTRL_FD;
-+                      if (phydev->speed == SPEED_100)
-+                              ctrl |= GRETH_CTRL_SP;
-                       else if (phydev->speed == SPEED_1000)
--                              GRETH_REGORIN(greth->regs->control, GRETH_CTRL_GB);
-+                              ctrl |= GRETH_CTRL_GB;
-+                      GRETH_REGSAVE(greth->regs->control, ctrl);
-                       greth->speed = phydev->speed;
-                       greth->duplex = phydev->duplex;
-                       status_change = 1;
diff --git a/target/linux/leon/patches/023-greth_handle_frame_error_interrupts.patch b/target/linux/leon/patches/023-greth_handle_frame_error_interrupts.patch
deleted file mode 100644 (file)
index 12bfb1c..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-From f62c047af910c9c9696db7b47472a3728b8100e8 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 11:56:22 +0100
-Subject: [PATCH] GRETH: handle frame error interrupts
-
-Not handling frame error interrupts are unlikly but may lead to dead
-lock if 128 error frames are recieved in a row.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    5 +++--
- drivers/net/greth.h |    2 ++
- 2 files changed, 5 insertions(+), 2 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -595,11 +595,12 @@ static irqreturn_t greth_interrupt(int i
-       status = GRETH_REGLOAD(greth->regs->status);
-       /* Handle rx and tx interrupts through poll */
--      if (status & (GRETH_INT_RX | GRETH_INT_TX)) {
-+      if (status & (GRETH_INT_RE | GRETH_INT_RX | GRETH_INT_TE | GRETH_INT_TX)) {
-               /* Clear interrupt status */
-               GRETH_REGSAVE(greth->regs->status,
--                            status & (GRETH_INT_RX | GRETH_INT_TX));
-+                            status & (GRETH_INT_RE | GRETH_INT_RX | 
-+                                      GRETH_INT_TE | GRETH_INT_TX));
-               retval = IRQ_HANDLED;
---- a/drivers/net/greth.h
-+++ b/drivers/net/greth.h
-@@ -23,6 +23,7 @@
- #define GRETH_BD_LEN 0x7FF
- #define GRETH_TXEN 0x1
-+#define GRETH_INT_TE 0x2
- #define GRETH_INT_TX 0x8
- #define GRETH_TXI 0x4
- #define GRETH_TXBD_STATUS 0x0001C000
-@@ -35,6 +36,7 @@
- #define GRETH_TXBD_ERR_UE 0x4000
- #define GRETH_TXBD_ERR_AL 0x8000
-+#define GRETH_INT_RE         0x1
- #define GRETH_INT_RX         0x4
- #define GRETH_RXEN           0x2
- #define GRETH_RXI            0x8
diff --git a/target/linux/leon/patches/024-greth_resolve_smp_and_other_issues.patch b/target/linux/leon/patches/024-greth_resolve_smp_and_other_issues.patch
deleted file mode 100644 (file)
index c2293ca..0000000
+++ /dev/null
@@ -1,399 +0,0 @@
-From 4439d933884ee3c7e320b8d33bd2e268dd5b6fa5 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 11:40:19 +0100
-Subject: [PATCH] GRETH: resolve SMP issues and other problems
-
-Fixes the following:
-1. POLL should not enable IRQ when work is not completed
-2. No locking between TX descriptor cleaning and XMIT descriptor handling
-3. No locking between RX POLL and XMIT modifying control register
-4. Since TX cleaning (called from POLL) is running in parallel with XMIT
-   unnecessary locking is needed.
-5. IRQ handler looks at RX frame status solely, this is wrong when IRQ is
-   temporarily disabled (in POLL), and when IRQ is shared.
-6. IRQ handler clears IRQ status, which is unnecessary
-7. TX queue was stopped in preventing cause when not MAX_SKB_FRAGS+1 descriptors
-   were available after a SKB been scheduled by XMIT. Instead the TX queue is
-   stopped first when not enough descriptors are available upon entering XMIT.
-
-It was hard to split up this patch in smaller pieces since all are tied
-together somehow.
-
-Note the RX flag used in the interrupt handler does not signal that interrtupt
-was asserted, but that a frame was received. Same goes for TX. Also, IRQ is not
-asserted when the RX flag is set before enabling IRQ enable until a new frame is
-received. So extra care must be taken to avoid enabling IRQ and all descriptors
-are already used, hence dead lock will upon us. See new POLL implementation that
-enableds IRQ then look at the RX flag to determine if one or more IRQs may have
-been missed. TX/RX flags are cleared before handling previously enabled
-descriptors, this ensures that the RX/TX flags are valid when determining if IRQ
-should be turned on again.
-
-By moving TX cleaning from POLL to XMIT in the standard case, removes some
-locking trouble. Enabling TX cleaning from poll only when not enough TX
-descriptors are available is safe because the TX queue is at the same time
-stopped, thus XMIT will not be called. The TX queue is woken up again when
-enough descriptrs are available.
-
-TX Frames are always enabled with IRQ, however the TX IRQ Enable flag will not
-be enabled until XMIT must wait for free descriptors.
-
-Locking RX and XMIT parts of the driver from each other is needed because the
-RX/TX enable bits share the same register.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |  158 ++++++++++++++++++++++++++++++---------------------
- 1 files changed, 93 insertions(+), 65 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -1,7 +1,7 @@
- /*
-  * Aeroflex Gaisler GRETH 10/100/1G Ethernet MAC.
-  *
-- * 2005-2009 (c) Aeroflex Gaisler AB
-+ * 2005-2010 (c) Aeroflex Gaisler AB
-  *
-  * This driver supports GRETH 10/100 and GRETH 10/100/1G Ethernet MACs
-  * available in the GRLIB VHDL IP core library.
-@@ -401,12 +401,20 @@ greth_start_xmit(struct sk_buff *skb, st
-       struct greth_private *greth = netdev_priv(dev);
-       struct greth_bd *bdp;
-       int err = NETDEV_TX_OK;
--      u32 status, dma_addr;
-+      u32 status, dma_addr, ctrl;
-+      unsigned long flags;
--      bdp = greth->tx_bd_base + greth->tx_next;
-+      /* Clean TX Ring */
-+      greth_clean_tx(greth->netdev);
-       if (unlikely(greth->tx_free <= 0)) {
-+              spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
-+              ctrl = GRETH_REGLOAD(greth->regs->control);
-+              /* Enable TX IRQ only if not already in poll() routine */
-+              if ( ctrl & GRETH_RXI )
-+                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
-               netif_stop_queue(dev);
-+              spin_unlock_irqrestore(&greth->devlock, flags);
-               return NETDEV_TX_BUSY;
-       }
-@@ -419,13 +427,14 @@ greth_start_xmit(struct sk_buff *skb, st
-               goto out;
-       }
-+      bdp = greth->tx_bd_base + greth->tx_next;
-       dma_addr = greth_read_bd(&bdp->addr);
-       memcpy((unsigned char *) phys_to_virt(dma_addr), skb->data, skb->len);
-       dma_sync_single_for_device(greth->dev, dma_addr, skb->len, DMA_TO_DEVICE);
--      status = GRETH_BD_EN | (skb->len & GRETH_BD_LEN);
-+      status = GRETH_BD_EN | GRETH_BD_IE | (skb->len & GRETH_BD_LEN);
-       /* Wrap around descriptor ring */
-       if (greth->tx_next == GRETH_TXBD_NUM_MASK) {
-@@ -435,22 +444,11 @@ greth_start_xmit(struct sk_buff *skb, st
-       greth->tx_next = NEXT_TX(greth->tx_next);
-       greth->tx_free--;
--      /* No more descriptors */
--      if (unlikely(greth->tx_free == 0)) {
--
--              /* Free transmitted descriptors */
--              greth_clean_tx(dev);
--
--              /* If nothing was cleaned, stop queue & wait for irq */
--              if (unlikely(greth->tx_free == 0)) {
--                      status |= GRETH_BD_IE;
--                      netif_stop_queue(dev);
--              }
--      }
--
-       /* Write descriptor control word and enable transmission */
-       greth_write_bd(&bdp->stat, status);
-+      spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
-       greth_enable_tx(greth);
-+      spin_unlock_irqrestore(&greth->devlock, flags);
- out:
-       dev_kfree_skb(skb);
-@@ -463,13 +461,24 @@ greth_start_xmit_gbit(struct sk_buff *sk
- {
-       struct greth_private *greth = netdev_priv(dev);
-       struct greth_bd *bdp;
--      u32 status = 0, dma_addr;
-+      u32 status = 0, dma_addr, ctrl;
-       int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
-+      unsigned long flags;
-       nr_frags = skb_shinfo(skb)->nr_frags;
-+      /* Clean TX Ring */
-+      greth_clean_tx_gbit(dev);
-+
-       if (greth->tx_free < nr_frags + 1) {
-+              spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
-+              ctrl = GRETH_REGLOAD(greth->regs->control);
-+              /* Enable TX IRQ only if not already in poll() routine */
-+              if ( ctrl & GRETH_RXI ) {
-+                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
-+              }
-               netif_stop_queue(dev);
-+              spin_unlock_irqrestore(&greth->devlock, flags);
-               err = NETDEV_TX_BUSY;
-               goto out;
-       }
-@@ -522,14 +531,8 @@ greth_start_xmit_gbit(struct sk_buff *sk
-               /* More fragments left */
-               if (i < nr_frags - 1)
-                       status |= GRETH_TXBD_MORE;
--
--              /* ... last fragment, check if out of descriptors  */
--              else if (greth->tx_free - nr_frags - 1 < (MAX_SKB_FRAGS + 1)) {
--
--                      /* Enable interrupts and stop queue */
--                      status |= GRETH_BD_IE;
--                      netif_stop_queue(dev);
--              }
-+              else
-+                      status |= GRETH_BD_IE; /* enable IRQ on last fragment */
-               greth_write_bd(&bdp->stat, status);
-@@ -557,7 +560,9 @@ greth_start_xmit_gbit(struct sk_buff *sk
-       wmb();
-+      spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
-       greth_enable_tx(greth);
-+      spin_unlock_irqrestore(&greth->devlock, flags);
-       return NETDEV_TX_OK;
-@@ -579,12 +584,11 @@ out:
-       return err;
- }
--
- static irqreturn_t greth_interrupt(int irq, void *dev_id)
- {
-       struct net_device *dev = dev_id;
-       struct greth_private *greth;
--      u32 status;
-+      u32 status, ctrl;
-       irqreturn_t retval = IRQ_NONE;
-       greth = netdev_priv(dev);
-@@ -594,13 +598,14 @@ static irqreturn_t greth_interrupt(int i
-       /* Get the interrupt events that caused us to be here. */
-       status = GRETH_REGLOAD(greth->regs->status);
--      /* Handle rx and tx interrupts through poll */
--      if (status & (GRETH_INT_RE | GRETH_INT_RX | GRETH_INT_TE | GRETH_INT_TX)) {
-+      /* Must see if interrupts are enabled also, INT_TX|INT_RX flags may be set regardless
-+       * of whether IRQ is enabled or not. Especially important when shared IRQ.
-+       */
-+      ctrl = GRETH_REGLOAD(greth->regs->control);
--              /* Clear interrupt status */
--              GRETH_REGSAVE(greth->regs->status,
--                            status & (GRETH_INT_RE | GRETH_INT_RX | 
--                                      GRETH_INT_TE | GRETH_INT_TX));
-+      /* Handle rx and tx interrupts through poll */
-+      if (((status & (GRETH_INT_RE | GRETH_INT_RX)) && (ctrl & GRETH_RXI)) ||
-+          ((status & (GRETH_INT_TE | GRETH_INT_TX)) && (ctrl & GRETH_TXI))) {
-               retval = IRQ_HANDLED;
-@@ -625,6 +630,8 @@ static void greth_clean_tx(struct net_de
-       while (1) {
-               bdp = greth->tx_bd_base + greth->tx_last;
-+              GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
-+              mb();
-               stat = greth_read_bd(&bdp->stat);
-               if (unlikely(stat & GRETH_BD_EN))
-@@ -685,7 +692,10 @@ static void greth_clean_tx_gbit(struct n
-               /* We only clean fully completed SKBs */
-               bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
--              stat = bdp_last_frag->stat;
-+
-+              GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
-+              mb();
-+              stat = greth_read_bd(&bdp_last_frag->stat);
-               if (stat & GRETH_BD_EN)
-                       break;
-@@ -717,23 +727,12 @@ static void greth_clean_tx_gbit(struct n
-               greth->tx_free += nr_frags+1;
-               dev_kfree_skb(skb);
-       }
--      if (greth->tx_free > (MAX_SKB_FRAGS + 1)) {
-+
-+      if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS + 1))) {
-               netif_wake_queue(dev);
-       }
- }
--static int greth_pending_packets(struct greth_private *greth)
--{
--      struct greth_bd *bdp;
--      u32 status;
--      bdp = greth->rx_bd_base + greth->rx_cur;
--      status = greth_read_bd(&bdp->stat);
--      if (status & GRETH_BD_EN)
--              return 0;
--      else
--              return 1;
--}
--
- static int greth_rx(struct net_device *dev, int limit)
- {
-       struct greth_private *greth;
-@@ -742,20 +741,24 @@ static int greth_rx(struct net_device *d
-       int pkt_len;
-       int bad, count;
-       u32 status, dma_addr;
-+      unsigned long flags;
-       greth = netdev_priv(dev);
-       for (count = 0; count < limit; ++count) {
-               bdp = greth->rx_bd_base + greth->rx_cur;
-+              GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
-+              mb();
-               status = greth_read_bd(&bdp->stat);
--              dma_addr = greth_read_bd(&bdp->addr);
--              bad = 0;
-               if (unlikely(status & GRETH_BD_EN)) {
-                       break;
-               }
-+              dma_addr = greth_read_bd(&bdp->addr);
-+              bad = 0;
-+
-               /* Check status for errors. */
-               if (unlikely(status & GRETH_RXBD_STATUS)) {
-                       if (status & GRETH_RXBD_ERR_FT) {
-@@ -817,7 +820,9 @@ static int greth_rx(struct net_device *d
-               dma_sync_single_for_device(greth->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
-+              spin_lock_irqsave(&greth->devlock, flags); /* save from XMIT */
-               greth_enable_rx(greth);
-+              spin_unlock_irqrestore(&greth->devlock, flags);
-               greth->rx_cur = NEXT_RX(greth->rx_cur);
-       }
-@@ -851,6 +856,7 @@ static int greth_rx_gbit(struct net_devi
-       int pkt_len;
-       int bad, count = 0;
-       u32 status, dma_addr;
-+      unsigned long flags;
-       greth = netdev_priv(dev);
-@@ -858,6 +864,8 @@ static int greth_rx_gbit(struct net_devi
-               bdp = greth->rx_bd_base + greth->rx_cur;
-               skb = greth->rx_skbuff[greth->rx_cur];
-+              GRETH_REGSAVE(greth->regs->status, GRETH_INT_RE | GRETH_INT_RX);
-+              mb();
-               status = greth_read_bd(&bdp->stat);
-               bad = 0;
-@@ -940,7 +948,9 @@ static int greth_rx_gbit(struct net_devi
-               wmb();
-               greth_write_bd(&bdp->stat, status);
-+              spin_lock_irqsave(&greth->devlock, flags);
-               greth_enable_rx(greth);
-+              spin_unlock_irqrestore(&greth->devlock, flags);
-               greth->rx_cur = NEXT_RX(greth->rx_cur);
-       }
-@@ -952,15 +962,19 @@ static int greth_poll(struct napi_struct
- {
-       struct greth_private *greth;
-       int work_done = 0;
-+      unsigned long flags;
-+      u32 mask, ctrl;
-       greth = container_of(napi, struct greth_private, napi);
--      if (greth->gbit_mac) {
--              greth_clean_tx_gbit(greth->netdev);
--      } else {
--              greth_clean_tx(greth->netdev);
-+restart_txrx_poll:
-+      if ( netif_queue_stopped(greth->netdev) ) {
-+              if (greth->gbit_mac) {
-+                      greth_clean_tx_gbit(greth->netdev);
-+              } else {
-+                      greth_clean_tx(greth->netdev);
-+              }
-       }
--restart_poll:
-       if (greth->gbit_mac) {
-               work_done += greth_rx_gbit(greth->netdev, budget - work_done);
-       } else {
-@@ -969,15 +983,29 @@ restart_poll:
-       if (work_done < budget) {
--              napi_complete(napi);
-+              spin_lock_irqsave(&greth->devlock, flags);
--              if (greth_pending_packets(greth)) {
--                      napi_reschedule(napi);
--                      goto restart_poll;
-+              ctrl = GRETH_REGLOAD(greth->regs->control);
-+              if (netif_queue_stopped(greth->netdev)) {
-+                      GRETH_REGSAVE(greth->regs->control,
-+                                      ctrl | GRETH_TXI | GRETH_RXI);
-+                      mask = GRETH_INT_RX | GRETH_INT_RE |
-+                             GRETH_INT_TX | GRETH_INT_TE;
-+              } else {
-+                      GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_RXI);
-+                      mask = GRETH_INT_RX | GRETH_INT_RE;
-+              }
-+
-+              if (GRETH_REGLOAD(greth->regs->status) & mask) {
-+                      GRETH_REGSAVE(greth->regs->control, ctrl);
-+                      spin_unlock_irqrestore(&greth->devlock, flags);
-+                      goto restart_txrx_poll;
-+              } else {
-+                      __napi_complete(napi);
-+                      spin_unlock_irqrestore(&greth->devlock, flags);
-               }
-       }
--      greth_enable_irqs(greth);
-       return work_done;
- }
-@@ -1172,11 +1200,11 @@ static const struct ethtool_ops greth_et
- };
- static struct net_device_ops greth_netdev_ops = {
--      .ndo_open = greth_open,
--      .ndo_stop = greth_close,
--      .ndo_start_xmit = greth_start_xmit,
--      .ndo_set_mac_address = greth_set_mac_add,
--      .ndo_validate_addr      = eth_validate_addr,
-+      .ndo_open               = greth_open,
-+      .ndo_stop               = greth_close,
-+      .ndo_start_xmit         = greth_start_xmit,
-+      .ndo_set_mac_address    = greth_set_mac_add,
-+      .ndo_validate_addr      = eth_validate_addr,
- };
- static inline int wait_for_mdio(struct greth_private *greth)
diff --git a/target/linux/leon/patches/025-greth_bootloader_disable_device_node.patch b/target/linux/leon/patches/025-greth_bootloader_disable_device_node.patch
deleted file mode 100644 (file)
index 836bab1..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-From 66d5b37cc6d32291419bf99161e83e2946ea5f25 Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 12:11:03 +0100
-Subject: [PATCH] GRETH: added option to disable a device node from bootloader.
-
-Signed-off-by: Daniel Hellstrom <daniel@gaisler.com>
----
- drivers/net/greth.c |    6 ++++++
- 1 files changed, 6 insertions(+), 0 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -1428,6 +1428,12 @@ static int __devinit greth_of_probe(stru
-       int err;
-       int tmp;
-       unsigned long timeout;
-+      int *ampopts;
-+
-+      /* Skip device if used by another OS instance */
-+      ampopts = (int *) of_get_property(ofdev->dev.of_node, "ampopts", NULL);
-+      if (ampopts && (*ampopts == 0))
-+              return -EIO;
-       dev = alloc_etherdev(sizeof(struct greth_private));
diff --git a/target/linux/leon/patches/026-greth_gbit_mac_set_ee_when_edcl.patch b/target/linux/leon/patches/026-greth_gbit_mac_set_ee_when_edcl.patch
deleted file mode 100644 (file)
index 94fa0bd..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-From 50fcb51c42bc721f18f1bfa10f705519cd344a2a Mon Sep 17 00:00:00 2001
-From: Daniel Hellstrom <daniel@gaisler.com>
-Date: Wed, 1 Dec 2010 16:20:01 +0100
-Subject: [PATCH] GRETH: Newer GBit MACs need setting EE bit when EDCL should be enabled
-
----
- drivers/net/greth.c |    2 +-
- drivers/net/greth.h |    1 +
- 2 files changed, 2 insertions(+), 1 deletions(-)
-
---- a/drivers/net/greth.c
-+++ b/drivers/net/greth.c
-@@ -1511,7 +1511,7 @@ static int __devinit greth_of_probe(stru
-       /* If we have EDCL we disable the EDCL speed-duplex FSM so
-        * it doesn't interfere with the software */
-       if (greth->edcl != 0)
--              GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX);
-+              GRETH_REGORIN(regs->control, GRETH_CTRL_DISDUPLEX|GRETH_CTRL_EE);
-       /* Check if MAC can handle MDIO interrupts */
-       greth->mdio_int_en = (tmp >> 26) & 1;
---- a/drivers/net/greth.h
-+++ b/drivers/net/greth.h
-@@ -15,6 +15,7 @@
- #define GRETH_CTRL_PSTATIEN   0x400
- #define GRETH_CTRL_MCEN       0x800
- #define GRETH_CTRL_DISDUPLEX  0x1000
-+#define GRETH_CTRL_EE         0x4000
- #define GRETH_STATUS_PHYSTAT  0x100
- #define GRETH_BD_EN 0x800
diff --git a/target/linux/leon/patches/027-sparc_v8_assembler.patch b/target/linux/leon/patches/027-sparc_v8_assembler.patch
deleted file mode 100644 (file)
index 5baea94..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-[PATCH] sparc32: Add -Av8 to assembler command line.
-
-Newer version of binutils are more strict about specifying the
-correct options to enable certain classes of instructions.
-
-The sparc32 build is done for v7 in order to support sun4c systems
-which lack hardware integer multiply and divide instructions.
-
-So we have to pass -Av8 when building the assembler routines that
-use these instructions and get patched into the kernel when we find
-out that we have a v8 capable cpu.
-
-Reported-by: Paul Gortmaker <paul.gortmaker@xxxxxxxxxxxxx>
-Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
----
- arch/sparc/Makefile |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile
-index ad1fb5d..eddcfb3 100644
---- a/arch/sparc/Makefile
-+++ b/arch/sparc/Makefile
-@@ -31,7 +31,7 @@ UTS_MACHINE    := sparc
- #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
- KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
--KBUILD_AFLAGS += -m32
-+KBUILD_AFLAGS += -m32 -Wa,-Av8
- #LDFLAGS_vmlinux = -N -Ttext 0xf0004000
- #  Since 2.5.40, the first stage is left not btfix-ed.