ARM: footbridge: move isa-dma support into footbridge
authorArnd Bergmann <arnd@arndb.de>
Fri, 1 Jul 2022 09:44:52 +0000 (11:44 +0200)
committerArnd Bergmann <arnd@arndb.de>
Fri, 9 Sep 2022 15:14:34 +0000 (17:14 +0200)
The dma-isa.c was shared between footbridge and shark a long time ago,
but as shark was removed, it can be made footbridge specific again.

The fb_dma bits in turn are not used at all and can be removed.

All the ISA related files are now built into the platform regardless
of CONFIG_ISA, as they just refer to on-chip devices rather than actual
ISA cards.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
arch/arm/Kconfig
arch/arm/include/asm/mach/dma.h
arch/arm/kernel/Makefile
arch/arm/kernel/dma-isa.c [deleted file]
arch/arm/mach-footbridge/Kconfig
arch/arm/mach-footbridge/Makefile
arch/arm/mach-footbridge/dma-isa.c [new file with mode: 0644]
arch/arm/mach-footbridge/dma.c [deleted file]
arch/arm/mach-footbridge/include/mach/isa-dma.h

index 87badeae3181ea7ffd7aaca09fd12e8b3cf456b6..ec7e48f6bd91da6b0e018d440f20248795ba0e70 100644 (file)
@@ -989,11 +989,6 @@ 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.
 
-# Select ISA DMA controller support
-config ISA_DMA
-       bool
-       select ISA_DMA_API
-
 # Select ISA DMA interface
 config ISA_DMA_API
        bool
index 1506422af3832201938fa4e7265a71fad7e4d20e..5ec11d7f0d0453ee5d4b548f1a661c2097d193ae 100644 (file)
@@ -44,8 +44,3 @@ struct dma_struct {
  * isa_dma_add - add an ISA-style DMA channel
  */
 extern int isa_dma_add(unsigned int, dma_t *dma);
-
-/*
- * Add the ISA DMA controller.  Always takes channels 0-7.
- */
-extern void isa_init_dma(void);
index 553866751e1a5ce66c805c083e392c1f0646088e..95034d32213c50106c7d0ae58b2b5dc7f852598e 100644 (file)
@@ -45,7 +45,6 @@ obj-$(CONFIG_ISA_DMA_API)     += dma.o
 obj-$(CONFIG_FIQ)              += fiq.o fiqasm.o
 obj-$(CONFIG_MODULES)          += armksyms.o module.o
 obj-$(CONFIG_ARM_MODULE_PLTS)  += module-plts.o
-obj-$(CONFIG_ISA_DMA)          += dma-isa.o
 obj-$(CONFIG_PCI)              += bios32.o isa.o
 obj-$(CONFIG_ARM_CPU_SUSPEND)  += sleep.o suspend.o
 obj-$(CONFIG_HIBERNATION)      += hibernate.o
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
deleted file mode 100644 (file)
index 2d90ecc..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *  linux/arch/arm/kernel/dma-isa.c
- *
- *  Copyright (C) 1999-2000 Russell King
- *
- *  ISA DMA primitives
- *  Taken from various sources, including:
- *   linux/include/asm/dma.h: Defines for using and allocating dma channels.
- *     Written by Hennus Bergman, 1992.
- *     High DMA channel support & info by Hannu Savolainen and John Boyd,
- *     Nov. 1992.
- *   arch/arm/kernel/dma-ebsa285.c
- *   Copyright (C) 1998 Phil Blundell
- */
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-
-#include <asm/dma.h>
-#include <asm/mach/dma.h>
-
-#define ISA_DMA_MASK           0
-#define ISA_DMA_MODE           1
-#define ISA_DMA_CLRFF          2
-#define ISA_DMA_PGHI           3
-#define ISA_DMA_PGLO           4
-#define ISA_DMA_ADDR           5
-#define ISA_DMA_COUNT          6
-
-static unsigned int isa_dma_port[8][7] = {
-       /* MASK   MODE   CLRFF  PAGE_HI PAGE_LO ADDR COUNT */
-       {  0x0a,  0x0b,  0x0c,  0x487,  0x087,  0x00, 0x01 },
-       {  0x0a,  0x0b,  0x0c,  0x483,  0x083,  0x02, 0x03 },
-       {  0x0a,  0x0b,  0x0c,  0x481,  0x081,  0x04, 0x05 },
-       {  0x0a,  0x0b,  0x0c,  0x482,  0x082,  0x06, 0x07 },
-       {  0xd4,  0xd6,  0xd8,  0x000,  0x000,  0xc0, 0xc2 },
-       {  0xd4,  0xd6,  0xd8,  0x48b,  0x08b,  0xc4, 0xc6 },
-       {  0xd4,  0xd6,  0xd8,  0x489,  0x089,  0xc8, 0xca },
-       {  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
-};
-
-static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
-{
-       unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
-       int count;
-
-       count = 1 + inb(io_port);
-       count |= inb(io_port) << 8;
-
-       return chan < 4 ? count : (count << 1);
-}
-
-static struct device isa_dma_dev = {
-       .init_name              = "fallback device",
-       .coherent_dma_mask      = ~(dma_addr_t)0,
-       .dma_mask               = &isa_dma_dev.coherent_dma_mask,
-};
-
-static void isa_enable_dma(unsigned int chan, dma_t *dma)
-{
-       if (dma->invalid) {
-               unsigned long address, length;
-               unsigned int mode;
-               enum dma_data_direction direction;
-
-               mode = (chan & 3) | dma->dma_mode;
-               switch (dma->dma_mode & DMA_MODE_MASK) {
-               case DMA_MODE_READ:
-                       direction = DMA_FROM_DEVICE;
-                       break;
-
-               case DMA_MODE_WRITE:
-                       direction = DMA_TO_DEVICE;
-                       break;
-
-               case DMA_MODE_CASCADE:
-                       direction = DMA_BIDIRECTIONAL;
-                       break;
-
-               default:
-                       direction = DMA_NONE;
-                       break;
-               }
-
-               if (!dma->sg) {
-                       /*
-                        * Cope with ISA-style drivers which expect cache
-                        * coherence.
-                        */
-                       dma->sg = &dma->buf;
-                       dma->sgcount = 1;
-                       dma->buf.length = dma->count;
-                       dma->buf.dma_address = dma_map_single(&isa_dma_dev,
-                               dma->addr, dma->count,
-                               direction);
-               }
-
-               address = dma->buf.dma_address;
-               length  = dma->buf.length - 1;
-
-               outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
-               outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
-
-               if (chan >= 4) {
-                       address >>= 1;
-                       length >>= 1;
-               }
-
-               outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
-
-               outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
-               outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
-
-               outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
-               outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
-
-               outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
-               dma->invalid = 0;
-       }
-       outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
-}
-
-static void isa_disable_dma(unsigned int chan, dma_t *dma)
-{
-       outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
-}
-
-static struct dma_ops isa_dma_ops = {
-       .type           = "ISA",
-       .enable         = isa_enable_dma,
-       .disable        = isa_disable_dma,
-       .residue        = isa_get_dma_residue,
-};
-
-static struct resource dma_resources[] = { {
-       .name   = "dma1",
-       .start  = 0x0000,
-       .end    = 0x000f
-}, {
-       .name   = "dma low page",
-       .start  = 0x0080,
-       .end    = 0x008f
-}, {
-       .name   = "dma2",
-       .start  = 0x00c0,
-       .end    = 0x00df
-}, {
-       .name   = "dma high page",
-       .start  = 0x0480,
-       .end    = 0x048f
-} };
-
-static dma_t isa_dma[8];
-
-/*
- * ISA DMA always starts at channel 0
- */
-void __init isa_init_dma(void)
-{
-       /*
-        * Try to autodetect presence of an ISA DMA controller.
-        * We do some minimal initialisation, and check that
-        * channel 0's DMA address registers are writeable.
-        */
-       outb(0xff, 0x0d);
-       outb(0xff, 0xda);
-
-       /*
-        * Write high and low address, and then read them back
-        * in the same order.
-        */
-       outb(0x55, 0x00);
-       outb(0xaa, 0x00);
-
-       if (inb(0) == 0x55 && inb(0) == 0xaa) {
-               unsigned int chan, i;
-
-               for (chan = 0; chan < 8; chan++) {
-                       isa_dma[chan].d_ops = &isa_dma_ops;
-                       isa_disable_dma(chan, NULL);
-               }
-
-               outb(0x40, 0x0b);
-               outb(0x41, 0x0b);
-               outb(0x42, 0x0b);
-               outb(0x43, 0x0b);
-
-               outb(0xc0, 0xd6);
-               outb(0x41, 0xd6);
-               outb(0x42, 0xd6);
-               outb(0x43, 0xd6);
-
-               outb(0, 0xd4);
-
-               outb(0x10, 0x08);
-               outb(0x10, 0xd0);
-
-               /*
-                * Is this correct?  According to my documentation, it
-                * doesn't appear to be.  It should be:
-                *  outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
-                */
-               outb(0x30, 0x40b);
-               outb(0x31, 0x40b);
-               outb(0x32, 0x40b);
-               outb(0x33, 0x40b);
-               outb(0x31, 0x4d6);
-               outb(0x32, 0x4d6);
-               outb(0x33, 0x4d6);
-
-               for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
-                       request_resource(&ioport_resource, dma_resources + i);
-
-               for (chan = 0; chan < 8; chan++) {
-                       int ret = isa_dma_add(chan, &isa_dma[chan]);
-                       if (ret)
-                               pr_err("ISADMA%u: unable to register: %d\n",
-                                      chan, ret);
-               }
-
-               request_dma(DMA_ISA_CASCADE, "cascade");
-       }
-}
index 3497ea8e91e37d3a78316637598ee6079cba13ff..1a3676109654c67f3c3e68ca0ca1ba7ebf60f114 100644 (file)
@@ -48,7 +48,7 @@ config FOOTBRIDGE
        def_bool y
        select ARCH_HAS_PHYS_TO_DMA
        select ARCH_MIGHT_HAVE_PC_SERIO
-       select ISA_DMA
+       select ISA_DMA_API
 
 config ARCH_EBSA285
        bool
index 30bae6684dce682ea752963664c9850c2db48851..55d570739f19847a61c4190d04aa54d8b89a6204 100644 (file)
@@ -5,7 +5,7 @@
 
 # Object file lists.
 
-obj-y                  := common.o dma.o isa-irq.o
+obj-y                  := common.o isa-irq.o isa.o isa-rtc.o dma-isa.o
 
 pci-y                  += dc21285.o
 pci-$(CONFIG_ARCH_CATS) += cats-pci.o
@@ -18,4 +18,3 @@ obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o isa-timer.o
 
 obj-$(CONFIG_PCI)      +=$(pci-y)
 
-obj-$(CONFIG_ISA)      += isa.o isa-rtc.o
diff --git a/arch/arm/mach-footbridge/dma-isa.c b/arch/arm/mach-footbridge/dma-isa.c
new file mode 100644 (file)
index 0000000..0fc0705
--- /dev/null
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *  Copyright (C) 1999-2000 Russell King
+ *
+ *  ISA DMA primitives
+ *  Taken from various sources, including:
+ *   linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ *     Written by Hennus Bergman, 1992.
+ *     High DMA channel support & info by Hannu Savolainen and John Boyd,
+ *     Nov. 1992.
+ *   arch/arm/kernel/dma-ebsa285.c
+ *   Copyright (C) 1998 Phil Blundell
+ */
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+
+#define ISA_DMA_MASK           0
+#define ISA_DMA_MODE           1
+#define ISA_DMA_CLRFF          2
+#define ISA_DMA_PGHI           3
+#define ISA_DMA_PGLO           4
+#define ISA_DMA_ADDR           5
+#define ISA_DMA_COUNT          6
+
+static unsigned int isa_dma_port[8][7] = {
+       /* MASK   MODE   CLRFF  PAGE_HI PAGE_LO ADDR COUNT */
+       {  0x0a,  0x0b,  0x0c,  0x487,  0x087,  0x00, 0x01 },
+       {  0x0a,  0x0b,  0x0c,  0x483,  0x083,  0x02, 0x03 },
+       {  0x0a,  0x0b,  0x0c,  0x481,  0x081,  0x04, 0x05 },
+       {  0x0a,  0x0b,  0x0c,  0x482,  0x082,  0x06, 0x07 },
+       {  0xd4,  0xd6,  0xd8,  0x000,  0x000,  0xc0, 0xc2 },
+       {  0xd4,  0xd6,  0xd8,  0x48b,  0x08b,  0xc4, 0xc6 },
+       {  0xd4,  0xd6,  0xd8,  0x489,  0x089,  0xc8, 0xca },
+       {  0xd4,  0xd6,  0xd8,  0x48a,  0x08a,  0xcc, 0xce }
+};
+
+static int isa_get_dma_residue(unsigned int chan, dma_t *dma)
+{
+       unsigned int io_port = isa_dma_port[chan][ISA_DMA_COUNT];
+       int count;
+
+       count = 1 + inb(io_port);
+       count |= inb(io_port) << 8;
+
+       return chan < 4 ? count : (count << 1);
+}
+
+static struct device isa_dma_dev = {
+       .init_name              = "fallback device",
+       .coherent_dma_mask      = ~(dma_addr_t)0,
+       .dma_mask               = &isa_dma_dev.coherent_dma_mask,
+};
+
+static void isa_enable_dma(unsigned int chan, dma_t *dma)
+{
+       if (dma->invalid) {
+               unsigned long address, length;
+               unsigned int mode;
+               enum dma_data_direction direction;
+
+               mode = (chan & 3) | dma->dma_mode;
+               switch (dma->dma_mode & DMA_MODE_MASK) {
+               case DMA_MODE_READ:
+                       direction = DMA_FROM_DEVICE;
+                       break;
+
+               case DMA_MODE_WRITE:
+                       direction = DMA_TO_DEVICE;
+                       break;
+
+               case DMA_MODE_CASCADE:
+                       direction = DMA_BIDIRECTIONAL;
+                       break;
+
+               default:
+                       direction = DMA_NONE;
+                       break;
+               }
+
+               if (!dma->sg) {
+                       /*
+                        * Cope with ISA-style drivers which expect cache
+                        * coherence.
+                        */
+                       dma->sg = &dma->buf;
+                       dma->sgcount = 1;
+                       dma->buf.length = dma->count;
+                       dma->buf.dma_address = dma_map_single(&isa_dma_dev,
+                               dma->addr, dma->count,
+                               direction);
+               }
+
+               address = dma->buf.dma_address;
+               length  = dma->buf.length - 1;
+
+               outb(address >> 16, isa_dma_port[chan][ISA_DMA_PGLO]);
+               outb(address >> 24, isa_dma_port[chan][ISA_DMA_PGHI]);
+
+               if (chan >= 4) {
+                       address >>= 1;
+                       length >>= 1;
+               }
+
+               outb(0, isa_dma_port[chan][ISA_DMA_CLRFF]);
+
+               outb(address, isa_dma_port[chan][ISA_DMA_ADDR]);
+               outb(address >> 8, isa_dma_port[chan][ISA_DMA_ADDR]);
+
+               outb(length, isa_dma_port[chan][ISA_DMA_COUNT]);
+               outb(length >> 8, isa_dma_port[chan][ISA_DMA_COUNT]);
+
+               outb(mode, isa_dma_port[chan][ISA_DMA_MODE]);
+               dma->invalid = 0;
+       }
+       outb(chan & 3, isa_dma_port[chan][ISA_DMA_MASK]);
+}
+
+static void isa_disable_dma(unsigned int chan, dma_t *dma)
+{
+       outb(chan | 4, isa_dma_port[chan][ISA_DMA_MASK]);
+}
+
+static struct dma_ops isa_dma_ops = {
+       .type           = "ISA",
+       .enable         = isa_enable_dma,
+       .disable        = isa_disable_dma,
+       .residue        = isa_get_dma_residue,
+};
+
+static struct resource dma_resources[] = { {
+       .name   = "dma1",
+       .start  = 0x0000,
+       .end    = 0x000f
+}, {
+       .name   = "dma low page",
+       .start  = 0x0080,
+       .end    = 0x008f
+}, {
+       .name   = "dma2",
+       .start  = 0x00c0,
+       .end    = 0x00df
+}, {
+       .name   = "dma high page",
+       .start  = 0x0480,
+       .end    = 0x048f
+} };
+
+static dma_t isa_dma[8];
+
+/*
+ * ISA DMA always starts at channel 0
+ */
+static int __init isa_dma_init(void)
+{
+       /*
+        * Try to autodetect presence of an ISA DMA controller.
+        * We do some minimal initialisation, and check that
+        * channel 0's DMA address registers are writeable.
+        */
+       outb(0xff, 0x0d);
+       outb(0xff, 0xda);
+
+       /*
+        * Write high and low address, and then read them back
+        * in the same order.
+        */
+       outb(0x55, 0x00);
+       outb(0xaa, 0x00);
+
+       if (inb(0) == 0x55 && inb(0) == 0xaa) {
+               unsigned int chan, i;
+
+               for (chan = 0; chan < 8; chan++) {
+                       isa_dma[chan].d_ops = &isa_dma_ops;
+                       isa_disable_dma(chan, NULL);
+               }
+
+               outb(0x40, 0x0b);
+               outb(0x41, 0x0b);
+               outb(0x42, 0x0b);
+               outb(0x43, 0x0b);
+
+               outb(0xc0, 0xd6);
+               outb(0x41, 0xd6);
+               outb(0x42, 0xd6);
+               outb(0x43, 0xd6);
+
+               outb(0, 0xd4);
+
+               outb(0x10, 0x08);
+               outb(0x10, 0xd0);
+
+               /*
+                * Is this correct?  According to my documentation, it
+                * doesn't appear to be.  It should be:
+                *  outb(0x3f, 0x40b); outb(0x3f, 0x4d6);
+                */
+               outb(0x30, 0x40b);
+               outb(0x31, 0x40b);
+               outb(0x32, 0x40b);
+               outb(0x33, 0x40b);
+               outb(0x31, 0x4d6);
+               outb(0x32, 0x4d6);
+               outb(0x33, 0x4d6);
+
+               for (i = 0; i < ARRAY_SIZE(dma_resources); i++)
+                       request_resource(&ioport_resource, dma_resources + i);
+
+               for (chan = 0; chan < 8; chan++) {
+                       int ret = isa_dma_add(chan, &isa_dma[chan]);
+                       if (ret)
+                               pr_err("ISADMA%u: unable to register: %d\n",
+                                      chan, ret);
+               }
+
+               request_dma(DMA_ISA_CASCADE, "cascade");
+       }
+
+       return 0;
+}
+core_initcall(isa_dma_init);
diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
deleted file mode 100644 (file)
index 228757c..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- *  linux/arch/arm/kernel/dma-ebsa285.c
- *
- *  Copyright (C) 1998 Phil Blundell
- *
- * DMA functions specific to EBSA-285/CATS architectures
- *
- *  Changelog:
- *   09-Nov-1998 RMK   Split out ISA DMA functions to dma-isa.c
- *   17-Mar-1999 RMK   Allow any EBSA285-like architecture to have
- *                     ISA DMA controllers.
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-#include <linux/scatterlist.h>
-
-#include <asm/dma.h>
-
-#include <asm/mach/dma.h>
-#include <asm/hardware/dec21285.h>
-
-#if 0
-static int fb_dma_request(unsigned int chan, dma_t *dma)
-{
-       return -EINVAL;
-}
-
-static void fb_dma_enable(unsigned int chan, dma_t *dma)
-{
-}
-
-static void fb_dma_disable(unsigned int chan, dma_t *dma)
-{
-}
-
-static struct dma_ops fb_dma_ops = {
-       .type           = "fb",
-       .request        = fb_dma_request,
-       .enable         = fb_dma_enable,
-       .disable        = fb_dma_disable,
-};
-#endif
-
-static int __init fb_dma_init(void)
-{
-#if 0
-       dma[_DC21285_DMA(0)].d_ops = &fb_dma_ops;
-       dma[_DC21285_DMA(1)].d_ops = &fb_dma_ops;
-#endif
-#ifdef CONFIG_ISA_DMA
-       isa_init_dma();
-#endif
-       return 0;
-}
-core_initcall(fb_dma_init);
index 8a1b991076e1668c7945dc81d6fcd0f8a489dec2..b10731a1f66a8b47c59d4d5e9a9a7d9c52cbd65d 100644 (file)
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 
-/*
- * The 21285 has two internal DMA channels; we call these 8 and 9.
- * On CATS hardware we have an additional eight ISA dma channels
- * numbered 0..7.
- */
-#define _ISA_DMA(x)            (0+(x))
-#define _DC21285_DMA(x)                (8+(x))
-
-#define MAX_DMA_CHANNELS       10
+#define MAX_DMA_CHANNELS       8
 
-#define DMA_FLOPPY             _ISA_DMA(2)
-#define DMA_ISA_CASCADE                _ISA_DMA(4)
+#define DMA_FLOPPY             (2)
+#define DMA_ISA_CASCADE                (4)
 
 #endif /* _ASM_ARCH_DMA_H */