* [PATCH 00/16] more mac68k fixes and cleanup
@ 2011-10-23 14:11 Finn Thain
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
` (16 more replies)
0 siblings, 17 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
Hi Geert,
It would be good if this whole series passes through the m68k tree.
I based this patch series on linux-3.1-rc5 + linux-m68k +
genirq conversion v6 + three patches* already sent.
The resulting build was tested on the following hardware.
PowerBook 520, 190, 180 and 150
Quadra 700, 660av, 650
LC 630, LC III
Mac IIfx
That covers VIA, RBV, OSS, PSC, Baboon, PMU V1 and PMU V2 code.
The workload exercised all drivers simultaneously and showed no regression.
I suppose that after all of the renaming recently this series will need
to be rebased (?)
I am sending it for review anyway.
Finn
*
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commitdiff;h=e544d704f9bea6892808e453e219aa305bc0269a
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commitdiff;h=ce43aa6c142d69820a267431ea342d1bd9f6d3ce
http://git.kernel.org/?p=linux/kernel/git/geert/linux-m68k.git;a=commitdiff;h=5679086ffdb93ec8168b8934d8197849d26f8fb6
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-11-24 14:34 ` Finn Thain
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
2011-10-23 14:11 ` [PATCH 02/16] macfb: fix black and white modes Finn Thain
` (15 subsequent siblings)
16 siblings, 2 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, Benjamin Herrenschmidt, linuxppc-dev
[-- Attachment #1: pmac-zilog-unexpected-irq --]
[-- Type: text/plain, Size: 3198 bytes --]
On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be masked. This can be a problem when pmac_zilog starts up.
For example, the serial debugging code in arch/m68k/kernel/head.S may be used beforehand. It disables the SCC interrupts at the chip but doesn't ack them. Then when a pmac_zilog port is opened and SCC chip interrupts become enabled, the machine locks up with "unexpected interrupt" because request_irq() hasn't happened yet.
Fix this by setting the SCC master interrupt enable bit only after the handler is installed. This is achieved by extracting that operation out of __pmz_startup() and placing it into a seperate routine.
A similar problem arises when the irq is freed. Fix this by resetting the chip first (on m68k mac).
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
This patch has been tested on a variety of m68k Macs but no PowerMacs.
Index: linux-m68k/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-m68k.orig/drivers/tty/serial/pmac_zilog.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/tty/serial/pmac_zilog.c 2011-10-22 23:02:38.000000000 +1100
@@ -910,8 +910,8 @@ static int __pmz_startup(struct uart_pma
/* Clear handshaking, enable BREAK interrupts */
uap->curregs[R15] = BRKIE;
- /* Master interrupt enable */
- uap->curregs[R9] |= NV | MIE;
+ /* No vector */
+ uap->curregs[R9] |= NV;
pmz_load_zsregs(uap, uap->curregs);
@@ -925,6 +925,17 @@ static int __pmz_startup(struct uart_pma
return pwr_delay;
}
+static void pmz_master_int_control(struct uart_pmac_port *uap, int enable)
+{
+ if (enable) {
+ uap->curregs[R9] |= MIE; /* Master interrupt enable */
+ write_zsreg(uap, R9, uap->curregs[R9]);
+ } else {
+ uap->curregs[R9] &= ~MIE;
+ write_zsreg(uap, 9, FHWRES);
+ }
+}
+
static void pmz_irda_reset(struct uart_pmac_port *uap)
{
uap->curregs[R5] |= DTR;
@@ -976,6 +987,19 @@ static int pmz_startup(struct uart_port
return -ENXIO;
}
+ /*
+ * Most 68k Mac models cannot mask the SCC IRQ so they must enable
+ * interrupts after the handler is installed and not before.
+ */
+#ifndef CONFIG_MAC
+ if (!ZS_IS_CONS(uap))
+#endif
+ {
+ spin_lock_irqsave(&port->lock, flags);
+ pmz_master_int_control(uap, 1);
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+
mutex_unlock(&pmz_irq_mutex);
/* Right now, we deal with delay by blocking here, I'll be
@@ -1015,6 +1039,11 @@ static void pmz_shutdown(struct uart_por
mutex_lock(&pmz_irq_mutex);
+#ifdef CONFIG_MAC
+ if (!ZS_IS_OPEN(uap->mate))
+ pmz_master_int_control(uap, 0);
+#endif
+
/* Release interrupt handler */
free_irq(uap->port.irq, uap);
@@ -1734,6 +1763,7 @@ static int pmz_resume(struct macio_dev *
goto bail;
}
pwr_delay = __pmz_startup(uap);
+ pmz_master_int_control(uap, 1);
/* Take care of config that may have changed while asleep */
__pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
@@ -2178,6 +2208,9 @@ static int __init pmz_console_setup(stru
* Enable the hardware
*/
pwr_delay = __pmz_startup(uap);
+#ifndef CONFIG_MAC
+ pmz_master_int_control(uap, 1);
+#endif
if (pwr_delay)
mdelay(pwr_delay);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 02/16] macfb: fix black and white modes
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-12-10 5:23 ` Finn Thain
2011-10-23 14:11 ` [PATCH 03/16] mac_sonic: add irq resources and cleanup Finn Thain
` (14 subsequent siblings)
16 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, Florian Tobias Schandinat, linux-fbdev
[-- Attachment #1: macfb-bw-fix --]
[-- Type: text/plain, Size: 5966 bytes --]
macfb won't init in black & white modes since fb_alloc_cmap() no longer works for zero cmap length. Fix this and also clean up a few printk's and some stylistic inconsistencies.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/drivers/video/macfb.c
===================================================================
--- linux-m68k.orig/drivers/video/macfb.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/video/macfb.c 2011-10-23 00:50:51.000000000 +1100
@@ -592,12 +592,12 @@ static int __init macfb_init(void)
if (!fb_info.screen_base)
return -ENODEV;
- printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
- macfb_fix.smem_start, fb_info.screen_base,
- macfb_fix.smem_len / 1024);
- printk("macfb: mode is %dx%dx%d, linelength=%d\n",
- macfb_defined.xres, macfb_defined.yres,
- macfb_defined.bits_per_pixel, macfb_fix.line_length);
+ pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+ macfb_fix.smem_start, fb_info.screen_base,
+ macfb_fix.smem_len / 1024);
+ pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
+ macfb_defined.xres, macfb_defined.yres,
+ macfb_defined.bits_per_pixel, macfb_fix.line_length);
/* Fill in the available video resolution */
macfb_defined.xres_virtual = macfb_defined.xres;
@@ -613,14 +613,10 @@ static int __init macfb_init(void)
switch (macfb_defined.bits_per_pixel) {
case 1:
- /*
- * XXX: I think this will catch any program that tries
- * to do FBIO_PUTCMAP when the visual is monochrome.
- */
macfb_defined.red.length = macfb_defined.bits_per_pixel;
macfb_defined.green.length = macfb_defined.bits_per_pixel;
macfb_defined.blue.length = macfb_defined.bits_per_pixel;
- video_cmap_len = 0;
+ video_cmap_len = 2;
macfb_fix.visual = FB_VISUAL_MONO01;
break;
case 2:
@@ -660,11 +656,10 @@ static int __init macfb_init(void)
macfb_fix.visual = FB_VISUAL_TRUECOLOR;
break;
default:
- video_cmap_len = 0;
- macfb_fix.visual = FB_VISUAL_MONO01;
- printk("macfb: unknown or unsupported bit depth: %d\n",
+ pr_err("macfb: unknown or unsupported bit depth: %d\n",
macfb_defined.bits_per_pixel);
- break;
+ err = -EINVAL;
+ goto fail_unmap;
}
/*
@@ -734,8 +729,8 @@ static int __init macfb_init(void)
case MAC_MODEL_Q950:
strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -744,8 +739,8 @@ static int __init macfb_init(void)
case MAC_MODEL_LCII:
strcpy(macfb_fix.id, "V8");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -758,8 +753,8 @@ static int __init macfb_init(void)
case MAC_MODEL_P600:
strcpy(macfb_fix.id, "Brazil");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -773,10 +768,10 @@ static int __init macfb_init(void)
case MAC_MODEL_P520:
case MAC_MODEL_P550:
case MAC_MODEL_P460:
- macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Sonora");
+ macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -786,10 +781,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_IICI:
case MAC_MODEL_IISI:
- macfb_setpalette = rbv_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "RBV");
+ macfb_setpalette = rbv_setpalette;
rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -797,10 +792,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_Q840:
case MAC_MODEL_C660:
- macfb_setpalette = civic_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Civic");
+ macfb_setpalette = civic_setpalette;
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
@@ -809,26 +804,26 @@ static int __init macfb_init(void)
* We think this may be like the LC II
*/
case MAC_MODEL_LC:
+ strcpy(macfb_fix.id, "LC");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "LC");
break;
/*
* We think this may be like the LC II
*/
case MAC_MODEL_CCL:
+ strcpy(macfb_fix.id, "Color Classic");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "Color Classic");
break;
/*
@@ -893,10 +888,10 @@ static int __init macfb_init(void)
case MAC_MODEL_PB270C:
case MAC_MODEL_PB280:
case MAC_MODEL_PB280C:
- macfb_setpalette = csc_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "CSC");
+ macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
default:
@@ -918,8 +913,9 @@ static int __init macfb_init(void)
if (err)
goto fail_dealloc;
- printk("fb%d: %s frame buffer device\n",
- fb_info.node, fb_info.fix.id);
+ pr_info("fb%d: %s frame buffer device\n",
+ fb_info.node, fb_info.fix.id);
+
return 0;
fail_dealloc:
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 03/16] mac_sonic: add irq resources and cleanup
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
2011-10-23 14:11 ` [PATCH 02/16] macfb: fix black and white modes Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-11-13 10:28 ` Geert Uytterhoeven
2011-12-10 5:23 ` Finn Thain
2011-10-23 14:11 ` [PATCH 04/16] m68k/mac: early console Finn Thain
` (13 subsequent siblings)
16 siblings, 2 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, David Miller, netdev
[-- Attachment #1: macsonic-platform-irq-rsrc --]
[-- Type: text/plain, Size: 6140 bytes --]
Make better use of the SONIC platform device by adding irq resources. This moves the via_type logic out of the NIC device driver which improves modularity.
Since interrupt handlers now run with CPU interrupts disabled, we don't need the macsonic_interrupt() wrapper. Remove it.
For consistency, rename retval as err.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:11.000000000 +1100
@@ -936,9 +936,16 @@ static struct platform_device esp_1_pdev
.id = 1,
};
+static struct resource sonic_rsrcs[] = {
+ { .flags = IORESOURCE_IRQ },
+ { .flags = IORESOURCE_IRQ },
+};
+
static struct platform_device sonic_pdev = {
.name = "macsonic",
.id = -1,
+ .num_resources = ARRAY_SIZE(sonic_rsrcs),
+ .resource = sonic_rsrcs,
};
static struct platform_device mace_pdev = {
@@ -1002,6 +1009,10 @@ int __init mac_platform_init(void)
switch (macintosh_config->ether_type) {
case MAC_ETHER_SONIC:
+ sonic_rsrcs[0].start = sonic_rsrcs[0].end = IRQ_NUBUS_9;
+ if (via_alt_mapping)
+ sonic_rsrcs[1].start = sonic_rsrcs[1].end = IRQ_AUTO_3;
+
platform_device_register(&sonic_pdev);
break;
case MAC_ETHER_MACE:
Index: linux-m68k/drivers/net/macsonic.c
===================================================================
--- linux-m68k.orig/drivers/net/macsonic.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/net/macsonic.c 2011-10-22 23:02:38.000000000 +1100
@@ -60,7 +60,6 @@
#include <asm/dma.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
-#include <asm/mac_via.h>
static char mac_sonic_string[] = "macsonic";
@@ -127,61 +126,49 @@ static inline void bit_reverse_addr(unsi
addr[i] = bitrev8(addr[i]);
}
-static irqreturn_t macsonic_interrupt(int irq, void *dev_id)
-{
- irqreturn_t result;
- unsigned long flags;
-
- local_irq_save(flags);
- result = sonic_interrupt(irq, dev_id);
- local_irq_restore(flags);
- return result;
-}
-
static int macsonic_open(struct net_device* dev)
{
- int retval;
+ struct sonic_local *lp = netdev_priv(dev);
+ int err;
- retval = request_irq(dev->irq, sonic_interrupt, 0, "sonic", dev);
- if (retval) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n",
- dev->name, dev->irq);
- goto err;
- }
- /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes
- * in at priority level 3. However, we sometimes get the level 2 inter-
- * rupt as well, which must prevent re-entrance of the sonic handler.
- */
- if (dev->irq == IRQ_AUTO_3) {
- retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt, 0,
- "sonic", dev);
- if (retval) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n",
- dev->name, IRQ_NUBUS_9);
- goto err_irq;
+ err = request_irq(dev->irq, sonic_interrupt, 0, "SONIC", dev);
+ if (err) {
+ pr_err("%s: unable to get IRQ %d\n", dev->name, dev->irq);
+ goto out;
+ }
+ if (lp->irq1) {
+ err = request_irq(lp->irq1, sonic_interrupt, 0, "SONIC", dev);
+ if (err) {
+ pr_err("%s: unable to get IRQ %d\n",
+ dev->name, lp->irq1);
+ goto out_irq;
}
}
- retval = sonic_open(dev);
- if (retval)
- goto err_irq_nubus;
+ err = sonic_open(dev);
+ if (err)
+ goto out_irq1;
+
return 0;
-err_irq_nubus:
- if (dev->irq == IRQ_AUTO_3)
- free_irq(IRQ_NUBUS_9, dev);
-err_irq:
+out_irq1:
+ if (lp->irq1)
+ free_irq(lp->irq1, dev);
+out_irq:
free_irq(dev->irq, dev);
-err:
- return retval;
+out:
+ return err;
}
static int macsonic_close(struct net_device* dev)
{
+ struct sonic_local *lp = netdev_priv(dev);
int err;
+
err = sonic_close(dev);
+
+ if (lp->irq1)
+ free_irq(lp->irq1, dev);
free_irq(dev->irq, dev);
- if (dev->irq == IRQ_AUTO_3)
- free_irq(IRQ_NUBUS_9, dev);
return err;
}
@@ -310,8 +297,9 @@ static void __devinit mac_onboard_sonic_
random_ether_addr(dev->dev_addr);
}
-static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
+static int __devinit mac_onboard_sonic_probe(struct platform_device *pdev)
{
+ struct net_device *dev = platform_get_drvdata(pdev);
struct sonic_local* lp = netdev_priv(dev);
int sr;
int commslot = 0;
@@ -348,10 +336,12 @@ static int __devinit mac_onboard_sonic_p
/* Danger! My arms are flailing wildly! You *must* set lp->reg_offset
* and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */
dev->base_addr = ONBOARD_SONIC_REGISTERS;
- if (via_alt_mapping)
- dev->irq = IRQ_AUTO_3;
- else
- dev->irq = IRQ_NUBUS_9;
+
+ dev->irq = platform_get_irq(pdev, 0);
+ lp->irq1 = platform_get_irq(pdev, 1);
+
+ if (!dev->irq)
+ return -ENODEV;
if (!sonic_version_printed) {
printk(KERN_INFO "%s", version);
@@ -590,7 +580,7 @@ static int __devinit mac_sonic_probe(str
platform_set_drvdata(pdev, dev);
/* This will catch fatal stuff like -ENOMEM as well as success */
- err = mac_onboard_sonic_probe(dev);
+ err = mac_onboard_sonic_probe(pdev);
if (err == 0)
goto found;
if (err != -ENODEV)
Index: linux-m68k/drivers/net/sonic.h
===================================================================
--- linux-m68k.orig/drivers/net/sonic.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/net/sonic.h 2011-10-22 23:02:38.000000000 +1100
@@ -318,6 +318,9 @@ struct sonic_local {
unsigned int eol_rx;
unsigned int eol_tx; /* last unacked transmit packet */
unsigned int next_tx; /* next free TD */
+#ifdef CONFIG_MAC
+ int irq1; /* Second IRQ for Mac Quadras */
+#endif
struct device *device; /* generic device */
struct net_device_stats stats;
};
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:10.000000000 +1100
@@ -40,7 +40,6 @@
volatile __u8 *via1, *via2;
int rbv_present;
int via_alt_mapping;
-EXPORT_SYMBOL(via_alt_mapping);
static __u8 rbv_clear;
/*
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 04/16] m68k/mac: early console
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (2 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 03/16] mac_sonic: add irq resources and cleanup Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 05/16] m68k/mac: cleanup mac_clear_irq Finn Thain
` (12 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: mac-early-console --]
[-- Type: text/plain, Size: 8445 bytes --]
Revive the old mac_serial_print() routine as mac_early_print(). mac_serial_print() did not function because it did not use the right offsets for its stack arguments. Fix this and make compilation conditional on CONFIG_EARLY_PRINTK instead of the obscure MAC_SERIAL_DEBUG macro.
Give mac_early_print() a new string length parameter to fit the early console API.
Send output to the framebuffer as well as serial ports.
Change the line rate to 38400 baud to match the default for the real (pmac_zilog) serial console.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/Kconfig.debug
===================================================================
--- linux-m68k.orig/arch/m68k/Kconfig.debug 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/Kconfig.debug 2011-10-22 23:02:38.000000000 +1100
@@ -4,7 +4,7 @@ source "lib/Kconfig.debug"
config EARLY_PRINTK
bool "Early printk" if EMBEDDED
- depends on MVME16x
+ depends on MVME16x || MAC
default y
help
Write kernel log output directly to a serial port.
Index: linux-m68k/arch/m68k/kernel/head.S
===================================================================
--- linux-m68k.orig/arch/m68k/kernel/head.S 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/kernel/head.S 2011-10-22 23:02:38.000000000 +1100
@@ -250,9 +250,8 @@
* USE_MFP: Use the ST-MFP port (Modem1) for serial debug.
*
* Macintosh constants:
- * MAC_SERIAL_DEBUG: Turns on serial debug output for the Macintosh.
- * MAC_USE_SCC_A: Use the SCC port A (modem) for serial debug.
- * MAC_USE_SCC_B: Use the SCC port B (printer) for serial debug (default).
+ * MAC_USE_SCC_A: Use SCC port A (modem) for serial debug and early console.
+ * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug and early console.
*/
#include <linux/linkage.h>
@@ -268,33 +267,25 @@
#include <asm/machw.h>
-/*
- * Macintosh console support
- */
-
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
#define CONSOLE
#define CONSOLE_PENGUIN
#endif
-/*
- * Macintosh serial debug support; outputs boot info to the printer
- * and/or modem serial ports
- */
-#undef MAC_SERIAL_DEBUG
+#ifdef CONFIG_EARLY_PRINTK
+#define SERIAL_DEBUG
+#else
+#undef SERIAL_DEBUG
+#endif
-/*
- * Macintosh serial debug port selection; define one or both;
- * requires MAC_SERIAL_DEBUG to be defined
- */
-#define MAC_USE_SCC_A /* Macintosh modem serial port */
-#define MAC_USE_SCC_B /* Macintosh printer serial port */
+#else /* !CONFIG_MAC */
-#endif /* CONFIG_MAC */
+#define SERIAL_DEBUG
+
+#endif /* !CONFIG_MAC */
#undef MMU_PRINT
#undef MMU_NOCACHE_KERNEL
-#define SERIAL_DEBUG
#undef DEBUG
/*
@@ -655,11 +646,11 @@ ENTRY(__start)
lea %pc@(L(mac_rowbytes)),%a1
movel %a0@,%a1@
-#ifdef MAC_SERIAL_DEBUG
+#ifdef SERIAL_DEBUG
get_bi_record BI_MAC_SCCBASE
lea %pc@(L(mac_sccbase)),%a1
movel %a0@,%a1@
-#endif /* MAC_SERIAL_DEBUG */
+#endif
#if 0
/*
@@ -1427,7 +1418,7 @@ L(mmu_fixup_done):
subl %d0,L(console_font)
subl %d0,L(console_font_data)
#endif
-#ifdef MAC_SERIAL_DEBUG
+#ifdef SERIAL_DEBUG
orl #0x50000000,L(mac_sccbase)
#endif
1:
@@ -1917,7 +1908,7 @@ mmu_030_print:
jbne 30b
mmu_print_done:
- puts "\n\n"
+ puts "\n"
func_return mmu_print
@@ -2768,7 +2759,7 @@ L(scc_initable_mac):
.byte 9,0 /* no interrupts */
.byte 10,0 /* NRZ */
.byte 11,0x50 /* use baud rate generator */
- .byte 12,10,13,0 /* 9600 baud */
+ .byte 12,1,13,0 /* 38400 baud */
.byte 14,1 /* Baud rate generator enable */
.byte 3,0xc1 /* enable receiver */
.byte 5,0xea /* enable transmitter */
@@ -2906,10 +2897,12 @@ func_start serial_init,%d0/%d1/%a0/%a1
#endif
#ifdef CONFIG_MAC
is_not_mac(L(serial_init_not_mac))
-#ifdef MAC_SERIAL_DEBUG
-#if !defined(MAC_USE_SCC_A) && !defined(MAC_USE_SCC_B)
-#define MAC_USE_SCC_B
-#endif
+
+#ifdef SERIAL_DEBUG
+/* You may define either or both of these. */
+#define MAC_USE_SCC_A /* Modem port */
+#define MAC_USE_SCC_B /* Printer port */
+
#define mac_scc_cha_b_ctrl_offset 0x0
#define mac_scc_cha_a_ctrl_offset 0x2
#define mac_scc_cha_b_data_offset 0x4
@@ -2940,7 +2933,7 @@ func_start serial_init,%d0/%d1/%a0/%a1
jra 7b
8:
#endif /* MAC_USE_SCC_B */
-#endif /* MAC_SERIAL_DEBUG */
+#endif /* SERIAL_DEBUG */
jra L(serial_init_done)
L(serial_init_not_mac):
@@ -3011,7 +3004,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1
#ifdef CONFIG_MAC
is_not_mac(5f)
-#ifdef MAC_SERIAL_DEBUG
+#ifdef SERIAL_DEBUG
#ifdef MAC_USE_SCC_A
movel %pc@(L(mac_sccbase)),%a1
@@ -3029,7 +3022,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1
moveb %d0,%a1@(mac_scc_cha_b_data_offset)
#endif /* MAC_USE_SCC_B */
-#endif /* MAC_SERIAL_DEBUG */
+#endif /* SERIAL_DEBUG */
jra L(serial_putc_done)
5:
@@ -3248,33 +3241,39 @@ func_return putn
#ifdef CONFIG_MAC
/*
- * mac_serial_print
+ * mac_early_print
*
* This routine takes its parameters on the stack. It then
- * turns around and calls the internal routine. This routine
- * is used until the Linux console driver initializes itself.
+ * turns around and calls the internal routines. This routine
+ * is used by the boot console.
*
* The calling parameters are:
- * void mac_serial_print(const char *str);
+ * void mac_early_print(const char *str, unsigned length);
*
* This routine does NOT understand variable arguments only
* simple strings!
*/
-ENTRY(mac_serial_print)
- moveml %d0/%a0,%sp@-
-#if 1
- move %sr,%sp@-
+ENTRY(mac_early_print)
+ moveml %d0/%d1/%a0,%sp@-
+ movew %sr,%sp@-
ori #0x0700,%sr
-#endif
- movel %sp@(10),%a0 /* fetch parameter */
+ movel %sp@(18),%a0 /* fetch parameter */
+ movel %sp@(22),%d1 /* fetch parameter */
jra 2f
-1: serial_putc %d0
-2: moveb %a0@+,%d0
- jne 1b
-#if 1
- move %sp@+,%sr
+1:
+#ifdef CONSOLE
+ console_putc %d0
#endif
- moveml %sp@+,%d0/%a0
+#ifdef SERIAL_DEBUG
+ serial_putc %d0
+#endif
+ subq #1,%d1
+2: jeq 3f
+ moveb %a0@+,%d0
+ jne 1b
+3:
+ movew %sp@+,%sr
+ moveml %sp@+,%d0/%d1/%a0
rts
#endif /* CONFIG_MAC */
@@ -3409,10 +3408,10 @@ func_start console_put_stats,%a0/%d7
* a0 = pointer to boot_info
* d7 = value of boot_info fields
*/
- puts "\nMacLinux\n\n"
+ puts "\nMacLinux\n"
#ifdef SERIAL_DEBUG
- puts " vidaddr:"
+ puts "\n vidaddr:"
putn %pc@(L(mac_videobase)) /* video addr. */
puts "\n _stext:"
@@ -3423,19 +3422,21 @@ func_start console_put_stats,%a0/%d7
lea %pc@(_end),%a0
putn %a0
- puts "\ncpuid:"
+ puts "\n cpuid:"
putn %pc@(L(cputype))
- putc '\n'
-#ifdef MAC_SERIAL_DEBUG
+# ifdef CONFIG_MAC
+ puts "\n sccbase:"
putn %pc@(L(mac_sccbase))
+# endif
+# ifdef MMU_PRINT
putc '\n'
-#endif
-# if defined(MMU_PRINT)
jbsr mmu_print_machine_cpu_types
-# endif /* MMU_PRINT */
+# endif
#endif /* SERIAL_DEBUG */
+ putc '\n'
+
func_return console_put_stats
#ifdef CONSOLE_PENGUIN
@@ -3896,11 +3897,11 @@ L(mac_dimensions):
.long 0
L(mac_rowbytes):
.long 0
-#ifdef MAC_SERIAL_DEBUG
+#ifdef SERIAL_DEBUG
L(mac_sccbase):
.long 0
-#endif /* MAC_SERIAL_DEBUG */
#endif
+#endif /* CONFIG_MAC */
#if defined (CONFIG_APOLLO)
LSRB0 = 0x10412
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:07.000000000 +1100
@@ -71,6 +71,31 @@ static void mac_get_model(char *str);
static void mac_identify(void);
static void mac_report_hardware(void);
+#ifdef CONFIG_EARLY_PRINTK
+asmlinkage void __init mac_early_print(const char *s, unsigned n);
+
+static void __init mac_early_cons_write(struct console *con,
+ const char *s, unsigned n)
+{
+ mac_early_print(s, n);
+}
+
+static struct console __initdata mac_early_cons = {
+ .name = "early",
+ .write = mac_early_cons_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1
+};
+
+int __init mac_unregister_early_cons(void)
+{
+ /* mac_early_print can't be used after init sections are discarded */
+ return unregister_console(&mac_early_cons);
+}
+
+late_initcall(mac_unregister_early_cons);
+#endif
+
static void __init mac_sched_init(irq_handler_t vector)
{
via_init_clock(vector);
@@ -164,6 +189,10 @@ void __init config_mac(void)
mach_beep = mac_mksound;
#endif
+#ifdef CONFIG_EARLY_PRINTK
+ register_console(&mac_early_cons);
+#endif
+
/*
* Determine hardware present
*/
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 05/16] m68k/mac: cleanup mac_clear_irq
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (3 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 04/16] m68k/mac: early console Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 06/16] m68k/mac: cleanup mac_irq_pending Finn Thain
` (11 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: cleanup-mac_clear_irq --]
[-- Type: text/plain, Size: 4610 bytes --]
mac_clear_irq() is dead code and has been dead for as long as I can recall. On certain Mac models, certain irqs can't be cleared this way. Outside of irq dispatch, this code appears be unusable without busy loops or worse, and for irq dispatch we duplicate the same logic. Remove mac_clear_irq() and supporting code.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/baboon.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/baboon.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/baboon.c 2011-10-23 00:51:09.000000000 +1100
@@ -124,13 +124,6 @@ void baboon_irq_disable(int irq)
mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
}
-void baboon_irq_clear(int irq)
-{
- int irq_idx = IRQ_IDX(irq);
-
- baboon->mb_ifr &= ~(1 << irq_idx);
-}
-
int baboon_irq_pending(int irq)
{
int irq_idx = IRQ_IDX(irq);
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:09.000000000 +1100
@@ -239,7 +239,6 @@ void __init mac_init_IRQ(void)
/*
* mac_irq_enable - enable an interrupt source
* mac_irq_disable - disable an interrupt source
- * mac_clear_irq - clears a pending interrupt
* mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
*
* These routines are just dispatchers to the VIA/OSS/PSC routines.
@@ -314,38 +313,6 @@ void mac_irq_disable(struct irq_data *da
break;
}
}
-
-void mac_clear_irq(unsigned int irq)
-{
- switch(IRQ_SRC(irq)) {
- case 1:
- via_irq_clear(irq);
- break;
- case 2:
- case 7:
- if (oss_present)
- oss_irq_clear(irq);
- else
- via_irq_clear(irq);
- break;
- case 3:
- case 5:
- case 6:
- if (psc_present)
- psc_irq_clear(irq);
- else if (oss_present)
- oss_irq_clear(irq);
- break;
- case 4:
- if (psc_present)
- psc_irq_clear(irq);
- break;
- case 8:
- if (baboon_present)
- baboon_irq_clear(irq);
- break;
- }
-}
int mac_irq_pending(unsigned int irq)
{
Index: linux-m68k/arch/m68k/mac/oss.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/oss.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/oss.c 2011-10-23 00:51:09.000000000 +1100
@@ -221,37 +221,6 @@ void oss_irq_disable(int irq) {
}
/*
- * Clear an OSS interrupt
- *
- * Not sure if this works or not but it's the only method I could
- * think of based on the contents of the mac_oss structure.
- */
-
-void oss_irq_clear(int irq) {
- /* FIXME: how to do this on OSS? */
- switch(irq) {
- case IRQ_MAC_SCC:
- oss->irq_pending &= ~OSS_IP_IOPSCC;
- break;
- case IRQ_MAC_ADB:
- oss->irq_pending &= ~OSS_IP_IOPISM;
- break;
- case IRQ_MAC_SCSI:
- oss->irq_pending &= ~OSS_IP_SCSI;
- break;
- case IRQ_NUBUS_9:
- case IRQ_NUBUS_A:
- case IRQ_NUBUS_B:
- case IRQ_NUBUS_C:
- case IRQ_NUBUS_D:
- case IRQ_NUBUS_E:
- irq -= NUBUS_SOURCE_BASE;
- oss->irq_pending &= ~(1 << irq);
- break;
- }
-}
-
-/*
* Check to see if a specific OSS interrupt is pending
*/
Index: linux-m68k/arch/m68k/mac/psc.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/psc.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/psc.c 2011-10-23 00:51:09.000000000 +1100
@@ -181,14 +181,6 @@ void psc_irq_disable(int irq) {
psc_write_byte(pIER, 1 << irq_idx);
}
-void psc_irq_clear(int irq) {
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int pIFR = pIERbase + (irq_src << 4);
-
- psc_write_byte(pIFR, 1 << irq_idx);
-}
-
int psc_irq_pending(int irq)
{
int irq_src = IRQ_SRC(irq);
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:09.000000000 +1100
@@ -584,22 +584,6 @@ void via_irq_disable(int irq) {
}
}
-void via_irq_clear(int irq) {
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int irq_bit = 1 << irq_idx;
-
- if (irq_src == 1) {
- via1[vIFR] = irq_bit;
- } else if (irq_src == 2) {
- via2[gIFR] = irq_bit | rbv_clear;
- } else if (irq_src == 7) {
- /* FIXME: There is no way to clear an individual nubus slot
- * IRQ flag, other than getting the device to do it.
- */
- }
-}
-
/*
* Returns nonzero if an interrupt is pending on the given
* VIA/IRQ combination.
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 06/16] m68k/mac: cleanup mac_irq_pending
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (4 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 05/16] m68k/mac: cleanup mac_clear_irq Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 07/16] m68k/mac: cleanup forward declarations Finn Thain
` (10 subsequent siblings)
16 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, James E.J. Bottomley, linux-scsi
[-- Attachment #1: replace-mac_irq_pending --]
[-- Type: text/plain, Size: 6998 bytes --]
mac_irq_pending() has only one caller (mac_esp.c). Nothing tests for Baboon, PSC or OSS pending interrupts. Until that need arises, let's keep it simple and remove all the unused abstraction. Replace it with a routine to check for SCSI DRQ.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/include/asm/macintosh.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/macintosh.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/macintosh.h 2011-10-23 00:51:07.000000000 +1100
@@ -11,7 +11,7 @@
extern void mac_reset(void);
extern void mac_poweroff(void);
extern void mac_init_IRQ(void);
-extern int mac_irq_pending(unsigned int);
+
extern void mac_irq_enable(struct irq_data *data);
extern void mac_irq_disable(struct irq_data *data);
Index: linux-m68k/arch/m68k/mac/baboon.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/baboon.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/baboon.c 2011-10-23 00:51:07.000000000 +1100
@@ -123,10 +123,3 @@ void baboon_irq_disable(int irq)
if (baboon_disabled)
mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
}
-
-int baboon_irq_pending(int irq)
-{
- int irq_idx = IRQ_IDX(irq);
-
- return baboon->mb_ifr & (1 << irq_idx);
-}
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:07.000000000 +1100
@@ -142,7 +142,6 @@ extern void via_register_interrupts(void
extern void via_irq_enable(int);
extern void via_irq_disable(int);
extern void via_irq_clear(int);
-extern int via_irq_pending(int);
/*
* OSS hooks
@@ -152,7 +151,6 @@ extern void oss_register_interrupts(void
extern void oss_irq_enable(int);
extern void oss_irq_disable(int);
extern void oss_irq_clear(int);
-extern int oss_irq_pending(int);
/*
* PSC hooks
@@ -162,7 +160,6 @@ extern void psc_register_interrupts(void
extern void psc_irq_enable(int);
extern void psc_irq_disable(int);
extern void psc_irq_clear(int);
-extern int psc_irq_pending(int);
/*
* IOP hooks
@@ -239,7 +236,6 @@ void __init mac_init_IRQ(void)
/*
* mac_irq_enable - enable an interrupt source
* mac_irq_disable - disable an interrupt source
- * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
*
* These routines are just dispatchers to the VIA/OSS/PSC routines.
*/
@@ -314,34 +310,6 @@ void mac_irq_disable(struct irq_data *da
}
}
-int mac_irq_pending(unsigned int irq)
-{
- switch(IRQ_SRC(irq)) {
- case 1:
- return via_irq_pending(irq);
- case 2:
- case 7:
- if (oss_present)
- return oss_irq_pending(irq);
- else
- return via_irq_pending(irq);
- case 3:
- case 5:
- case 6:
- if (psc_present)
- return psc_irq_pending(irq);
- else if (oss_present)
- return oss_irq_pending(irq);
- break;
- case 4:
- if (psc_present)
- return psc_irq_pending(irq);
- break;
- }
- return 0;
-}
-EXPORT_SYMBOL(mac_irq_pending);
-
static int num_debug[8];
irqreturn_t mac_debug_handler(int irq, void *dev_id)
Index: linux-m68k/arch/m68k/mac/oss.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/oss.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/oss.c 2011-10-23 00:51:07.000000000 +1100
@@ -219,32 +219,3 @@ void oss_irq_disable(int irq) {
#endif
}
}
-
-/*
- * Check to see if a specific OSS interrupt is pending
- */
-
-int oss_irq_pending(int irq)
-{
- switch(irq) {
- case IRQ_MAC_SCC:
- return oss->irq_pending & OSS_IP_IOPSCC;
- break;
- case IRQ_MAC_ADB:
- return oss->irq_pending & OSS_IP_IOPISM;
- break;
- case IRQ_MAC_SCSI:
- return oss->irq_pending & OSS_IP_SCSI;
- break;
- case IRQ_NUBUS_9:
- case IRQ_NUBUS_A:
- case IRQ_NUBUS_B:
- case IRQ_NUBUS_C:
- case IRQ_NUBUS_D:
- case IRQ_NUBUS_E:
- irq -= NUBUS_SOURCE_BASE;
- return oss->irq_pending & (1 << irq);
- break;
- }
- return 0;
-}
Index: linux-m68k/arch/m68k/mac/psc.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/psc.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/psc.c 2011-10-22 23:02:38.000000000 +1100
@@ -180,12 +180,3 @@ void psc_irq_disable(int irq) {
#endif
psc_write_byte(pIER, 1 << irq_idx);
}
-
-int psc_irq_pending(int irq)
-{
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int pIFR = pIERbase + (irq_src << 4);
-
- return psc_read_byte(pIFR) & (1 << irq_idx);
-}
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:07.000000000 +1100
@@ -584,28 +584,6 @@ void via_irq_disable(int irq) {
}
}
-/*
- * Returns nonzero if an interrupt is pending on the given
- * VIA/IRQ combination.
- */
-
-int via_irq_pending(int irq)
-{
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int irq_bit = 1 << irq_idx;
-
- if (irq_src == 1) {
- return via1[vIFR] & irq_bit;
- } else if (irq_src == 2) {
- return via2[gIFR] & irq_bit;
- } else if (irq_src == 7) {
- /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */
- return ~via2[gBufA] & irq_bit;
- }
- return 0;
-}
-
void via1_set_head(int head)
{
if (head == 0)
@@ -614,3 +592,9 @@ void via1_set_head(int head)
via1[vBufA] |= VIA1A_vHeadSel;
}
EXPORT_SYMBOL(via1_set_head);
+
+int via2_scsi_drq_pending(void)
+{
+ return via2[gIFR] & (1 << IRQ_IDX(IRQ_MAC_SCSIDRQ));
+}
+EXPORT_SYMBOL(via2_scsi_drq_pending);
Index: linux-m68k/drivers/scsi/mac_esp.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_esp.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_esp.c 2011-10-22 23:02:38.000000000 +1100
@@ -25,6 +25,7 @@
#include <asm/dma.h>
#include <asm/macints.h>
#include <asm/macintosh.h>
+#include <asm/mac_via.h>
#include <scsi/scsi_host.h>
@@ -149,7 +150,7 @@ static inline int mac_esp_wait_for_dreq(
do {
if (mep->pdma_regs == NULL) {
- if (mac_irq_pending(IRQ_MAC_SCSIDRQ))
+ if (via2_scsi_drq_pending())
return 0;
} else {
if (nubus_readl(mep->pdma_regs) & 0x200)
Index: linux-m68k/arch/m68k/include/asm/mac_via.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_via.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_via.h 2011-10-23 00:51:07.000000000 +1100
@@ -254,6 +254,8 @@
extern volatile __u8 *via1,*via2;
extern int rbv_present,via_alt_mapping;
+extern int via2_scsi_drq_pending(void);
+
static inline int rbv_set_video_bpp(int bpp)
{
char val = (bpp==1)?0:(bpp==2)?1:(bpp==4)?2:(bpp==8)?3:-1;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 07/16] m68k/mac: cleanup forward declarations
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (5 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 06/16] m68k/mac: cleanup mac_irq_pending Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 08/16] m68k/mac: enable via_alt_mapping on performa 580 Finn Thain
` (9 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: cleanup-headers --]
[-- Type: text/plain, Size: 7275 bytes --]
Move some forward declarations into header files and adjust includes.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/include/asm/macintosh.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/macintosh.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/macintosh.h 2011-10-23 00:51:01.000000000 +1100
@@ -16,12 +16,6 @@ extern void mac_irq_enable(struct irq_da
extern void mac_irq_disable(struct irq_data *data);
/*
- * Floppy driver magic hook - probably shouldn't be here
- */
-
-extern void via1_set_head(int);
-
-/*
* Macintosh Table
*/
Index: linux-m68k/drivers/block/swim.c
===================================================================
--- linux-m68k.orig/drivers/block/swim.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/block/swim.c 2011-10-22 23:02:38.000000000 +1100
@@ -26,7 +26,6 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
-#include <asm/macintosh.h>
#include <asm/mac_via.h>
#define CARDNAME "swim"
Index: linux-m68k/arch/m68k/include/asm/mac_baboon.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_baboon.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_baboon.h 2011-10-22 23:02:38.000000000 +1100
@@ -29,4 +29,10 @@ struct baboon {
*/
};
+extern int baboon_present;
+
+extern void baboon_register_interrupts(void);
+extern void baboon_irq_enable(int);
+extern void baboon_irq_disable(int);
+
#endif /* __ASSEMBLY **/
Index: linux-m68k/arch/m68k/include/asm/mac_iop.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_iop.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_iop.h 2011-10-22 23:02:38.000000000 +1100
@@ -159,4 +159,6 @@ extern void iop_upload_code(uint, __u8 *
extern void iop_download_code(uint, __u8 *, uint, __u16);
extern __u8 *iop_compare_code(uint, __u8 *, uint, __u16);
+extern void iop_register_interrupts(void);
+
#endif /* __ASSEMBLY__ */
Index: linux-m68k/arch/m68k/include/asm/mac_oss.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_oss.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_oss.h 2011-10-23 00:51:05.000000000 +1100
@@ -91,4 +91,8 @@ struct mac_oss {
extern volatile struct mac_oss *oss;
extern int oss_present;
+extern void oss_register_interrupts(void);
+extern void oss_irq_enable(int);
+extern void oss_irq_disable(int);
+
#endif /* __ASSEMBLY__ */
Index: linux-m68k/arch/m68k/include/asm/mac_psc.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_psc.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_psc.h 2011-10-22 23:02:38.000000000 +1100
@@ -211,6 +211,10 @@
extern volatile __u8 *psc;
extern int psc_present;
+extern void psc_register_interrupts(void);
+extern void psc_irq_enable(int);
+extern void psc_irq_disable(int);
+
/*
* Access functions
*/
Index: linux-m68k/arch/m68k/include/asm/mac_via.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_via.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_via.h 2011-10-23 00:51:06.000000000 +1100
@@ -254,6 +254,11 @@
extern volatile __u8 *via1,*via2;
extern int rbv_present,via_alt_mapping;
+extern void via_register_interrupts(void);
+extern void via_irq_enable(int);
+extern void via_irq_disable(int);
+extern void via1_irq(unsigned int irq, struct irq_desc *desc);
+extern void via1_set_head(int);
extern int via2_scsi_drq_pending(void);
static inline int rbv_set_video_bpp(int bpp)
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:07.000000000 +1100
@@ -110,75 +110,27 @@
*
*/
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/interrupt.h> /* for intr_count */
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/delay.h>
-#include <linux/seq_file.h>
-#include <asm/system.h>
#include <asm/irq.h>
-#include <asm/traps.h>
-#include <asm/bootinfo.h>
#include <asm/macintosh.h>
+#include <asm/macints.h>
#include <asm/mac_via.h>
#include <asm/mac_psc.h>
+#include <asm/mac_oss.h>
+#include <asm/mac_iop.h>
+#include <asm/mac_baboon.h>
#include <asm/hwtest.h>
-#include <asm/errno.h>
-#include <asm/macints.h>
#include <asm/irq_regs.h>
-#include <asm/mac_oss.h>
#define SHUTUP_SONIC
/*
- * VIA/RBV hooks
- */
-
-extern void via_register_interrupts(void);
-extern void via_irq_enable(int);
-extern void via_irq_disable(int);
-extern void via_irq_clear(int);
-
-/*
- * OSS hooks
- */
-
-extern void oss_register_interrupts(void);
-extern void oss_irq_enable(int);
-extern void oss_irq_disable(int);
-extern void oss_irq_clear(int);
-
-/*
- * PSC hooks
- */
-
-extern void psc_register_interrupts(void);
-extern void psc_irq_enable(int);
-extern void psc_irq_disable(int);
-extern void psc_irq_clear(int);
-
-/*
- * IOP hooks
- */
-
-extern void iop_register_interrupts(void);
-
-/*
- * Baboon hooks
- */
-
-extern int baboon_present;
-
-extern void baboon_register_interrupts(void);
-extern void baboon_irq_enable(int);
-extern void baboon_irq_disable(int);
-extern void baboon_irq_clear(int);
-
-/*
* console_loglevel determines NMI handler function
*/
Index: linux-m68k/arch/m68k/mac/oss.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/oss.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/oss.c 2011-10-23 00:51:05.000000000 +1100
@@ -30,8 +30,6 @@
int oss_present;
volatile struct mac_oss *oss;
-extern void via1_irq(unsigned int irq, struct irq_desc *desc);
-
/*
* Initialize the OSS
*
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:07.000000000 +1100
@@ -77,9 +77,6 @@ static int gIER,gIFR,gBufA,gBufB;
static u8 nubus_disabled;
void via_debug_dump(void);
-void via_irq_enable(int irq);
-void via_irq_disable(int irq);
-void via_irq_clear(int irq);
/*
* Initialize the VIAs
Index: linux-m68k/arch/m68k/mac/baboon.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/baboon.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/baboon.c 2011-10-23 00:51:04.000000000 +1100
@@ -8,13 +8,8 @@
#include <linux/types.h>
#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/init.h>
#include <linux/irq.h>
-#include <asm/traps.h>
-#include <asm/bootinfo.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_baboon.h>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 08/16] m68k/mac: enable via_alt_mapping on performa 580
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (6 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 07/16] m68k/mac: cleanup forward declarations Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 09/16] m68k/mac: fix nubus slot irq disable and shutdown Finn Thain
` (8 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: via_alt_mapping --]
[-- Type: text/plain, Size: 3422 bytes --]
Enable via_alt_mapping on the Performa 588 and tidy up related documentation.
I'm betting that remapped IRQs work just fine on the Performa 580 series since it works on the LC 630 and the logic board part numbers are reputedly the same.
And the consensus seems to be that the Mac TV is essentially a Performa 550, not dissimilar to the Performa 520, so set the via_type accordingly.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:06.000000000 +1100
@@ -42,6 +42,18 @@
*
* 6 - off switch (?)
*
+ * Machines with Quadra-like VIA hardware, except PSC and PMU machines, support
+ * an alternate interrupt mapping, as used by A/UX. It spreads ethernet and
+ * sound out to their own autovector IRQs and gives VIA1 a higher priority:
+ *
+ * 1 - unused (?)
+ *
+ * 3 - on-board SONIC
+ *
+ * 5 - Apple Sound Chip (ASC)
+ *
+ * 6 - VIA1
+ *
* For OSS Macintoshes (IIfx only at this point):
*
* 3 - Nubus interrupt
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:05.000000000 +1100
@@ -594,7 +594,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_TV,
.name = "TV",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_QUADRA,
+ .via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:06.000000000 +1100
@@ -193,38 +193,17 @@ void __init via_init(void)
if (oss_present)
return;
- /* Some machines support an alternate IRQ mapping that spreads */
- /* Ethernet and Sound out to their own autolevel IRQs and moves */
- /* VIA1 to level 6. A/UX uses this mapping and we do too. Note */
- /* that the IIfx emulates this alternate mapping using the OSS. */
-
- via_alt_mapping = 0;
- if (macintosh_config->via_type == MAC_VIA_QUADRA)
- switch (macintosh_config->ident) {
- case MAC_MODEL_C660:
- case MAC_MODEL_Q840:
- /* not applicable */
- break;
- case MAC_MODEL_P588:
- case MAC_MODEL_TV:
- case MAC_MODEL_PB140:
- case MAC_MODEL_PB145:
- case MAC_MODEL_PB160:
- case MAC_MODEL_PB165:
- case MAC_MODEL_PB165C:
- case MAC_MODEL_PB170:
- case MAC_MODEL_PB180:
- case MAC_MODEL_PB180C:
- case MAC_MODEL_PB190:
- case MAC_MODEL_PB520:
- /* not yet tested */
- break;
- default:
- via_alt_mapping = 1;
- via1[vDirB] |= 0x40;
- via1[vBufB] &= ~0x40;
- break;
- }
+ if ((macintosh_config->via_type == MAC_VIA_QUADRA) &&
+ (macintosh_config->adb_type != MAC_ADB_PB1) &&
+ (macintosh_config->adb_type != MAC_ADB_PB2) &&
+ (macintosh_config->ident != MAC_MODEL_C660) &&
+ (macintosh_config->ident != MAC_MODEL_Q840)) {
+ via_alt_mapping = 1;
+ via1[vDirB] |= 0x40;
+ via1[vBufB] &= ~0x40;
+ } else {
+ via_alt_mapping = 0;
+ }
/*
* Now initialize VIA2. For RBV we just kill all interrupts;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 09/16] m68k/mac: fix nubus slot irq disable and shutdown
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (7 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 08/16] m68k/mac: enable via_alt_mapping on performa 580 Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 10/16] m68k/mac: oss irq fixes Finn Thain
` (7 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: fix-nubus-slot-irq --]
[-- Type: text/plain, Size: 9105 bytes --]
Improve NuBus slot interrupt handling code and documentation. This patch fixes the NuBus NIC (mac8390) in my Quadra 700.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:02.000000000 +1100
@@ -62,18 +62,47 @@ static int gIER,gIFR,gBufA,gBufB;
#define MAC_CLOCK_LOW (MAC_CLOCK_TICK&0xFF)
#define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8)
-/* To disable a NuBus slot on Quadras we make that slot IRQ line an output set
- * high. On RBV we just use the slot interrupt enable register. On Macs with
- * genuine VIA chips we must use nubus_disabled to keep track of disabled slot
- * interrupts. When any slot IRQ is disabled we mask the (edge triggered) CA1
- * or "SLOTS" interrupt. When no slot is disabled, we unmask the CA1 interrupt.
- * So, on genuine VIAs, having more than one NuBus IRQ can mean trouble,
- * because closing one of those drivers can mask all of the NuBus interrupts.
- * Also, since we can't mask the unregistered slot IRQs on genuine VIAs, it's
- * possible to get interrupts from cards that MacOS or the ROM has configured
- * but we have not. FWIW, "Designing Cards and Drivers for Macintosh II and
- * Macintosh SE", page 9-8, says, a slot IRQ with no driver would crash MacOS.
+
+/*
+ * On Macs with a genuine VIA chip there is no way to mask an individual slot
+ * interrupt. This limitation also seems to apply to VIA clone logic cores in
+ * Quadra-like ASICs. (RBV and OSS machines don't have this limitation.)
+ *
+ * We used to fake it by configuring the relevent VIA pin as an output
+ * (to mask the interrupt) or input (to unmask). That scheme did not work on
+ * (at least) the Quadra 700. A NuBus card's /NMRQ signal is an open-collector
+ * circuit (see Designing Cards and Drivers for Macintosh II and Macintosh SE,
+ * p. 10-11 etc) but VIA outputs are not (see datasheet).
+ *
+ * Driving these outputs high must cause the VIA to source current and the
+ * card to sink current when it asserts /NMRQ. Current will flow but the pin
+ * voltage is uncertain and so the /NMRQ condition may still cause a transition
+ * at the VIA2 CA1 input (which explains the lost interrupts). A side effect
+ * is that a disabled slot IRQ can never be tested as pending or not.
+ *
+ * Driving these outputs low doesn't work either. All the slot /NMRQ lines are
+ * (active low) OR'd together to generate the CA1 (aka "SLOTS") interrupt (see
+ * The Guide To Macintosh Family Hardware, 2nd edition p. 167). If we drive a
+ * disabled /NMRQ line low, the falling edge immediately triggers a CA1
+ * interrupt and all slot interrupts after that will generate no transition
+ * and therefore no interrupt, even after being re-enabled.
+ *
+ * So we make the VIA port A I/O lines inputs and use nubus_disabled to keep
+ * track of their states. When any slot IRQ becomes disabled we mask the CA1
+ * umbrella interrupt. Only when all slot IRQs become enabled do we unmask
+ * the CA1 interrupt. It must remain enabled even when cards have no interrupt
+ * handler registered. Drivers must therefore disable a slot interrupt at the
+ * device before they call free_irq (like shared and autovector interrupts).
+ *
+ * There is also a related problem when MacOS is used to boot Linux. A network
+ * card brought up by a MacOS driver may raise an interrupt while Linux boots.
+ * This can be fatal since it can't be handled until the right driver loads
+ * (if such a driver exists at all). Apparently related to this hardware
+ * limitation, "Designing Cards and Drivers", p. 9-8, says that a slot
+ * interrupt with no driver would crash MacOS (the book was written before
+ * the appearance of Macs with RBV or OSS).
*/
+
static u8 nubus_disabled;
void via_debug_dump(void);
@@ -353,34 +382,55 @@ void __init via_nubus_init(void)
via2[gBufB] |= 0x02;
}
- /* Disable all the slot interrupts (where possible). */
+ /*
+ * Disable the slot interrupts. On some hardware that's not possible.
+ * On some hardware it's unclear what all of these I/O lines do.
+ */
switch (macintosh_config->via_type) {
case MAC_VIA_II:
- /* Just make the port A lines inputs. */
- switch(macintosh_config->ident) {
- case MAC_MODEL_II:
- case MAC_MODEL_IIX:
- case MAC_MODEL_IICX:
- case MAC_MODEL_SE30:
- /* The top two bits are RAM size outputs. */
- via2[vDirA] &= 0xC0;
- break;
- default:
- via2[vDirA] &= 0x80;
- }
+ case MAC_VIA_QUADRA:
+ pr_debug("VIA2 vDirA is 0x%02X\n", via2[vDirA]);
break;
case MAC_VIA_IIci:
/* RBV. Disable all the slot interrupts. SIER works like IER. */
via2[rSIER] = 0x7F;
break;
+ }
+}
+
+void via_nubus_irq_startup(int irq)
+{
+ int irq_idx = IRQ_IDX(irq);
+
+ switch (macintosh_config->via_type) {
+ case MAC_VIA_II:
case MAC_VIA_QUADRA:
- /* Disable the inactive slot interrupts by making those lines outputs. */
- if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2)) {
- via2[vBufA] |= 0x7F;
- via2[vDirA] |= 0x7F;
+ /* Make the port A line an input. Probably redundant. */
+ if (macintosh_config->via_type == MAC_VIA_II) {
+ /* The top two bits are RAM size outputs. */
+ via2[vDirA] &= 0xC0 | ~(1 << irq_idx);
+ } else {
+ /* Allow NuBus slots 9 through F. */
+ via2[vDirA] &= 0x80 | ~(1 << irq_idx);
}
+ /* fall through */
+ case MAC_VIA_IIci:
+ via_irq_enable(irq);
+ break;
+ }
+}
+
+void via_nubus_irq_shutdown(int irq)
+{
+ switch (macintosh_config->via_type) {
+ case MAC_VIA_II:
+ case MAC_VIA_QUADRA:
+ /* Ensure that the umbrella CA1 interrupt remains enabled. */
+ via_irq_enable(irq);
+ break;
+ case MAC_VIA_IIci:
+ via_irq_disable(irq);
break;
}
}
@@ -506,6 +556,7 @@ void via_irq_enable(int irq) {
} else if (irq_src == 7) {
switch (macintosh_config->via_type) {
case MAC_VIA_II:
+ case MAC_VIA_QUADRA:
nubus_disabled &= ~(1 << irq_idx);
/* Enable the CA1 interrupt when no slot is disabled. */
if (!nubus_disabled)
@@ -517,14 +568,6 @@ void via_irq_enable(int irq) {
*/
via2[rSIER] = IER_SET_BIT(irq_idx);
break;
- case MAC_VIA_QUADRA:
- /* Make the port A line an input to enable the slot irq.
- * But not on PowerBooks, that's ADB.
- */
- if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2))
- via2[vDirA] &= ~(1 << irq_idx);
- break;
}
}
}
@@ -544,6 +587,7 @@ void via_irq_disable(int irq) {
} else if (irq_src == 7) {
switch (macintosh_config->via_type) {
case MAC_VIA_II:
+ case MAC_VIA_QUADRA:
nubus_disabled |= 1 << irq_idx;
if (nubus_disabled)
via2[gIER] = IER_CLR_BIT(1);
@@ -551,11 +595,6 @@ void via_irq_disable(int irq) {
case MAC_VIA_IIci:
via2[rSIER] = IER_CLR_BIT(irq_idx);
break;
- case MAC_VIA_QUADRA:
- if ((macintosh_config->adb_type != MAC_ADB_PB1) &&
- (macintosh_config->adb_type != MAC_ADB_PB2))
- via2[vDirA] |= 1 << irq_idx;
- break;
}
}
}
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:05.000000000 +1100
@@ -151,10 +151,15 @@ irqreturn_t mac_debug_handler(int, void
/* #define DEBUG_MACINTS */
+static unsigned int mac_irq_startup(struct irq_data *);
+static void mac_irq_shutdown(struct irq_data *);
+
static struct irq_chip mac_irq_chip = {
.name = "mac",
.irq_enable = mac_irq_enable,
.irq_disable = mac_irq_disable,
+ .irq_startup = mac_irq_startup,
+ .irq_shutdown = mac_irq_shutdown,
};
void __init mac_init_IRQ(void)
@@ -274,6 +279,28 @@ void mac_irq_disable(struct irq_data *da
}
}
+static unsigned int mac_irq_startup(struct irq_data *data)
+{
+ int irq = data->irq;
+
+ if (IRQ_SRC(irq) == 7 && !oss_present)
+ via_nubus_irq_startup(irq);
+ else
+ mac_irq_enable(data);
+
+ return 0;
+}
+
+static void mac_irq_shutdown(struct irq_data *data)
+{
+ int irq = data->irq;
+
+ if (IRQ_SRC(irq) == 7 && !oss_present)
+ via_nubus_irq_shutdown(irq);
+ else
+ mac_irq_disable(data);
+}
+
static int num_debug[8];
irqreturn_t mac_debug_handler(int irq, void *dev_id)
Index: linux-m68k/arch/m68k/include/asm/mac_via.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_via.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_via.h 2011-10-22 23:02:39.000000000 +1100
@@ -257,6 +257,8 @@ extern int rbv_present,via_alt_mapping;
extern void via_register_interrupts(void);
extern void via_irq_enable(int);
extern void via_irq_disable(int);
+extern void via_nubus_irq_startup(int irq);
+extern void via_nubus_irq_shutdown(int irq);
extern void via1_irq(unsigned int irq, struct irq_desc *desc);
extern void via1_set_head(int);
extern int via2_scsi_drq_pending(void);
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 10/16] m68k/mac: oss irq fixes
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (8 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 09/16] m68k/mac: fix nubus slot irq disable and shutdown Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 11/16] m68k/mac: fix baboon irq disable and shutdown Finn Thain
` (6 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: fix-oss-irqs --]
[-- Type: text/plain, Size: 12606 bytes --]
The IOP driver calls into the OSS driver to enable its IRQ. This undesirable coupling between drivers only exists because the OSS driver doesn't correctly handle all of its machspec IRQs.
Fix OSS handling of enable/disable for VIA1 IRQs (8 thru 15) which includes MAC_IRQ_ADB.
Back when I implemented pmac_zilog support I redefined IRQ_MAC_SCC incorrectly. Change this to a machspec IRQ so that it works on OSS.
Clean up the unused OSS audio IRQ and OSS_IRQLEV_* cruft that only confuses things.
Fix the OSS description in macints.c and remove an obsolete comment.
Don't enable the VIA1 irq before registering the handler.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:50:51.000000000 +1100
@@ -26,10 +26,6 @@
* - slot 6: timer 1 (not on IIci)
* - slot 7: status of IRQ; signals 'any enabled int.'
*
- * 2 - OSS (IIfx only?)
- * - slot 0: SCSI interrupt
- * - slot 1: Sound interrupt
- *
* Levels 3-6 vary by machine type. For VIA or RBV Macintoshes:
*
* 3 - unused (?)
@@ -54,21 +50,18 @@
*
* 6 - VIA1
*
- * For OSS Macintoshes (IIfx only at this point):
+ * For OSS Macintoshes (IIfx only), we apply an interrupt mapping similar to
+ * the Quadra (A/UX) mapping:
*
- * 3 - Nubus interrupt
- * - slot 0: Slot $9
- * - slot 1: Slot $A
- * - slot 2: Slot $B
- * - slot 3: Slot $C
- * - slot 4: Slot $D
- * - slot 5: Slot $E
+ * 1 - ISM IOP (ADB)
*
- * 4 - SCC IOP
+ * 2 - SCSI
*
- * 5 - ISM IOP (ADB?)
+ * 3 - NuBus
*
- * 6 - unused
+ * 4 - SCC IOP
+ *
+ * 6 - VIA1
*
* For PSC Macintoshes (660AV, 840AV):
*
@@ -112,14 +105,6 @@
* case. They're hidden behind the Nubus slot $C interrupt thus adding a
* third layer of indirection. Why oh why did the Apple engineers do that?
*
- * - We support "fast" and "slow" handlers, just like the Amiga port. The
- * fast handlers are called first and with all interrupts disabled. They
- * are expected to execute quickly (hence the name). The slow handlers are
- * called last with interrupts enabled and the interrupt level restored.
- * They must therefore be reentrant.
- *
- * TODO:
- *
*/
#include <linux/types.h>
@@ -216,8 +201,6 @@ void mac_irq_enable(struct irq_data *dat
switch(irq_src) {
case 1:
- via_irq_enable(irq);
- break;
case 2:
case 7:
if (oss_present)
@@ -226,6 +209,7 @@ void mac_irq_enable(struct irq_data *dat
via_irq_enable(irq);
break;
case 3:
+ case 4:
case 5:
case 6:
if (psc_present)
@@ -233,10 +217,6 @@ void mac_irq_enable(struct irq_data *dat
else if (oss_present)
oss_irq_enable(irq);
break;
- case 4:
- if (psc_present)
- psc_irq_enable(irq);
- break;
case 8:
if (baboon_present)
baboon_irq_enable(irq);
@@ -251,8 +231,6 @@ void mac_irq_disable(struct irq_data *da
switch(irq_src) {
case 1:
- via_irq_disable(irq);
- break;
case 2:
case 7:
if (oss_present)
@@ -261,6 +239,7 @@ void mac_irq_disable(struct irq_data *da
via_irq_disable(irq);
break;
case 3:
+ case 4:
case 5:
case 6:
if (psc_present)
@@ -268,10 +247,6 @@ void mac_irq_disable(struct irq_data *da
else if (oss_present)
oss_irq_disable(irq);
break;
- case 4:
- if (psc_present)
- psc_irq_disable(irq);
- break;
case 8:
if (baboon_present)
baboon_irq_disable(irq);
Index: linux-m68k/arch/m68k/mac/oss.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/oss.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/oss.c 2011-10-22 23:02:39.000000000 +1100
@@ -1,5 +1,5 @@
/*
- * OSS handling
+ * Operating System Services (OSS) chip handling
* Written by Joshua M. Thompson (funaho@jurai.org)
*
*
@@ -49,10 +49,8 @@ void __init oss_init(void)
/* do this by setting the source's interrupt level to zero. */
for (i = 0; i <= OSS_NUM_SOURCES; i++) {
- oss->irq_level[i] = OSS_IRQLEV_DISABLED;
+ oss->irq_level[i] = 0;
}
- /* If we disable VIA1 here, we never really handle it... */
- oss->irq_level[OSS_VIA1] = OSS_IRQLEV_VIA1;
}
/*
@@ -64,17 +62,13 @@ void __init oss_nubus_init(void)
}
/*
- * Handle miscellaneous OSS interrupts. Right now that's just sound
- * and SCSI; everything else is routed to its own autovector IRQ.
+ * Handle miscellaneous OSS interrupts.
*/
static void oss_irq(unsigned int irq, struct irq_desc *desc)
{
- int events;
-
- events = oss->irq_pending & (OSS_IP_SOUND|OSS_IP_SCSI);
- if (!events)
- return;
+ int events = oss->irq_pending &
+ (OSS_IP_IOPSCC | OSS_IP_SCSI | OSS_IP_IOPISM);
#ifdef DEBUG_IRQS
if ((console_loglevel == 10) && !(events & OSS_IP_SCSI)) {
@@ -82,16 +76,20 @@ static void oss_irq(unsigned int irq, st
(int) oss->irq_pending);
}
#endif
- /* FIXME: how do you clear a pending IRQ? */
- if (events & OSS_IP_SOUND) {
- oss->irq_pending &= ~OSS_IP_SOUND;
- /* FIXME: call sound handler */
- } else if (events & OSS_IP_SCSI) {
+ if (events & OSS_IP_IOPSCC) {
+ oss->irq_pending &= ~OSS_IP_IOPSCC;
+ generic_handle_irq(IRQ_MAC_SCC);
+ }
+
+ if (events & OSS_IP_SCSI) {
oss->irq_pending &= ~OSS_IP_SCSI;
generic_handle_irq(IRQ_MAC_SCSI);
- } else {
- /* FIXME: error check here? */
+ }
+
+ if (events & OSS_IP_IOPISM) {
+ oss->irq_pending &= ~OSS_IP_IOPISM;
+ generic_handle_irq(IRQ_MAC_ADB);
}
}
@@ -130,14 +128,29 @@ static void oss_nubus_irq(unsigned int i
/*
* Register the OSS and NuBus interrupt dispatchers.
+ *
+ * This IRQ mapping is laid out with two things in mind: first, we try to keep
+ * things on their own levels to avoid having to do double-dispatches. Second,
+ * the levels match as closely as possible the alternate IRQ mapping mode (aka
+ * "A/UX mode") available on some VIA machines.
*/
+#define OSS_IRQLEV_IOPISM IRQ_AUTO_1
+#define OSS_IRQLEV_SCSI IRQ_AUTO_2
+#define OSS_IRQLEV_NUBUS IRQ_AUTO_3
+#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4
+#define OSS_IRQLEV_VIA1 IRQ_AUTO_6
+
void __init oss_register_interrupts(void)
{
- irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq);
- irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq);
- irq_set_chained_handler(OSS_IRQLEV_SOUND, oss_irq);
- irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq);
+ irq_set_chained_handler(OSS_IRQLEV_IOPISM, oss_irq);
+ irq_set_chained_handler(OSS_IRQLEV_SCSI, oss_irq);
+ irq_set_chained_handler(OSS_IRQLEV_NUBUS, oss_nubus_irq);
+ irq_set_chained_handler(OSS_IRQLEV_IOPSCC, oss_irq);
+ irq_set_chained_handler(OSS_IRQLEV_VIA1, via1_irq);
+
+ /* OSS_VIA1 gets enabled here because it has no machspec interrupt. */
+ oss->irq_level[OSS_VIA1] = IRQ_AUTO_6;
}
/*
@@ -156,13 +169,13 @@ void oss_irq_enable(int irq) {
switch(irq) {
case IRQ_MAC_SCC:
oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_IOPSCC;
- break;
+ return;
case IRQ_MAC_ADB:
oss->irq_level[OSS_IOPISM] = OSS_IRQLEV_IOPISM;
- break;
+ return;
case IRQ_MAC_SCSI:
oss->irq_level[OSS_SCSI] = OSS_IRQLEV_SCSI;
- break;
+ return;
case IRQ_NUBUS_9:
case IRQ_NUBUS_A:
case IRQ_NUBUS_B:
@@ -171,13 +184,11 @@ void oss_irq_enable(int irq) {
case IRQ_NUBUS_E:
irq -= NUBUS_SOURCE_BASE;
oss->irq_level[irq] = OSS_IRQLEV_NUBUS;
- break;
-#ifdef DEBUG_IRQUSE
- default:
- printk("%s unknown irq %d\n", __func__, irq);
- break;
-#endif
+ return;
}
+
+ if (IRQ_SRC(irq) == 1)
+ via_irq_enable(irq);
}
/*
@@ -193,14 +204,14 @@ void oss_irq_disable(int irq) {
#endif
switch(irq) {
case IRQ_MAC_SCC:
- oss->irq_level[OSS_IOPSCC] = OSS_IRQLEV_DISABLED;
- break;
+ oss->irq_level[OSS_IOPSCC] = 0;
+ return;
case IRQ_MAC_ADB:
- oss->irq_level[OSS_IOPISM] = OSS_IRQLEV_DISABLED;
- break;
+ oss->irq_level[OSS_IOPISM] = 0;
+ return;
case IRQ_MAC_SCSI:
- oss->irq_level[OSS_SCSI] = OSS_IRQLEV_DISABLED;
- break;
+ oss->irq_level[OSS_SCSI] = 0;
+ return;
case IRQ_NUBUS_9:
case IRQ_NUBUS_A:
case IRQ_NUBUS_B:
@@ -208,12 +219,10 @@ void oss_irq_disable(int irq) {
case IRQ_NUBUS_D:
case IRQ_NUBUS_E:
irq -= NUBUS_SOURCE_BASE;
- oss->irq_level[irq] = OSS_IRQLEV_DISABLED;
- break;
-#ifdef DEBUG_IRQUSE
- default:
- printk("%s unknown irq %d\n", __func__, irq);
- break;
-#endif
+ oss->irq_level[irq] = 0;
+ return;
}
+
+ if (IRQ_SRC(irq) == 1)
+ via_irq_disable(irq);
}
Index: linux-m68k/arch/m68k/mac/iop.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/iop.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/iop.c 2011-10-22 23:02:39.000000000 +1100
@@ -115,7 +115,6 @@
#include <asm/macintosh.h>
#include <asm/macints.h>
#include <asm/mac_iop.h>
-#include <asm/mac_oss.h>
/*#define DEBUG_IOP*/
@@ -149,8 +148,6 @@ static struct listener iop_listeners[NUM
irqreturn_t iop_ism_irq(int, void *);
-extern void oss_irq_enable(int);
-
/*
* Private access functions
*/
@@ -304,11 +301,10 @@ void __init iop_init(void)
void __init iop_register_interrupts(void)
{
if (iop_ism_present) {
- if (oss_present) {
- if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq, 0,
+ if (macintosh_config->ident == MAC_MODEL_IIFX) {
+ if (request_irq(IRQ_MAC_ADB, iop_ism_irq, 0,
"ISM IOP", (void *)IOP_NUM_ISM))
pr_err("Couldn't register ISM IOP interrupt\n");
- oss_irq_enable(IRQ_MAC_ADB);
} else {
if (request_irq(IRQ_VIA2_0, iop_ism_irq, 0, "ISM IOP",
(void *)IOP_NUM_ISM))
Index: linux-m68k/arch/m68k/include/asm/mac_oss.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_oss.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_oss.h 2011-10-22 23:02:39.000000000 +1100
@@ -58,25 +58,6 @@
#define OSS_POWEROFF 0x80
-/*
- * OSS Interrupt levels for various sub-systems
- *
- * This mapping is laid out with two things in mind: first, we try to keep
- * things on their own levels to avoid having to do double-dispatches. Second,
- * the levels match as closely as possible the alternate IRQ mapping mode (aka
- * "A/UX mode") available on some VIA machines.
- */
-
-#define OSS_IRQLEV_DISABLED 0
-#define OSS_IRQLEV_IOPISM 1 /* ADB? */
-#define OSS_IRQLEV_SCSI IRQ_AUTO_2
-#define OSS_IRQLEV_NUBUS IRQ_AUTO_3 /* keep this on its own level */
-#define OSS_IRQLEV_IOPSCC IRQ_AUTO_4 /* matches VIA alternate mapping */
-#define OSS_IRQLEV_SOUND IRQ_AUTO_5 /* matches VIA alternate mapping */
-#define OSS_IRQLEV_60HZ 6 /* matches VIA alternate mapping */
-#define OSS_IRQLEV_VIA1 IRQ_AUTO_6 /* matches VIA alternate mapping */
-#define OSS_IRQLEV_PARITY 7 /* matches VIA alternate mapping */
-
#ifndef __ASSEMBLY__
struct mac_oss {
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:03.000000000 +1100
@@ -893,8 +893,14 @@ static void __init mac_identify(void)
scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC_B;
break;
default:
- scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC;
- scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC;
+ /* On non-PSC machines, the serial ports share an IRQ. */
+ if (macintosh_config->ident == MAC_MODEL_IIFX) {
+ scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_MAC_SCC;
+ scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_MAC_SCC;
+ } else {
+ scc_a_rsrcs[1].start = scc_a_rsrcs[1].end = IRQ_AUTO_4;
+ scc_b_rsrcs[1].start = scc_b_rsrcs[1].end = IRQ_AUTO_4;
+ }
break;
}
Index: linux-m68k/arch/m68k/include/asm/macints.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/macints.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/macints.h 2011-10-22 23:02:39.000000000 +1100
@@ -104,6 +104,9 @@
#define IRQ_PSC4_3 (35)
#define IRQ_MAC_MACE_DMA IRQ_PSC4_3
+/* OSS Level 4 interrupts */
+#define IRQ_MAC_SCC (33)
+
/* Level 5 (PSC, AV Macs only) interrupts */
#define IRQ_PSC5_0 (40)
#define IRQ_PSC5_1 (41)
@@ -131,9 +134,6 @@
#define IRQ_BABOON_2 (66)
#define IRQ_BABOON_3 (67)
-/* On non-PSC machines, the serial ports share an IRQ */
-#define IRQ_MAC_SCC IRQ_AUTO_4
-
#define SLOT2IRQ(x) (x + 47)
#define IRQ2SLOT(x) (x - 47)
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 11/16] m68k/mac: fix baboon irq disable and shutdown
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (9 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 10/16] m68k/mac: oss irq fixes Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 12/16] m68k/mac: fix powerbook 150 adb_type Finn Thain
` (5 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: remove-baboon-irq-disabled --]
[-- Type: text/plain, Size: 2116 bytes --]
The baboon_disabled hack is broken because it is missing an irq shutdown method. So releasing a Baboon irq kills the other Baboon irqs. But we don't really need this hack because we don't have media bay support and TREX uses a NuBus IRQ. Remove it.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/baboon.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/baboon.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/baboon.c 2011-10-22 23:02:39.000000000 +1100
@@ -18,7 +18,6 @@
int baboon_present;
static volatile struct baboon *baboon;
-static unsigned char baboon_disabled;
#if 0
extern int macide_ack_intr(struct ata_channel *);
@@ -84,37 +83,32 @@ static void baboon_irq(unsigned int irq,
void __init baboon_register_interrupts(void)
{
- baboon_disabled = 0;
irq_set_chained_handler(IRQ_NUBUS_C, baboon_irq);
}
/*
- * The means for masking individual baboon interrupts remains a mystery, so
- * enable the umbrella interrupt only when no baboon interrupt is disabled.
+ * The means for masking individual Baboon interrupts remains a mystery.
+ * However, since we only use the IDE IRQ, we can just enable/disable all
+ * Baboon interrupts. If/when we handle more than one Baboon IRQ, we must
+ * either figure out how to mask them individually or else implement the
+ * same workaround that's used for NuBus slots (see nubus_disabled and
+ * via_nubus_irq_shutdown).
*/
void baboon_irq_enable(int irq)
{
- int irq_idx = IRQ_IDX(irq);
-
#ifdef DEBUG_IRQUSE
printk("baboon_irq_enable(%d)\n", irq);
#endif
- baboon_disabled &= ~(1 << irq_idx);
- if (!baboon_disabled)
- mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
+ mac_irq_enable(irq_get_irq_data(IRQ_NUBUS_C));
}
void baboon_irq_disable(int irq)
{
- int irq_idx = IRQ_IDX(irq);
-
#ifdef DEBUG_IRQUSE
printk("baboon_irq_disable(%d)\n", irq);
#endif
- baboon_disabled |= 1 << irq_idx;
- if (baboon_disabled)
- mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
+ mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
}
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 12/16] m68k/mac: fix powerbook 150 adb_type
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (10 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 11/16] m68k/mac: fix baboon irq disable and shutdown Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks Finn Thain
` (4 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: pb150-adb_type --]
[-- Type: text/plain, Size: 863 bytes --]
The PowerBook 150 is a actually a Duo underneath. Fix the adb_type.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
The kernel doesn't actually treat MAC_ADB_PB1 any differently to MAC_ADB_PB2 hardware and so the PMU driver doesn't work on "V1" PMU hardware. It does work on the PowerBook 150, as that's actually V2.
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:01.000000000 +1100
@@ -674,7 +674,7 @@ static struct mac_model mac_data_table[]
}, {
.ident = MAC_MODEL_PB150,
.name = "PowerBook 150",
- .adb_type = MAC_ADB_PB1,
+ .adb_type = MAC_ADB_PB2,
.via_type = MAC_VIA_IIci,
.scsi_type = MAC_SCSI_OLD,
.ide_type = MAC_IDE_PB,
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (11 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 12/16] m68k/mac: fix powerbook 150 adb_type Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 14/16] m68k/mac: cleanup macro case Finn Thain
` (3 subsequent siblings)
16 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, James E.J. Bottomley, linux-scsi
[-- Attachment #1: fix-scsi-interrupt --]
[-- Type: text/plain, Size: 1824 bytes --]
Fix the mac_scsi interrupt edge trigger on non-RBV PowerBooks. This doesn't appear to help my PowerBook 520 but the NetBSD source reveals that the PowerBook 500 series is different than the others.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:01.000000000 +1100
@@ -252,22 +252,28 @@ void __init via_init(void)
via2[vACR] &= ~0x03; /* disable port A & B latches */
}
+ /* Everything below this point is VIA2 only... */
+
+ if (rbv_present)
+ return;
+
/*
- * Set vPCR for control line interrupts (but not on RBV)
+ * Set vPCR for control line interrupts.
+ *
+ * CA1 (SLOTS IRQ), CB1 (ASC IRQ): negative edge trigger.
+ *
+ * Macs with ESP SCSI have a negative edge triggered SCSI interrupt.
+ * Testing reveals that PowerBooks do too. However, the SE/30
+ * schematic diagram shows an active high NCR5380 IRQ line.
*/
- if (!rbv_present) {
- /* For all VIA types, CA1 (SLOTS IRQ) and CB1 (ASC IRQ)
- * are made negative edge triggered here.
- */
- if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
- /* CB2 (IRQ) indep. input, positive edge */
- /* CA2 (DRQ) indep. input, positive edge */
- via2[vPCR] = 0x66;
- } else {
- /* CB2 (IRQ) indep. input, negative edge */
- /* CA2 (DRQ) indep. input, negative edge */
- via2[vPCR] = 0x22;
- }
+
+ pr_debug("VIA2 vPCR is 0x%02X\n", via2[vPCR]);
+ if (macintosh_config->via_type == MAC_VIA_II) {
+ /* CA2 (SCSI DRQ), CB2 (SCSI IRQ): indep. input, pos. edge */
+ via2[vPCR] = 0x66;
+ } else {
+ /* CA2 (SCSI DRQ), CB2 (SCSI IRQ): indep. input, neg. edge */
+ via2[vPCR] = 0x22;
}
}
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 14/16] m68k/mac: cleanup macro case
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (12 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-10-23 14:11 ` [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it Finn Thain
` (2 subsequent siblings)
16 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k
[-- Attachment #1: fix-macro-case --]
[-- Type: text/plain, Size: 10054 bytes --]
Code style convention has macro names in uppercase. Change MAC_VIA_IIci to MAC_VIA_IICI.
Also remove an obsolete comment.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/arch/m68k/include/asm/macintosh.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/macintosh.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/macintosh.h 2011-10-22 23:02:39.000000000 +1100
@@ -42,7 +42,7 @@ struct mac_model
#define MAC_ADB_IOP 6
#define MAC_VIA_II 1
-#define MAC_VIA_IIci 2
+#define MAC_VIA_IICI 2
#define MAC_VIA_QUADRA 3
#define MAC_SCSI_NONE 0
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-22 23:02:39.000000000 +1100
@@ -221,7 +221,7 @@ void __init config_mac(void)
* inaccurate, so look here if a new Mac model won't run. Example: if
* a Mac crashes immediately after the VIA1 registers have been dumped
* to the screen, it probably died attempting to read DirB on a RBV.
- * Meaning it should have MAC_VIA_IIci here :-)
+ * Meaning it should have MAC_VIA_IICI here :-)
*/
struct mac_model *macintosh_config;
@@ -296,7 +296,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_IICI,
.name = "IIci",
.adb_type = MAC_ADB_II,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -305,7 +305,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_IIFX,
.name = "IIfx",
.adb_type = MAC_ADB_IOP,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_IOP,
.nubus_type = MAC_NUBUS,
@@ -314,7 +314,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_IISI,
.name = "IIsi",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -323,7 +323,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_IIVI,
.name = "IIvi",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -332,7 +332,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_IIVX,
.name = "IIvx",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -347,7 +347,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_CLII,
.name = "Classic II",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -356,7 +356,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_CCL,
.name = "Color Classic",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -365,7 +365,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_CCLII,
.name = "Color Classic II",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -380,7 +380,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_LC,
.name = "LC",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -389,7 +389,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_LCII,
.name = "LC II",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -398,7 +398,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_LCIII,
.name = "LC III",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -526,7 +526,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_P460,
.name = "Performa 460",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -553,7 +553,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_P520,
.name = "Performa 520",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -562,7 +562,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_P550,
.name = "Performa 550",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -594,7 +594,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_TV,
.name = "TV",
.adb_type = MAC_ADB_CUDA,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -603,7 +603,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_P600,
.name = "Performa 600",
.adb_type = MAC_ADB_IISI,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
@@ -675,7 +675,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB150,
.name = "PowerBook 150",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.ide_type = MAC_IDE_PB,
.scc_type = MAC_SCC_QUADRA,
@@ -761,17 +761,13 @@ static struct mac_model mac_data_table[]
* PowerBook Duos are pretty much like normal PowerBooks
* All of these probably have onboard SONIC in the Dock which
* means we'll have to probe for it eventually.
- *
- * Are these really MAC_VIA_IIci? The developer notes for the
- * Duos show pretty much the same custom parts as in most of
- * the other PowerBooks which would imply MAC_VIA_QUADRA.
*/
{
.ident = MAC_MODEL_PB210,
.name = "PowerBook Duo 210",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
@@ -780,7 +776,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB230,
.name = "PowerBook Duo 230",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
@@ -789,7 +785,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB250,
.name = "PowerBook Duo 250",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
@@ -798,7 +794,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB270C,
.name = "PowerBook Duo 270c",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
@@ -807,7 +803,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB280,
.name = "PowerBook Duo 280",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
@@ -816,7 +812,7 @@ static struct mac_model mac_data_table[]
.ident = MAC_MODEL_PB280C,
.name = "PowerBook Duo 280c",
.adb_type = MAC_ADB_PB2,
- .via_type = MAC_VIA_IIci,
+ .via_type = MAC_VIA_IICI,
.scsi_type = MAC_SCSI_OLD,
.scc_type = MAC_SCC_QUADRA,
.nubus_type = MAC_NUBUS,
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:50:51.000000000 +1100
@@ -125,7 +125,7 @@ void __init via_init(void)
/* IIci, IIsi, IIvx, IIvi (P6xx), LC series */
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
via1 = (void *) VIA1_BASE;
if (macintosh_config->ident == MAC_MODEL_IIFX) {
via2 = NULL;
@@ -398,7 +398,7 @@ void __init via_nubus_init(void)
case MAC_VIA_QUADRA:
pr_debug("VIA2 vDirA is 0x%02X\n", via2[vDirA]);
break;
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
/* RBV. Disable all the slot interrupts. SIER works like IER. */
via2[rSIER] = 0x7F;
break;
@@ -421,7 +421,7 @@ void via_nubus_irq_startup(int irq)
via2[vDirA] &= 0x80 | ~(1 << irq_idx);
}
/* fall through */
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
via_irq_enable(irq);
break;
}
@@ -435,7 +435,7 @@ void via_nubus_irq_shutdown(int irq)
/* Ensure that the umbrella CA1 interrupt remains enabled. */
via_irq_enable(irq);
break;
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
via_irq_disable(irq);
break;
}
@@ -568,7 +568,7 @@ void via_irq_enable(int irq) {
if (!nubus_disabled)
via2[gIER] = IER_SET_BIT(1);
break;
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
/* On RBV, enable the slot interrupt.
* SIER works like IER.
*/
@@ -598,7 +598,7 @@ void via_irq_disable(int irq) {
if (nubus_disabled)
via2[gIER] = IER_CLR_BIT(1);
break;
- case MAC_VIA_IIci:
+ case MAC_VIA_IICI:
via2[rSIER] = IER_CLR_BIT(irq_idx);
break;
}
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (13 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 14/16] m68k/mac: cleanup macro case Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 16/16] mac_esp: rename irq Finn Thain
2011-10-31 18:35 ` [PATCH 00/16] more mac68k fixes and cleanup Geert Uytterhoeven
16 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, James E.J. Bottomley, linux-scsi
[-- Attachment #1: mac-scsi-dont-enable-irq --]
[-- Type: text/plain, Size: 1009 bytes --]
Don't enable the SCSI irq when initialising the chip -- the irq has no handler yet.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/drivers/scsi/mac_scsi.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_scsi.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_scsi.c 2011-10-22 23:44:51.000000000 +1100
@@ -339,9 +339,6 @@ static void mac_scsi_reset_boot(struct S
printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
- /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
- disable_irq(IRQ_MAC_SCSI);
-
/* get in phase */
NCR5380_write( TARGET_COMMAND_REG,
PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
@@ -357,9 +354,6 @@ static void mac_scsi_reset_boot(struct S
for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
barrier();
- /* switch on SCSI IRQ again */
- enable_irq(IRQ_MAC_SCSI);
-
printk(KERN_INFO " done\n" );
}
#endif
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 16/16] mac_esp: rename irq
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (14 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it Finn Thain
@ 2011-10-23 14:11 ` Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-31 18:35 ` [PATCH 00/16] more mac68k fixes and cleanup Geert Uytterhoeven
16 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-10-23 14:11 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: linux-m68k, James E.J. Bottomley, linux-scsi
[-- Attachment #1: mac-esp-irq-name --]
[-- Type: text/plain, Size: 787 bytes --]
Rename the "Mac ESP" irq as "ESP" to be consistent with all the other Mac drivers and ESP drivers.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Index: linux-m68k/drivers/scsi/mac_esp.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_esp.c 2011-10-23 18:18:46.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_esp.c 2011-10-23 18:19:30.000000000 +1100
@@ -565,8 +565,7 @@ static int __devinit esp_mac_probe(struc
esp_chips[dev->id] = esp;
mb();
if (esp_chips[!dev->id] == NULL) {
- err = request_irq(host->irq, mac_scsi_esp_intr, 0,
- "Mac ESP", NULL);
+ err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
if (err < 0) {
esp_chips[dev->id] = NULL;
goto fail_free_priv;
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 00/16] more mac68k fixes and cleanup
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
` (15 preceding siblings ...)
2011-10-23 14:11 ` [PATCH 16/16] mac_esp: rename irq Finn Thain
@ 2011-10-31 18:35 ` Geert Uytterhoeven
2011-10-31 19:16 ` Geert Uytterhoeven
16 siblings, 1 reply; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-10-31 18:35 UTC (permalink / raw)
To: Finn Thain; +Cc: linux-m68k
Hi Finn,
On Sun, Oct 23, 2011 at 16:11, Finn Thain <fthain@telegraphics.com.au> wrote:
> It would be good if this whole series passes through the m68k tree.
OK, I'll apply all of them.
But several of them will have to go in via other maintainers' trees,
or get acked.
> I suppose that after all of the renaming recently this series will need
> to be rebased (?)
"git am" is smart enough to detect that drivers/net/ got restructured.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 00/16] more mac68k fixes and cleanup
2011-10-31 18:35 ` [PATCH 00/16] more mac68k fixes and cleanup Geert Uytterhoeven
@ 2011-10-31 19:16 ` Geert Uytterhoeven
0 siblings, 0 replies; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-10-31 19:16 UTC (permalink / raw)
To: Finn Thain; +Cc: linux-m68k
On Mon, Oct 31, 2011 at 19:35, Geert Uytterhoeven <geert@linux-m68k.org> wrote:
>> I suppose that after all of the renaming recently this series will need
>> to be rebased (?)
>
> "git am" is smart enough to detect that drivers/net/ got restructured.
Doh, s/am/rebase/
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 03/16] mac_sonic: add irq resources and cleanup
2011-10-23 14:11 ` [PATCH 03/16] mac_sonic: add irq resources and cleanup Finn Thain
@ 2011-11-13 10:28 ` Geert Uytterhoeven
2011-11-13 14:30 ` Finn Thain
2011-12-10 5:23 ` Finn Thain
1 sibling, 1 reply; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-11-13 10:28 UTC (permalink / raw)
To: Finn Thain, David Miller; +Cc: linux-m68k, netdev
On Sun, Oct 23, 2011 at 16:11, Finn Thain <fthain@telegraphics.com.au> wrote:
> Make better use of the SONIC platform device by adding irq resources. This moves the via_type logic out of the NIC device driver which improves modularity.
>
> Since interrupt handlers now run with CPU interrupts disabled, we don't need the macsonic_interrupt() wrapper. Remove it.
Please wrap lines at 75, for easier to read "git log" output.
> For consistency, rename retval as err.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
David: Is it OK for this patch to go in through the m68k tree, as it touches
core m68k files?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 03/16] mac_sonic: add irq resources and cleanup
2011-11-13 10:28 ` Geert Uytterhoeven
@ 2011-11-13 14:30 ` Finn Thain
2011-11-13 17:36 ` Geert Uytterhoeven
0 siblings, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-11-13 14:30 UTC (permalink / raw)
To: Geert Uytterhoeven; +Cc: David Miller, linux-m68k, netdev
On Sun, 13 Nov 2011, Geert Uytterhoeven wrote:
> Please wrap lines at 75, for easier to read "git log" output.
Yes, sorry about that. It was my first batch submission by "quilt mail"
(in the past I've always used Alpine to hard wrap individual patch
headers). I can fix them up and re-submit if that's easier for you.
Finn
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 03/16] mac_sonic: add irq resources and cleanup
2011-11-13 14:30 ` Finn Thain
@ 2011-11-13 17:36 ` Geert Uytterhoeven
0 siblings, 0 replies; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-11-13 17:36 UTC (permalink / raw)
To: Finn Thain; +Cc: David Miller, linux-m68k, netdev
On Sun, Nov 13, 2011 at 15:30, Finn Thain <fthain@telegraphics.com.au> wrote:
> On Sun, 13 Nov 2011, Geert Uytterhoeven wrote:
>> Please wrap lines at 75, for easier to read "git log" output.
>
> Yes, sorry about that. It was my first batch submission by "quilt mail"
> (in the past I've always used Alpine to hard wrap individual patch
Ah, you're a few years behind ;-)
I went al^H^Hpine -> quilt mail -> git send-email. I don't want to go
back.
> headers). I can fix them up and re-submit if that's easier for you.
That's unnecessary. I already did that in the m68k-queue/for-3.3 branch.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
@ 2011-11-24 14:34 ` Finn Thain
2011-11-24 14:56 ` Alan Cox
2011-11-24 15:28 ` David Laight
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
1 sibling, 2 replies; 51+ messages in thread
From: Finn Thain @ 2011-11-24 14:34 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linux-serial, linux-m68k, linuxppc-dev, Geert Uytterhoeven
On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
masked. This can be a problem when pmac_zilog starts up.
For example, the serial debugging code in arch/m68k/kernel/head.S may be
used beforehand. It disables the SCC interrupts at the chip but doesn't
ack them. Then when a pmac_zilog port is opened and SCC chip interrupts
become enabled, the machine locks up with "unexpected interrupt" because
request_irq() hasn't happened yet.
Fix this by setting the SCC master interrupt enable bit only after the
handler is installed. This is achieved by extracting that operation out of
__pmz_startup() and placing it into a seperate routine.
A similar problem arises when the irq is freed. Fix this by resetting the
chip first (on m68k mac).
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
This patch has been tested on a variety of m68k Macs but no PowerMacs.
I am re-sending this patch Cc linux-serial. It still needs a suitable ack
so that Geert can push it through his tree.
Index: linux-m68k/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-m68k.orig/drivers/tty/serial/pmac_zilog.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/tty/serial/pmac_zilog.c 2011-10-22 23:02:38.000000000 +1100
@@ -910,8 +910,8 @@ static int __pmz_startup(struct uart_pma
/* Clear handshaking, enable BREAK interrupts */
uap->curregs[R15] = BRKIE;
- /* Master interrupt enable */
- uap->curregs[R9] |= NV | MIE;
+ /* No vector */
+ uap->curregs[R9] |= NV;
pmz_load_zsregs(uap, uap->curregs);
@@ -925,6 +925,17 @@ static int __pmz_startup(struct uart_pma
return pwr_delay;
}
+static void pmz_master_int_control(struct uart_pmac_port *uap, int enable)
+{
+ if (enable) {
+ uap->curregs[R9] |= MIE; /* Master interrupt enable */
+ write_zsreg(uap, R9, uap->curregs[R9]);
+ } else {
+ uap->curregs[R9] &= ~MIE;
+ write_zsreg(uap, 9, FHWRES);
+ }
+}
+
static void pmz_irda_reset(struct uart_pmac_port *uap)
{
uap->curregs[R5] |= DTR;
@@ -976,6 +987,19 @@ static int pmz_startup(struct uart_port
return -ENXIO;
}
+ /*
+ * Most 68k Mac models cannot mask the SCC IRQ so they must enable
+ * interrupts after the handler is installed and not before.
+ */
+#ifndef CONFIG_MAC
+ if (!ZS_IS_CONS(uap))
+#endif
+ {
+ spin_lock_irqsave(&port->lock, flags);
+ pmz_master_int_control(uap, 1);
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+
mutex_unlock(&pmz_irq_mutex);
/* Right now, we deal with delay by blocking here, I'll be
@@ -1015,6 +1039,11 @@ static void pmz_shutdown(struct uart_por
mutex_lock(&pmz_irq_mutex);
+#ifdef CONFIG_MAC
+ if (!ZS_IS_OPEN(uap->mate))
+ pmz_master_int_control(uap, 0);
+#endif
+
/* Release interrupt handler */
free_irq(uap->port.irq, uap);
@@ -1734,6 +1763,7 @@ static int pmz_resume(struct macio_dev *
goto bail;
}
pwr_delay = __pmz_startup(uap);
+ pmz_master_int_control(uap, 1);
/* Take care of config that may have changed while asleep */
__pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
@@ -2178,6 +2208,9 @@ static int __init pmz_console_setup(stru
* Enable the hardware
*/
pwr_delay = __pmz_startup(uap);
+#ifndef CONFIG_MAC
+ pmz_master_int_control(uap, 1);
+#endif
if (pwr_delay)
mdelay(pwr_delay);
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-24 14:34 ` Finn Thain
@ 2011-11-24 14:56 ` Alan Cox
2011-11-24 20:41 ` Benjamin Herrenschmidt
2011-11-25 3:15 ` Finn Thain
2011-11-24 15:28 ` David Laight
1 sibling, 2 replies; 51+ messages in thread
From: Alan Cox @ 2011-11-24 14:56 UTC (permalink / raw)
To: Finn Thain
Cc: Benjamin Herrenschmidt, linux-serial, linux-m68k, linuxppc-dev,
Geert Uytterhoeven
On Fri, 25 Nov 2011 01:34:58 +1100 (EST)
Finn Thain <fthain@telegraphics.com.au> wrote:
>
> On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> masked. This can be a problem when pmac_zilog starts up.
>
> For example, the serial debugging code in arch/m68k/kernel/head.S may be
> used beforehand. It disables the SCC interrupts at the chip but doesn't
> ack them. Then when a pmac_zilog port is opened and SCC chip interrupts
> become enabled, the machine locks up with "unexpected interrupt" because
> request_irq() hasn't happened yet.
>
> Fix this by setting the SCC master interrupt enable bit only after the
> handler is installed. This is achieved by extracting that operation out of
> __pmz_startup() and placing it into a seperate routine.
>
> A similar problem arises when the irq is freed. Fix this by resetting the
> chip first (on m68k mac).
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
>
> ---
>
> This patch has been tested on a variety of m68k Macs but no PowerMacs.
>
> I am re-sending this patch Cc linux-serial. It still needs a suitable ack
> so that Geert can push it through his tree.
Given the change should work for all hardware do we really need the
ifdefs. Far better I would have thought to just change it so we don't
have to maintain what is effectively two versions of the code between now
and 2038.
So no ack from me yet - I'd like to understand the ifdef decision first.
Otherwise it looks sensible.
Alan
^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-24 14:34 ` Finn Thain
2011-11-24 14:56 ` Alan Cox
@ 2011-11-24 15:28 ` David Laight
2011-11-24 20:43 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 51+ messages in thread
From: David Laight @ 2011-11-24 15:28 UTC (permalink / raw)
To: Finn Thain, Benjamin Herrenschmidt
Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
> On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> masked. This can be a problem when pmac_zilog starts up.
Wouldn't this also happen if the interrupt were shared?
Hopefully nothing vaguely modern uses the borked Zilog 8530 SCC
(which I presume is the part in question - brings back
too many nightmares....)
David
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-24 14:56 ` Alan Cox
@ 2011-11-24 20:41 ` Benjamin Herrenschmidt
2011-11-25 3:15 ` Finn Thain
1 sibling, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-11-24 20:41 UTC (permalink / raw)
To: Alan Cox
Cc: Finn Thain, linux-serial, linux-m68k, linuxppc-dev,
Geert Uytterhoeven
On Thu, 2011-11-24 at 14:56 +0000, Alan Cox wrote:
> > This patch has been tested on a variety of m68k Macs but no
> PowerMacs.
> >
> > I am re-sending this patch Cc linux-serial. It still needs a
> suitable ack
> > so that Geert can push it through his tree.
>
> Given the change should work for all hardware do we really need the
> ifdefs. Far better I would have thought to just change it so we don't
> have to maintain what is effectively two versions of the code between
> now
> and 2038.
>
> So no ack from me yet - I'd like to understand the ifdef decision
> first.
> Otherwise it looks sensible.
Yes, agreed. Sorry, that one was one my to-do list for a while, I meant
to look into more details and test on a ppc or two here see if it breaks
anything, and never got to do it.
I'll try to give it a go before hell freezes over.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* RE: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-24 15:28 ` David Laight
@ 2011-11-24 20:43 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-11-24 20:43 UTC (permalink / raw)
To: David Laight
Cc: Finn Thain, Geert Uytterhoeven, linux-m68k, linuxppc-dev,
linux-serial
On Thu, 2011-11-24 at 15:28 +0000, David Laight wrote:
> > On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> > masked. This can be a problem when pmac_zilog starts up.
>
> Wouldn't this also happen if the interrupt were shared?
> Hopefully nothing vaguely modern uses the borked Zilog 8530 SCC
> (which I presume is the part in question - brings back
> too many nightmares....)
Yup. Afaik, the most recent you can find with that are PowerMacs which
used it for their internal modem (even my G5 has one wired to the
internal slot afaik), tho none of those had shared interrupts.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-24 14:56 ` Alan Cox
2011-11-24 20:41 ` Benjamin Herrenschmidt
@ 2011-11-25 3:15 ` Finn Thain
2011-11-28 0:30 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-11-25 3:15 UTC (permalink / raw)
To: Alan Cox
Cc: Benjamin Herrenschmidt, linux-serial, linux-m68k, linuxppc-dev,
Geert Uytterhoeven
On Thu, 24 Nov 2011, Alan Cox wrote:
> Given the change should work for all hardware do we really need the
> ifdefs. Far better I would have thought to just change it so we don't
> have to maintain what is effectively two versions of the code between
> now and 2038.
I agree.
>
> So no ack from me yet - I'd like to understand the ifdef decision first.
Removing ifdefs makes the changes more invasive and the suspend/resume
code then has to be addressed, which I've avoided.
The suspend/resume code path can't be tested on m68k macs and the common
code paths I can't easily test on a powermac.
This patch should not be needed because the chip reset shouldn't leave the
tx and rx interrupts enabled. Those interrupts are explicitly enabled only
after request_irq(), so patching the master interrupt enable behaviour
should be redundant. But that's not the case in practice.
The chip reset code is already messy. I was inclined towards ifdefs and
reluctant to share more code after practical experience suggested possible
differences in the SCC/ESCC devices.
I guess I was hoping that the powermac maintainers might prefer ifdefs to
increased risk of destabilising the driver on powermacs...
But a more invasive patch would make for better code. I will see if I can
borrow a suitable PCI PowerMac.
Finn
> Otherwise it looks sensible.
>
> Alan
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16] pmac_zilog: fix unexpected irq
2011-11-25 3:15 ` Finn Thain
@ 2011-11-28 0:30 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-11-28 0:30 UTC (permalink / raw)
To: Finn Thain
Cc: Alan Cox, linux-serial, linux-m68k, linuxppc-dev,
Geert Uytterhoeven
> Removing ifdefs makes the changes more invasive and the suspend/resume
> code then has to be addressed, which I've avoided.
>
> The suspend/resume code path can't be tested on m68k macs and the common
> code paths I can't easily test on a powermac.
>
> This patch should not be needed because the chip reset shouldn't leave the
> tx and rx interrupts enabled. Those interrupts are explicitly enabled only
> after request_irq(), so patching the master interrupt enable behaviour
> should be redundant. But that's not the case in practice.
>
> The chip reset code is already messy. I was inclined towards ifdefs and
> reluctant to share more code after practical experience suggested possible
> differences in the SCC/ESCC devices.
>
> I guess I was hoping that the powermac maintainers might prefer ifdefs to
> increased risk of destabilising the driver on powermacs...
>
> But a more invasive patch would make for better code. I will see if I can
> borrow a suitable PCI PowerMac.
Please do the more invasive patch, I'll beat it up on powermacs.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 01/16 v2] pmac_zilog: fix unexpected irq
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
2011-11-24 14:34 ` Finn Thain
@ 2011-12-06 15:13 ` Finn Thain
2011-12-06 15:27 ` Geert Uytterhoeven
` (2 more replies)
1 sibling, 3 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-06 15:13 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Benjamin Herrenschmidt, linux-m68k, linuxppc-dev, linux-serial
On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
masked. This can be a problem when pmac_zilog starts up.
For example, the serial debugging code in arch/m68k/kernel/head.S may be
used beforehand. It disables the SCC interrupts at the chip but doesn't
ack them. Then when a pmac_zilog port is opened and SCC chip interrupts
become enabled, the machine locks up with "unexpected interrupt" because
request_irq() hasn't happened yet.
Fix this by setting the interrupt enable bits only after the handler is
installed and before it is uninstalled. Also move this bit flipping into a
separate pmz_interrupt_control() routine. Replace all instances of these
operations with calls to this routine.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-implemented since v1 using a simpler approach that avoids messing with
the Master Interrupt Enable bit. As well as the ifdef problem, it turns
out that v1 was not sufficient to entirely fix the problem.
This patch has been tested on a PowerBook 520 but no PowerMacs yet.
Index: linux-git/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-07 01:56:43.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-07 01:56:55.000000000 +1100
@@ -216,6 +216,18 @@ static void pmz_maybe_update_regs(struct
}
}
+static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
+{
+ if (enable) {
+ uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
+ if (!ZS_IS_EXTCLK(uap))
+ uap->curregs[1] |= EXT_INT_ENAB;
+ } else {
+ uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
+ }
+ write_zsreg(uap, R1, uap->curregs[1]);
+}
+
static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
{
struct tty_struct *tty = NULL;
@@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_ch
return tty;
flood:
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
- zssync(uap);
+ pmz_interrupt_control(uap, 0);
pmz_error("pmz: rx irq flood !\n");
return tty;
}
@@ -990,12 +1000,9 @@ static int pmz_startup(struct uart_port
if (ZS_IS_IRDA(uap))
pmz_irda_reset(uap);
- /* Enable interrupts emission from the chip */
+ /* Enable interrupt requests for the channel */
spin_lock_irqsave(&port->lock, flags);
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
+ pmz_interrupt_control(uap, 1);
spin_unlock_irqrestore(&port->lock, flags);
pmz_debug("pmz: startup() done.\n");
@@ -1015,6 +1022,25 @@ static void pmz_shutdown(struct uart_por
mutex_lock(&pmz_irq_mutex);
+ if (!ZS_IS_ASLEEP(uap)) {
+ spin_lock_irqsave(&port->lock, flags);
+
+ if (!ZS_IS_CONS(uap)) {
+ /* Disable receiver and transmitter */
+ uap->curregs[R3] &= ~RxENABLE;
+ uap->curregs[R5] &= ~TxENABLE;
+
+ /* Disable BRK assertion */
+ uap->curregs[R5] &= ~SND_BRK;
+ pmz_maybe_update_regs(uap);
+ }
+
+ /* Disable interrupt requests for the channel */
+ pmz_interrupt_control(uap, 0);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+ }
+
/* Release interrupt handler */
free_irq(uap->port.irq, uap);
@@ -1025,29 +1051,8 @@ static void pmz_shutdown(struct uart_por
if (!ZS_IS_OPEN(uap->mate))
pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
- /* Disable interrupts */
- if (!ZS_IS_ASLEEP(uap)) {
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
- zssync(uap);
- }
-
- if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
- spin_unlock_irqrestore(&port->lock, flags);
- mutex_unlock(&pmz_irq_mutex);
- return;
- }
-
- /* Disable receiver and transmitter. */
- uap->curregs[R3] &= ~RxENABLE;
- uap->curregs[R5] &= ~TxENABLE;
-
- /* Disable all interrupts and BRK assertion. */
- uap->curregs[R5] &= ~SND_BRK;
- pmz_maybe_update_regs(uap);
-
- /* Shut the chip down */
- pmz_set_scc_power(uap, 0);
+ if (!ZS_IS_ASLEEP(uap) && !ZS_IS_CONS(uap))
+ pmz_set_scc_power(uap, 0); /* Shut the chip down */
spin_unlock_irqrestore(&port->lock, flags);
@@ -1352,19 +1357,15 @@ static void pmz_set_termios(struct uart_
spin_lock_irqsave(&port->lock, flags);
/* Disable IRQs on the port */
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
+ pmz_interrupt_control(uap, 0);
/* Setup new port configuration */
__pmz_set_termios(port, termios, old);
/* Re-enable IRQs on the port */
- if (ZS_IS_OPEN(uap)) {
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
- }
+ if (ZS_IS_OPEN(uap))
+ pmz_interrupt_control(uap, 1);
+
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -1670,15 +1671,13 @@ static int pmz_suspend(struct macio_dev
spin_lock_irqsave(&uap->port.lock, flags);
+ /* Disable receiver and transmitter. */
+ uap->curregs[R3] &= ~RxENABLE;
+ uap->curregs[R5] &= ~TxENABLE;
+
+ pmz_interrupt_control(uap, 0);
+
if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
- /* Disable receiver and transmitter. */
- uap->curregs[R3] &= ~RxENABLE;
- uap->curregs[R5] &= ~TxENABLE;
-
- /* Disable all interrupts and BRK assertion. */
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- uap->curregs[R5] &= ~SND_BRK;
- pmz_load_zsregs(uap, uap->curregs);
uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
mb();
}
@@ -1738,14 +1737,6 @@ static int pmz_resume(struct macio_dev *
/* Take care of config that may have changed while asleep */
__pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
- if (ZS_IS_OPEN(uap)) {
- /* Enable interrupts */
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
- }
-
spin_unlock_irqrestore(&uap->port.lock, flags);
if (ZS_IS_CONS(uap))
@@ -1757,6 +1748,12 @@ static int pmz_resume(struct macio_dev *
enable_irq(uap->port.irq);
}
+ if (ZS_IS_OPEN(uap)) {
+ spin_lock_irqsave(&uap->port.lock, flags);
+ pmz_interrupt_control(uap, 1);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ }
+
bail:
mutex_unlock(&state->port.mutex);
mutex_unlock(&pmz_irq_mutex);
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v2] pmac_zilog: fix unexpected irq
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
@ 2011-12-06 15:27 ` Geert Uytterhoeven
2011-12-07 1:26 ` Finn Thain
2011-12-06 15:39 ` Alan Cox
2011-12-07 3:49 ` [PATCH 01/16 v3] " Finn Thain
2 siblings, 1 reply; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-12-06 15:27 UTC (permalink / raw)
To: Finn Thain; +Cc: Benjamin Herrenschmidt, linux-m68k, linuxppc-dev, linux-serial
Hi Finn,
On Tue, Dec 6, 2011 at 16:13, Finn Thain <fthain@telegraphics.com.au> wrote:
> +static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
> +{
> + if (enable) {
> + uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
> + if (!ZS_IS_EXTCLK(uap))
> + uap->curregs[1] |= EXT_INT_ENAB;
> + } else {
> + uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
Should there be a call to zssync() here?
The old code always did that after disabling interrupts.
> + }
> + write_zsreg(uap, R1, uap->curregs[1]);
> +}
> +
> static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
> {
> struct tty_struct *tty = NULL;
> @@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_ch
>
> return tty;
> flood:
> - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> - write_zsreg(uap, R1, uap->curregs[R1]);
> - zssync(uap);
Cfr. e.g. here.
> + pmz_interrupt_control(uap, 0);
> pmz_error("pmz: rx irq flood !\n");
> return tty;
> }
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v2] pmac_zilog: fix unexpected irq
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
2011-12-06 15:27 ` Geert Uytterhoeven
@ 2011-12-06 15:39 ` Alan Cox
2011-12-07 3:49 ` [PATCH 01/16 v3] " Finn Thain
2 siblings, 0 replies; 51+ messages in thread
From: Alan Cox @ 2011-12-06 15:39 UTC (permalink / raw)
To: Finn Thain
Cc: Geert Uytterhoeven, Benjamin Herrenschmidt, linux-m68k,
linuxppc-dev, linux-serial
On Wed, 7 Dec 2011 02:13:41 +1100 (EST)
Finn Thain <fthain@telegraphics.com.au> wrote:
>
> On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> masked. This can be a problem when pmac_zilog starts up.
>
> For example, the serial debugging code in arch/m68k/kernel/head.S may be
> used beforehand. It disables the SCC interrupts at the chip but doesn't
> ack them. Then when a pmac_zilog port is opened and SCC chip interrupts
> become enabled, the machine locks up with "unexpected interrupt" because
> request_irq() hasn't happened yet.
>
> Fix this by setting the interrupt enable bits only after the handler is
> installed and before it is uninstalled. Also move this bit flipping into a
> separate pmz_interrupt_control() routine. Replace all instances of these
> operations with calls to this routine.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Nice
Acked-by: Alan Cox <alan@linux.intel.com>
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v2] pmac_zilog: fix unexpected irq
2011-12-06 15:27 ` Geert Uytterhoeven
@ 2011-12-07 1:26 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-07 1:26 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Benjamin Herrenschmidt, linux-m68k, linuxppc-dev, linux-serial
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2634 bytes --]
On Tue, 6 Dec 2011, Geert Uytterhoeven wrote:
> Hi Finn,
>
> On Tue, Dec 6, 2011 at 16:13, Finn Thain <fthain@telegraphics.com.au> wrote:
> > +static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
> > +{
> > + if (enable) {
> > + uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
> > + if (!ZS_IS_EXTCLK(uap))
> > + uap->curregs[1] |= EXT_INT_ENAB;
> > + } else {
> > + uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
>
> Should there be a call to zssync() here?
I don't think so. Though I should have mentioned the change in the patch
header.
> The old code always did that after disabling interrupts.
pmz_load_zsregs(), pmz_set_termios() and pmz_suspend() don't do it.
sunzilog only does it on sparc64 and only when writing to the data
register or writing command modifiers to the control register ("On 64-bit
sparc we only need to flush single writes to ensure completion.")
I can't find any purpose for control register reads in the chip manual.
The zssync() calls following some WR1 writes originate here:
http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=9e9d9f693c7def3900725c04c6b64311655eea51
So I don't see any need for control register reads but hopefully Ben can
say for sure.
Reading the patch now I notice that I dropped a pmz_maybe_update_regs() or
pmz_load_zsregs() in the suspend path. I will send a new patch.
Finn
>
> > + }
> > + write_zsreg(uap, R1, uap->curregs[1]);
> > +}
> > +
> > static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
> > {
> > struct tty_struct *tty = NULL;
> > @@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_ch
> >
> > return tty;
> > flood:
> > - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> > - write_zsreg(uap, R1, uap->curregs[R1]);
> > - zssync(uap);
>
> Cfr. e.g. here.
>
> > + pmz_interrupt_control(uap, 0);
> > pmz_error("pmz: rx irq flood !\n");
> > return tty;
> > }
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
> -- Linus Torvalds
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
2011-12-06 15:27 ` Geert Uytterhoeven
2011-12-06 15:39 ` Alan Cox
@ 2011-12-07 3:49 ` Finn Thain
2011-12-08 3:17 ` Benjamin Herrenschmidt
2011-12-08 4:20 ` Benjamin Herrenschmidt
2 siblings, 2 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-07 3:49 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Benjamin Herrenschmidt, linux-m68k, linuxppc-dev, linux-serial
On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
masked. This can be a problem when pmac_zilog starts up.
For example, the serial debugging code in arch/m68k/kernel/head.S may be
used beforehand. It disables the SCC interrupts at the chip but doesn't
ack them. Then when a pmac_zilog port is used, the machine locks up with
"unexpected interrupt".
This can happen in pmz_shutdown() since the irq is freed before the
channel interrupts are disabled.
Fix this by clearing interrupt enable bits before the handler is
uninstalled. Also move the interrupt control bit flipping into a separate
pmz_interrupt_control() routine. Replace all instances of these operations
with calls to this routine. Omit the zssync() calls that seem to serve no
purpose.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Acked-by: Alan Cox <alan@linux.intel.com>
---
Re-implemented as v2 using a simpler approach that avoids messing with the
Master Interrupt Enable bit. As well as the ifdef problem, it turns out
that v1 was not sufficient to entirely fix the problem.
v3 avoids needless changes to the logic and locking in the suspend and
shutdown code and tries to keep register writes closer to their original
sequence.
This patch has been tested on a PowerBook 520 but no PowerMacs yet.
Index: linux-git/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-07 12:36:32.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-07 14:29:21.000000000 +1100
@@ -216,6 +216,18 @@ static void pmz_maybe_update_regs(struct
}
}
+static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
+{
+ if (enable) {
+ uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
+ if (!ZS_IS_EXTCLK(uap))
+ uap->curregs[1] |= EXT_INT_ENAB;
+ } else {
+ uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
+ }
+ write_zsreg(uap, R1, uap->curregs[1]);
+}
+
static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
{
struct tty_struct *tty = NULL;
@@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_ch
return tty;
flood:
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
- zssync(uap);
+ pmz_interrupt_control(uap, 0);
pmz_error("pmz: rx irq flood !\n");
return tty;
}
@@ -990,12 +1000,9 @@ static int pmz_startup(struct uart_port
if (ZS_IS_IRDA(uap))
pmz_irda_reset(uap);
- /* Enable interrupts emission from the chip */
+ /* Enable interrupt requests for the channel */
spin_lock_irqsave(&port->lock, flags);
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
+ pmz_interrupt_control(uap, 1);
spin_unlock_irqrestore(&port->lock, flags);
pmz_debug("pmz: startup() done.\n");
@@ -1015,6 +1022,25 @@ static void pmz_shutdown(struct uart_por
mutex_lock(&pmz_irq_mutex);
+ spin_lock_irqsave(&port->lock, flags);
+
+ if (!ZS_IS_ASLEEP(uap)) {
+ /* Disable interrupt requests for the channel */
+ pmz_interrupt_control(uap, 0);
+
+ if (!ZS_IS_CONS(uap)) {
+ /* Disable receiver and transmitter */
+ uap->curregs[R3] &= ~RxENABLE;
+ uap->curregs[R5] &= ~TxENABLE;
+
+ /* Disable break assertion */
+ uap->curregs[R5] &= ~SND_BRK;
+ pmz_maybe_update_regs(uap);
+ }
+ }
+
+ spin_unlock_irqrestore(&port->lock, flags);
+
/* Release interrupt handler */
free_irq(uap->port.irq, uap);
@@ -1025,29 +1051,8 @@ static void pmz_shutdown(struct uart_por
if (!ZS_IS_OPEN(uap->mate))
pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
- /* Disable interrupts */
- if (!ZS_IS_ASLEEP(uap)) {
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
- zssync(uap);
- }
-
- if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
- spin_unlock_irqrestore(&port->lock, flags);
- mutex_unlock(&pmz_irq_mutex);
- return;
- }
-
- /* Disable receiver and transmitter. */
- uap->curregs[R3] &= ~RxENABLE;
- uap->curregs[R5] &= ~TxENABLE;
-
- /* Disable all interrupts and BRK assertion. */
- uap->curregs[R5] &= ~SND_BRK;
- pmz_maybe_update_regs(uap);
-
- /* Shut the chip down */
- pmz_set_scc_power(uap, 0);
+ if (!ZS_IS_ASLEEP(uap) && !ZS_IS_CONS(uap))
+ pmz_set_scc_power(uap, 0); /* Shut the chip down */
spin_unlock_irqrestore(&port->lock, flags);
@@ -1352,19 +1357,15 @@ static void pmz_set_termios(struct uart_
spin_lock_irqsave(&port->lock, flags);
/* Disable IRQs on the port */
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
- write_zsreg(uap, R1, uap->curregs[R1]);
+ pmz_interrupt_control(uap, 0);
/* Setup new port configuration */
__pmz_set_termios(port, termios, old);
/* Re-enable IRQs on the port */
- if (ZS_IS_OPEN(uap)) {
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
- }
+ if (ZS_IS_OPEN(uap))
+ pmz_interrupt_control(uap, 1);
+
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -1671,14 +1672,17 @@ static int pmz_suspend(struct macio_dev
spin_lock_irqsave(&uap->port.lock, flags);
if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
- /* Disable receiver and transmitter. */
+ /* Disable interrupt requests for the channel */
+ pmz_interrupt_control(uap, 0);
+
+ /* Disable receiver and transmitter */
uap->curregs[R3] &= ~RxENABLE;
uap->curregs[R5] &= ~TxENABLE;
- /* Disable all interrupts and BRK assertion. */
- uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
+ /* Disable break assertion */
uap->curregs[R5] &= ~SND_BRK;
pmz_load_zsregs(uap, uap->curregs);
+
uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
mb();
}
@@ -1738,14 +1742,6 @@ static int pmz_resume(struct macio_dev *
/* Take care of config that may have changed while asleep */
__pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
- if (ZS_IS_OPEN(uap)) {
- /* Enable interrupts */
- uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
- if (!ZS_IS_EXTCLK(uap))
- uap->curregs[R1] |= EXT_INT_ENAB;
- write_zsreg(uap, R1, uap->curregs[R1]);
- }
-
spin_unlock_irqrestore(&uap->port.lock, flags);
if (ZS_IS_CONS(uap))
@@ -1757,6 +1753,12 @@ static int pmz_resume(struct macio_dev *
enable_irq(uap->port.irq);
}
+ if (ZS_IS_OPEN(uap)) {
+ spin_lock_irqsave(&uap->port.lock, flags);
+ pmz_interrupt_control(uap, 1);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ }
+
bail:
mutex_unlock(&state->port.mutex);
mutex_unlock(&pmz_irq_mutex);
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-07 3:49 ` [PATCH 01/16 v3] " Finn Thain
@ 2011-12-08 3:17 ` Benjamin Herrenschmidt
2011-12-08 4:20 ` Benjamin Herrenschmidt
1 sibling, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-08 3:17 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Wed, 2011-12-07 at 14:49 +1100, Finn Thain wrote:
> On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> masked. This can be a problem when pmac_zilog starts up.
Thanks. I'll test it on a powermac or two and will merge it via the
powerpc -next tree if it works out allright.
Cheers,
Ben.
> For example, the serial debugging code in arch/m68k/kernel/head.S may be
> used beforehand. It disables the SCC interrupts at the chip but doesn't
> ack them. Then when a pmac_zilog port is used, the machine locks up with
> "unexpected interrupt".
>
> This can happen in pmz_shutdown() since the irq is freed before the
> channel interrupts are disabled.
>
> Fix this by clearing interrupt enable bits before the handler is
> uninstalled. Also move the interrupt control bit flipping into a separate
> pmz_interrupt_control() routine. Replace all instances of these operations
> with calls to this routine. Omit the zssync() calls that seem to serve no
> purpose.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Acked-by: Alan Cox <alan@linux.intel.com>
>
> ---
>
> Re-implemented as v2 using a simpler approach that avoids messing with the
> Master Interrupt Enable bit. As well as the ifdef problem, it turns out
> that v1 was not sufficient to entirely fix the problem.
>
> v3 avoids needless changes to the logic and locking in the suspend and
> shutdown code and tries to keep register writes closer to their original
> sequence.
>
> This patch has been tested on a PowerBook 520 but no PowerMacs yet.
>
>
> Index: linux-git/drivers/tty/serial/pmac_zilog.c
> ===================================================================
> --- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-07 12:36:32.000000000 +1100
> +++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-07 14:29:21.000000000 +1100
> @@ -216,6 +216,18 @@ static void pmz_maybe_update_regs(struct
> }
> }
>
> +static void pmz_interrupt_control(struct uart_pmac_port *uap, int enable)
> +{
> + if (enable) {
> + uap->curregs[1] |= INT_ALL_Rx | TxINT_ENAB;
> + if (!ZS_IS_EXTCLK(uap))
> + uap->curregs[1] |= EXT_INT_ENAB;
> + } else {
> + uap->curregs[1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> + }
> + write_zsreg(uap, R1, uap->curregs[1]);
> +}
> +
> static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
> {
> struct tty_struct *tty = NULL;
> @@ -339,9 +351,7 @@ static struct tty_struct *pmz_receive_ch
>
> return tty;
> flood:
> - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> - write_zsreg(uap, R1, uap->curregs[R1]);
> - zssync(uap);
> + pmz_interrupt_control(uap, 0);
> pmz_error("pmz: rx irq flood !\n");
> return tty;
> }
> @@ -990,12 +1000,9 @@ static int pmz_startup(struct uart_port
> if (ZS_IS_IRDA(uap))
> pmz_irda_reset(uap);
>
> - /* Enable interrupts emission from the chip */
> + /* Enable interrupt requests for the channel */
> spin_lock_irqsave(&port->lock, flags);
> - uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
> - if (!ZS_IS_EXTCLK(uap))
> - uap->curregs[R1] |= EXT_INT_ENAB;
> - write_zsreg(uap, R1, uap->curregs[R1]);
> + pmz_interrupt_control(uap, 1);
> spin_unlock_irqrestore(&port->lock, flags);
>
> pmz_debug("pmz: startup() done.\n");
> @@ -1015,6 +1022,25 @@ static void pmz_shutdown(struct uart_por
>
> mutex_lock(&pmz_irq_mutex);
>
> + spin_lock_irqsave(&port->lock, flags);
> +
> + if (!ZS_IS_ASLEEP(uap)) {
> + /* Disable interrupt requests for the channel */
> + pmz_interrupt_control(uap, 0);
> +
> + if (!ZS_IS_CONS(uap)) {
> + /* Disable receiver and transmitter */
> + uap->curregs[R3] &= ~RxENABLE;
> + uap->curregs[R5] &= ~TxENABLE;
> +
> + /* Disable break assertion */
> + uap->curregs[R5] &= ~SND_BRK;
> + pmz_maybe_update_regs(uap);
> + }
> + }
> +
> + spin_unlock_irqrestore(&port->lock, flags);
> +
> /* Release interrupt handler */
> free_irq(uap->port.irq, uap);
>
> @@ -1025,29 +1051,8 @@ static void pmz_shutdown(struct uart_por
> if (!ZS_IS_OPEN(uap->mate))
> pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
>
> - /* Disable interrupts */
> - if (!ZS_IS_ASLEEP(uap)) {
> - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> - write_zsreg(uap, R1, uap->curregs[R1]);
> - zssync(uap);
> - }
> -
> - if (ZS_IS_CONS(uap) || ZS_IS_ASLEEP(uap)) {
> - spin_unlock_irqrestore(&port->lock, flags);
> - mutex_unlock(&pmz_irq_mutex);
> - return;
> - }
> -
> - /* Disable receiver and transmitter. */
> - uap->curregs[R3] &= ~RxENABLE;
> - uap->curregs[R5] &= ~TxENABLE;
> -
> - /* Disable all interrupts and BRK assertion. */
> - uap->curregs[R5] &= ~SND_BRK;
> - pmz_maybe_update_regs(uap);
> -
> - /* Shut the chip down */
> - pmz_set_scc_power(uap, 0);
> + if (!ZS_IS_ASLEEP(uap) && !ZS_IS_CONS(uap))
> + pmz_set_scc_power(uap, 0); /* Shut the chip down */
>
> spin_unlock_irqrestore(&port->lock, flags);
>
> @@ -1352,19 +1357,15 @@ static void pmz_set_termios(struct uart_
> spin_lock_irqsave(&port->lock, flags);
>
> /* Disable IRQs on the port */
> - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> - write_zsreg(uap, R1, uap->curregs[R1]);
> + pmz_interrupt_control(uap, 0);
>
> /* Setup new port configuration */
> __pmz_set_termios(port, termios, old);
>
> /* Re-enable IRQs on the port */
> - if (ZS_IS_OPEN(uap)) {
> - uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
> - if (!ZS_IS_EXTCLK(uap))
> - uap->curregs[R1] |= EXT_INT_ENAB;
> - write_zsreg(uap, R1, uap->curregs[R1]);
> - }
> + if (ZS_IS_OPEN(uap))
> + pmz_interrupt_control(uap, 1);
> +
> spin_unlock_irqrestore(&port->lock, flags);
> }
>
> @@ -1671,14 +1672,17 @@ static int pmz_suspend(struct macio_dev
> spin_lock_irqsave(&uap->port.lock, flags);
>
> if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
> - /* Disable receiver and transmitter. */
> + /* Disable interrupt requests for the channel */
> + pmz_interrupt_control(uap, 0);
> +
> + /* Disable receiver and transmitter */
> uap->curregs[R3] &= ~RxENABLE;
> uap->curregs[R5] &= ~TxENABLE;
>
> - /* Disable all interrupts and BRK assertion. */
> - uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
> + /* Disable break assertion */
> uap->curregs[R5] &= ~SND_BRK;
> pmz_load_zsregs(uap, uap->curregs);
> +
> uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
> mb();
> }
> @@ -1738,14 +1742,6 @@ static int pmz_resume(struct macio_dev *
> /* Take care of config that may have changed while asleep */
> __pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
>
> - if (ZS_IS_OPEN(uap)) {
> - /* Enable interrupts */
> - uap->curregs[R1] |= INT_ALL_Rx | TxINT_ENAB;
> - if (!ZS_IS_EXTCLK(uap))
> - uap->curregs[R1] |= EXT_INT_ENAB;
> - write_zsreg(uap, R1, uap->curregs[R1]);
> - }
> -
> spin_unlock_irqrestore(&uap->port.lock, flags);
>
> if (ZS_IS_CONS(uap))
> @@ -1757,6 +1753,12 @@ static int pmz_resume(struct macio_dev *
> enable_irq(uap->port.irq);
> }
>
> + if (ZS_IS_OPEN(uap)) {
> + spin_lock_irqsave(&uap->port.lock, flags);
> + pmz_interrupt_control(uap, 1);
> + spin_unlock_irqrestore(&uap->port.lock, flags);
> + }
> +
> bail:
> mutex_unlock(&state->port.mutex);
> mutex_unlock(&pmz_irq_mutex);
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-07 3:49 ` [PATCH 01/16 v3] " Finn Thain
2011-12-08 3:17 ` Benjamin Herrenschmidt
@ 2011-12-08 4:20 ` Benjamin Herrenschmidt
2011-12-08 4:30 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-08 4:20 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Wed, 2011-12-07 at 14:49 +1100, Finn Thain wrote:
> On most 68k Macs the SCC IRQ is an autovector interrupt and cannot be
> masked. This can be a problem when pmac_zilog starts up.
>
> For example, the serial debugging code in arch/m68k/kernel/head.S may be
> used beforehand. It disables the SCC interrupts at the chip but doesn't
> ack them. Then when a pmac_zilog port is used, the machine locks up with
> "unexpected interrupt".
>
> This can happen in pmz_shutdown() since the irq is freed before the
> channel interrupts are disabled.
>
> Fix this by clearing interrupt enable bits before the handler is
> uninstalled. Also move the interrupt control bit flipping into a separate
> pmz_interrupt_control() routine. Replace all instances of these operations
> with calls to this routine. Omit the zssync() calls that seem to serve no
> purpose.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Acked-by: Alan Cox <alan@linux.intel.com>
>
> ---
So basic operations seem to work, I've applied the patch to
powerpc-next.
However, the internal modem on my Pismo powerbook doesn't appear to
survive suspend/resume. I'll dig into that and merge a fixup patch asap.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-08 4:20 ` Benjamin Herrenschmidt
@ 2011-12-08 4:30 ` Benjamin Herrenschmidt
2011-12-08 11:26 ` Finn Thain
0 siblings, 1 reply; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-08 4:30 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Thu, 2011-12-08 at 15:20 +1100, Benjamin Herrenschmidt wrote:
> So basic operations seem to work, I've applied the patch to
> powerpc-next.
>
> However, the internal modem on my Pismo powerbook doesn't appear to
> survive suspend/resume. I'll dig into that and merge a fixup patch asap.
BTW. I applied anyway because suspend/resume was already broken (you
spotted that we don't clear the suspended flag for example).
Fixing the flag alone helps a bit. We can't use the modem if we
suspend/resume with the open port, but closing and re-opening works.
Lockdep also picked-up a A->B B->A between the port mutex and the pmz
irq mutex on suspend.
I'll try to fix all these, and will let you know (I may not have time
today).
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-08 4:30 ` Benjamin Herrenschmidt
@ 2011-12-08 11:26 ` Finn Thain
2011-12-08 11:54 ` Geert Uytterhoeven
` (2 more replies)
0 siblings, 3 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-08 11:26 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Thu, 8 Dec 2011, Benjamin Herrenschmidt wrote:
> On Thu, 2011-12-08 at 15:20 +1100, Benjamin Herrenschmidt wrote:
>
> > So basic operations seem to work, I've applied the patch to
> > powerpc-next.
Then I guess Geert should not push this for 3.3 -- or does it make no
difference?
> > However, the internal modem on my Pismo powerbook doesn't appear to
> > survive suspend/resume. I'll dig into that and merge a fixup patch
> > asap.
>
> BTW. I applied anyway because suspend/resume was already broken (you
> spotted that we don't clear the suspended flag for example).
>
> Fixing the flag alone helps a bit. We can't use the modem if we
> suspend/resume with the open port,
If the SCC IRQ counters change across suspend/resume, perhaps the modem
itself is not powering up...
> but closing and re-opening works.
Maybe the modem wants a transition on DTR or similar, but it hasn't had
time to initialise when that happens during SCC resumption.
If so, calling pmz_shutdown() then pmz_startup() from the tail of
pmz_resume() without delay should probably fail to revive it...
>
> Lockdep also picked-up a A->B B->A between the port mutex and the pmz
> irq mutex on suspend.
>
> I'll try to fix all these, and will let you know (I may not have time
> today).
Thanks.
Finn
>
> Cheers,
> Ben.
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-08 11:26 ` Finn Thain
@ 2011-12-08 11:54 ` Geert Uytterhoeven
2011-12-08 19:44 ` Benjamin Herrenschmidt
2011-12-11 23:48 ` Benjamin Herrenschmidt
2 siblings, 0 replies; 51+ messages in thread
From: Geert Uytterhoeven @ 2011-12-08 11:54 UTC (permalink / raw)
To: Finn Thain; +Cc: Benjamin Herrenschmidt, linux-m68k, linuxppc-dev, linux-serial
Hi Finn,
On Thu, Dec 8, 2011 at 12:26, Finn Thain <fthain@telegraphics.com.au> wrote:
> On Thu, 8 Dec 2011, Benjamin Herrenschmidt wrote:
>> On Thu, 2011-12-08 at 15:20 +1100, Benjamin Herrenschmidt wrote:
>> > So basic operations seem to work, I've applied the patch to
>> > powerpc-next.
>
> Then I guess Geert should not push this for 3.3 -- or does it make no
> difference?
I do not plan to push it myself, that's why it's not in my for-next branch.
The for-3.3 is just indicative.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-08 11:26 ` Finn Thain
2011-12-08 11:54 ` Geert Uytterhoeven
@ 2011-12-08 19:44 ` Benjamin Herrenschmidt
2011-12-11 23:48 ` Benjamin Herrenschmidt
2 siblings, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-08 19:44 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Thu, 2011-12-08 at 22:26 +1100, Finn Thain wrote:
>
> Maybe the modem wants a transition on DTR or similar, but it hasn't had
> time to initialise when that happens during SCC resumption.
>
> If so, calling pmz_shutdown() then pmz_startup() from the tail of
> pmz_resume() without delay should probably fail to revive it...
Well, we power the modem down and back up... but it's possible that we
fail to re-enable something, I'll check. That used to work (at least
with macserial, maybe I never tried this specific torture with pmz...).
I'll figure it out eventually.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 02/16] macfb: fix black and white modes
2011-10-23 14:11 ` [PATCH 02/16] macfb: fix black and white modes Finn Thain
@ 2011-12-10 5:23 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:23 UTC (permalink / raw)
To: Florian Tobias Schandinat; +Cc: linux-fbdev, linux-m68k, Geert Uytterhoeven
macfb won't init in black & white modes since fb_alloc_cmap() no longer
works for zero cmap length. Fix this and also clean up a few printk's
and some stylistic inconsistencies.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/drivers/video/macfb.c
===================================================================
--- linux-m68k.orig/drivers/video/macfb.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/video/macfb.c 2011-10-23 00:50:51.000000000 +1100
@@ -592,12 +592,12 @@ static int __init macfb_init(void)
if (!fb_info.screen_base)
return -ENODEV;
- printk("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
- macfb_fix.smem_start, fb_info.screen_base,
- macfb_fix.smem_len / 1024);
- printk("macfb: mode is %dx%dx%d, linelength=%d\n",
- macfb_defined.xres, macfb_defined.yres,
- macfb_defined.bits_per_pixel, macfb_fix.line_length);
+ pr_info("macfb: framebuffer at 0x%08lx, mapped to 0x%p, size %dk\n",
+ macfb_fix.smem_start, fb_info.screen_base,
+ macfb_fix.smem_len / 1024);
+ pr_info("macfb: mode is %dx%dx%d, linelength=%d\n",
+ macfb_defined.xres, macfb_defined.yres,
+ macfb_defined.bits_per_pixel, macfb_fix.line_length);
/* Fill in the available video resolution */
macfb_defined.xres_virtual = macfb_defined.xres;
@@ -613,14 +613,10 @@ static int __init macfb_init(void)
switch (macfb_defined.bits_per_pixel) {
case 1:
- /*
- * XXX: I think this will catch any program that tries
- * to do FBIO_PUTCMAP when the visual is monochrome.
- */
macfb_defined.red.length = macfb_defined.bits_per_pixel;
macfb_defined.green.length = macfb_defined.bits_per_pixel;
macfb_defined.blue.length = macfb_defined.bits_per_pixel;
- video_cmap_len = 0;
+ video_cmap_len = 2;
macfb_fix.visual = FB_VISUAL_MONO01;
break;
case 2:
@@ -660,11 +656,10 @@ static int __init macfb_init(void)
macfb_fix.visual = FB_VISUAL_TRUECOLOR;
break;
default:
- video_cmap_len = 0;
- macfb_fix.visual = FB_VISUAL_MONO01;
- printk("macfb: unknown or unsupported bit depth: %d\n",
+ pr_err("macfb: unknown or unsupported bit depth: %d\n",
macfb_defined.bits_per_pixel);
- break;
+ err = -EINVAL;
+ goto fail_unmap;
}
/*
@@ -734,8 +729,8 @@ static int __init macfb_init(void)
case MAC_MODEL_Q950:
strcpy(macfb_fix.id, "DAFB");
macfb_setpalette = dafb_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
dafb_cmap_regs = ioremap(DAFB_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -744,8 +739,8 @@ static int __init macfb_init(void)
case MAC_MODEL_LCII:
strcpy(macfb_fix.id, "V8");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -758,8 +753,8 @@ static int __init macfb_init(void)
case MAC_MODEL_P600:
strcpy(macfb_fix.id, "Brazil");
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -773,10 +768,10 @@ static int __init macfb_init(void)
case MAC_MODEL_P520:
case MAC_MODEL_P550:
case MAC_MODEL_P460:
- macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Sonora");
+ macfb_setpalette = v8_brazil_setpalette;
v8_brazil_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -786,10 +781,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_IICI:
case MAC_MODEL_IISI:
- macfb_setpalette = rbv_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "RBV");
+ macfb_setpalette = rbv_setpalette;
rbv_cmap_regs = ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
/*
@@ -797,10 +792,10 @@ static int __init macfb_init(void)
*/
case MAC_MODEL_Q840:
case MAC_MODEL_C660:
- macfb_setpalette = civic_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "Civic");
+ macfb_setpalette = civic_setpalette;
civic_cmap_regs = ioremap(CIVIC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
@@ -809,26 +804,26 @@ static int __init macfb_init(void)
* We think this may be like the LC II
*/
case MAC_MODEL_LC:
+ strcpy(macfb_fix.id, "LC");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "LC");
break;
/*
* We think this may be like the LC II
*/
case MAC_MODEL_CCL:
+ strcpy(macfb_fix.id, "Color Classic");
if (vidtest) {
macfb_setpalette = v8_brazil_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
v8_brazil_cmap_regs =
ioremap(DAC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
}
- strcpy(macfb_fix.id, "Color Classic");
break;
/*
@@ -893,10 +888,10 @@ static int __init macfb_init(void)
case MAC_MODEL_PB270C:
case MAC_MODEL_PB280:
case MAC_MODEL_PB280C:
- macfb_setpalette = csc_setpalette;
- macfb_defined.activate = FB_ACTIVATE_NOW;
strcpy(macfb_fix.id, "CSC");
+ macfb_setpalette = csc_setpalette;
csc_cmap_regs = ioremap(CSC_BASE, 0x1000);
+ macfb_defined.activate = FB_ACTIVATE_NOW;
break;
default:
@@ -918,8 +913,9 @@ static int __init macfb_init(void)
if (err)
goto fail_dealloc;
- printk("fb%d: %s frame buffer device\n",
- fb_info.node, fb_info.fix.id);
+ pr_info("fb%d: %s frame buffer device\n",
+ fb_info.node, fb_info.fix.id);
+
return 0;
fail_dealloc:
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 03/16] mac_sonic: add irq resources and cleanup
2011-10-23 14:11 ` [PATCH 03/16] mac_sonic: add irq resources and cleanup Finn Thain
2011-11-13 10:28 ` Geert Uytterhoeven
@ 2011-12-10 5:23 ` Finn Thain
1 sibling, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-m68k, Geert Uytterhoeven
Make better use of the SONIC platform device by adding irq resources.
This moves the via_type logic out of the NIC device driver which
improves modularity.
Since interrupt handlers now run with CPU interrupts disabled, we don't
need the macsonic_interrupt() wrapper. Remove it.
For consistency, rename retval as err.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/arch/m68k/mac/config.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/config.c 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/mac/config.c 2011-10-23 00:51:11.000000000 +1100
@@ -936,9 +936,16 @@ static struct platform_device esp_1_pdev
.id = 1,
};
+static struct resource sonic_rsrcs[] = {
+ { .flags = IORESOURCE_IRQ },
+ { .flags = IORESOURCE_IRQ },
+};
+
static struct platform_device sonic_pdev = {
.name = "macsonic",
.id = -1,
+ .num_resources = ARRAY_SIZE(sonic_rsrcs),
+ .resource = sonic_rsrcs,
};
static struct platform_device mace_pdev = {
@@ -1002,6 +1009,10 @@ int __init mac_platform_init(void)
switch (macintosh_config->ether_type) {
case MAC_ETHER_SONIC:
+ sonic_rsrcs[0].start = sonic_rsrcs[0].end = IRQ_NUBUS_9;
+ if (via_alt_mapping)
+ sonic_rsrcs[1].start = sonic_rsrcs[1].end = IRQ_AUTO_3;
+
platform_device_register(&sonic_pdev);
break;
case MAC_ETHER_MACE:
Index: linux-m68k/drivers/net/macsonic.c
===================================================================
--- linux-m68k.orig/drivers/net/macsonic.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/net/macsonic.c 2011-10-22 23:02:38.000000000 +1100
@@ -60,7 +60,6 @@
#include <asm/dma.h>
#include <asm/macintosh.h>
#include <asm/macints.h>
-#include <asm/mac_via.h>
static char mac_sonic_string[] = "macsonic";
@@ -127,61 +126,49 @@ static inline void bit_reverse_addr(unsi
addr[i] = bitrev8(addr[i]);
}
-static irqreturn_t macsonic_interrupt(int irq, void *dev_id)
-{
- irqreturn_t result;
- unsigned long flags;
-
- local_irq_save(flags);
- result = sonic_interrupt(irq, dev_id);
- local_irq_restore(flags);
- return result;
-}
-
static int macsonic_open(struct net_device* dev)
{
- int retval;
+ struct sonic_local *lp = netdev_priv(dev);
+ int err;
- retval = request_irq(dev->irq, sonic_interrupt, 0, "sonic", dev);
- if (retval) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n",
- dev->name, dev->irq);
- goto err;
- }
- /* Under the A/UX interrupt scheme, the onboard SONIC interrupt comes
- * in at priority level 3. However, we sometimes get the level 2 inter-
- * rupt as well, which must prevent re-entrance of the sonic handler.
- */
- if (dev->irq == IRQ_AUTO_3) {
- retval = request_irq(IRQ_NUBUS_9, macsonic_interrupt, 0,
- "sonic", dev);
- if (retval) {
- printk(KERN_ERR "%s: unable to get IRQ %d.\n",
- dev->name, IRQ_NUBUS_9);
- goto err_irq;
+ err = request_irq(dev->irq, sonic_interrupt, 0, "SONIC", dev);
+ if (err) {
+ pr_err("%s: unable to get IRQ %d\n", dev->name, dev->irq);
+ goto out;
+ }
+ if (lp->irq1) {
+ err = request_irq(lp->irq1, sonic_interrupt, 0, "SONIC", dev);
+ if (err) {
+ pr_err("%s: unable to get IRQ %d\n",
+ dev->name, lp->irq1);
+ goto out_irq;
}
}
- retval = sonic_open(dev);
- if (retval)
- goto err_irq_nubus;
+ err = sonic_open(dev);
+ if (err)
+ goto out_irq1;
+
return 0;
-err_irq_nubus:
- if (dev->irq == IRQ_AUTO_3)
- free_irq(IRQ_NUBUS_9, dev);
-err_irq:
+out_irq1:
+ if (lp->irq1)
+ free_irq(lp->irq1, dev);
+out_irq:
free_irq(dev->irq, dev);
-err:
- return retval;
+out:
+ return err;
}
static int macsonic_close(struct net_device* dev)
{
+ struct sonic_local *lp = netdev_priv(dev);
int err;
+
err = sonic_close(dev);
+
+ if (lp->irq1)
+ free_irq(lp->irq1, dev);
free_irq(dev->irq, dev);
- if (dev->irq == IRQ_AUTO_3)
- free_irq(IRQ_NUBUS_9, dev);
return err;
}
@@ -310,8 +297,9 @@ static void __devinit mac_onboard_sonic_
random_ether_addr(dev->dev_addr);
}
-static int __devinit mac_onboard_sonic_probe(struct net_device *dev)
+static int __devinit mac_onboard_sonic_probe(struct platform_device *pdev)
{
+ struct net_device *dev = platform_get_drvdata(pdev);
struct sonic_local* lp = netdev_priv(dev);
int sr;
int commslot = 0;
@@ -348,10 +336,12 @@ static int __devinit mac_onboard_sonic_p
/* Danger! My arms are flailing wildly! You *must* set lp->reg_offset
* and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */
dev->base_addr = ONBOARD_SONIC_REGISTERS;
- if (via_alt_mapping)
- dev->irq = IRQ_AUTO_3;
- else
- dev->irq = IRQ_NUBUS_9;
+
+ dev->irq = platform_get_irq(pdev, 0);
+ lp->irq1 = platform_get_irq(pdev, 1);
+
+ if (!dev->irq)
+ return -ENODEV;
if (!sonic_version_printed) {
printk(KERN_INFO "%s", version);
@@ -590,7 +580,7 @@ static int __devinit mac_sonic_probe(str
platform_set_drvdata(pdev, dev);
/* This will catch fatal stuff like -ENOMEM as well as success */
- err = mac_onboard_sonic_probe(dev);
+ err = mac_onboard_sonic_probe(pdev);
if (err == 0)
goto found;
if (err != -ENODEV)
Index: linux-m68k/drivers/net/sonic.h
===================================================================
--- linux-m68k.orig/drivers/net/sonic.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/drivers/net/sonic.h 2011-10-22 23:02:38.000000000 +1100
@@ -318,6 +318,9 @@ struct sonic_local {
unsigned int eol_rx;
unsigned int eol_tx; /* last unacked transmit packet */
unsigned int next_tx; /* next free TD */
+#ifdef CONFIG_MAC
+ int irq1; /* Second IRQ for Mac Quadras */
+#endif
struct device *device; /* generic device */
struct net_device_stats stats;
};
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:10.000000000 +1100
@@ -40,7 +40,6 @@
volatile __u8 *via1, *via2;
int rbv_present;
int via_alt_mapping;
-EXPORT_SYMBOL(via_alt_mapping);
static __u8 rbv_clear;
/*
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 06/16] m68k/mac: cleanup mac_irq_pending
2011-10-23 14:11 ` [PATCH 06/16] m68k/mac: cleanup mac_irq_pending Finn Thain
@ 2011-12-10 5:24 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:24 UTC (permalink / raw)
To: James E.J. Bottomley; +Cc: linux-scsi, linux-m68k, Geert Uytterhoeven
mac_irq_pending() has only one caller (mac_esp.c). Nothing tests for
Baboon, PSC or OSS pending interrupts. Until that need arises, let's
keep it simple and remove all the unused abstraction. Replace it with a
routine to check for SCSI DRQ.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/arch/m68k/include/asm/macintosh.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/macintosh.h 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/macintosh.h 2011-10-23 00:51:07.000000000 +1100
@@ -11,7 +11,7 @@
extern void mac_reset(void);
extern void mac_poweroff(void);
extern void mac_init_IRQ(void);
-extern int mac_irq_pending(unsigned int);
+
extern void mac_irq_enable(struct irq_data *data);
extern void mac_irq_disable(struct irq_data *data);
Index: linux-m68k/arch/m68k/mac/baboon.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/baboon.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/baboon.c 2011-10-23 00:51:07.000000000 +1100
@@ -123,10 +123,3 @@ void baboon_irq_disable(int irq)
if (baboon_disabled)
mac_irq_disable(irq_get_irq_data(IRQ_NUBUS_C));
}
-
-int baboon_irq_pending(int irq)
-{
- int irq_idx = IRQ_IDX(irq);
-
- return baboon->mb_ifr & (1 << irq_idx);
-}
Index: linux-m68k/arch/m68k/mac/macints.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/macints.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/macints.c 2011-10-23 00:51:07.000000000 +1100
@@ -142,7 +142,6 @@ extern void via_register_interrupts(void
extern void via_irq_enable(int);
extern void via_irq_disable(int);
extern void via_irq_clear(int);
-extern int via_irq_pending(int);
/*
* OSS hooks
@@ -152,7 +151,6 @@ extern void oss_register_interrupts(void
extern void oss_irq_enable(int);
extern void oss_irq_disable(int);
extern void oss_irq_clear(int);
-extern int oss_irq_pending(int);
/*
* PSC hooks
@@ -162,7 +160,6 @@ extern void psc_register_interrupts(void
extern void psc_irq_enable(int);
extern void psc_irq_disable(int);
extern void psc_irq_clear(int);
-extern int psc_irq_pending(int);
/*
* IOP hooks
@@ -239,7 +236,6 @@ void __init mac_init_IRQ(void)
/*
* mac_irq_enable - enable an interrupt source
* mac_irq_disable - disable an interrupt source
- * mac_irq_pending - returns the pending status of an IRQ (nonzero = pending)
*
* These routines are just dispatchers to the VIA/OSS/PSC routines.
*/
@@ -314,34 +310,6 @@ void mac_irq_disable(struct irq_data *da
}
}
-int mac_irq_pending(unsigned int irq)
-{
- switch(IRQ_SRC(irq)) {
- case 1:
- return via_irq_pending(irq);
- case 2:
- case 7:
- if (oss_present)
- return oss_irq_pending(irq);
- else
- return via_irq_pending(irq);
- case 3:
- case 5:
- case 6:
- if (psc_present)
- return psc_irq_pending(irq);
- else if (oss_present)
- return oss_irq_pending(irq);
- break;
- case 4:
- if (psc_present)
- return psc_irq_pending(irq);
- break;
- }
- return 0;
-}
-EXPORT_SYMBOL(mac_irq_pending);
-
static int num_debug[8];
irqreturn_t mac_debug_handler(int irq, void *dev_id)
Index: linux-m68k/arch/m68k/mac/oss.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/oss.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/oss.c 2011-10-23 00:51:07.000000000 +1100
@@ -219,32 +219,3 @@ void oss_irq_disable(int irq) {
#endif
}
}
-
-/*
- * Check to see if a specific OSS interrupt is pending
- */
-
-int oss_irq_pending(int irq)
-{
- switch(irq) {
- case IRQ_MAC_SCC:
- return oss->irq_pending & OSS_IP_IOPSCC;
- break;
- case IRQ_MAC_ADB:
- return oss->irq_pending & OSS_IP_IOPISM;
- break;
- case IRQ_MAC_SCSI:
- return oss->irq_pending & OSS_IP_SCSI;
- break;
- case IRQ_NUBUS_9:
- case IRQ_NUBUS_A:
- case IRQ_NUBUS_B:
- case IRQ_NUBUS_C:
- case IRQ_NUBUS_D:
- case IRQ_NUBUS_E:
- irq -= NUBUS_SOURCE_BASE;
- return oss->irq_pending & (1 << irq);
- break;
- }
- return 0;
-}
Index: linux-m68k/arch/m68k/mac/psc.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/psc.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/psc.c 2011-10-22 23:02:38.000000000 +1100
@@ -180,12 +180,3 @@ void psc_irq_disable(int irq) {
#endif
psc_write_byte(pIER, 1 << irq_idx);
}
-
-int psc_irq_pending(int irq)
-{
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int pIFR = pIERbase + (irq_src << 4);
-
- return psc_read_byte(pIFR) & (1 << irq_idx);
-}
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:07.000000000 +1100
@@ -584,28 +584,6 @@ void via_irq_disable(int irq) {
}
}
-/*
- * Returns nonzero if an interrupt is pending on the given
- * VIA/IRQ combination.
- */
-
-int via_irq_pending(int irq)
-{
- int irq_src = IRQ_SRC(irq);
- int irq_idx = IRQ_IDX(irq);
- int irq_bit = 1 << irq_idx;
-
- if (irq_src == 1) {
- return via1[vIFR] & irq_bit;
- } else if (irq_src == 2) {
- return via2[gIFR] & irq_bit;
- } else if (irq_src == 7) {
- /* Always 0 for MAC_VIA_QUADRA if the slot irq is disabled. */
- return ~via2[gBufA] & irq_bit;
- }
- return 0;
-}
-
void via1_set_head(int head)
{
if (head == 0)
@@ -614,3 +592,9 @@ void via1_set_head(int head)
via1[vBufA] |= VIA1A_vHeadSel;
}
EXPORT_SYMBOL(via1_set_head);
+
+int via2_scsi_drq_pending(void)
+{
+ return via2[gIFR] & (1 << IRQ_IDX(IRQ_MAC_SCSIDRQ));
+}
+EXPORT_SYMBOL(via2_scsi_drq_pending);
Index: linux-m68k/drivers/scsi/mac_esp.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_esp.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_esp.c 2011-10-22 23:02:38.000000000 +1100
@@ -25,6 +25,7 @@
#include <asm/dma.h>
#include <asm/macints.h>
#include <asm/macintosh.h>
+#include <asm/mac_via.h>
#include <scsi/scsi_host.h>
@@ -149,7 +150,7 @@ static inline int mac_esp_wait_for_dreq(
do {
if (mep->pdma_regs == NULL) {
- if (mac_irq_pending(IRQ_MAC_SCSIDRQ))
+ if (via2_scsi_drq_pending())
return 0;
} else {
if (nubus_readl(mep->pdma_regs) & 0x200)
Index: linux-m68k/arch/m68k/include/asm/mac_via.h
===================================================================
--- linux-m68k.orig/arch/m68k/include/asm/mac_via.h 2011-10-22 23:02:22.000000000 +1100
+++ linux-m68k/arch/m68k/include/asm/mac_via.h 2011-10-23 00:51:07.000000000 +1100
@@ -254,6 +254,8 @@
extern volatile __u8 *via1,*via2;
extern int rbv_present,via_alt_mapping;
+extern int via2_scsi_drq_pending(void);
+
static inline int rbv_set_video_bpp(int bpp)
{
char val = (bpp==1)?0:(bpp==2)?1:(bpp==4)?2:(bpp==8)?3:-1;
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks
2011-10-23 14:11 ` [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks Finn Thain
@ 2011-12-10 5:24 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:24 UTC (permalink / raw)
To: James E.J. Bottomley; +Cc: linux-scsi, linux-m68k, Geert Uytterhoeven
Fix the mac_scsi interrupt edge trigger on non-RBV PowerBooks. This
doesn't appear to help my PowerBook 520 but the NetBSD source reveals
that the PowerBook 500 series is different than the others.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/arch/m68k/mac/via.c
===================================================================
--- linux-m68k.orig/arch/m68k/mac/via.c 2011-10-22 23:02:39.000000000 +1100
+++ linux-m68k/arch/m68k/mac/via.c 2011-10-23 00:51:01.000000000 +1100
@@ -252,22 +252,28 @@ void __init via_init(void)
via2[vACR] &= ~0x03; /* disable port A & B latches */
}
+ /* Everything below this point is VIA2 only... */
+
+ if (rbv_present)
+ return;
+
/*
- * Set vPCR for control line interrupts (but not on RBV)
+ * Set vPCR for control line interrupts.
+ *
+ * CA1 (SLOTS IRQ), CB1 (ASC IRQ): negative edge trigger.
+ *
+ * Macs with ESP SCSI have a negative edge triggered SCSI interrupt.
+ * Testing reveals that PowerBooks do too. However, the SE/30
+ * schematic diagram shows an active high NCR5380 IRQ line.
*/
- if (!rbv_present) {
- /* For all VIA types, CA1 (SLOTS IRQ) and CB1 (ASC IRQ)
- * are made negative edge triggered here.
- */
- if (macintosh_config->scsi_type == MAC_SCSI_OLD) {
- /* CB2 (IRQ) indep. input, positive edge */
- /* CA2 (DRQ) indep. input, positive edge */
- via2[vPCR] = 0x66;
- } else {
- /* CB2 (IRQ) indep. input, negative edge */
- /* CA2 (DRQ) indep. input, negative edge */
- via2[vPCR] = 0x22;
- }
+
+ pr_debug("VIA2 vPCR is 0x%02X\n", via2[vPCR]);
+ if (macintosh_config->via_type == MAC_VIA_II) {
+ /* CA2 (SCSI DRQ), CB2 (SCSI IRQ): indep. input, pos. edge */
+ via2[vPCR] = 0x66;
+ } else {
+ /* CA2 (SCSI DRQ), CB2 (SCSI IRQ): indep. input, neg. edge */
+ via2[vPCR] = 0x22;
}
}
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it
2011-10-23 14:11 ` [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it Finn Thain
@ 2011-12-10 5:24 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:24 UTC (permalink / raw)
To: James E.J. Bottomley; +Cc: linux-scsi, linux-m68k, Geert Uytterhoeven
Don't enable the SCSI irq when initialising the chip -- the irq has no
handler yet.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/drivers/scsi/mac_scsi.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_scsi.c 2011-10-22 23:02:38.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_scsi.c 2011-10-22 23:44:51.000000000 +1100
@@ -339,9 +339,6 @@ static void mac_scsi_reset_boot(struct S
printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
- /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
- disable_irq(IRQ_MAC_SCSI);
-
/* get in phase */
NCR5380_write( TARGET_COMMAND_REG,
PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
@@ -357,9 +354,6 @@ static void mac_scsi_reset_boot(struct S
for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
barrier();
- /* switch on SCSI IRQ again */
- enable_irq(IRQ_MAC_SCSI);
-
printk(KERN_INFO " done\n" );
}
#endif
^ permalink raw reply [flat|nested] 51+ messages in thread
* [PATCH 16/16] mac_esp: rename irq
2011-10-23 14:11 ` [PATCH 16/16] mac_esp: rename irq Finn Thain
@ 2011-12-10 5:24 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-10 5:24 UTC (permalink / raw)
To: James E.J. Bottomley; +Cc: linux-scsi, linux-m68k, Geert Uytterhoeven
Rename the "Mac ESP" irq as "ESP" to be consistent with all the other
Mac drivers and ESP drivers.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
---
Re-sending unchanged. Still needs the right ack.
Index: linux-m68k/drivers/scsi/mac_esp.c
===================================================================
--- linux-m68k.orig/drivers/scsi/mac_esp.c 2011-10-23 18:18:46.000000000 +1100
+++ linux-m68k/drivers/scsi/mac_esp.c 2011-10-23 18:19:30.000000000 +1100
@@ -565,8 +565,7 @@ static int __devinit esp_mac_probe(struc
esp_chips[dev->id] = esp;
mb();
if (esp_chips[!dev->id] == NULL) {
- err = request_irq(host->irq, mac_scsi_esp_intr, 0,
- "Mac ESP", NULL);
+ err = request_irq(host->irq, mac_scsi_esp_intr, 0, "ESP", NULL);
if (err < 0) {
esp_chips[dev->id] = NULL;
goto fail_free_priv;
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-08 11:26 ` Finn Thain
2011-12-08 11:54 ` Geert Uytterhoeven
2011-12-08 19:44 ` Benjamin Herrenschmidt
@ 2011-12-11 23:48 ` Benjamin Herrenschmidt
2011-12-11 23:55 ` Benjamin Herrenschmidt
2011-12-12 13:34 ` Finn Thain
2 siblings, 2 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-11 23:48 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
Any chance you can test this patch ? I would not be surprised if it
broke m68k since I had to do some of the changes in there "blind",
so let me know... with this, I can again suspend/resume properly on
a Pismo while using the internal modem among other things.
>From c2dbe7117bb94c59a4b2a215fc87fe7eabb7658d Mon Sep 17 00:00:00 2001
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Mon, 12 Dec 2011 10:44:08 +1100
Subject: [PATCH 2/2] tty/serial/pmac_zilog: Fix suspend & resume
This patch reworks & simplifies pmac_zilog handling of suspend/resume,
essentially removing all the specific code in there and using the
generic uart helpers.
This required properly registering the tty as a child of the macio (or platform)
device, so I had to delay the registration a bit (we used to register the ports
very very early). We still register the kernel console early though.
I removed a couple of unused or useless flags as well, relying on the
core to not call us when asleep. I also removed the essentially useless
interrupt mutex, simplifying the locking a bit.
I removed some code for handling unexpected interrupt which should never
be hit and could potentially be harmful (causing us to access a register
on a powered off SCC). We diable port interrupts on close always so there
should be no need to drain data on a closed port.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/tty/serial/pmac_zilog.c | 350 ++++++++++-----------------------------
drivers/tty/serial/pmac_zilog.h | 18 +-
2 files changed, 99 insertions(+), 269 deletions(-)
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 51941f0..46cb39b 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -106,7 +106,6 @@ MODULE_LICENSE("GPL");
*/
static struct uart_pmac_port pmz_ports[MAX_ZS_PORTS];
static int pmz_ports_count;
-static DEFINE_MUTEX(pmz_irq_mutex);
static struct uart_driver pmz_uart_reg = {
.owner = THIS_MODULE,
@@ -126,9 +125,6 @@ static void pmz_load_zsregs(struct uart_pmac_port *uap, u8 *regs)
{
int i;
- if (ZS_IS_ASLEEP(uap))
- return;
-
/* Let pending transmits finish. */
for (i = 0; i < 1000; i++) {
unsigned char stat = read_zsreg(uap, R1);
@@ -234,26 +230,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
unsigned char ch, r1, drop, error, flag;
int loops = 0;
- /* The interrupt can be enabled when the port isn't open, typically
- * that happens when using one port is open and the other closed (stale
- * interrupt) or when one port is used as a console.
- */
- if (!ZS_IS_OPEN(uap)) {
- pmz_debug("pmz: draining input\n");
- /* Port is closed, drain input data */
- for (;;) {
- if ((++loops) > 1000)
- goto flood;
- (void)read_zsreg(uap, R1);
- write_zsreg(uap, R0, ERR_RES);
- (void)read_zsdata(uap);
- ch = read_zsreg(uap, R0);
- if (!(ch & Rx_CH_AV))
- break;
- }
- return NULL;
- }
-
/* Sanity check, make sure the old bug is no longer happening */
if (uap->port.state == NULL || uap->port.state->port.tty == NULL) {
WARN_ON(1);
@@ -393,8 +369,6 @@ static void pmz_transmit_chars(struct uart_pmac_port *uap)
{
struct circ_buf *xmit;
- if (ZS_IS_ASLEEP(uap))
- return;
if (ZS_IS_CONS(uap)) {
unsigned char status = read_zsreg(uap, R0);
@@ -485,12 +459,16 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)
spin_lock(&uap_a->port.lock);
r3 = read_zsreg(uap_a, R3);
-#ifdef DEBUG_HARD
+#ifde DEBUG_HARD
pmz_debug("irq, r3: %x\n", r3);
#endif
/* Channel A */
tty = NULL;
if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
+ if (!ZS_IS_OPEN(uap_a)) {
+ pmz_debug("ChanA interrupt while open !\n");
+ goto skip_a;
+ }
write_zsreg(uap_a, R0, RES_H_IUS);
zssync(uap_a);
if (r3 & CHAEXT)
@@ -501,16 +479,21 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)
pmz_transmit_chars(uap_a);
rc = IRQ_HANDLED;
}
+ skip_a:
spin_unlock(&uap_a->port.lock);
if (tty != NULL)
tty_flip_buffer_push(tty);
- if (uap_b->node == NULL)
+ if (!uap_b)
goto out;
spin_lock(&uap_b->port.lock);
tty = NULL;
if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
+ if (!ZS_IS_OPEN(uap_a)) {
+ pmz_debug("ChanB interrupt while open !\n");
+ goto skip_b;
+ }
write_zsreg(uap_b, R0, RES_H_IUS);
zssync(uap_b);
if (r3 & CHBEXT)
@@ -521,14 +504,12 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id)
pmz_transmit_chars(uap_b);
rc = IRQ_HANDLED;
}
+ skip_b:
spin_unlock(&uap_b->port.lock);
if (tty != NULL)
tty_flip_buffer_push(tty);
out:
-#ifdef DEBUG_HARD
- pmz_debug("irq done.\n");
-#endif
return rc;
}
@@ -553,12 +534,8 @@ static inline u8 pmz_peek_status(struct uart_pmac_port *uap)
*/
static unsigned int pmz_tx_empty(struct uart_port *port)
{
- struct uart_pmac_port *uap = to_pmz(port);
unsigned char status;
- if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
- return TIOCSER_TEMT;
-
status = pmz_peek_status(to_pmz(port));
if (status & Tx_BUF_EMP)
return TIOCSER_TEMT;
@@ -580,8 +557,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
if (ZS_IS_IRDA(uap))
return;
/* We get called during boot with a port not up yet */
- if (ZS_IS_ASLEEP(uap) ||
- !(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)))
+ if (!(ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)))
return;
set_bits = clear_bits = 0;
@@ -600,8 +576,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl)
/* NOTE: Not subject to 'transmitter active' rule. */
uap->curregs[R5] |= set_bits;
uap->curregs[R5] &= ~clear_bits;
- if (ZS_IS_ASLEEP(uap))
- return;
+
write_zsreg(uap, R5, uap->curregs[R5]);
pmz_debug("pmz_set_mctrl: set bits: %x, clear bits: %x -> %x\n",
set_bits, clear_bits, uap->curregs[R5]);
@@ -619,9 +594,6 @@ static unsigned int pmz_get_mctrl(struct uart_port *port)
unsigned char status;
unsigned int ret;
- if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
- return 0;
-
status = read_zsreg(uap, R0);
ret = 0;
@@ -659,9 +631,6 @@ static void pmz_start_tx(struct uart_port *port)
uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
- if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
- return;
-
status = read_zsreg(uap, R0);
/* TX busy? Just wait for the TX done interrupt. */
@@ -700,9 +669,6 @@ static void pmz_stop_rx(struct uart_port *port)
{
struct uart_pmac_port *uap = to_pmz(port);
- if (ZS_IS_ASLEEP(uap) || uap->node == NULL)
- return;
-
pmz_debug("pmz: stop_rx()()\n");
/* Disable all RX interrupts. */
@@ -721,14 +687,12 @@ static void pmz_enable_ms(struct uart_port *port)
struct uart_pmac_port *uap = to_pmz(port);
unsigned char new_reg;
- if (ZS_IS_IRDA(uap) || uap->node == NULL)
+ if (ZS_IS_IRDA(uap))
return;
new_reg = uap->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
if (new_reg != uap->curregs[R15]) {
uap->curregs[R15] = new_reg;
- if (ZS_IS_ASLEEP(uap))
- return;
/* NOTE: Not subject to 'transmitter active' rule. */
write_zsreg(uap, R15, uap->curregs[R15]);
}
@@ -744,8 +708,6 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
unsigned char set_bits, clear_bits, new_reg;
unsigned long flags;
- if (uap->node == NULL)
- return;
set_bits = clear_bits = 0;
if (break_state)
@@ -758,12 +720,6 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
new_reg = (uap->curregs[R5] | set_bits) & ~clear_bits;
if (new_reg != uap->curregs[R5]) {
uap->curregs[R5] = new_reg;
-
- /* NOTE: Not subject to 'transmitter active' rule. */
- if (ZS_IS_ASLEEP(uap)) {
- spin_unlock_irqrestore(&port->lock, flags);
- return;
- }
write_zsreg(uap, R5, uap->curregs[R5]);
}
@@ -937,14 +893,21 @@ static int __pmz_startup(struct uart_pmac_port *uap)
static void pmz_irda_reset(struct uart_pmac_port *uap)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&uap->port.lock, flags);
uap->curregs[R5] |= DTR;
write_zsreg(uap, R5, uap->curregs[R5]);
zssync(uap);
- mdelay(110);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ msleep(110);
+
+ spin_lock_irqsave(&uap->port.lock, flags);
uap->curregs[R5] &= ~DTR;
write_zsreg(uap, R5, uap->curregs[R5]);
zssync(uap);
- mdelay(10);
+ spin_unlock_irqrestore(&uap->port.lock, flags);
+ msleep(10);
}
/*
@@ -959,13 +922,6 @@ static int pmz_startup(struct uart_port *port)
pmz_debug("pmz: startup()\n");
- if (ZS_IS_ASLEEP(uap))
- return -EAGAIN;
- if (uap->node == NULL)
- return -ENODEV;
-
- mutex_lock(&pmz_irq_mutex);
-
uap->flags |= PMACZILOG_FLAG_IS_OPEN;
/* A console is never powered down. Else, power up and
@@ -976,18 +932,14 @@ static int pmz_startup(struct uart_port *port)
pwr_delay = __pmz_startup(uap);
spin_unlock_irqrestore(&port->lock, flags);
}
-
- pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
+ sprintf(uap->irq_name, PMACZILOG_NAME"%d", uap->port.line);
if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED,
- "SCC", uap)) {
+ uap->irq_name, uap)) {
pmz_error("Unable to register zs interrupt handler.\n");
pmz_set_scc_power(uap, 0);
- mutex_unlock(&pmz_irq_mutex);
return -ENXIO;
}
- mutex_unlock(&pmz_irq_mutex);
-
/* Right now, we deal with delay by blocking here, I'll be
* smarter later on
*/
@@ -1017,26 +969,19 @@ static void pmz_shutdown(struct uart_port *port)
pmz_debug("pmz: shutdown()\n");
- if (uap->node == NULL)
- return;
-
- mutex_lock(&pmz_irq_mutex);
-
spin_lock_irqsave(&port->lock, flags);
- if (!ZS_IS_ASLEEP(uap)) {
- /* Disable interrupt requests for the channel */
- pmz_interrupt_control(uap, 0);
+ /* Disable interrupt requests for the channel */
+ pmz_interrupt_control(uap, 0);
- if (!ZS_IS_CONS(uap)) {
- /* Disable receiver and transmitter */
- uap->curregs[R3] &= ~RxENABLE;
- uap->curregs[R5] &= ~TxENABLE;
+ if (!ZS_IS_CONS(uap)) {
+ /* Disable receiver and transmitter */
+ uap->curregs[R3] &= ~RxENABLE;
+ uap->curregs[R5] &= ~TxENABLE;
- /* Disable break assertion */
- uap->curregs[R5] &= ~SND_BRK;
- pmz_maybe_update_regs(uap);
- }
+ /* Disable break assertion */
+ uap->curregs[R5] &= ~SND_BRK;
+ pmz_maybe_update_regs(uap);
}
spin_unlock_irqrestore(&port->lock, flags);
@@ -1048,16 +993,11 @@ static void pmz_shutdown(struct uart_port *port)
uap->flags &= ~PMACZILOG_FLAG_IS_OPEN;
- if (!ZS_IS_OPEN(uap->mate))
- pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
-
- if (!ZS_IS_ASLEEP(uap) && !ZS_IS_CONS(uap))
+ if (!ZS_IS_CONS(uap))
pmz_set_scc_power(uap, 0); /* Shut the chip down */
spin_unlock_irqrestore(&port->lock, flags);
- mutex_unlock(&pmz_irq_mutex);
-
pmz_debug("pmz: shutdown() done.\n");
}
@@ -1305,9 +1245,6 @@ static void __pmz_set_termios(struct uart_port *port, struct ktermios *termios,
pmz_debug("pmz: set_termios()\n");
- if (ZS_IS_ASLEEP(uap))
- return;
-
memcpy(&uap->termios_cache, termios, sizeof(struct ktermios));
/* XXX Check which revs of machines actually allow 1 and 4Mb speeds
@@ -1605,25 +1542,34 @@ static void pmz_dispose_port(struct uart_pmac_port *uap)
*/
static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
+ struct uart_pmac_port *uap;
int i;
/* Iterate the pmz_ports array to find a matching entry
*/
for (i = 0; i < MAX_ZS_PORTS; i++)
- if (pmz_ports[i].node == mdev->ofdev.dev.of_node) {
- struct uart_pmac_port *uap = &pmz_ports[i];
-
- uap->dev = mdev;
- dev_set_drvdata(&mdev->ofdev.dev, uap);
- if (macio_request_resources(uap->dev, "pmac_zilog"))
- printk(KERN_WARNING "%s: Failed to request resource"
- ", port still active\n",
- uap->node->name);
- else
- uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED;
- return 0;
- }
- return -ENODEV;
+ if (pmz_ports[i].node == mdev->ofdev.dev.of_node)
+ break;
+ if (i >= MAX_ZS_PORTS)
+ return -ENODEV;
+
+
+ uap = &pmz_ports[i];
+ uap->dev = mdev;
+ uap->port.dev = &mdev->ofdev.dev;
+ dev_set_drvdata(&mdev->ofdev.dev, uap);
+
+ /* We still activate the port even when failing to request resources
+ * to work around bugs in ancient Apple device-trees
+ */
+ if (macio_request_resources(uap->dev, "pmac_zilog"))
+ printk(KERN_WARNING "%s: Failed to request resource"
+ ", port still active\n",
+ uap->node->name);
+ else
+ uap->flags |= PMACZILOG_FLAG_RSRC_REQUESTED;
+
+ return uart_add_one_port(&pmz_uart_reg, &uap->port);
}
/*
@@ -1637,12 +1583,15 @@ static int pmz_detach(struct macio_dev *mdev)
if (!uap)
return -ENODEV;
+ uart_remove_one_port(&pmz_uart_reg, &uap->port);
+
if (uap->flags & PMACZILOG_FLAG_RSRC_REQUESTED) {
macio_release_resources(uap->dev);
uap->flags &= ~PMACZILOG_FLAG_RSRC_REQUESTED;
}
dev_set_drvdata(&mdev->ofdev.dev, NULL);
uap->dev = NULL;
+ uap->port.dev = NULL;
return 0;
}
@@ -1651,62 +1600,13 @@ static int pmz_detach(struct macio_dev *mdev)
static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
{
struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
- struct uart_state *state;
- unsigned long flags;
if (uap == NULL) {
printk("HRM... pmz_suspend with NULL uap\n");
return 0;
}
- if (pm_state.event == mdev->ofdev.dev.power.power_state.event)
- return 0;
-
- pmz_debug("suspend, switching to state %d\n", pm_state.event);
-
- state = pmz_uart_reg.state + uap->port.line;
-
- mutex_lock(&pmz_irq_mutex);
- mutex_lock(&state->port.mutex);
-
- spin_lock_irqsave(&uap->port.lock, flags);
-
- if (ZS_IS_OPEN(uap) || ZS_IS_CONS(uap)) {
- /* Disable interrupt requests for the channel */
- pmz_interrupt_control(uap, 0);
-
- /* Disable receiver and transmitter */
- uap->curregs[R3] &= ~RxENABLE;
- uap->curregs[R5] &= ~TxENABLE;
-
- /* Disable break assertion */
- uap->curregs[R5] &= ~SND_BRK;
- pmz_load_zsregs(uap, uap->curregs);
-
- uap->flags |= PMACZILOG_FLAG_IS_ASLEEP;
- mb();
- }
-
- spin_unlock_irqrestore(&uap->port.lock, flags);
-
- if (ZS_IS_OPEN(uap) || ZS_IS_OPEN(uap->mate))
- if (ZS_IS_ASLEEP(uap->mate) && ZS_IS_IRQ_ON(pmz_get_port_A(uap))) {
- pmz_get_port_A(uap)->flags &= ~PMACZILOG_FLAG_IS_IRQ_ON;
- disable_irq(uap->port.irq);
- }
-
- if (ZS_IS_CONS(uap))
- uap->port.cons->flags &= ~CON_ENABLED;
-
- /* Shut the chip down */
- pmz_set_scc_power(uap, 0);
-
- mutex_unlock(&state->port.mutex);
- mutex_unlock(&pmz_irq_mutex);
-
- pmz_debug("suspend, switching complete\n");
-
- mdev->ofdev.dev.power.power_state = pm_state;
+ uart_suspend_port(&pmz_uart_reg, &uap->port);
return 0;
}
@@ -1715,74 +1615,20 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state)
static int pmz_resume(struct macio_dev *mdev)
{
struct uart_pmac_port *uap = dev_get_drvdata(&mdev->ofdev.dev);
- struct uart_state *state;
- unsigned long flags;
- int pwr_delay = 0;
if (uap == NULL)
return 0;
- if (mdev->ofdev.dev.power.power_state.event == PM_EVENT_ON)
- return 0;
-
- pmz_debug("resume, switching to state 0\n");
-
- state = pmz_uart_reg.state + uap->port.line;
-
- mutex_lock(&pmz_irq_mutex);
- mutex_lock(&state->port.mutex);
-
- spin_lock_irqsave(&uap->port.lock, flags);
- if (!ZS_IS_OPEN(uap) && !ZS_IS_CONS(uap)) {
- spin_unlock_irqrestore(&uap->port.lock, flags);
- goto bail;
- }
- pwr_delay = __pmz_startup(uap);
-
- /* Take care of config that may have changed while asleep */
- __pmz_set_termios(&uap->port, &uap->termios_cache, NULL);
-
- spin_unlock_irqrestore(&uap->port.lock, flags);
-
- if (ZS_IS_CONS(uap))
- uap->port.cons->flags |= CON_ENABLED;
-
- /* Re-enable IRQ on the controller */
- if (ZS_IS_OPEN(uap) && !ZS_IS_IRQ_ON(pmz_get_port_A(uap))) {
- pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
- enable_irq(uap->port.irq);
- }
-
- if (ZS_IS_OPEN(uap)) {
- spin_lock_irqsave(&uap->port.lock, flags);
- pmz_interrupt_control(uap, 1);
- spin_unlock_irqrestore(&uap->port.lock, flags);
- }
-
- bail:
- mutex_unlock(&state->port.mutex);
- mutex_unlock(&pmz_irq_mutex);
-
- /* Right now, we deal with delay by blocking here, I'll be
- * smarter later on
- */
- if (pwr_delay != 0) {
- pmz_debug("pmz: delaying %d ms\n", pwr_delay);
- msleep(pwr_delay);
- }
-
- pmz_debug("resume, switching complete\n");
-
- mdev->ofdev.dev.power.power_state.event = PM_EVENT_ON;
+ uart_resume_port(&pmz_uart_reg, &uap->port);
return 0;
}
/*
* Probe all ports in the system and build the ports array, we register
- * with the serial layer at this point, the macio-type probing is only
- * used later to "attach" to the sysfs tree so we get power management
- * events
+ * with the serial layer later, so we get a proper struct device which
+ * allows the tty to attach properly. This is later than it used to be
+ * but the tty layer really wants it that way.
*/
static int __init pmz_probe(void)
{
@@ -1818,8 +1664,10 @@ static int __init pmz_probe(void)
/*
* Fill basic fields in the port structures
*/
- pmz_ports[count].mate = &pmz_ports[count+1];
- pmz_ports[count+1].mate = &pmz_ports[count];
+ if (node_b != NULL) {
+ pmz_ports[count].mate = &pmz_ports[count+1];
+ pmz_ports[count+1].mate = &pmz_ports[count];
+ }
pmz_ports[count].flags = PMACZILOG_FLAG_IS_CHANNEL_A;
pmz_ports[count].node = node_a;
pmz_ports[count+1].node = node_b;
@@ -1887,19 +1735,19 @@ static int __init pmz_probe(void)
pmz_ports_count = 0;
- pmz_ports[0].mate = &pmz_ports[1];
pmz_ports[0].port.line = 0;
pmz_ports[0].flags = PMACZILOG_FLAG_IS_CHANNEL_A;
- pmz_ports[0].node = &scc_a_pdev;
+ pmz_ports[0].pdev = &scc_a_pdev;
err = pmz_init_port(&pmz_ports[0]);
if (err)
return err;
pmz_ports_count++;
+ pmz_ports[0].mate = &pmz_ports[1];
pmz_ports[1].mate = &pmz_ports[0];
pmz_ports[1].port.line = 1;
pmz_ports[1].flags = 0;
- pmz_ports[1].node = &scc_b_pdev;
+ pmz_ports[1].pdev = &scc_b_pdev;
err = pmz_init_port(&pmz_ports[1]);
if (err)
return err;
@@ -1918,13 +1766,22 @@ static int __init pmz_attach(struct platform_device *pdev)
int i;
for (i = 0; i < pmz_ports_count; i++)
- if (pmz_ports[i].node == pdev)
- return 0;
- return -ENODEV;
+ if (pmz_ports[i].pdev == pdev)
+ break;
+ if (i >= pmz_ports_count)
+ return -ENODEV;
+
+ uap = &pmz_ports[i];
+ uap->port.dev = &pdev->dev;
+ dev_set_drvdata(&mdev->ofdev.dev, uap);
+
+ return uart_add_one_port(&pmz_uart_reg,
+ &pmz_ports[i]->port);
}
static int __exit pmz_detach(struct platform_device *pdev)
{
+ uart_remove_one_port(&pmz_uart_reg, &uap->port);
return 0;
}
@@ -1956,38 +1813,13 @@ static struct console pmz_console = {
*/
static int __init pmz_register(void)
{
- int i, rc;
-
pmz_uart_reg.nr = pmz_ports_count;
pmz_uart_reg.cons = PMACZILOG_CONSOLE;
/*
* Register this driver with the serial core
*/
- rc = uart_register_driver(&pmz_uart_reg);
- if (rc)
- return rc;
-
- /*
- * Register each port with the serial core
- */
- for (i = 0; i < pmz_ports_count; i++) {
- struct uart_pmac_port *uport = &pmz_ports[i];
- /* NULL node may happen on wallstreet */
- if (uport->node != NULL)
- rc = uart_add_one_port(&pmz_uart_reg, &uport->port);
- if (rc)
- goto err_out;
- }
-
- return 0;
-err_out:
- while (i-- > 0) {
- struct uart_pmac_port *uport = &pmz_ports[i];
- uart_remove_one_port(&pmz_uart_reg, &uport->port);
- }
- uart_unregister_driver(&pmz_uart_reg);
- return rc;
+ return uart_register_driver(&pmz_uart_reg);
}
#ifdef CONFIG_PPC_PMAC
@@ -2086,10 +1918,8 @@ static void __exit exit_pmz(void)
for (i = 0; i < pmz_ports_count; i++) {
struct uart_pmac_port *uport = &pmz_ports[i];
- if (uport->node != NULL) {
- uart_remove_one_port(&pmz_uart_reg, &uport->port);
+ if (uport->node != NULL)
pmz_dispose_port(uport);
- }
}
/* Unregister UART driver */
uart_unregister_driver(&pmz_uart_reg);
@@ -2116,8 +1946,6 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c
struct uart_pmac_port *uap = &pmz_ports[con->index];
unsigned long flags;
- if (ZS_IS_ASLEEP(uap))
- return;
spin_lock_irqsave(&uap->port.lock, flags);
/* Turn of interrupts and enable the transmitter. */
@@ -2162,8 +1990,10 @@ static int __init pmz_console_setup(struct console *co, char *options)
if (co->index >= pmz_ports_count)
co->index = 0;
uap = &pmz_ports[co->index];
+#ifdef CONFIG_PPC_PMAC
if (uap->node == NULL)
return -ENODEV;
+#endif
port = &uap->port;
/*
diff --git a/drivers/tty/serial/pmac_zilog.h b/drivers/tty/serial/pmac_zilog.h
index cbc34fb..9ae4556 100644
--- a/drivers/tty/serial/pmac_zilog.h
+++ b/drivers/tty/serial/pmac_zilog.h
@@ -2,9 +2,12 @@
#define __PMAC_ZILOG_H__
#ifdef CONFIG_PPC_PMAC
-#define pmz_debug(fmt, arg...) dev_dbg(&uap->dev->ofdev.dev, fmt, ## arg)
-#define pmz_error(fmt, arg...) dev_err(&uap->dev->ofdev.dev, fmt, ## arg)
-#define pmz_info(fmt, arg...) dev_info(&uap->dev->ofdev.dev, fmt, ## arg)
+/* We cannot use dev_* because this can be called early, way before
+ * we are matched with a device (when using it as a kernel console)
+ */
+#define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg)
+#define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg)
+#define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg)
#else
#define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg)
#define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg)
@@ -35,7 +38,7 @@ struct uart_pmac_port {
*/
struct device_node *node;
#else
- struct platform_device *node;
+ struct platform_device *pdev;
#endif
/* Port type as obtained from device tree (IRDA, modem, ...) */
@@ -50,14 +53,11 @@ struct uart_pmac_port {
#define PMACZILOG_FLAG_REGS_HELD 0x00000010
#define PMACZILOG_FLAG_TX_STOPPED 0x00000020
#define PMACZILOG_FLAG_TX_ACTIVE 0x00000040
-#define PMACZILOG_FLAG_ENABLED 0x00000080
#define PMACZILOG_FLAG_IS_IRDA 0x00000100
#define PMACZILOG_FLAG_IS_INTMODEM 0x00000200
#define PMACZILOG_FLAG_HAS_DMA 0x00000400
#define PMACZILOG_FLAG_RSRC_REQUESTED 0x00000800
-#define PMACZILOG_FLAG_IS_ASLEEP 0x00001000
#define PMACZILOG_FLAG_IS_OPEN 0x00002000
-#define PMACZILOG_FLAG_IS_IRQ_ON 0x00004000
#define PMACZILOG_FLAG_IS_EXTCLK 0x00008000
#define PMACZILOG_FLAG_BREAK 0x00010000
@@ -74,6 +74,8 @@ struct uart_pmac_port {
volatile struct dbdma_regs __iomem *rx_dma_regs;
#endif
+ unsigned char irq_name[8];
+
struct ktermios termios_cache;
};
@@ -388,9 +390,7 @@ static inline void zssync(struct uart_pmac_port *port)
#define ZS_IS_IRDA(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRDA)
#define ZS_IS_INTMODEM(UP) ((UP)->flags & PMACZILOG_FLAG_IS_INTMODEM)
#define ZS_HAS_DMA(UP) ((UP)->flags & PMACZILOG_FLAG_HAS_DMA)
-#define ZS_IS_ASLEEP(UP) ((UP)->flags & PMACZILOG_FLAG_IS_ASLEEP)
#define ZS_IS_OPEN(UP) ((UP)->flags & PMACZILOG_FLAG_IS_OPEN)
-#define ZS_IS_IRQ_ON(UP) ((UP)->flags & PMACZILOG_FLAG_IS_IRQ_ON)
#define ZS_IS_EXTCLK(UP) ((UP)->flags & PMACZILOG_FLAG_IS_EXTCLK)
#endif /* __PMAC_ZILOG_H__ */
--
1.7.7.3
^ permalink raw reply related [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-11 23:48 ` Benjamin Herrenschmidt
@ 2011-12-11 23:55 ` Benjamin Herrenschmidt
2011-12-12 13:34 ` Finn Thain
1 sibling, 0 replies; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-11 23:55 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Mon, 2011-12-12 at 10:48 +1100, Benjamin Herrenschmidt wrote:
> Any chance you can test this patch ? I would not be surprised if it
> broke m68k since I had to do some of the changes in there "blind",
> so let me know... with this, I can again suspend/resume properly on
> a Pismo while using the internal modem among other things.
..../....
Forgot to commit a fix before sending, but it's a trivial one:
> -#ifdef DEBUG_HARD
> +#ifde DEBUG_HARD
> pmz_debug("irq, r3: %x\n", r3);
> #endif
Remove that hunk :-)
Cheers,
Ben.
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-11 23:48 ` Benjamin Herrenschmidt
2011-12-11 23:55 ` Benjamin Herrenschmidt
@ 2011-12-12 13:34 ` Finn Thain
2011-12-12 20:06 ` Benjamin Herrenschmidt
1 sibling, 1 reply; 51+ messages in thread
From: Finn Thain @ 2011-12-12 13:34 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Mon, 12 Dec 2011, Benjamin Herrenschmidt wrote:
> Any chance you can test this patch ? I would not be surprised if it
> broke m68k since I had to do some of the changes in there "blind", so
> let me know... with this, I can again suspend/resume properly on a Pismo
> while using the internal modem among other things.
The patch works on a PowerBook 520 given a few changes (below). This
PowerBook only has one serial port that I can test (the internal modem is
not supported on 68k Macs). Can you test a machine with two ports? The
rest of my Mac hardware is in storage since I moved house last week.
Finn
Index: linux-git/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-13 00:18:02.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-13 00:23:55.000000000 +1100
@@ -1705,8 +1705,8 @@ static int __init pmz_init_port(struct u
struct resource *r_ports;
int irq;
- r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0);
- irq = platform_get_irq(uap->node, 0);
+ r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(uap->pdev, 0);
if (!r_ports || !irq)
return -ENODEV;
@@ -1763,8 +1763,10 @@ static void pmz_dispose_port(struct uart
static int __init pmz_attach(struct platform_device *pdev)
{
+ struct uart_pmac_port *uap;
int i;
+ /* Iterate the pmz_ports array to find a matching entry */
for (i = 0; i < pmz_ports_count; i++)
if (pmz_ports[i].pdev == pdev)
break;
@@ -1773,15 +1775,23 @@ static int __init pmz_attach(struct plat
uap = &pmz_ports[i];
uap->port.dev = &pdev->dev;
- dev_set_drvdata(&mdev->ofdev.dev, uap);
+ platform_set_drvdata(pdev, uap);
- return uart_add_one_port(&pmz_uart_reg,
- &pmz_ports[i]->port);
+ return uart_add_one_port(&pmz_uart_reg, &uap->port);
}
static int __exit pmz_detach(struct platform_device *pdev)
{
+ struct uart_pmac_port *uap = platform_get_drvdata(pdev);
+
+ if (!uap)
+ return -ENODEV;
+
uart_remove_one_port(&pmz_uart_reg, &uap->port);
+
+ platform_set_drvdata(pdev, NULL);
+ uap->port.dev = NULL;
+
return 0;
}
@@ -1918,8 +1928,13 @@ static void __exit exit_pmz(void)
for (i = 0; i < pmz_ports_count; i++) {
struct uart_pmac_port *uport = &pmz_ports[i];
+#ifdef CONFIG_PPC_PMAC
if (uport->node != NULL)
pmz_dispose_port(uport);
+#else
+ if (uport->pdev != NULL)
+ pmz_dispose_port(uport);
+#endif
}
/* Unregister UART driver */
uart_unregister_driver(&pmz_uart_reg);
@@ -1993,6 +2008,9 @@ static int __init pmz_console_setup(stru
#ifdef CONFIG_PPC_PMAC
if (uap->node == NULL)
return -ENODEV;
+#else
+ if (uap->pdev == NULL)
+ return -ENODEV;
#endif
port = &uap->port;
Index: linux-git/drivers/tty/serial/pmac_zilog.h
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.h 2011-12-13 00:18:02.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.h 2011-12-13 00:23:55.000000000 +1100
@@ -1,18 +1,9 @@
#ifndef __PMAC_ZILOG_H__
#define __PMAC_ZILOG_H__
-#ifdef CONFIG_PPC_PMAC
-/* We cannot use dev_* because this can be called early, way before
- * we are matched with a device (when using it as a kernel console)
- */
#define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg)
#define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg)
#define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg)
-#else
-#define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg)
-#define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg)
-#define pmz_info(fmt, arg...) dev_info(&uap->node->dev, fmt, ## arg)
-#endif
/*
* At most 2 ESCCs with 2 ports each
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-12 13:34 ` Finn Thain
@ 2011-12-12 20:06 ` Benjamin Herrenschmidt
2011-12-13 1:24 ` Finn Thain
0 siblings, 1 reply; 51+ messages in thread
From: Benjamin Herrenschmidt @ 2011-12-12 20:06 UTC (permalink / raw)
To: Finn Thain; +Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Tue, 2011-12-13 at 00:34 +1100, Finn Thain wrote:
> On Mon, 12 Dec 2011, Benjamin Herrenschmidt wrote:
>
> > Any chance you can test this patch ? I would not be surprised if it
> > broke m68k since I had to do some of the changes in there "blind", so
> > let me know... with this, I can again suspend/resume properly on a Pismo
> > while using the internal modem among other things.
>
> The patch works on a PowerBook 520 given a few changes (below). This
> PowerBook only has one serial port that I can test (the internal modem is
> not supported on 68k Macs).
Interesting. The modem is a soft-modem "geoport" or a hw serial modem ?
In the later case it's probably just a matter of finding the right GPIO
bit in Apple ASIC to turn the power on :-)
> Can you test a machine with two ports? The
> rest of my Mac hardware is in storage since I moved house last week.
I tried on 2 port powermacs, but I only have one adapter, so I've
basically been running with one serial port open and shooting irda frame
on the other (with nothing to check wether I got the frames on the other
hand), oh well ...
I'll apply your patch and commit via my tree.
Cheers,
Ben.
> Finn
>
>
> Index: linux-git/drivers/tty/serial/pmac_zilog.c
> ===================================================================
> --- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-13 00:18:02.000000000 +1100
> +++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-13 00:23:55.000000000 +1100
> @@ -1705,8 +1705,8 @@ static int __init pmz_init_port(struct u
> struct resource *r_ports;
> int irq;
>
> - r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0);
> - irq = platform_get_irq(uap->node, 0);
> + r_ports = platform_get_resource(uap->pdev, IORESOURCE_MEM, 0);
> + irq = platform_get_irq(uap->pdev, 0);
> if (!r_ports || !irq)
> return -ENODEV;
>
> @@ -1763,8 +1763,10 @@ static void pmz_dispose_port(struct uart
>
> static int __init pmz_attach(struct platform_device *pdev)
> {
> + struct uart_pmac_port *uap;
> int i;
>
> + /* Iterate the pmz_ports array to find a matching entry */
> for (i = 0; i < pmz_ports_count; i++)
> if (pmz_ports[i].pdev == pdev)
> break;
> @@ -1773,15 +1775,23 @@ static int __init pmz_attach(struct plat
>
> uap = &pmz_ports[i];
> uap->port.dev = &pdev->dev;
> - dev_set_drvdata(&mdev->ofdev.dev, uap);
> + platform_set_drvdata(pdev, uap);
>
> - return uart_add_one_port(&pmz_uart_reg,
> - &pmz_ports[i]->port);
> + return uart_add_one_port(&pmz_uart_reg, &uap->port);
> }
>
> static int __exit pmz_detach(struct platform_device *pdev)
> {
> + struct uart_pmac_port *uap = platform_get_drvdata(pdev);
> +
> + if (!uap)
> + return -ENODEV;
> +
> uart_remove_one_port(&pmz_uart_reg, &uap->port);
> +
> + platform_set_drvdata(pdev, NULL);
> + uap->port.dev = NULL;
> +
> return 0;
> }
>
> @@ -1918,8 +1928,13 @@ static void __exit exit_pmz(void)
>
> for (i = 0; i < pmz_ports_count; i++) {
> struct uart_pmac_port *uport = &pmz_ports[i];
> +#ifdef CONFIG_PPC_PMAC
> if (uport->node != NULL)
> pmz_dispose_port(uport);
> +#else
> + if (uport->pdev != NULL)
> + pmz_dispose_port(uport);
> +#endif
> }
> /* Unregister UART driver */
> uart_unregister_driver(&pmz_uart_reg);
> @@ -1993,6 +2008,9 @@ static int __init pmz_console_setup(stru
> #ifdef CONFIG_PPC_PMAC
> if (uap->node == NULL)
> return -ENODEV;
> +#else
> + if (uap->pdev == NULL)
> + return -ENODEV;
> #endif
> port = &uap->port;
>
> Index: linux-git/drivers/tty/serial/pmac_zilog.h
> ===================================================================
> --- linux-git.orig/drivers/tty/serial/pmac_zilog.h 2011-12-13 00:18:02.000000000 +1100
> +++ linux-git/drivers/tty/serial/pmac_zilog.h 2011-12-13 00:23:55.000000000 +1100
> @@ -1,18 +1,9 @@
> #ifndef __PMAC_ZILOG_H__
> #define __PMAC_ZILOG_H__
>
> -#ifdef CONFIG_PPC_PMAC
> -/* We cannot use dev_* because this can be called early, way before
> - * we are matched with a device (when using it as a kernel console)
> - */
> #define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg)
> #define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg)
> #define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg)
> -#else
> -#define pmz_debug(fmt, arg...) dev_dbg(&uap->node->dev, fmt, ## arg)
> -#define pmz_error(fmt, arg...) dev_err(&uap->node->dev, fmt, ## arg)
> -#define pmz_info(fmt, arg...) dev_info(&uap->node->dev, fmt, ## arg)
> -#endif
>
> /*
> * At most 2 ESCCs with 2 ports each
^ permalink raw reply [flat|nested] 51+ messages in thread
* Re: [PATCH 01/16 v3] pmac_zilog: fix unexpected irq
2011-12-12 20:06 ` Benjamin Herrenschmidt
@ 2011-12-13 1:24 ` Finn Thain
0 siblings, 0 replies; 51+ messages in thread
From: Finn Thain @ 2011-12-13 1:24 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Geert Uytterhoeven, linux-m68k, linuxppc-dev, linux-serial
On Tue, 13 Dec 2011, Benjamin Herrenschmidt wrote:
> On Tue, 2011-12-13 at 00:34 +1100, Finn Thain wrote:
> > On Mon, 12 Dec 2011, Benjamin Herrenschmidt wrote:
> >
> > > Any chance you can test this patch ? I would not be surprised if it
> > > broke m68k since I had to do some of the changes in there "blind",
> > > so let me know... with this, I can again suspend/resume properly on
> > > a Pismo while using the internal modem among other things.
> >
> > The patch works on a PowerBook 520 given a few changes (below). This
> > PowerBook only has one serial port that I can test (the internal modem
> > is not supported on 68k Macs).
>
> Interesting. The modem is a soft-modem "geoport" or a hw serial modem ?
It's the latter.
> In the later case it's probably just a matter of finding the right GPIO
> bit in Apple ASIC to turn the power on :-)
Surely feasible, but not high on the list of missing hardware support.
>
> > Can you test a machine with two ports? The rest of my Mac hardware is
> > in storage since I moved house last week.
>
> I tried on 2 port powermacs, but I only have one adapter, so I've
> basically been running with one serial port open and shooting irda frame
> on the other (with nothing to check wether I got the frames on the other
> hand), oh well ...
>
> I'll apply your patch and commit via my tree.
I forgot to include this fix for your logging change.
Finn
Index: linux-git/drivers/tty/serial/pmac_zilog.c
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.c 2011-12-13 12:12:05.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.c 2011-12-13 12:13:29.000000000 +1100
@@ -99,6 +99,10 @@ MODULE_LICENSE("GPL");
#define PMACZILOG_NAME "ttyPZ"
#endif
+#define pmz_debug(fmt, arg...) pr_debug(PMACZILOG_NAME "%d: " fmt, uap->port.line, ## arg)
+#define pmz_error(fmt, arg...) pr_err(PMACZILOG_NAME "%d: " fmt, uap->port.line, ## arg)
+#define pmz_info(fmt, arg...) pr_info(PMACZILOG_NAME "%d: " fmt, uap->port.line, ## arg)
+
/*
* For the sake of early serial console, we can do a pre-probe
Index: linux-git/drivers/tty/serial/pmac_zilog.h
===================================================================
--- linux-git.orig/drivers/tty/serial/pmac_zilog.h 2011-12-13 12:12:05.000000000 +1100
+++ linux-git/drivers/tty/serial/pmac_zilog.h 2011-12-13 12:12:28.000000000 +1100
@@ -1,10 +1,6 @@
#ifndef __PMAC_ZILOG_H__
#define __PMAC_ZILOG_H__
-#define pmz_debug(fmt, arg...) pr_debug("ttyPZ%d: " fmt, uap->port.line, ## arg)
-#define pmz_error(fmt, arg...) pr_err("ttyPZ%d: " fmt, uap->port.line, ## arg)
-#define pmz_info(fmt, arg...) pr_info("ttyPZ%d: " fmt, uap->port.line, ## arg)
-
/*
* At most 2 ESCCs with 2 ports each
*/
^ permalink raw reply [flat|nested] 51+ messages in thread
end of thread, other threads:[~2011-12-13 1:24 UTC | newest]
Thread overview: 51+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-23 14:11 [PATCH 00/16] more mac68k fixes and cleanup Finn Thain
2011-10-23 14:11 ` [PATCH 01/16] pmac_zilog: fix unexpected irq Finn Thain
2011-11-24 14:34 ` Finn Thain
2011-11-24 14:56 ` Alan Cox
2011-11-24 20:41 ` Benjamin Herrenschmidt
2011-11-25 3:15 ` Finn Thain
2011-11-28 0:30 ` Benjamin Herrenschmidt
2011-11-24 15:28 ` David Laight
2011-11-24 20:43 ` Benjamin Herrenschmidt
2011-12-06 15:13 ` [PATCH 01/16 v2] " Finn Thain
2011-12-06 15:27 ` Geert Uytterhoeven
2011-12-07 1:26 ` Finn Thain
2011-12-06 15:39 ` Alan Cox
2011-12-07 3:49 ` [PATCH 01/16 v3] " Finn Thain
2011-12-08 3:17 ` Benjamin Herrenschmidt
2011-12-08 4:20 ` Benjamin Herrenschmidt
2011-12-08 4:30 ` Benjamin Herrenschmidt
2011-12-08 11:26 ` Finn Thain
2011-12-08 11:54 ` Geert Uytterhoeven
2011-12-08 19:44 ` Benjamin Herrenschmidt
2011-12-11 23:48 ` Benjamin Herrenschmidt
2011-12-11 23:55 ` Benjamin Herrenschmidt
2011-12-12 13:34 ` Finn Thain
2011-12-12 20:06 ` Benjamin Herrenschmidt
2011-12-13 1:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 02/16] macfb: fix black and white modes Finn Thain
2011-12-10 5:23 ` Finn Thain
2011-10-23 14:11 ` [PATCH 03/16] mac_sonic: add irq resources and cleanup Finn Thain
2011-11-13 10:28 ` Geert Uytterhoeven
2011-11-13 14:30 ` Finn Thain
2011-11-13 17:36 ` Geert Uytterhoeven
2011-12-10 5:23 ` Finn Thain
2011-10-23 14:11 ` [PATCH 04/16] m68k/mac: early console Finn Thain
2011-10-23 14:11 ` [PATCH 05/16] m68k/mac: cleanup mac_clear_irq Finn Thain
2011-10-23 14:11 ` [PATCH 06/16] m68k/mac: cleanup mac_irq_pending Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 07/16] m68k/mac: cleanup forward declarations Finn Thain
2011-10-23 14:11 ` [PATCH 08/16] m68k/mac: enable via_alt_mapping on performa 580 Finn Thain
2011-10-23 14:11 ` [PATCH 09/16] m68k/mac: fix nubus slot irq disable and shutdown Finn Thain
2011-10-23 14:11 ` [PATCH 10/16] m68k/mac: oss irq fixes Finn Thain
2011-10-23 14:11 ` [PATCH 11/16] m68k/mac: fix baboon irq disable and shutdown Finn Thain
2011-10-23 14:11 ` [PATCH 12/16] m68k/mac: fix powerbook 150 adb_type Finn Thain
2011-10-23 14:11 ` [PATCH 13/16] mac_scsi: fix mac_scsi on some powerbooks Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 14/16] m68k/mac: cleanup macro case Finn Thain
2011-10-23 14:11 ` [PATCH 15/16] mac_scsi: dont enable mac_scsi irq before requesting it Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-23 14:11 ` [PATCH 16/16] mac_esp: rename irq Finn Thain
2011-12-10 5:24 ` Finn Thain
2011-10-31 18:35 ` [PATCH 00/16] more mac68k fixes and cleanup Geert Uytterhoeven
2011-10-31 19:16 ` Geert Uytterhoeven
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox