|
@@ -49,6 +49,7 @@
|
|
|
#include <asm/atari_stdma.h>
|
|
|
#include <asm/irq.h>
|
|
|
#include <asm/entry.h>
|
|
|
+#include <asm/io.h>
|
|
|
|
|
|
|
|
|
/*
|
|
@@ -177,6 +178,80 @@ 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
|
|
|
+ * Possibly need this mapped on demand anyway -
|
|
|
+ * EtherNAT USB driver needs to disable IRQ before
|
|
|
+ * startup!
|
|
|
+ */
|
|
|
+
|
|
|
+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;
|
|
|
+ /*
|
|
|
+ * map CPLD interrupt register
|
|
|
+ */
|
|
|
+ if (!enat_cpld)
|
|
|
+ enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
|
|
|
+ *enat_cpld |= 1 << enat_num;
|
|
|
+}
|
|
|
+
|
|
|
+static void atari_ethernat_disable(struct irq_data *data)
|
|
|
+{
|
|
|
+ int enat_num = 140 - data->irq + 1;
|
|
|
+ /*
|
|
|
+ * map CPLD interrupt register
|
|
|
+ */
|
|
|
+ if (!enat_cpld)
|
|
|
+ enat_cpld = (unsigned char *)ioremap((ATARI_ETHERNAT_PHYS_ADDR+0x23), 0x2);
|
|
|
+ *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 +343,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);
|
|
|
}
|
|
|
|
|
|
|