[PATCH 1/2] pmac-zilog: add platform driver

Geert Uytterhoeven geert at linux-m68k.org
Thu Dec 24 07:16:38 EST 2009


On Tue, Nov 17, 2009 at 10:04, Finn Thain <fthain at telegraphics.com.au> wrote:
> Add platform driver to the pmac-zilog driver for mac 68k, putting the
> powermac-specific bits inside #ifdef CONFIG_PPC_PMAC.

Ben, OK for you?

> This patch should be applied after "[PATCH 3/13] pmac-zilog: cleanup". It
> renders obsolete the version in "[PATCH 4/13] pmac-zilog, mac68k: replace
> mac68k SCC code with platform".
>
> Signed-off-by: Finn Thain <fthain at telegraphics.com.au>
>
> ---
>  arch/m68k/configs/mac_defconfig   |    5 +
>  arch/m68k/configs/multi_defconfig |    5 +
>  drivers/serial/Kconfig            |   12 +-
>  drivers/serial/pmac_zilog.c       |  159 +++++++++++++++++++++++++++++++++-----
>  drivers/serial/pmac_zilog.h       |   14 +++
>  5 files changed, 169 insertions(+), 26 deletions(-)
>
> Index: linux-2.6.31/drivers/serial/Kconfig
> ===================================================================
> --- linux-2.6.31.orig/drivers/serial/Kconfig    2009-11-17 17:05:27.000000000 +1100
> +++ linux-2.6.31/drivers/serial/Kconfig 2009-11-17 17:07:38.000000000 +1100
> @@ -1079,12 +1079,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
> @@ -1109,16 +1109,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
> Index: linux-2.6.31/arch/m68k/configs/mac_defconfig
> ===================================================================
> --- linux-2.6.31.orig/arch/m68k/configs/mac_defconfig   2009-11-17 17:07:29.000000000 +1100
> +++ linux-2.6.31/arch/m68k/configs/mac_defconfig        2009-11-17 17:07:38.000000000 +1100
> @@ -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
> Index: linux-2.6.31/arch/m68k/configs/multi_defconfig
> ===================================================================
> --- linux-2.6.31.orig/arch/m68k/configs/multi_defconfig 2009-11-17 17:07:29.000000000 +1100
> +++ linux-2.6.31/arch/m68k/configs/multi_defconfig      2009-11-17 17:07:38.000000000 +1100
> @@ -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
> Index: linux-2.6.31/drivers/serial/pmac_zilog.c
> ===================================================================
> --- linux-2.6.31.orig/drivers/serial/pmac_zilog.c       2009-11-17 17:07:28.000000000 +1100
> +++ linux-2.6.31/drivers/serial/pmac_zilog.c    2009-11-17 17:07:38.000000000 +1100
> @@ -63,11 +63,18 @@
>  #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>
> +#include <asm/macints.h>
> +#define machine_is_compatible(x) (0)
> +#endif
>
>  #if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
>  #define SUPPORT_SYSRQ
> @@ -83,11 +90,9 @@
>
>  static char version[] __initdata = "pmac_zilog: 0.6 (Benjamin Herrenschmidt <benh at kernel.crashing.org>)";
>  MODULE_AUTHOR("Benjamin Herrenschmidt <benh at 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
> @@ -341,7 +346,7 @@ static struct tty_struct *pmz_receive_ch
>        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;
>  }
>
> @@ -746,6 +751,8 @@ static void pmz_break_ctl(struct uart_po
>        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.)
> @@ -781,6 +788,15 @@ static int pmz_set_scc_power(struct uart
>        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
> @@ -943,9 +959,9 @@ static int pmz_startup(struct uart_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;
> @@ -1185,7 +1201,7 @@ static void pmz_irda_setup(struct uart_p
>        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);
> @@ -1201,7 +1217,7 @@ static void pmz_irda_setup(struct uart_p
>                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;
>                }
>        }
> @@ -1222,8 +1238,7 @@ static void pmz_irda_setup(struct uart_p
>        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);
> @@ -1231,8 +1246,7 @@ static void pmz_irda_setup(struct uart_p
>        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;
>        }
>
> @@ -1241,19 +1255,17 @@ static void pmz_irda_setup(struct uart_p
>        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",
> -                *baud, version);
> +       pmz_info("IrDA setup for %ld bps, dongle version: %d\n",
> +                *baud, version);
>
>        (void)read_zsdata(uap);
>        (void)read_zsdata(uap);
> @@ -1402,7 +1414,7 @@ static void pmz_poll_put_char(struct uar
>        write_zsdata(uap, c);
>  }
>
> -#endif
> +#endif /* CONFIG_CONSOLE_POLL */
>
>  static struct uart_ops pmz_pops = {
>        .tx_empty       =       pmz_tx_empty,
> @@ -1427,6 +1439,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
> @@ -1823,6 +1837,88 @@ next:
>        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 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 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);
> @@ -1883,6 +1979,8 @@ err_out:
>        return rc;
>  }
>
> +#ifdef CONFIG_PPC_PMAC
> +
>  static struct of_device_id pmz_match[] =
>  {
>        {
> @@ -1904,6 +2002,19 @@ static struct macio_driver pmz_driver =
>        .resume         = pmz_resume,
>  };
>
> +#else
> +
> +static struct platform_driver pmz_driver = {
> +       .probe          = pmz_attach,
> +       .remove         = __devexit_p(pmz_detach),
> +       .driver         = {
> +               .name           = "scc",
> +               .owner          = THIS_MODULE,
> +       },
> +};
> +
> +#endif /* !CONFIG_PPC_PMAC */
> +
>  static int __init init_pmz(void)
>  {
>        int rc, i;
> @@ -1942,15 +2053,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_register(&pmz_driver);
> +#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];
> Index: linux-2.6.31/drivers/serial/pmac_zilog.h
> ===================================================================
> --- linux-2.6.31.orig/drivers/serial/pmac_zilog.h       2009-11-17 17:07:28.000000000 +1100
> +++ linux-2.6.31/drivers/serial/pmac_zilog.h    2009-11-17 17:07:38.000000000 +1100
> @@ -1,7 +1,15 @@
>  #ifndef __PMAC_ZILOG_H__
>  #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)
> +#else
> +#define pmz_debug(fmt, arg...) do { } while (0)
> +#define pmz_error(fmt, arg...) printk(KERN_ERR fmt, ## arg)
> +#define pmz_info(fmt, arg...)  printk(KERN_INFO fmt, ## arg)
> +#endif
>
>  /*
>  * At most 2 ESCCs with 2 ports each
> @@ -17,6 +25,7 @@ struct uart_pmac_port {
>        struct uart_port                port;
>        struct uart_pmac_port           *mate;
>
> +#ifdef CONFIG_PPC_PMAC
>        /* macio_dev for the escc holding this port (maybe be null on
>         * early inited port)
>         */
> @@ -25,6 +34,9 @@ struct uart_pmac_port {
>         * of "escc" node (ie. ch-a or ch-b)
>         */
>        struct device_node              *node;
> +#else
> +       struct platform_device          *node;
> +#endif
>
>        /* Port type as obtained from device tree (IRDA, modem, ...) */
>        int                             port_type;
> @@ -55,10 +67,12 @@ struct uart_pmac_port {
>        volatile u8                     __iomem *control_reg;
>        volatile u8                     __iomem *data_reg;
>
> +#ifdef CONFIG_PPC_PMAC
>        unsigned int                    tx_dma_irq;
>        unsigned int                    rx_dma_irq;
>        volatile struct dbdma_regs      __iomem *tx_dma_regs;
>        volatile struct dbdma_regs      __iomem *rx_dma_regs;
> +#endif
>
>        struct ktermios                 termios_cache;
>  };
> --
> To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at 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


More information about the Linuxppc-dev mailing list