19406Sbde/*- 26261Sjkh * cyclades cyclom-y serial driver 36261Sjkh * Andrew Herbert <andrew@werple.apana.org.au>, 17 August 1993 46261Sjkh * 56261Sjkh * Copyright (c) 1993 Andrew Herbert. 66261Sjkh * All rights reserved. 76261Sjkh * 86261Sjkh * Redistribution and use in source and binary forms, with or without 96261Sjkh * modification, are permitted provided that the following conditions 106261Sjkh * are met: 116261Sjkh * 1. Redistributions of source code must retain the above copyright 126261Sjkh * notice, this list of conditions and the following disclaimer. 136261Sjkh * 2. Redistributions in binary form must reproduce the above copyright 146261Sjkh * notice, this list of conditions and the following disclaimer in the 156261Sjkh * documentation and/or other materials provided with the distribution. 166261Sjkh * 3. The name Andrew Herbert may not be used to endorse or promote products 176261Sjkh * derived from this software without specific prior written permission. 186261Sjkh * 196261Sjkh * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY EXPRESS OR IMPLIED 206261Sjkh * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 216261Sjkh * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 226261Sjkh * NO EVENT SHALL I BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 236261Sjkh * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 246261Sjkh * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 256261Sjkh * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 266261Sjkh * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 276261Sjkh * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 286261Sjkh * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 296261Sjkh */ 306261Sjkh 31128804Sbde/* 32128804Sbde * Cyclades Y ISA serial interface driver 33128804Sbde */ 34128804Sbde 35115703Sobrien#include <sys/cdefs.h> 36115703Sobrien__FBSDID("$FreeBSD$"); 37115703Sobrien 386261Sjkh#include <sys/param.h> 396261Sjkh#include <sys/systm.h> 4076166Smarkm#include <sys/bus.h> 416261Sjkh#include <sys/kernel.h> 42129879Sphk#include <sys/module.h> 4376166Smarkm 44127885Sbde#include <machine/bus.h> 45127885Sbde#include <sys/rman.h> 46127885Sbde#include <machine/resource.h> 476261Sjkh 48128800Sbde#include <isa/isavar.h> 496261Sjkh 50128800Sbde#include <dev/cy/cyreg.h> 51128800Sbde#include <dev/cy/cyvar.h> 52128800Sbde 53128804Sbdestatic int cy_isa_attach(device_t dev); 54128804Sbdestatic int cy_isa_probe(device_t dev); 559406Sbde 56127885Sbdestatic device_method_t cy_isa_methods[] = { 57127885Sbde /* Device interface. */ 58127885Sbde DEVMETHOD(device_probe, cy_isa_probe), 59127885Sbde DEVMETHOD(device_attach, cy_isa_attach), 60127885Sbde 61127885Sbde { 0, 0 } 6212962Sbde}; 6312675Sjulian 64127885Sbdestatic driver_t cy_isa_driver = { 65128800Sbde cy_driver_name, 66127885Sbde cy_isa_methods, 67127885Sbde 0, 68127885Sbde}; 69127885Sbde 70127885SbdeDRIVER_MODULE(cy, isa, cy_isa_driver, cy_devclass, 0, 0); 71127885Sbde 729406Sbdestatic int 73127885Sbdecy_isa_probe(device_t dev) 749406Sbde{ 75127885Sbde struct resource *mem_res; 76127885Sbde cy_addr iobase; 77165996Sbde int error, mem_rid; 786261Sjkh 79127885Sbde if (isa_get_logicalid(dev) != 0) /* skip PnP probes */ 80127885Sbde return (ENXIO); 816261Sjkh 82127885Sbde mem_rid = 0; 83127885Sbde mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid, 84127885Sbde 0ul, ~0ul, 0ul, RF_ACTIVE); 85127885Sbde if (mem_res == NULL) { 86127885Sbde device_printf(dev, "ioport resource allocation failed\n"); 87127885Sbde return (ENXIO); 88127885Sbde } 89127885Sbde iobase = rman_get_virtual(mem_res); 90127885Sbde 919406Sbde /* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */ 9241309Sbde cy_inb(iobase, CY16_RESET, 0); /* XXX? */ 93128804Sbde DELAY(500); /* wait for the board to get its act together */ 946261Sjkh 9511424Sdg /* this is needed to get the board out of reset */ 9641309Sbde cy_outb(iobase, CY_CLEAR_INTR, 0, 0); 9711424Sdg DELAY(500); 9811424Sdg 99165996Sbde error = (cy_units(iobase, 0) == 0 ? ENXIO : 0); 100127885Sbde bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); 101165996Sbde return (error); 10218901Sdg} 10318901Sdg 10418901Sdgstatic int 105127885Sbdecy_isa_attach(device_t dev) 1066261Sjkh{ 107127885Sbde struct resource *irq_res, *mem_res; 108127885Sbde void *irq_cookie, *vaddr, *vsc; 109127885Sbde int irq_rid, mem_rid; 1106261Sjkh 111127885Sbde irq_res = NULL; 112127885Sbde mem_res = NULL; 11329047Sbde 114127885Sbde mem_rid = 0; 115127885Sbde mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid, 116127885Sbde 0ul, ~0ul, 0ul, RF_ACTIVE); 117127885Sbde if (mem_res == NULL) { 118127885Sbde device_printf(dev, "memory resource allocation failed\n"); 119127885Sbde goto fail; 12018901Sdg } 121127885Sbde vaddr = rman_get_virtual(mem_res); 122123104Sbde 123127885Sbde vsc = cyattach_common(vaddr, 0); 124127885Sbde if (vsc == NULL) { 125127885Sbde device_printf(dev, "no ports found!\n"); 126127885Sbde goto fail; 127127885Sbde } 128127885Sbde 129127885Sbde irq_rid = 0; 130127885Sbde irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &irq_rid, 0ul, ~0ul, 0ul, 131127885Sbde RF_SHAREABLE | RF_ACTIVE); 132127885Sbde if (irq_res == NULL) { 133127885Sbde device_printf(dev, "interrupt resource allocation failed\n"); 134127885Sbde goto fail; 135127885Sbde } 136166901Spiso if (bus_setup_intr(dev, irq_res, INTR_TYPE_TTY, 137166901Spiso cyintr, NULL, vsc, &irq_cookie) != 0) { 138127885Sbde device_printf(dev, "interrupt setup failed\n"); 139127885Sbde goto fail; 140127885Sbde } 141127885Sbde 142127885Sbde return (0); 143127885Sbde 144127885Sbdefail: 145127885Sbde if (irq_res != NULL) 146127885Sbde bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); 147127885Sbde if (mem_res != NULL) 148127885Sbde bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); 149127885Sbde return (ENXIO); 15018901Sdg} 151