public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
* Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch
@ 2013-03-30  0:27 Michael Schmitz
  2013-03-30  0:27 ` [PATCH 01/12] m68k/atari: ROM port ISA adapter support Michael Schmitz
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k

Hi Geert,

here's the patch series for m68k-queue again, slightly redone for easier
separation of the debatable polled timer patch. In the first instance,
patches 1, 3, 5, 6, 7, 8, 9 and 10 I would like to see merged upstream. 

All but 7 and 8 should go through your tree, 7 and 8 through netdev, right? 

I will send out the two patches to netdev for comment shortly. 

01/12 m68k/atari: ROM port ISA adapter support
02/12 m68k/irq: Add handle_polled_irq() for timer based soft interrupts
03/12 m68k/atari: use dedicated irq_chip for timer D interrupts
04/12 m68k/atari: use polled interrupt handler for timer D interrupts
05/12 m68k/atari: EtherNAT - platform device and IRQ support code
06/12 m68k/atari: EtherNEC - add platform device support
07/12 m68k/atari: EtherNAT - ethernet support - new driver (smc91x)
08/12 m68k/atari: EtherNEC - ethernet support - new driver (ne.c)
09/12 m68k/atari: EtherNAT - add interrupt chip definition for CPLD interrupts
10/12 m68k: Implement ndelay() based on the existing udelay() logic
11/12 m68k/atari: USB - add platform devices for EtherNAT/NetUSBee ISP1160 HCD
12/12 m68k/atari: USB - add ISP1160 USB host controller support

Cheers,

	Michael

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/12] m68k/atari: ROM port ISA adapter support
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 02/12] m68k/irq: Add handle_polled_irq() for timer based soft interrupts Michael Schmitz
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz, Michael Schmitz

From: Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de>

Atari ROM port ISA adapter support for EtherNEC and NetUSBee adapters

16 bit access for ROM port adapters follows debugging and
clarification by David Galvez <dgalvez75@gmail.com>. The NetUSBee
ISP1160 USB chip uses these macros.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/Kconfig.bus          |   10 +++
 arch/m68k/include/asm/io_mm.h  |  136 ++++++++++++++++++++++++++++++++++++++--
 arch/m68k/include/asm/raw_io.h |  109 +++++++++++++++++++++++++++++++-
 arch/m68k/kernel/setup_mm.c    |    6 ++
 4 files changed, 254 insertions(+), 7 deletions(-)

diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus
index 93ef034..675b087 100644
--- a/arch/m68k/Kconfig.bus
+++ b/arch/m68k/Kconfig.bus
@@ -45,6 +45,16 @@ config ISA
 	  (MCA) or VESA.  ISA is an older system, now being displaced by PCI;
 	  newer boards don't support it.  If you have ISA, say Y, otherwise N.
 
+config ATARI_ROM_ISA
+	bool "Atari ROM port ISA adapter support"
+	depends on ATARI
+	help
+	  This option enables support for the ROM port ISA adapter used to
+	  operate ISA cards on Atari. Only 8  bit cards are supported, and
+	  no interrupt lines are connected.
+	  The only driver currently using this adapter is the EtherNEC
+	  driver for RTL8019AS based NE2000 compatible network cards.
+
 config GENERIC_ISA_DMA
 	def_bool ISA
 
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index a6686d2..ffdf54f 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -63,6 +63,23 @@
 #endif
 #endif /* AMIGA_PCMCIA */
 
+#ifdef CONFIG_ATARI_ROM_ISA
+
+#define enec_isa_read_base  0xfffa0000
+#define enec_isa_write_base 0xfffb0000
+
+#define ENEC_ISA_IO_B(ioaddr)	(enec_isa_read_base+((((unsigned long)(ioaddr))&0x7F)<<9))
+#define ENEC_ISA_IO_W(ioaddr)	(enec_isa_read_base+((((unsigned long)(ioaddr))&0x7F)<<9))
+#define ENEC_ISA_MEM_B(madr)	(enec_isa_read_base+((((unsigned long)(madr))&0x7F)<<9))
+#define ENEC_ISA_MEM_W(madr)	(enec_isa_read_base+((((unsigned long)(madr))&0x7F)<<9))
+
+#ifndef MULTI_ISA
+#define MULTI_ISA 0
+#else
+#undef MULTI_ISA
+#define MULTI_ISA 1
+#endif
+#endif /* ATARI_ROM_ISA */
 
 
 #if defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE)
@@ -111,14 +128,15 @@ void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len);
 #define readw(addr)	in_le16(addr)
 #define writew(v, addr)	out_le16((addr), (v))
 
-#elif defined(CONFIG_ISA)
+#elif defined(CONFIG_ISA) || defined(CONFIG_ATARI_ROM_ISA)
 
 #if MULTI_ISA == 0
 #undef MULTI_ISA
 #endif
 
-#define ISA_TYPE_Q40 (1)
-#define ISA_TYPE_AG  (2)
+#define ISA_TYPE_Q40  (1)
+#define ISA_TYPE_AG   (2)
+#define ISA_TYPE_ENEC (3)
 
 #if defined(CONFIG_Q40) && !defined(MULTI_ISA)
 #define ISA_TYPE ISA_TYPE_Q40
@@ -128,6 +146,10 @@ void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len);
 #define ISA_TYPE ISA_TYPE_AG
 #define ISA_SEX  1
 #endif
+#if defined(CONFIG_ATARI_ROM_ISA) && !defined(MULTI_ISA)
+#define ISA_TYPE ISA_TYPE_ENEC
+#define ISA_SEX  0
+#endif
 
 #ifdef MULTI_ISA
 extern int isa_type;
@@ -152,6 +174,9 @@ static inline u8 __iomem *isa_itb(unsigned long addr)
 #ifdef CONFIG_AMIGA_PCMCIA
     case ISA_TYPE_AG: return (u8 __iomem *)AG_ISA_IO_B(addr);
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+    case ISA_TYPE_ENEC: return (u8 __iomem *)ENEC_ISA_IO_B(addr);
+#endif
     default: return NULL; /* avoid warnings, just in case */
     }
 }
@@ -165,6 +190,9 @@ static inline u16 __iomem *isa_itw(unsigned long addr)
 #ifdef CONFIG_AMIGA_PCMCIA
     case ISA_TYPE_AG: return (u16 __iomem *)AG_ISA_IO_W(addr);
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+    case ISA_TYPE_ENEC: return (u16 __iomem *)ENEC_ISA_IO_W(addr);
+#endif
     default: return NULL; /* avoid warnings, just in case */
     }
 }
@@ -188,6 +216,9 @@ static inline u8 __iomem *isa_mtb(unsigned long addr)
 #ifdef CONFIG_AMIGA_PCMCIA
     case ISA_TYPE_AG: return (u8 __iomem *)addr;
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+    case ISA_TYPE_ENEC: return (u8 __iomem *)ENEC_ISA_MEM_B(addr);
+#endif
     default: return NULL; /* avoid warnings, just in case */
     }
 }
@@ -201,6 +232,9 @@ static inline u16 __iomem *isa_mtw(unsigned long addr)
 #ifdef CONFIG_AMIGA_PCMCIA
     case ISA_TYPE_AG: return (u16 __iomem *)addr;
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+    case ISA_TYPE_ENEC: return (u16 __iomem *)ENEC_ISA_MEM_W(addr);
+#endif
     default: return NULL; /* avoid warnings, just in case */
     }
 }
@@ -222,6 +256,36 @@ static inline u16 __iomem *isa_mtw(unsigned long addr)
 	(ISA_SEX ? out_be16(isa_mtw((unsigned long)(p)),(val))	\
 		 : out_le16(isa_mtw((unsigned long)(p)),(val)))
 
+#ifdef CONFIG_ATARI_ROM_ISA
+#define isa_rom_inb(port)      rom_in_8(isa_itb(port))
+#define isa_rom_inw(port)	\
+	(ISA_SEX ? rom_in_be16(isa_itw(port))	\
+		 : rom_in_le16(isa_itw(port)))
+
+#define isa_rom_outb(val, port) rom_out_8(isa_itb(port), (val))
+#define isa_rom_outw(val, port)	\
+	(ISA_SEX ? rom_out_be16(isa_itw(port), (val))	\
+		 : rom_out_le16(isa_itw(port), (val)))
+
+#define isa_rom_readb(p)       rom_in_8(isa_mtb((unsigned long)(p)))
+#define isa_rom_readw(p)       \
+	(ISA_SEX ? rom_in_be16(isa_mtw((unsigned long)(p)))	\
+		 : rom_in_le16(isa_mtw((unsigned long)(p))))
+#define isa_rom_readw_swap(p)       \
+	(ISA_SEX ? rom_in_le16(isa_mtw((unsigned long)(p)))	\
+		 : rom_in_be16(isa_mtw((unsigned long)(p))))
+#define isa_rom_readw_raw(p)   rom_in_be16(isa_mtw((unsigned long)(p)))
+
+#define isa_rom_writeb(val, p)  rom_out_8(isa_mtb((unsigned long)(p)), (val))
+#define isa_rom_writew(val, p)  \
+	(ISA_SEX ? rom_out_be16(isa_mtw((unsigned long)(p)), (val))	\
+		 : rom_out_le16(isa_mtw((unsigned long)(p)), (val)))
+#define isa_rom_writew_swap(val, p)  \
+	(ISA_SEX ? rom_out_le16(isa_mtw((unsigned long)(p)), (val))	\
+		 : rom_out_be16(isa_mtw((unsigned long)(p)), (val)))
+#define isa_rom_writew_raw(val, p)  rom_out_be16(isa_mtw((unsigned long)(p)), (val))
+#endif /* CONFIG_ATARI_ROM_ISA */
+
 static inline void isa_delay(void)
 {
   switch(ISA_TYPE)
@@ -232,6 +296,9 @@ static inline void isa_delay(void)
 #ifdef CONFIG_AMIGA_PCMCIA
     case ISA_TYPE_AG: break;
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+    case ISA_TYPE_ENEC: break;
+#endif
     default: break; /* avoid warnings */
     }
 }
@@ -263,6 +330,29 @@ static inline void isa_delay(void)
                   raw_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)<<1))
 
 
+#ifdef CONFIG_ATARI_ROM_ISA
+#define isa_rom_inb_p(p)	({ u8 _v = isa_rom_inb(p); isa_delay(); _v; })
+#define isa_rom_inw_p(p)	({ u16 _v = isa_rom_inw(p); isa_delay(); _v; })
+#define isa_rom_outb_p(v, p)	({ isa_rom_outb((v), (p)); isa_delay(); })
+#define isa_rom_outw_p(v, p)	({ isa_rom_outw((v), (p)); isa_delay(); })
+
+#define isa_rom_insb(port, buf, nr) raw_rom_insb(isa_itb(port), (u8 *)(buf), (nr))
+
+#define isa_rom_insw(port, buf, nr)     \
+       (ISA_SEX ? raw_rom_insw(isa_itw(port), (u16 *)(buf), (nr)) :    \
+		  raw_rom_insw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+
+#define isa_rom_outsb(port, buf, nr) raw_rom_outsb(isa_itb(port), (u8 *)(buf), (nr))
+
+#define isa_rom_outsw(port, buf, nr)    \
+       (ISA_SEX ? raw_rom_outsw(isa_itw(port), (u16 *)(buf), (nr)) :  \
+		  raw_rom_outsw_swapw(isa_itw(port), (u16 *)(buf), (nr)))
+#endif /* CONFIG_ATARI_ROM_ISA */
+
+#endif  /* CONFIG_ISA || CONFIG_ATARI_ROM_ISA */
+
+
+#if defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA)
 #define inb     isa_inb
 #define inb_p   isa_inb_p
 #define outb    isa_outb
@@ -285,9 +375,43 @@ static inline void isa_delay(void)
 #define readw   isa_readw
 #define writeb  isa_writeb
 #define writew  isa_writew
+#endif  /* CONFIG_ISA && !CONFIG_ATARI_ROM_ISA */
 
-#else  /* CONFIG_ISA */
-
+#ifdef CONFIG_ATARI_ROM_ISA
+/*
+ * kernel with both ROM port ISA and IDE compiled in, those have
+ * conflicting defs for in/out. Simply consider port < 1024
+ * ROM port ISA and everything else regular ISA for IDE. read,write defined
+ * below.
+ */
+#define inb(port)	((port) < 1024 ? isa_rom_inb(port) : in_8(port))
+#define inb_p(port)	((port) < 1024 ? isa_rom_inb_p(port) : in_8(port))
+#define inw(port)	((port) < 1024 ? isa_rom_inw(port) : in_le16(port))
+#define inw_p(port)	((port) < 1024 ? isa_rom_inw_p(port) : in_le16(port))
+#define inl		isa_inl
+#define inl_p		isa_inl_p
+
+#define outb(val, port)	((port) < 1024 ? isa_rom_outb((val), (port)) : out_8((port), (val)))
+#define outb_p(val, port) ((port) < 1024 ? isa_rom_outb_p((val), (port)) : out_8((port), (val)))
+#define outw(val, port)	((port) < 1024 ? isa_rom_outw((val), (port)) : out_le16((port), (val)))
+#define outw_p(val, port) ((port) < 1024 ? isa_rom_outw_p((val), (port)) : out_le16((port), (val)))
+#define outl		isa_outl
+#define outl_p		isa_outl_p
+
+#define insb(port, buf, nr)	((port) < 1024 ? isa_rom_insb((port), (buf), (nr)) : isa_insb((port), (buf), (nr)))
+#define insw(port, buf, nr)	((port) < 1024 ? isa_rom_insw((port), (buf), (nr)) : isa_insw((port), (buf), (nr)))
+#define insl			isa_insl
+#define outsb(port, buf, nr)	((port) < 1024 ? isa_rom_outsb((port), (buf), (nr)) : isa_outsb((port), (buf), (nr)))
+#define outsw(port, buf, nr)	((port) < 1024 ? isa_rom_outsw((port), (buf), (nr)) : isa_outsw((port), (buf), (nr)))
+#define outsl			isa_outsl
+
+#define readb(addr)		in_8(addr)
+#define writeb(val, addr)	out_8((addr), (val))
+#define readw(addr)		in_le16(addr)
+#define writew(val, addr)	out_le16((addr), (val))
+#endif /* CONFIG_ATARI_ROM_ISA */
+
+#if !defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA)
 /*
  * We need to define dummy functions for GENERIC_IOMAP support.
  */
@@ -319,7 +443,7 @@ static inline void isa_delay(void)
 #define readw(addr)      in_le16(addr)
 #define writew(val,addr) out_le16((addr),(val))
 
-#endif /* CONFIG_ISA */
+#endif /* !CONFIG_ISA && !CONFIG_ATARI_ROM_ISA */
 
 #define readl(addr)      in_le32(addr)
 #define writel(val,addr) out_le32((addr),(val))
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index d9eb983..932faa3 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -10,7 +10,7 @@
 
 #ifdef __KERNEL__
 
-#include <asm/types.h>
+#include <asm/byteorder.h>
 
 
 /* Values for nocacheflag and cmode */
@@ -60,6 +60,57 @@ extern void __iounmap(void *addr, unsigned long size);
 #define __raw_writew(val,addr) out_be16((addr),(val))
 #define __raw_writel(val,addr) out_be32((addr),(val))
 
+/*
+ * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000
+ * network card driver.
+ * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4,
+ * and hardwires the rest of the ISA addresses for a base address of 0x300.
+ *
+ * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading.
+ * For writes, address lines A1-A8 are latched to ISA data lines D0-D7
+ * (meaning the bit pattern on A1-A8 can be read back as byte).
+ *
+ * Read and write operations are distinguished by the base address used:
+ * reads are from the ROM A side range, writes are through the B side range
+ * addresses (A side base + 0x10000).
+ *
+ * Reads and writes are byte only.
+ *
+ * 16 bit reads and writes are necessary for the NetUSBee adapter's USB
+ * chipset - 16 bit words are read straight off the ROM port while 16 bit
+ * reads are split into two byte writes. The low byte is latched to the
+ * NetUSBee buffer by a read from the _read_ window (with the data pattern
+ * asserted as A1-A8 address pattern). The high byte is then written to the
+ * write range as usual, completing the write cycle.
+ */
+
+#if defined(CONFIG_ATARI_ROM_ISA)
+#define rom_in_8(addr) \
+	({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; })
+#define rom_in_be16(addr) \
+	({ u16 __v = (*(__force volatile u16 *) (addr)); __v; })
+#define rom_in_le16(addr) \
+	({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; })
+
+#define rom_out_8(addr, b)	\
+	({u8 __w, __v = (b);  u32 _addr = ((u32) (addr)); \
+	__w = ((*(__force volatile u8 *)  ((_addr | 0x10000) + (__v<<1)))); })
+#define rom_out_be16(addr, w)	\
+	({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
+	__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \
+	__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); })
+#define rom_out_le16(addr, w)	\
+	({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \
+	__w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \
+	__w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); })
+
+#define raw_rom_inb rom_in_8
+#define raw_rom_inw rom_in_be16
+
+#define raw_rom_outb(val, port) rom_out_8((port), (val))
+#define raw_rom_outw(val, port) rom_out_be16((port), (val))
+#endif /* CONFIG_ATARI_ROM_ISA */
+
 static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
 {
 	unsigned int i;
@@ -342,6 +393,62 @@ static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
 		: "d0", "a0", "a1", "d6");
 }
 
+
+#if defined(CONFIG_ATARI_ROM_ISA)
+static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len)
+{
+	unsigned int i;
+
+	for (i = 0; i < len; i++)
+		*buf++ = rom_in_8(port);
+}
+
+static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf,
+			     unsigned int len)
+{
+	unsigned int i;
+
+	for (i = 0; i < len; i++)
+		rom_out_8(port, *buf++);
+}
+
+static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf,
+				   unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		*buf++ = rom_in_be16(port);
+}
+
+static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf,
+				   unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		rom_out_be16(port, *buf++);
+}
+
+static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf,
+				   unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		*buf++ = rom_in_le16(port);
+}
+
+static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf,
+				   unsigned int nr)
+{
+	unsigned int i;
+
+	for (i = 0; i < nr; i++)
+		rom_out_le16(port, *buf++);
+}
+#endif /* CONFIG_ATARI_ROM_ISA */
+
 #endif /* __KERNEL__ */
 
 #endif /* _RAW_IO_H */
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index 80cfbe5..e67e531 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -381,6 +381,12 @@ void __init setup_arch(char **cmdline_p)
 		isa_sex = 1;
 	}
 #endif
+#ifdef CONFIG_ATARI_ROM_ISA
+	if (MACH_IS_ATARI) {
+		isa_type = ISA_TYPE_ENEC;
+		isa_sex = 0;
+	}
+#endif
 #endif
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/12] m68k/irq: Add handle_polled_irq() for timer based soft interrupts
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
  2013-03-30  0:27 ` [PATCH 01/12] m68k/atari: ROM port ISA adapter support Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 03/12] m68k/atari: use dedicated irq_chip for timer D interrupts Michael Schmitz
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Experimental hack to avoid unhandled interrupt timer to fire
on EtherNEC/NetUSBee cards that have no hardware interrupt
and need to be polled from a timer interrupt.

This patch adds a special 'polled interrupt' handler for timer based
software interrupts.

handle_simple_irq() will respond to excessive unhandled interrupts
(as are expected for a polling timer interrupt) by disabling the
apparently unhandled interrupt source.

handle_polled_irq() prevents this by setting the IRQS_POLL_INPROGRESS
flag which will cause the unhandled interrupt events to be ignored.

This is a temporary hack to allow timer based polling of the Atari ROM
port network and USB cards only. Suggestions on how to properly handle
this in the normal interrupt framework are most welcome.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 include/linux/irq.h |    1 +
 kernel/irq/chip.c   |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 0 deletions(-)

diff --git a/include/linux/irq.h b/include/linux/irq.h
index bc4e066..5064385 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -407,6 +407,7 @@ extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
+extern void handle_polled_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_percpu_devid_irq(unsigned int irq, struct irq_desc *desc);
 extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index cbd97ce..667e4c1 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -353,6 +353,42 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(handle_simple_irq);
 
+/**
+ *	handle_polled_irq - Simple and software-decoded IRQs.
+ *	@irq:	the interrupt number
+ *	@desc:	the interrupt description structure for this irq
+ *
+ *	Polled interrupts are sent from a demultiplexing software interrupt
+ *	handler, where no interrupt hardware control is necessary.
+ */
+void
+handle_polled_irq(unsigned int irq, struct irq_desc *desc)
+{
+	raw_spin_lock(&desc->lock);
+
+	if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
+		if (!irq_check_poll(desc))
+			goto out_unlock;
+
+	desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+	kstat_incr_irqs_this_cpu(irq, desc);
+
+	if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+		desc->istate |= IRQS_PENDING;
+		goto out_unlock;
+	}
+
+	desc->istate |= IRQS_POLL_INPROGRESS;
+
+	handle_irq_event(desc);
+
+	desc->istate &= ~(IRQS_POLL_INPROGRESS);
+
+out_unlock:
+	raw_spin_unlock(&desc->lock);
+}
+EXPORT_SYMBOL_GPL(handle_polled_irq);
+
 /*
  * Called unconditionally from handle_level_irq() and only for oneshot
  * interrupts from handle_fasteoi_irq()
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/12] m68k/atari: use dedicated irq_chip for timer D interrupts
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
  2013-03-30  0:27 ` [PATCH 01/12] m68k/atari: ROM port ISA adapter support Michael Schmitz
  2013-03-30  0:27 ` [PATCH 02/12] m68k/irq: Add handle_polled_irq() for timer based soft interrupts Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 04/12] m68k/atari: use polled interrupt handler " Michael Schmitz
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add a special irq_chip for the Atari MFP timer D interrupt,
which is used as a polling timer for EtherNEC and NetUSBee

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/ataints.c         |   70 +++++++++++++++++++++++++++++++++++++
 arch/m68k/include/asm/atariints.h |    9 +++++
 2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 3f41092..f699c82 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -122,6 +122,62 @@ static struct irq_chip atari_irq_chip = {
 };
 
 /*
+ * ST-MFP timer D chained interrupts - each driver gets its own timer
+ * interrupt instance.
+ */
+
+struct mfptimerbase {
+	volatile struct MFP *mfp;
+	unsigned char mfp_mask, mfp_data;
+	unsigned short int_mask;
+	int handler_irq, mfptimer_irq, server_irq;
+	char *name;
+} stmfp_base = {
+	.mfp		= &st_mfp,
+	.int_mask	= 0x0,
+	.handler_irq	= IRQ_MFP_TIMD,
+	.mfptimer_irq	= IRQ_MFP_TIMER1,
+	.name		= "MFP Timer D"
+};
+
+static irqreturn_t mfptimer_handler(int irq, void *dev_id)
+{
+	struct mfptimerbase *base = dev_id;
+	int mach_irq;
+	unsigned char ints;
+
+	mach_irq = base->mfptimer_irq;
+	ints = base->int_mask;
+	for (; ints; mach_irq++, ints >>= 1) {
+		if (ints & 1)
+			generic_handle_irq(mach_irq);
+	}
+	return IRQ_HANDLED;
+}
+
+
+static void atari_mfptimer_enable(struct irq_data *data)
+{
+	int mfp_num = data->irq - IRQ_MFP_TIMER1;
+	stmfp_base.int_mask |= 1 << mfp_num;
+	atari_enable_irq(IRQ_MFP_TIMD);
+}
+
+static void atari_mfptimer_disable(struct irq_data *data)
+{
+	int mfp_num = data->irq - IRQ_MFP_TIMER1;
+	stmfp_base.int_mask &= ~(1 << mfp_num);
+	if (!stmfp_base.int_mask)
+		atari_disable_irq(IRQ_MFP_TIMD);
+}
+
+static struct irq_chip atari_mfptimer_chip = {
+	.name		= "timer_d",
+	.irq_enable	= atari_mfptimer_enable,
+	.irq_disable	= atari_mfptimer_disable,
+};
+
+/*
  * void atari_init_IRQ (void)
  *
  * Parameters:	None
@@ -198,6 +254,20 @@ void __init atari_init_IRQ(void)
 	/* Initialize the PSG: all sounds off, both ports output */
 	sound_ym.rd_data_reg_sel = 7;
 	sound_ym.wd_data = 0xff;
+
+	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
+				  IRQ_MFP_TIMER1, 8);
+
+	/* prepare timer D data for use as poll interrupt */
+	/* set Timer D data Register - needs to be > 0 */
+	st_mfp.tim_dt_d = 254;	/* < 100 Hz */
+	/* start timer D, div = 1:100 */
+	st_mfp.tim_ct_cd = (st_mfp.tim_ct_cd & 0xf0) | 0x6;
+
+	/* request timer D dispatch handler */
+	if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED,
+			stmfp_base.name, &stmfp_base))
+		pr_err("Couldn't register %s interrupt\n", stmfp_base.name);
 }
 
 
diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h
index 5fc13bd..8f71504 100644
--- a/arch/m68k/include/asm/atariints.h
+++ b/arch/m68k/include/asm/atariints.h
@@ -94,6 +94,15 @@
 #define IRQ_SCCA_RX	     (52)
 #define IRQ_SCCA_SPCOND	     (54)
 
+/* shared MFP timer D interrupts - hires timer for EtherNEC et al. */
+#define IRQ_MFP_TIMER1       (64)
+#define IRQ_MFP_TIMER2       (65)
+#define IRQ_MFP_TIMER3       (66)
+#define IRQ_MFP_TIMER4       (67)
+#define IRQ_MFP_TIMER5       (68)
+#define IRQ_MFP_TIMER6       (69)
+#define IRQ_MFP_TIMER7       (70)
+#define IRQ_MFP_TIMER8       (71)
 
 #define INT_CLK   24576	    /* CLK while int_clk =2.456MHz and divide = 100 */
 #define INT_TICKS 246	    /* to make sched_time = 99.902... HZ */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/12] m68k/atari: use polled interrupt handler for timer D interrupts
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (2 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 03/12] m68k/atari: use dedicated irq_chip for timer D interrupts Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 05/12] m68k/atari: EtherNAT - platform device and IRQ support code Michael Schmitz
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Make use of handle_polled_irq instead of handle_simple_irq for the MFP
timer D interrupts - this avoids 'unhandled interrupt' messages and
disabling of the timer interrupts after idle periods.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/ataints.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index f699c82..2cf7349 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -255,7 +255,7 @@ void __init atari_init_IRQ(void)
 	sound_ym.rd_data_reg_sel = 7;
 	sound_ym.wd_data = 0xff;
 
-	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_simple_irq,
+	m68k_setup_irq_controller(&atari_mfptimer_chip, handle_polled_irq,
 				  IRQ_MFP_TIMER1, 8);
 
 	/* prepare timer D data for use as poll interrupt */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/12] m68k/atari: EtherNAT - platform device and IRQ support code
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (3 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 04/12] m68k/atari: use polled interrupt handler " Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 06/12] m68k/atari: EtherNEC - add platform device support Michael Schmitz
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add platform device and interrupt definitions necessary for the EtherNAT
Ethernet/USB adapter for the Falcon extension port. EtherNAT interrupt
numbers are 139/140 so the max. interrupt number for Atari has to be
increased.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/config.c          |   62 +++++++++++++++++++++++++++++++++++++
 arch/m68k/include/asm/atarihw.h   |    6 +++
 arch/m68k/include/asm/atariints.h |    2 +-
 arch/m68k/include/asm/irq.h       |    6 +++-
 4 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index 037c11c..d35e89d 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/platform_device.h>
 #include <linux/vt_kern.h>
 #include <linux/module.h>
 
@@ -655,3 +656,64 @@ static void atari_get_hardware_list(struct seq_file *m)
 	ATARIHW_ANNOUNCE(VME, "VME Bus");
 	ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
 }
+
+/*
+ * MSch: initial platform device support for Atari,
+ * required for EtherNAT/EtherNEC/NetUSBee drivers
+ */
+
+/*
+ * EtherNAT: SMC91C111 Ethernet chipset, handled by smc91x driver
+ */
+
+#define ATARI_ETHERNAT_IRQ		140
+
+static struct resource smc91x_resources[] = {
+	[0] = {
+		.name	= "smc91x-regs",
+		.start	= ATARI_ETHERNAT_PHYS_ADDR,
+		.end	= ATARI_ETHERNAT_PHYS_ADDR + 0xfffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "smc91x-irq",
+		.start	= ATARI_ETHERNAT_IRQ,
+		.end	= ATARI_ETHERNAT_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smc91x_device = {
+	.name		= "smc91x",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(smc91x_resources),
+	.resource	= smc91x_resources,
+};
+
+static struct platform_device *atari_ethernat_devices[] __initdata = {
+	&smc91x_device
+};
+
+int __init atari_platform_init(void)
+{
+	int rv = 0;
+
+	if (!MACH_IS_ATARI)
+		return -ENODEV;
+
+#ifdef CONFIG_ATARI_ETHERNAT
+	{
+		unsigned char *enatc_virt;
+		enatc_virt = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0xf);
+		if (hwreg_present(enatc_virt)) {
+			rv = platform_add_devices(atari_ethernat_devices,
+						ARRAY_SIZE(atari_ethernat_devices));
+		}
+		iounmap(enatc_virt);
+	}
+#endif
+
+	return rv;
+}
+
+arch_initcall(atari_platform_init);
diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h
index c0cb363..d887050 100644
--- a/arch/m68k/include/asm/atarihw.h
+++ b/arch/m68k/include/asm/atarihw.h
@@ -805,5 +805,11 @@ struct MSTE_RTC {
 
 #define mste_rtc ((*(volatile struct MSTE_RTC *)MSTE_RTC_BAS))
 
+/*
+** EtherNAT add-on card for Falcon - combined ethernet and USB adapter
+*/
+
+#define ATARI_ETHERNAT_PHYS_ADDR	0x80000000
+
 #endif /* linux/atarihw.h */
 
diff --git a/arch/m68k/include/asm/atariints.h b/arch/m68k/include/asm/atariints.h
index 8f71504..953e0ac 100644
--- a/arch/m68k/include/asm/atariints.h
+++ b/arch/m68k/include/asm/atariints.h
@@ -32,7 +32,7 @@
 #define VME_SOURCE_BASE    56
 #define VME_MAX_SOURCES    16
 
-#define NUM_ATARI_SOURCES   (VME_SOURCE_BASE+VME_MAX_SOURCES-STMFP_SOURCE_BASE)
+#define NUM_ATARI_SOURCES  141
 
 /* convert vector number to int source number */
 #define IRQ_VECTOR_TO_SOURCE(v)	((v) - ((v) < 0x20 ? 0x18 : (0x40-8)))
diff --git a/arch/m68k/include/asm/irq.h b/arch/m68k/include/asm/irq.h
index c1155f0..81ca118 100644
--- a/arch/m68k/include/asm/irq.h
+++ b/arch/m68k/include/asm/irq.h
@@ -6,12 +6,16 @@
  * different m68k hosts compiled into the kernel.
  * Currently the Atari has 72 and the Amiga 24, but if both are
  * supported in the kernel it is better to make room for 72.
+ * With EtherNAT add-on card on Atari, the highest interrupt
+ * number is 140 so NR_IRQS needs to be 141.
  */
 #if defined(CONFIG_COLDFIRE)
 #define NR_IRQS 256
 #elif defined(CONFIG_VME) || defined(CONFIG_SUN3) || defined(CONFIG_SUN3X)
 #define NR_IRQS 200
-#elif defined(CONFIG_ATARI) || defined(CONFIG_MAC)
+#elif defined(CONFIG_ATARI)
+#define NR_IRQS 141
+#elif defined(CONFIG_MAC)
 #define NR_IRQS 72
 #elif defined(CONFIG_Q40)
 #define NR_IRQS	43
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/12] m68k/atari: EtherNEC - add platform device support
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (4 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 05/12] m68k/atari: EtherNAT - platform device and IRQ support code Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 07/12] m68k/atari: EtherNAT - ethernet support - new driver (smc91x) Michael Schmitz
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add platform device for the Atari ROM port ethernet adapter, EtherNEC.
This platform device will be used by the ne.c driver.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/config.c |   50 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index d35e89d..fdcd875 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -694,6 +694,41 @@ static struct platform_device *atari_ethernat_devices[] __initdata = {
 	&smc91x_device
 };
 
+/*
+ * EtherNEC: RTL8019 (NE2000 compatible) Ethernet chipset,
+ * handled by ne.c driver
+ */
+
+#define ATARI_ETHERNEC_PHYS_ADDR	0xfffa0000
+#define ATARI_ETHERNEC_BASE		0x300
+#define ATARI_ETHERNEC_IRQ		IRQ_MFP_TIMER1
+
+static struct resource rtl8019_resources[] = {
+	[0] = {
+		.name	= "rtl8019-regs",
+		.start	= ATARI_ETHERNEC_BASE,
+		.end	= ATARI_ETHERNEC_BASE + 0x20 - 1,
+		.flags	= IORESOURCE_IO,
+	},
+	[1] = {
+		.name	= "rtl8019-irq",
+		.start	= ATARI_ETHERNEC_IRQ,
+		.end	= ATARI_ETHERNEC_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device rtl8019_device = {
+	.name		= "ne",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(rtl8019_resources),
+	.resource	= rtl8019_resources,
+};
+
+static struct platform_device *atari_ethernec_devices[] __initdata = {
+	&rtl8019_device
+};
+
 int __init atari_platform_init(void)
 {
 	int rv = 0;
@@ -713,6 +748,21 @@ int __init atari_platform_init(void)
 	}
 #endif
 
+#ifdef CONFIG_ATARI_ETHERNEC
+	{
+		int error;
+		unsigned char *enec_virt;
+		enec_virt = (unsigned char *)ioremap((ATARI_ETHERNEC_PHYS_ADDR), 0xf);
+		if (hwreg_present(enec_virt)) {
+			error = platform_add_devices(atari_ethernec_devices,
+						ARRAY_SIZE(atari_ethernec_devices));
+			if (error && !rv)
+				rv = error;
+		}
+		iounmap(enec_virt);
+	}
+#endif
+
 	return rv;
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/12] m68k/atari: EtherNAT - ethernet support - new driver (smc91x)
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (5 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 06/12] m68k/atari: EtherNEC - add platform device support Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c) Michael Schmitz
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add Atari specific code to the smc91x Ethernet driver. This code is used
on the EtherNAT adapter card for the Atari Falcon extension port.

Without the patch to smc91x.h, the first two bytes of every ethernet packet
sent out are swapped, resulting in a wrong MAC address being read by the
packet's target, and failure to establish communication.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/Kconfig.devices          |   10 ++++++
 drivers/net/ethernet/smsc/Kconfig  |    4 +-
 drivers/net/ethernet/smsc/smc91x.h |   63 ++++++++++++++++++++++++++++++++++-
 3 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
index 4bc945d..d50ecbf 100644
--- a/arch/m68k/Kconfig.devices
+++ b/arch/m68k/Kconfig.devices
@@ -55,6 +55,16 @@ config NFETH
 	  which will emulate a regular ethernet device while presenting an
 	  ethertap device to the host system.
 
+config ATARI_ETHERNAT
+	bool "Atari EtherNAT Ethernet support"
+	depends on ATARI
+	---help---
+	  Say Y to include support for the EtherNAT network adapter for the
+	  CT/60 extension port.
+
+	  To compile the actual ethernet driver, choose Y or M for the SMC91X
+	  option in the network device section; the module will be called smc91x.
+
 endmenu
 
 menu "Character devices"
diff --git a/drivers/net/ethernet/smsc/Kconfig b/drivers/net/ethernet/smsc/Kconfig
index 5a689af..d3485cf 100644
--- a/drivers/net/ethernet/smsc/Kconfig
+++ b/drivers/net/ethernet/smsc/Kconfig
@@ -6,7 +6,7 @@ config NET_VENDOR_SMSC
 	bool "SMC (SMSC)/Western Digital devices"
 	default y
 	depends on ARM || ISA || MAC || ARM || MIPS || M32R || SUPERH || \
-		BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA
+		BLACKFIN || MN10300 || COLDFIRE || PCI || PCMCIA || ATARI
 	---help---
 	  If you have a network (Ethernet) card belonging to this class, say Y
 	  and read the Ethernet-HOWTO, available from
@@ -40,7 +40,7 @@ config SMC91X
 	select NET_CORE
 	select MII
 	depends on (ARM || M32R || SUPERH || MIPS || BLACKFIN || \
-		    MN10300 || COLDFIRE)
+		    MN10300 || COLDFIRE || ATARI_ETHERNAT)
 	---help---
 	  This is a driver for SMC's 91x series of Ethernet chipsets,
 	  including the SMC91C94 and the SMC91C111. Say Y if you want it
diff --git a/drivers/net/ethernet/smsc/smc91x.h b/drivers/net/ethernet/smsc/smc91x.h
index 370e13d..528f7ba 100644
--- a/drivers/net/ethernet/smsc/smc91x.h
+++ b/drivers/net/ethernet/smsc/smc91x.h
@@ -231,6 +231,30 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 
 #include <unit/smc91111.h>
 
+#elif defined(CONFIG_ATARI)
+
+#define SMC_CAN_USE_8BIT        1
+#define SMC_CAN_USE_16BIT       1
+#define SMC_CAN_USE_32BIT       1
+#define SMC_NOWAIT              1
+
+#define writew_be(val, addr) out_be16((addr), (val))
+
+#define SMC_inb(a, r)           readb((a) + (r))
+#define SMC_inw(a, r)           readw((a) + (r))
+#define SMC_inl(a, r)           readl((a) + (r))
+#define SMC_outb(v, a, r)       writeb(v, (a) + (r))
+#define SMC_outw(v, a, r)       writew(v, (a) + (r))
+#define SMC_outw_be(v, a, r)    writew_be(v, (a) + (r))
+#define SMC_outl(v, a, r)       writel(v, (a) + (r))
+#define SMC_insw(a, r, p, l)    readsw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)   writesw((a) + (r), p, l)
+#define SMC_insl(a, r, p, l)    readsl((a) + (r), p, l)
+#define SMC_outsl(a, r, p, l)   writesl((a) + (r), p, l)
+
+#define RPC_LSA_DEFAULT         RPC_LED_100_10
+#define RPC_LSB_DEFAULT         RPC_LED_TX_RX
+
 #elif defined(CONFIG_ARCH_MSM)
 
 #define SMC_CAN_USE_8BIT	0
@@ -1116,6 +1140,40 @@ static const char * chip_ids[ 16 ] =  {
 		}							\
 	} while (0)
 
+#if defined(CONFIG_ATARI)
+/*
+ * MSch: EtherNAT is 32 bit, so the misaligned data buffer hack applies.
+ * This appears to hurt quite a lot ... we actually need to byte swap the
+ * misaligned write because the data end up in the packet buffer swapped
+ * otherwise (resulting in the first two bytes of the target MAC address
+ * being swapped)
+ */
+#define SMC_PUSH_DATA(lp, p, l)					\
+	do {								\
+		if (SMC_32BIT(lp)) {				\
+			void *__ptr = (p);				\
+			int __len = (l);				\
+			void __iomem *__ioaddr = ioaddr;		\
+			if (__len >= 2 && (unsigned long)__ptr & 2) {	\
+				__len -= 2;				\
+				SMC_outw_be(*(u16 *)__ptr, ioaddr,	\
+					DATA_REG(lp));		\
+				__ptr += 2;				\
+			}						\
+			if (SMC_CAN_USE_DATACS && lp->datacs)		\
+				__ioaddr = lp->datacs;			\
+			SMC_outsl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
+			if (__len & 2) {				\
+				__ptr += (__len & ~3);			\
+				SMC_outw_be(*((u16 *)__ptr), ioaddr,	\
+					 DATA_REG(lp));		\
+			}						\
+		} else if (SMC_16BIT(lp))				\
+			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1); \
+		else if (SMC_8BIT(lp))				\
+			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
+	} while (0)
+#else
 #define SMC_PUSH_DATA(lp, p, l)					\
 	do {								\
 		if (SMC_32BIT(lp)) {				\
@@ -1137,10 +1195,11 @@ static const char * chip_ids[ 16 ] =  {
 					 DATA_REG(lp));		\
 			}						\
 		} else if (SMC_16BIT(lp))				\
-			SMC_outsw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
+			SMC_outsw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
 		else if (SMC_8BIT(lp))				\
 			SMC_outsb(ioaddr, DATA_REG(lp), p, l);	\
 	} while (0)
+#endif
 
 #define SMC_PULL_DATA(lp, p, l)					\
 	do {								\
@@ -1172,7 +1231,7 @@ static const char * chip_ids[ 16 ] =  {
 			__len += 2;					\
 			SMC_insl(__ioaddr, DATA_REG(lp), __ptr, __len>>2); \
 		} else if (SMC_16BIT(lp))				\
-			SMC_insw(ioaddr, DATA_REG(lp), p, (l) >> 1);	\
+			SMC_insw(ioaddr, DATA_REG(lp), (u16 *) p, (l) >> 1);	\
 		else if (SMC_8BIT(lp))				\
 			SMC_insb(ioaddr, DATA_REG(lp), p, l);		\
 	} while (0)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c)
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (6 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 07/12] m68k/atari: EtherNAT - ethernet support - new driver (smc91x) Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 09/12] m68k/atari: EtherNAT - add interrupt chip definition for CPLD interrupts Michael Schmitz
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Support for Atari EtherNEC ROM port adapters in ne.c

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/Kconfig.devices         |   14 ++++++++++++++
 drivers/net/ethernet/8390/Kconfig |    3 ++-
 drivers/net/ethernet/8390/ne.c    |    2 ++
 3 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
index d50ecbf..d163991 100644
--- a/arch/m68k/Kconfig.devices
+++ b/arch/m68k/Kconfig.devices
@@ -65,6 +65,20 @@ config ATARI_ETHERNAT
 	  To compile the actual ethernet driver, choose Y or M for the SMC91X
 	  option in the network device section; the module will be called smc91x.
 
+config ATARI_ETHERNEC
+	bool "Atari EtherNEC Ethernet support"
+	depends on ATARI_ROM_ISA
+	---help---
+	  Say Y to include support for the EtherNEC network adapter for the
+	  ROM port. The driver works by polling instead of interrupts, so it
+	  is quite slow.
+
+	  This driver also suppports the ethernet part of the NetUSBee ROM
+	  port combined Ethernet/USB adapter.
+
+	  To compile the actual ethernet driver, choose Y or M in for the NE2000
+	  option in the network device section; the module will be called ne.
+
 endmenu
 
 menu "Character devices"
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index a5f91e1..53abc78 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -91,7 +91,8 @@ config MCF8390
 
 config NE2000
 	tristate "NE2000/NE1000 support"
-	depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX)
+	depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX || \
+		    ATARI_ETHERNEC)
 	select CRC32
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index 47618e5..49948f6 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -166,6 +166,8 @@ bad_clone_list[] __initdata = {
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
    defined(CONFIG_MACH_TX49XX)
 #  define DCR_VAL 0x48		/* 8-bit mode */
+#elif defined(CONFIG_ATARI)	/* 8-bit mode on Atari, normal on Q40 */
+#  define DCR_VAL (MACH_IS_ATARI ? 0x48 : 0x49)
 #else
 #  define DCR_VAL 0x49
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/12] m68k/atari: EtherNAT - add interrupt chip definition for CPLD interrupts
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (7 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c) Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 10/12] m68k: Implement ndelay() based on the existing udelay() logic Michael Schmitz
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add a dedicated interrupt chip definition for the EtherNAT CPLD interrupts. SMC91C111 and
ISP1160 chips have separate interrupts that can be enabled and disabled in a CPLD register
at offset 0x23 from the card base.

The smc91x and isp116x-hcd drivers will use this feature.

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/ataints.c |   68 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c
index 2cf7349..525e641 100644
--- a/arch/m68k/atari/ataints.c
+++ b/arch/m68k/atari/ataints.c
@@ -49,6 +49,7 @@
 #include <asm/atari_stdma.h>
 #include <asm/irq.h>
 #include <asm/entry.h>
+#include <asm/io.h>
 
 
 /*
@@ -177,6 +178,66 @@ static struct irq_chip atari_mfptimer_chip = {
 	.irq_disable	= atari_mfptimer_disable,
 };
 
+
+/*
+ * EtherNAT CPLD interrupt handling
+ * CPLD interrupt register is at phys. 0x80000023
+ * Need this mapped in at interrupt startup time
+ */
+
+static unsigned char *enat_cpld;
+
+static unsigned int atari_ethernat_startup(struct irq_data *data)
+{
+	int enat_num = 140 - data->irq + 1;
+
+	m68k_irq_startup(data);
+	/*
+	* map CPLD interrupt register
+	*/
+	if (!enat_cpld)
+		enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
+	/*
+	 * do _not_ enable the USB chip interrupt here - causes interrupt storm
+	 * and triggers dead interrupt watchdog
+	 * Need to reset the USB chip to a sane state in early startup before removing this hack
+	 */
+	if (enat_num == 1)
+		*enat_cpld |= 1 << enat_num;
+
+	return 0;
+}
+
+static void atari_ethernat_enable(struct irq_data *data)
+{
+	int enat_num = 140 - data->irq + 1;
+	*enat_cpld |= 1 << enat_num;
+}
+
+static void atari_ethernat_disable(struct irq_data *data)
+{
+	int enat_num = 140 - data->irq + 1;
+	*enat_cpld &= ~(1 << enat_num);
+}
+
+static void atari_ethernat_shutdown(struct irq_data *data)
+{
+	int enat_num = 140 - data->irq + 1;
+	if (enat_cpld) {
+		*enat_cpld &= ~(1 << enat_num);
+		iounmap(enat_cpld);
+		enat_cpld = NULL;
+	}
+}
+
+static struct irq_chip atari_ethernat_chip = {
+	.name		= "ethernat",
+	.irq_startup	= atari_ethernat_startup,
+	.irq_shutdown	= atari_ethernat_shutdown,
+	.irq_enable	= atari_ethernat_enable,
+	.irq_disable	= atari_ethernat_disable,
+};
+
 /*
  * void atari_init_IRQ (void)
  *
@@ -268,6 +329,13 @@ void __init atari_init_IRQ(void)
 	if (request_irq(IRQ_MFP_TIMD, mfptimer_handler, IRQF_SHARED,
 			stmfp_base.name, &stmfp_base))
 		pr_err("Couldn't register %s interrupt\n", stmfp_base.name);
+
+	/*
+	 * EtherNAT ethernet / USB interrupt handlers
+	 */
+
+	m68k_setup_irq_controller(&atari_ethernat_chip, handle_simple_irq,
+				  139, 2);
 }
 
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/12] m68k: Implement ndelay() based on the existing udelay() logic
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (8 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 09/12] m68k/atari: EtherNAT - add interrupt chip definition for CPLD interrupts Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 11/12] m68k/atari: USB - add platform devices for EtherNAT/NetUSBee ISP1160 HCD Michael Schmitz
  2013-03-30  0:27 ` [PATCH 12/12] m68k/atari: USB - add ISP1160 USB host controller support Michael Schmitz
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add a ndelay macro modeled after the Coldfire udelay(). The ISP1160
driver needs a 150ns delay, so we need to have ndelay().

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/include/asm/delay.h |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h
index 12d8fe4..8a9971d 100644
--- a/arch/m68k/include/asm/delay.h
+++ b/arch/m68k/include/asm/delay.h
@@ -92,5 +92,25 @@ static inline void __udelay(unsigned long usecs)
 #define udelay(n) (__builtin_constant_p(n) ? \
 	((n) > 20000 ? __bad_udelay() : __const_udelay(n)) : __udelay(n))
 
+/*
+ * nanosecond delay:
+ *
+ * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6) is the number of loops per microsecond
+ *
+ * 1000 / ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6) is the number of nanoseconds per loop
+ *
+ * So n / ( 1000 / ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6) ) would be the number of loops for n nanoseconds
+ */
+
+/*
+ * The simpler m68k and ColdFire processors do not have a 32*32->64
+ * multiply instruction. So we need to handle them a little differently.
+ * We use a bit of shifting and a single 32*32->32 multiply to get close.
+ * This is a macro so that the const version can factor out the first
+ * multiply and shift.
+ */
+#define	HZSCALE		(268435456 / (1000000 / HZ))
+
+#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
 
 #endif /* defined(_M68K_DELAY_H) */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/12] m68k/atari: USB - add platform devices for EtherNAT/NetUSBee ISP1160 HCD
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (9 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 10/12] m68k: Implement ndelay() based on the existing udelay() logic Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  2013-03-30  0:27 ` [PATCH 12/12] m68k/atari: USB - add ISP1160 USB host controller support Michael Schmitz
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add platform devices used by the isp116x-hcd driver for EtherNAT and
NetUSBee. Note that the NetUSBee also contains a RTL8019 Ethernet chip,
so its platform device is used to cover the EtherNEC case, too.
Register definitions thanks to David Galvez <dgalvez75@gmail.com>

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/atari/config.c |  131 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 126 insertions(+), 5 deletions(-)

diff --git a/arch/m68k/atari/config.c b/arch/m68k/atari/config.c
index fdcd875..29ffc1a 100644
--- a/arch/m68k/atari/config.c
+++ b/arch/m68k/atari/config.c
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
+#include <linux/usb/isp116x.h>
 #include <linux/vt_kern.h>
 #include <linux/module.h>
 
@@ -690,8 +691,70 @@ static struct platform_device smc91x_device = {
 	.resource	= smc91x_resources,
 };
 
+/*
+ * ISP 1160 - using the isp116x-hcd module
+ */
+
+#define ATARI_USB_PHYS_ADDR	0x80000012
+#define ATARI_USB_IRQ		139
+
+static struct resource isp1160_resources[] = {
+	[0] = {
+		.name	= "isp1160-data",
+		.start	= ATARI_USB_PHYS_ADDR,
+		.end	= ATARI_USB_PHYS_ADDR + 0x1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "isp1160-regs",
+		.start	= ATARI_USB_PHYS_ADDR + 0x4,
+		.end	= ATARI_USB_PHYS_ADDR + 0x5,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.name	= "isp1160-irq",
+		.start	= ATARI_USB_IRQ,
+		.end	= ATARI_USB_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void isp1160_delay(struct device *dev, int delay)
+{
+	ndelay(delay);
+}
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data isp1160_platform_data = {
+	/* Enable internal resistors on downstream ports */
+	.sel15Kres		= 1,
+	/* On-chip overcurrent protection */
+	.oc_enable		= 1,
+	/* INT output polarity */
+	.int_act_high		= 1,
+	/* INT edge or level triggered */
+	.int_edge_triggered	= 0,
+
+	/* WAKEUP pin connected - NOT SUPPORTED  */
+	/* .remote_wakeup_connected = 0, */
+	/* Wakeup by devices on usb bus enabled */
+	.remote_wakeup_enable	= 0,
+	.delay			= isp1160_delay,
+};
+
+static struct platform_device isp1160_device = {
+	.name		= "isp116x-hcd",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(isp1160_resources),
+	.resource	= isp1160_resources,
+	.dev			= {
+		.platform_data	= &isp1160_platform_data,
+	},
+};
+
 static struct platform_device *atari_ethernat_devices[] __initdata = {
-	&smc91x_device
+	&smc91x_device,
+	&isp1160_device
 };
 
 /*
@@ -725,8 +788,66 @@ static struct platform_device rtl8019_device = {
 	.resource	= rtl8019_resources,
 };
 
-static struct platform_device *atari_ethernec_devices[] __initdata = {
-	&rtl8019_device
+/*
+ * NetUSBee: ISP1160 USB host adapter via ROM-port adapter
+ */
+
+#define ATARI_NETUSBEE_PHYS_ADDR	0xfffa8000
+#define ATARI_NETUSBEE_BASE		0x340
+#define ATARI_NETUSBEE_IRQ		IRQ_MFP_TIMER2
+
+static struct resource netusbee_resources[] = {
+	[0] = {
+		.name	= "isp1160-data",
+		.start	= ATARI_NETUSBEE_BASE,
+		.end	= ATARI_NETUSBEE_BASE + 0x1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.name	= "isp1160-regs",
+		.start	= ATARI_NETUSBEE_BASE + 0x20,
+		.end	= ATARI_NETUSBEE_BASE + 0x21,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.name	= "isp1160-irq",
+		.start	= ATARI_NETUSBEE_IRQ,
+		.end	= ATARI_NETUSBEE_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+/* (DataBusWidth16|AnalogOCEnable|DREQOutputPolarity|DownstreamPort15KRSel ) */
+static struct isp116x_platform_data netusbee_platform_data = {
+	/* Enable internal resistors on downstream ports */
+	.sel15Kres		= 1,
+	/* On-chip overcurrent protection */
+	.oc_enable		= 1,
+	/* INT output polarity */
+	.int_act_high		= 1,
+	/* INT edge or level triggered */
+	.int_edge_triggered	= 0,
+
+	/* WAKEUP pin connected - NOT SUPPORTED  */
+	/* .remote_wakeup_connected = 0, */
+	/* Wakeup by devices on usb bus enabled */
+	.remote_wakeup_enable	= 0,
+	.delay			= isp1160_delay,
+};
+
+static struct platform_device netusbee_device = {
+	.name		= "isp116x-hcd",
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(netusbee_resources),
+	.resource	= netusbee_resources,
+	.dev			= {
+		.platform_data	= &netusbee_platform_data,
+	},
+};
+
+static struct platform_device *atari_netusbee_devices[] __initdata = {
+	&rtl8019_device,
+	&netusbee_device
 };
 
 int __init atari_platform_init(void)
@@ -754,8 +875,8 @@ int __init atari_platform_init(void)
 		unsigned char *enec_virt;
 		enec_virt = (unsigned char *)ioremap((ATARI_ETHERNEC_PHYS_ADDR), 0xf);
 		if (hwreg_present(enec_virt)) {
-			error = platform_add_devices(atari_ethernec_devices,
-						ARRAY_SIZE(atari_ethernec_devices));
+			error = platform_add_devices(atari_netusbee_devices,
+						ARRAY_SIZE(atari_netusbee_devices));
 			if (error && !rv)
 				rv = error;
 		}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 12/12] m68k/atari: USB - add ISP1160 USB host controller support
  2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
                   ` (10 preceding siblings ...)
  2013-03-30  0:27 ` [PATCH 11/12] m68k/atari: USB - add platform devices for EtherNAT/NetUSBee ISP1160 HCD Michael Schmitz
@ 2013-03-30  0:27 ` Michael Schmitz
  11 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-03-30  0:27 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Add Atari specific quirks to the isp116x-hcd USB driver used for
EtherNAT and NetUSBee.

Debugging of FIFO register access code and NetUSBee support by
David Galvez <dgalvez75@gmail.com> (MiNT driver author)

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/Kconfig.bus          |   11 ++++
 drivers/usb/host/isp116x-hcd.c |  109 +++++++++++++++++++++++++++++++++++++++-
 drivers/usb/host/isp116x.h     |   41 ++++++++++++---
 3 files changed, 150 insertions(+), 11 deletions(-)

diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus
index 675b087..efb6aab 100644
--- a/arch/m68k/Kconfig.bus
+++ b/arch/m68k/Kconfig.bus
@@ -55,6 +55,17 @@ config ATARI_ROM_ISA
 	  The only driver currently using this adapter is the EtherNEC
 	  driver for RTL8019AS based NE2000 compatible network cards.
 
+config ATARI_USB
+	bool "Atari USB host controller support"
+	depends on ATARI
+	select USB_SUPPORT
+	select USB_ARCH_HAS_HCD
+	help
+	  This option enables support for USB host controllers contained on
+	  the EtherNAT and NetUSBee cards for Atari. You will have to select
+	  an appropriate HCD driver in the USB section (the ISP1160 one is
+	  the most commonly used one).
+
 config GENERIC_ISA_DMA
 	def_bool ISA
 
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index b64e661..fce2766 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -82,8 +82,25 @@ MODULE_LICENSE("GPL");
 
 static const char hcd_name[] = "isp116x-hcd";
 
+#ifdef CONFIG_ATARI
+static unsigned char *enat_cr;		/* EtherNAT CPLD control register for USB interrupt enable */
+#endif
+
 /*-----------------------------------------------------------------*/
 
+  /*
+   * 16 bit data bus byte swapped in hardware
+   *
+   * isp116x_write_addr uses raw_readw - hw byte swap takes care of different endianness
+   *
+   * isp116x_write_data16 uses raw_readw - byte swap done in hw so BE data ends up in proper LE format
+   * isp116x_raw_write_data16 uses readw - effectively same endiannes retained, use for LE format data
+   *
+   * reversed semantics of primitives allows to keep the register
+   * access functions unchanged for commands and control data - byte
+   * swap done transparently
+   */
+
 /*
   Write len bytes to fifo, pad till 32-bit boundary
  */
@@ -100,18 +117,27 @@ static void write_ptddata_to_fifo(struct isp116x *isp116x, void *buf, int len)
 
 	if ((unsigned long)dp2 & 1) {
 		/* not aligned */
+
 		for (; len > 1; len -= 2) {
 			w = *dp++;
 			w |= *dp++ << 8;
 			isp116x_raw_write_data16(isp116x, w);
 		}
 		if (len)
+#ifdef CONFIG_ATARI	/* MSch: needs swap */
+			isp116x_raw_write_data16(isp116x, (u16) *dp);
+#else
 			isp116x_write_data16(isp116x, (u16) * dp);
+#endif
 	} else {
 		/* aligned */
 		for (; len > 1; len -= 2) {
 			/* Keep byte order ! */
+#ifdef CONFIG_ATARI	/* MSch: needs swap */
+			isp116x_write_data16(isp116x, cpu_to_le16(*dp2++));
+#else
 			isp116x_raw_write_data16(isp116x, cpu_to_le16(*dp2++));
+#endif
 		}
 
 		if (len)
@@ -137,6 +163,7 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
 
 	if ((unsigned long)dp2 & 1) {
 		/* not aligned */
+
 		for (; len > 1; len -= 2) {
 			w = isp116x_raw_read_data16(isp116x);
 			*dp++ = w & 0xff;
@@ -144,12 +171,20 @@ static void read_ptddata_from_fifo(struct isp116x *isp116x, void *buf, int len)
 		}
 
 		if (len)
+#ifdef CONFIG_ATARI	/* MSch: needs swap */
+			*dp = 0xff & isp116x_raw_read_data16(isp116x);
+#else
 			*dp = 0xff & isp116x_read_data16(isp116x);
+#endif
 	} else {
 		/* aligned */
 		for (; len > 1; len -= 2) {
 			/* Keep byte order! */
+#ifdef CONFIG_ATARI	/* MSch: needs swap */
+			*dp2++ = le16_to_cpu(isp116x_read_data16(isp116x));
+#else
 			*dp2++ = le16_to_cpu(isp116x_raw_read_data16(isp116x));
+#endif
 		}
 
 		if (len)
@@ -593,6 +628,11 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd)
 	u16 irqstat;
 	irqreturn_t ret = IRQ_NONE;
 
+#ifdef CONFIG_ATARI
+	if ((unsigned long) hcd->rsrc_start >= 0x80000000UL)
+		/* EtherNAT control register, disable interrupt for USB */
+		*enat_cr = (*enat_cr) & 0xFB;
+#endif
 	spin_lock(&isp116x->lock);
 	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
 	irqstat = isp116x_read_reg16(isp116x, HCuPINT);
@@ -636,6 +676,10 @@ static irqreturn_t isp116x_irq(struct usb_hcd *hcd)
 	isp116x_write_reg16(isp116x, HCuPINTENB, isp116x->irqenb);
       done:
 	spin_unlock(&isp116x->lock);
+#ifdef CONFIG_ATARI
+	if ((unsigned long) hcd->rsrc_start >= 0x80000000UL)
+		*enat_cr = (*enat_cr) | 0x04;		/* EtherNAT control register, enable interrupt for USB */
+#endif
 	return ret;
 }
 
@@ -1259,8 +1303,11 @@ static int isp116x_reset(struct usb_hcd *hcd)
 	struct isp116x *isp116x = hcd_to_isp116x(hcd);
 	unsigned long t;
 	u16 clkrdy = 0;
+#ifdef CONFIG_ATARI
+	int ret, timeout = 200 /* ms */ ;
+#else
 	int ret, timeout = 15 /* ms */ ;
-
+#endif
 	ret = isp116x_sw_reset(isp116x);
 	if (ret)
 		return ret;
@@ -1291,6 +1338,12 @@ static void isp116x_stop(struct usb_hcd *hcd)
 	u32 val;
 
 	spin_lock_irqsave(&isp116x->lock, flags);
+
+#ifdef CONFIG_ATARI
+	if ((unsigned long) hcd->rsrc_start >= 0x80000000UL)
+		/* EtherNAT control register, disable interrupt for USB */
+		*enat_cr = (*enat_cr) & 0xFB;
+#endif
 	isp116x_write_reg16(isp116x, HCuPINTENB, 0);
 
 	/* Switch off ports' power, some devices don't come up
@@ -1356,6 +1409,12 @@ static int isp116x_start(struct usb_hcd *hcd)
 	val |= RH_A_PSM;
 	/* Report overcurrent per port */
 	val |= RH_A_OCPM;
+#ifdef CONFIG_ATARI
+	/* Galvez: For NetUSBee, Overcurrent protection disable,
+	   to stop interrupt storm because OC events */
+	if ((unsigned long) hcd->rsrc_start < 0x80000000UL)
+		val |= (RH_A_NOCP | RH_A_NPS);
+#endif
 	isp116x_write_reg32(isp116x, HCRHDESCA, val);
 	isp116x->rhdesca = isp116x_read_reg32(isp116x, HCRHDESCA);
 
@@ -1394,6 +1453,10 @@ static int isp116x_start(struct usb_hcd *hcd)
 	isp116x_write_reg32(isp116x, HCRHPORT1, RH_PS_CCS);
 	isp116x_write_reg32(isp116x, HCRHPORT2, RH_PS_CCS);
 
+#ifdef CONFIG_ATARI
+	if ((unsigned long) hcd->rsrc_start >= 0x80000000UL)
+		*enat_cr = (*enat_cr) | 0x04;		/* EtherNAT control register, enable interrupt for USB */
+#endif
 	isp116x_show_regs_log(isp116x);
 	spin_unlock_irqrestore(&isp116x->lock, flags);
 	return 0;
@@ -1539,6 +1602,9 @@ static int isp116x_remove(struct platform_device *pdev)
 	struct usb_hcd *hcd = platform_get_drvdata(pdev);
 	struct isp116x *isp116x;
 	struct resource *res;
+#ifdef CONFIG_ATARI
+	unsigned long enat_cr_phys;
+#endif
 
 	if (!hcd)
 		return 0;
@@ -1552,7 +1618,14 @@ static int isp116x_remove(struct platform_device *pdev)
 	iounmap(isp116x->addr_reg);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(res->start, 2);
-
+#ifdef CONFIG_ATARI
+	if ((unsigned long) hcd->rsrc_start >= 0x80000000UL) {
+		iounmap(enat_cr);
+		/* unmap & release EtherNAT CPLD control register - at 0x23 off board base address */
+		enat_cr_phys = (res->start & 0xFFFFFF00) + 0x23;
+		release_mem_region(enat_cr_phys, 2);
+	}
+#endif
 	usb_put_hcd(hcd);
 	return 0;
 }
@@ -1567,6 +1640,9 @@ static int isp116x_probe(struct platform_device *pdev)
 	int irq;
 	int ret = 0;
 	unsigned long irqflags;
+#ifdef CONFIG_ATARI
+	unsigned long enat_cr_phys;
+#endif
 
 	if (usb_disabled())
 		return -ENODEV;
@@ -1613,6 +1689,26 @@ static int isp116x_probe(struct platform_device *pdev)
 		goto err4;
 	}
 
+#ifdef CONFIG_ATARI
+	if ((unsigned long) data->start >= 0x80000000UL) {
+		/* map EtherNAT CPLD control register - at 0x23 off board base address */
+		enat_cr_phys = (data->start & 0xffffff00) + 0x23;
+		if (!request_mem_region(enat_cr_phys, 2, hcd_name)) {
+			ret = -EBUSY;
+			goto err41;
+		}
+		enat_cr = ioremap(enat_cr_phys, 2);
+		if (enat_cr == NULL) {
+			ret = -ENOMEM;
+			goto err42;
+		}
+		/* Disable USB interrupt in the EtherNat board */
+		*enat_cr = (*enat_cr) & 0xFB;
+	}
+	pr_info("ISP116X probe: data %p virt. %p, addr %p virt. %p\n",
+		(void *)data->start, data_reg, (void *)addr->start, addr_reg);
+#endif
+
 	/* allocate and initialize hcd */
 	hcd = usb_create_hcd(&isp116x_hc_driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd) {
@@ -1653,11 +1749,20 @@ static int isp116x_probe(struct platform_device *pdev)
 
 	return 0;
 
+
       err7:
 	usb_remove_hcd(hcd);
       err6:
 	usb_put_hcd(hcd);
       err5:
+#ifdef CONFIG_ATARI
+	if ((unsigned long) data->start >= 0x80000000UL)
+		iounmap(enat_cr);
+      err42:
+	if ((unsigned long) data->start >= 0x80000000UL)
+		release_mem_region(enat_cr_phys, 2);
+      err41:
+#endif
 	iounmap(data_reg);
       err4:
 	release_mem_region(data->start, 2);
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h
index 9a2c400..6359ccb 100644
--- a/drivers/usb/host/isp116x.h
+++ b/drivers/usb/host/isp116x.h
@@ -364,22 +364,45 @@ struct isp116x_ep {
 #define	IRQ_TEST()	do{}while(0)
 #endif
 
+
+#ifdef CONFIG_ATARI
+  /*
+   * 16 bit data bus byte swapped in hardware on both Atari variants.
+   * EtherNAT variant of ISP1160 integration is memory mapped at 0x800000XX,
+   * and uses regular readw/__raw_readw (but semantics swapped).
+   * NetUSBee variant is hooked up through ROM port and uses ROM port
+   * IO access, with fake IO address of 0x3XX.
+   * Selection of the appropriate accessors relies on ioremapped addresses still
+   * retaining the 0x3XX bit.
+   */
+#define isp_readw(p)		((((unsigned long)(__pa(p)) & 0x00000F00) == 0x00000300UL) ? isa_rom_readw_raw(__pa(p)) : __raw_readw((p)))
+#define isp_writew(v, p)	((((unsigned long)(__pa(p)) & 0x00000F00) == 0x00000300UL) ? isa_rom_writew_raw((v), __pa(p)) : __raw_writew((v), (p)))
+#define isp_raw_readw(p)	((((unsigned long)(__pa(p)) & 0x00000F00) == 0x00000300UL) ? isa_rom_readw(__pa(p)) : readw((p)))
+#define isp_raw_writew(v, p)	((((unsigned long)(__pa(p)) & 0x00000F00) == 0x00000300UL) ? isa_rom_writew((v), __pa(p)) : writew((v), (p)))
+#else
+  /* sane hardware */
+#define isp_readw		readw
+#define isp_writew		writew
+#define isp_raw_readw		__raw_readw
+#define isp_raw_writew		__raw_writew
+#endif
+
 static inline void isp116x_write_addr(struct isp116x *isp116x, unsigned reg)
 {
 	IRQ_TEST();
-	writew(reg & 0xff, isp116x->addr_reg);
+	isp_writew(reg & 0xff, isp116x->addr_reg);
 	isp116x_delay(isp116x, 300);
 }
 
 static inline void isp116x_write_data16(struct isp116x *isp116x, u16 val)
 {
-	writew(val, isp116x->data_reg);
+	isp_writew(val, isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
 }
 
 static inline void isp116x_raw_write_data16(struct isp116x *isp116x, u16 val)
 {
-	__raw_writew(val, isp116x->data_reg);
+	isp_raw_writew(val, isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
 }
 
@@ -387,7 +410,7 @@ static inline u16 isp116x_read_data16(struct isp116x *isp116x)
 {
 	u16 val;
 
-	val = readw(isp116x->data_reg);
+	val = isp_readw(isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
 	return val;
 }
@@ -396,16 +419,16 @@ static inline u16 isp116x_raw_read_data16(struct isp116x *isp116x)
 {
 	u16 val;
 
-	val = __raw_readw(isp116x->data_reg);
+	val = isp_raw_readw(isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
 	return val;
 }
 
 static inline void isp116x_write_data32(struct isp116x *isp116x, u32 val)
 {
-	writew(val & 0xffff, isp116x->data_reg);
+	isp_writew(val & 0xffff, isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
-	writew(val >> 16, isp116x->data_reg);
+	isp_writew(val >> 16, isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
 }
 
@@ -413,9 +436,9 @@ static inline u32 isp116x_read_data32(struct isp116x *isp116x)
 {
 	u32 val;
 
-	val = (u32) readw(isp116x->data_reg);
+	val = (u32) isp_readw(isp116x->data_reg);
 	isp116x_delay(isp116x, 150);
-	val |= ((u32) readw(isp116x->data_reg)) << 16;
+	val |= ((u32) isp_readw(isp116x->data_reg)) << 16;
 	isp116x_delay(isp116x, 150);
 	return val;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c)
  2013-04-06  0:26 [PATCH 0/13] Atari EtherNAT/EtherNEC/NetUSBee support Michael Schmitz
@ 2013-04-06  0:26 ` Michael Schmitz
  0 siblings, 0 replies; 14+ messages in thread
From: Michael Schmitz @ 2013-04-06  0:26 UTC (permalink / raw)
  To: geert; +Cc: linux-m68k, Michael Schmitz

Support for Atari EtherNEC ROM port adapters in ne.c

Signed-off-by: Michael Schmitz <schmitz@debian.org>
---
 arch/m68k/Kconfig.devices         |   14 ++++++++++++++
 drivers/net/ethernet/8390/Kconfig |    3 ++-
 drivers/net/ethernet/8390/ne.c    |    2 ++
 3 files changed, 18 insertions(+), 1 deletions(-)

diff --git a/arch/m68k/Kconfig.devices b/arch/m68k/Kconfig.devices
index d50ecbf..d163991 100644
--- a/arch/m68k/Kconfig.devices
+++ b/arch/m68k/Kconfig.devices
@@ -65,6 +65,20 @@ config ATARI_ETHERNAT
 	  To compile the actual ethernet driver, choose Y or M for the SMC91X
 	  option in the network device section; the module will be called smc91x.
 
+config ATARI_ETHERNEC
+	bool "Atari EtherNEC Ethernet support"
+	depends on ATARI_ROM_ISA
+	---help---
+	  Say Y to include support for the EtherNEC network adapter for the
+	  ROM port. The driver works by polling instead of interrupts, so it
+	  is quite slow.
+
+	  This driver also suppports the ethernet part of the NetUSBee ROM
+	  port combined Ethernet/USB adapter.
+
+	  To compile the actual ethernet driver, choose Y or M in for the NE2000
+	  option in the network device section; the module will be called ne.
+
 endmenu
 
 menu "Character devices"
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig
index a5f91e1..53abc78 100644
--- a/drivers/net/ethernet/8390/Kconfig
+++ b/drivers/net/ethernet/8390/Kconfig
@@ -91,7 +91,8 @@ config MCF8390
 
 config NE2000
 	tristate "NE2000/NE1000 support"
-	depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX)
+	depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX || \
+		    ATARI_ETHERNEC)
 	select CRC32
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c
index 47618e5..49948f6 100644
--- a/drivers/net/ethernet/8390/ne.c
+++ b/drivers/net/ethernet/8390/ne.c
@@ -166,6 +166,8 @@ bad_clone_list[] __initdata = {
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
    defined(CONFIG_MACH_TX49XX)
 #  define DCR_VAL 0x48		/* 8-bit mode */
+#elif defined(CONFIG_ATARI)	/* 8-bit mode on Atari, normal on Q40 */
+#  define DCR_VAL (MACH_IS_ATARI ? 0x48 : 0x49)
 #else
 #  define DCR_VAL 0x49
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-04-06  0:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-30  0:27 Atari Ethernet/USB paches for m68k-queue and upstream, refactored timer D interrupt patch Michael Schmitz
2013-03-30  0:27 ` [PATCH 01/12] m68k/atari: ROM port ISA adapter support Michael Schmitz
2013-03-30  0:27 ` [PATCH 02/12] m68k/irq: Add handle_polled_irq() for timer based soft interrupts Michael Schmitz
2013-03-30  0:27 ` [PATCH 03/12] m68k/atari: use dedicated irq_chip for timer D interrupts Michael Schmitz
2013-03-30  0:27 ` [PATCH 04/12] m68k/atari: use polled interrupt handler " Michael Schmitz
2013-03-30  0:27 ` [PATCH 05/12] m68k/atari: EtherNAT - platform device and IRQ support code Michael Schmitz
2013-03-30  0:27 ` [PATCH 06/12] m68k/atari: EtherNEC - add platform device support Michael Schmitz
2013-03-30  0:27 ` [PATCH 07/12] m68k/atari: EtherNAT - ethernet support - new driver (smc91x) Michael Schmitz
2013-03-30  0:27 ` [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c) Michael Schmitz
2013-03-30  0:27 ` [PATCH 09/12] m68k/atari: EtherNAT - add interrupt chip definition for CPLD interrupts Michael Schmitz
2013-03-30  0:27 ` [PATCH 10/12] m68k: Implement ndelay() based on the existing udelay() logic Michael Schmitz
2013-03-30  0:27 ` [PATCH 11/12] m68k/atari: USB - add platform devices for EtherNAT/NetUSBee ISP1160 HCD Michael Schmitz
2013-03-30  0:27 ` [PATCH 12/12] m68k/atari: USB - add ISP1160 USB host controller support Michael Schmitz
  -- strict thread matches above, loose matches on Subject: below --
2013-04-06  0:26 [PATCH 0/13] Atari EtherNAT/EtherNEC/NetUSBee support Michael Schmitz
2013-04-06  0:26 ` [PATCH 08/12] m68k/atari: EtherNEC - ethernet support - new driver (ne.c) Michael Schmitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox