Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 182200
b: refs/heads/master
c: ec9cbe0
h: refs/heads/master
v: v3
  • Loading branch information
Finn Thain authored and Geert Uytterhoeven committed Feb 27, 2010
1 parent baea551 commit dcab8e4
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1f7b5fff505232521a7a770a639b63cd17636549
refs/heads/master: ec9cbe09899e36b5f216c3232215520dcf0320ab
5 changes: 5 additions & 0 deletions trunk/arch/m68k/configs/mac_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,11 @@ CONFIG_VT_HW_CONSOLE_BINDING=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_PMACZILOG=y
CONFIG_SERIAL_PMACZILOG_TTYS=y
CONFIG_SERIAL_PMACZILOG_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
Expand Down
5 changes: 5 additions & 0 deletions trunk/arch/m68k/configs/multi_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,11 @@ CONFIG_A2232=y
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_PMACZILOG=y
CONFIG_SERIAL_PMACZILOG_TTYS=y
CONFIG_SERIAL_PMACZILOG_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
Expand Down
12 changes: 6 additions & 6 deletions trunk/drivers/serial/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1086,12 +1086,12 @@ config SERIAL_68360
default y

config SERIAL_PMACZILOG
tristate "PowerMac z85c30 ESCC support"
depends on PPC_OF && PPC_PMAC
tristate "Mac or PowerMac z85c30 ESCC support"
depends on (M68K && MAC) || (PPC_OF && PPC_PMAC)
select SERIAL_CORE
help
This driver supports the Zilog z85C30 serial ports found on
PowerMac machines.
(Power)Mac machines.
Say Y or M if you want to be able to these serial ports.

config SERIAL_PMACZILOG_TTYS
Expand All @@ -1116,16 +1116,16 @@ config SERIAL_PMACZILOG_TTYS
unable to use the 8250 module for PCMCIA or other 16C550-style
UARTs.

Say N unless you need the z85c30 ports on your powermac
Say N unless you need the z85c30 ports on your (Power)Mac
to appear as /dev/ttySn.

config SERIAL_PMACZILOG_CONSOLE
bool "Console on PowerMac z85c30 serial port"
bool "Console on Mac or PowerMac z85c30 serial port"
depends on SERIAL_PMACZILOG=y
select SERIAL_CORE_CONSOLE
help
If you would like to be able to use the z85c30 serial port
on your PowerMac as the console, you can do so by answering
on your (Power)Mac as the console, you can do so by answering
Y to this option.

config SERIAL_LH7A40X
Expand Down
155 changes: 136 additions & 19 deletions trunk/drivers/serial/pmac_zilog.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,17 @@
#include <asm/sections.h>
#include <asm/io.h>
#include <asm/irq.h>

#ifdef CONFIG_PPC_PMAC
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/dbdma.h>
#include <asm/macio.h>
#else
#include <linux/platform_device.h>
#define of_machine_is_compatible(x) (0)
#endif

#if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
#define SUPPORT_SYSRQ
Expand All @@ -83,11 +89,9 @@

static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
MODULE_DESCRIPTION("Driver for the PowerMac serial ports.");
MODULE_DESCRIPTION("Driver for the Mac and PowerMac serial ports.");
MODULE_LICENSE("GPL");

#define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg)

#ifdef CONFIG_SERIAL_PMACZILOG_TTYS
#define PMACZILOG_MAJOR TTY_MAJOR
#define PMACZILOG_MINOR 64
Expand Down Expand Up @@ -341,7 +345,7 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap)
uap->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
write_zsreg(uap, R1, uap->curregs[R1]);
zssync(uap);
dev_err(&uap->dev->ofdev.dev, "pmz: rx irq flood !\n");
pmz_error("pmz: rx irq flood !\n");
return tty;
}

Expand Down Expand Up @@ -757,6 +761,8 @@ static void pmz_break_ctl(struct uart_port *port, int break_state)
spin_unlock_irqrestore(&port->lock, flags);
}

#ifdef CONFIG_PPC_PMAC

/*
* Turn power on or off to the SCC and associated stuff
* (port drivers, modem, IR port, etc.)
Expand Down Expand Up @@ -792,6 +798,15 @@ static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
return delay;
}

#else

static int pmz_set_scc_power(struct uart_pmac_port *uap, int state)
{
return 0;
}

#endif /* !CONFIG_PPC_PMAC */

/*
* FixZeroBug....Works around a bug in the SCC receving channel.
* Inspired from Darwin code, 15 Sept. 2000 -DanM
Expand Down Expand Up @@ -954,9 +969,9 @@ static int pmz_startup(struct uart_port *port)
}

pmz_get_port_A(uap)->flags |= PMACZILOG_FLAG_IS_IRQ_ON;
if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED, "PowerMac Zilog", uap)) {
dev_err(&uap->dev->ofdev.dev,
"Unable to register zs interrupt handler.\n");
if (request_irq(uap->port.irq, pmz_interrupt, IRQF_SHARED,
"SCC", uap)) {
pmz_error("Unable to register zs interrupt handler.\n");
pmz_set_scc_power(uap, 0);
mutex_unlock(&pmz_irq_mutex);
return -ENXIO;
Expand Down Expand Up @@ -1196,7 +1211,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0
|| (read_zsreg(uap, R1) & ALL_SNT) == 0) {
if (--t <= 0) {
dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n");
pmz_error("transmitter didn't drain\n");
return;
}
udelay(10);
Expand All @@ -1212,7 +1227,7 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
read_zsdata(uap);
mdelay(10);
if (--t <= 0) {
dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n");
pmz_error("receiver didn't drain\n");
return;
}
}
Expand All @@ -1233,17 +1248,15 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
t = 5000;
while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
if (--t <= 0) {
dev_err(&uap->dev->ofdev.dev,
"irda_setup timed out on get_version byte\n");
pmz_error("irda_setup timed out on get_version byte\n");
goto out;
}
udelay(10);
}
version = read_zsdata(uap);

if (version < 4) {
dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n",
version);
pmz_info("IrDA: dongle version %d not supported\n", version);
goto out;
}

Expand All @@ -1252,18 +1265,16 @@ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud)
t = 5000;
while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) {
if (--t <= 0) {
dev_err(&uap->dev->ofdev.dev,
"irda_setup timed out on speed mode byte\n");
pmz_error("irda_setup timed out on speed mode byte\n");
goto out;
}
udelay(10);
}
t = read_zsdata(uap);
if (t != cmdbyte)
dev_err(&uap->dev->ofdev.dev,
"irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);
pmz_error("irda_setup speed mode byte = %x (%x)\n", t, cmdbyte);

dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n",
pmz_info("IrDA setup for %ld bps, dongle version: %d\n",
*baud, version);

(void)read_zsdata(uap);
Expand Down Expand Up @@ -1413,7 +1424,7 @@ static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
write_zsdata(uap, c);
}

#endif
#endif /* CONFIG_CONSOLE_POLL */

static struct uart_ops pmz_pops = {
.tx_empty = pmz_tx_empty,
Expand All @@ -1438,6 +1449,8 @@ static struct uart_ops pmz_pops = {
#endif
};

#ifdef CONFIG_PPC_PMAC

/*
* Setup one port structure after probing, HW is down at this point,
* Unlike sunzilog, we don't need to pre-init the spinlock as we don't
Expand Down Expand Up @@ -1834,6 +1847,88 @@ static int __init pmz_probe(void)
return 0;
}

#else

extern struct platform_device scc_a_pdev, scc_b_pdev;

static int __init pmz_init_port(struct uart_pmac_port *uap)
{
struct resource *r_ports;
int irq;

r_ports = platform_get_resource(uap->node, IORESOURCE_MEM, 0);
irq = platform_get_irq(uap->node, 0);
if (!r_ports || !irq)
return -ENODEV;

uap->port.mapbase = r_ports->start;
uap->port.membase = (unsigned char __iomem *) r_ports->start;
uap->port.iotype = UPIO_MEM;
uap->port.irq = irq;
uap->port.uartclk = ZS_CLOCK;
uap->port.fifosize = 1;
uap->port.ops = &pmz_pops;
uap->port.type = PORT_PMAC_ZILOG;
uap->port.flags = 0;

uap->control_reg = uap->port.membase;
uap->data_reg = uap->control_reg + 4;
uap->port_type = 0;

pmz_convert_to_zs(uap, CS8, 0, 9600);

return 0;
}

static int __init pmz_probe(void)
{
int err;

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;
err = pmz_init_port(&pmz_ports[0]);
if (err)
return err;
pmz_ports_count++;

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;
err = pmz_init_port(&pmz_ports[1]);
if (err)
return err;
pmz_ports_count++;

return 0;
}

static void pmz_dispose_port(struct uart_pmac_port *uap)
{
memset(uap, 0, sizeof(struct uart_pmac_port));
}

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;
}

static int __exit pmz_detach(struct platform_device *pdev)
{
return 0;
}

#endif /* !CONFIG_PPC_PMAC */

#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE

static void pmz_console_write(struct console *con, const char *s, unsigned int count);
Expand Down Expand Up @@ -1894,6 +1989,8 @@ static int __init pmz_register(void)
return rc;
}

#ifdef CONFIG_PPC_PMAC

static struct of_device_id pmz_match[] =
{
{
Expand All @@ -1915,6 +2012,18 @@ static struct macio_driver pmz_driver = {
.resume = pmz_resume,
};

#else

static struct platform_driver pmz_driver = {
.remove = __exit_p(pmz_detach),
.driver = {
.name = "scc",
.owner = THIS_MODULE,
},
};

#endif /* !CONFIG_PPC_PMAC */

static int __init init_pmz(void)
{
int rc, i;
Expand Down Expand Up @@ -1953,15 +2062,23 @@ static int __init init_pmz(void)
/*
* Then we register the macio driver itself
*/
#ifdef CONFIG_PPC_PMAC
return macio_register_driver(&pmz_driver);
#else
return platform_driver_probe(&pmz_driver, pmz_attach);
#endif
}

static void __exit exit_pmz(void)
{
int i;

#ifdef CONFIG_PPC_PMAC
/* Get rid of macio-driver (detach from macio) */
macio_unregister_driver(&pmz_driver);
#else
platform_driver_unregister(&pmz_driver);
#endif

for (i = 0; i < pmz_ports_count; i++) {
struct uart_pmac_port *uport = &pmz_ports[i];
Expand Down
Loading

0 comments on commit dcab8e4

Please sign in to comment.