16174e6edSMarcel Moolenaar /*- 2718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3718cf2ccSPedro F. Giffuni * 46174e6edSMarcel Moolenaar * Copyright (c) 2004-2006 Marcel Moolenaar 56174e6edSMarcel Moolenaar * All rights reserved. 66174e6edSMarcel Moolenaar * 76174e6edSMarcel Moolenaar * Redistribution and use in source and binary forms, with or without 86174e6edSMarcel Moolenaar * modification, are permitted provided that the following conditions 96174e6edSMarcel Moolenaar * are met: 106174e6edSMarcel Moolenaar * 116174e6edSMarcel Moolenaar * 1. Redistributions of source code must retain the above copyright 126174e6edSMarcel Moolenaar * notice, this list of conditions and the following disclaimer. 136174e6edSMarcel Moolenaar * 2. Redistributions in binary form must reproduce the above copyright 146174e6edSMarcel Moolenaar * notice, this list of conditions and the following disclaimer in the 156174e6edSMarcel Moolenaar * documentation and/or other materials provided with the distribution. 166174e6edSMarcel Moolenaar * 176174e6edSMarcel Moolenaar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 186174e6edSMarcel Moolenaar * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 196174e6edSMarcel Moolenaar * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 206174e6edSMarcel Moolenaar * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 216174e6edSMarcel Moolenaar * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 226174e6edSMarcel Moolenaar * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236174e6edSMarcel Moolenaar * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246174e6edSMarcel Moolenaar * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256174e6edSMarcel Moolenaar * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 266174e6edSMarcel Moolenaar * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276174e6edSMarcel Moolenaar */ 286174e6edSMarcel Moolenaar 296174e6edSMarcel Moolenaar #include <sys/cdefs.h> 306174e6edSMarcel Moolenaar __FBSDID("$FreeBSD$"); 316174e6edSMarcel Moolenaar 326174e6edSMarcel Moolenaar #include <sys/param.h> 336174e6edSMarcel Moolenaar #include <sys/systm.h> 346174e6edSMarcel Moolenaar #include <sys/bus.h> 356174e6edSMarcel Moolenaar #include <sys/conf.h> 366174e6edSMarcel Moolenaar #include <sys/kernel.h> 376174e6edSMarcel Moolenaar #include <sys/module.h> 386174e6edSMarcel Moolenaar 396174e6edSMarcel Moolenaar #include <machine/bus.h> 406174e6edSMarcel Moolenaar #include <sys/rman.h> 416174e6edSMarcel Moolenaar #include <machine/resource.h> 426174e6edSMarcel Moolenaar 436174e6edSMarcel Moolenaar #include <dev/scc/scc_bus.h> 446174e6edSMarcel Moolenaar 456174e6edSMarcel Moolenaar #include <dev/uart/uart.h> 466174e6edSMarcel Moolenaar #include <dev/uart/uart_bus.h> 476174e6edSMarcel Moolenaar 486174e6edSMarcel Moolenaar static int uart_scc_attach(device_t dev); 496174e6edSMarcel Moolenaar static int uart_scc_probe(device_t dev); 506174e6edSMarcel Moolenaar 516174e6edSMarcel Moolenaar static device_method_t uart_scc_methods[] = { 526174e6edSMarcel Moolenaar /* Device interface */ 536174e6edSMarcel Moolenaar DEVMETHOD(device_probe, uart_scc_probe), 546174e6edSMarcel Moolenaar DEVMETHOD(device_attach, uart_scc_attach), 556174e6edSMarcel Moolenaar DEVMETHOD(device_detach, uart_bus_detach), 566174e6edSMarcel Moolenaar /* Serdev interface */ 576174e6edSMarcel Moolenaar DEVMETHOD(serdev_ihand, uart_bus_ihand), 586174e6edSMarcel Moolenaar DEVMETHOD(serdev_sysdev, uart_bus_sysdev), 596174e6edSMarcel Moolenaar { 0, 0 } 606174e6edSMarcel Moolenaar }; 616174e6edSMarcel Moolenaar 626174e6edSMarcel Moolenaar static driver_t uart_scc_driver = { 636174e6edSMarcel Moolenaar uart_driver_name, 646174e6edSMarcel Moolenaar uart_scc_methods, 656174e6edSMarcel Moolenaar sizeof(struct uart_softc), 666174e6edSMarcel Moolenaar }; 676174e6edSMarcel Moolenaar 686174e6edSMarcel Moolenaar static int 696174e6edSMarcel Moolenaar uart_scc_attach(device_t dev) 706174e6edSMarcel Moolenaar { 716174e6edSMarcel Moolenaar device_t parent; 726174e6edSMarcel Moolenaar struct uart_softc *sc; 736174e6edSMarcel Moolenaar uintptr_t mtx; 746174e6edSMarcel Moolenaar 756174e6edSMarcel Moolenaar parent = device_get_parent(dev); 766174e6edSMarcel Moolenaar sc = device_get_softc(dev); 776174e6edSMarcel Moolenaar 786174e6edSMarcel Moolenaar if (BUS_READ_IVAR(parent, dev, SCC_IVAR_HWMTX, &mtx)) 796174e6edSMarcel Moolenaar return (ENXIO); 806174e6edSMarcel Moolenaar sc->sc_hwmtx = (struct mtx *)(void *)mtx; 816174e6edSMarcel Moolenaar return (uart_bus_attach(dev)); 826174e6edSMarcel Moolenaar } 836174e6edSMarcel Moolenaar 846174e6edSMarcel Moolenaar static int 856174e6edSMarcel Moolenaar uart_scc_probe(device_t dev) 866174e6edSMarcel Moolenaar { 876174e6edSMarcel Moolenaar device_t parent; 886174e6edSMarcel Moolenaar struct uart_softc *sc; 896174e6edSMarcel Moolenaar uintptr_t ch, cl, md, rs; 906174e6edSMarcel Moolenaar 916174e6edSMarcel Moolenaar parent = device_get_parent(dev); 926174e6edSMarcel Moolenaar sc = device_get_softc(dev); 936174e6edSMarcel Moolenaar 946174e6edSMarcel Moolenaar if (BUS_READ_IVAR(parent, dev, SCC_IVAR_MODE, &md) || 956174e6edSMarcel Moolenaar BUS_READ_IVAR(parent, dev, SCC_IVAR_CLASS, &cl)) 966174e6edSMarcel Moolenaar return (ENXIO); 976174e6edSMarcel Moolenaar if (md != SCC_MODE_ASYNC) 986174e6edSMarcel Moolenaar return (ENXIO); 996174e6edSMarcel Moolenaar switch (cl) { 100e1ef7811SRafal Jaworowski case SCC_CLASS_QUICC: 101e1ef7811SRafal Jaworowski sc->sc_class = &uart_quicc_class; 102e1ef7811SRafal Jaworowski break; 1036174e6edSMarcel Moolenaar case SCC_CLASS_SAB82532: 1046174e6edSMarcel Moolenaar sc->sc_class = &uart_sab82532_class; 1056174e6edSMarcel Moolenaar break; 1066174e6edSMarcel Moolenaar case SCC_CLASS_Z8530: 1076174e6edSMarcel Moolenaar sc->sc_class = &uart_z8530_class; 1086174e6edSMarcel Moolenaar break; 1096174e6edSMarcel Moolenaar default: 1106174e6edSMarcel Moolenaar return (ENXIO); 1116174e6edSMarcel Moolenaar } 1126174e6edSMarcel Moolenaar if (BUS_READ_IVAR(parent, dev, SCC_IVAR_CHANNEL, &ch) || 1136174e6edSMarcel Moolenaar BUS_READ_IVAR(parent, dev, SCC_IVAR_CLOCK, &cl) || 1146174e6edSMarcel Moolenaar BUS_READ_IVAR(parent, dev, SCC_IVAR_REGSHFT, &rs)) 1156174e6edSMarcel Moolenaar return (ENXIO); 1166174e6edSMarcel Moolenaar 117*381388b9SMatt Macy return (uart_bus_probe(dev, rs, 0, cl, 0, ch, 0)); 1186174e6edSMarcel Moolenaar } 1196174e6edSMarcel Moolenaar 1206174e6edSMarcel Moolenaar DRIVER_MODULE(uart, scc, uart_scc_driver, uart_devclass, 0, 0); 121