/*
 * Copyright (c) 2006 Jon Sevy <jsevy@cs.drexel.edu>
 * All rights reserved.
 * 
 * Based on ixp12x0.c
 *
 * Copyright (c) 2002, 2003
 *    Ichiro FUKUHARA <ichiro@ichiro.org>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by Ichiro FUKUHARA.
 * 4. The name of the company nor the name of the author may be used to
 *    endorse or promote products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ixp12x0.c,v 1.13 2004/08/30 15:05:16 drochner Exp $");

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <uvm/uvm.h>

#include <machine/bus.h>

#include <arm/vx115/vx115_reg.h>
#include <arm/vx115/vx115_var.h>

#include <locators.h>


#define DEBUG_APB

#ifdef DEBUG_APB
#define DPRINTF(fmt...)  printf(fmt)
#else
#define DPRINTF(fmt...)  
#endif


static int vx115_apb_match(struct device *parent, struct cfdata *cf, void *aux);
static void vx115_apb_attach(struct device *parent, struct device *self, void *aux);
static int vx115_apb_search(struct device * parent, struct cfdata * cf, void *aux);


CFATTACH_DECL(vx115_apb, sizeof(struct vx115_softc), vx115_apb_match, vx115_apb_attach, NULL, NULL);



static int
vx115_apb_print(void *aux, const char *name)
{
    struct vx115_attach_args *sa = (struct vx115_attach_args *) aux;

    if (sa->sa_size)
        aprint_normal(" addr 0x%lx", sa->sa_addr);
    if (sa->sa_size > 1)
        aprint_normal("-0x%lx", sa->sa_addr + sa->sa_size - 1);
    if (sa->sa_intr != VX115_APBCF_INTR_DEFAULT)
        aprint_normal(" intr %d", sa->sa_intr);
    if (sa->sa_index != VX115_APBCF_INDEX_DEFAULT)
        aprint_normal(" unit %d", sa->sa_index);
    aprint_normal("\n");
    
    return (UNCONF);
}

static int
vx115_apb_match(struct device *parent, struct cfdata *cf, void *aux)
{
    DPRINTF("vx115_apb_match\n");
    
    return (1);
}


void
vx115_apb_attach(struct device *parent, struct device *self, void *aux)
{
    struct vx115_softc *sc = (struct vx115_softc *) self;
    
    DPRINTF("\nvx115_apb_attach\n");
    
    /* assign bus tag: standard vx115 bus ops */
    sc->sc_iot = &vx115_bs_tag;

    /* attach devices */
    config_search(vx115_apb_search, self, NULL);
    
    return;
}


int
vx115_apb_search(struct device * parent, struct cfdata * cf, void *aux)
{
    struct vx115_softc *sc = (struct vx115_softc *) parent;
    struct vx115_attach_args aa;

    DPRINTF("vx115_apb_search\n");
    
    aa.sa_iot   = sc->sc_iot;
    aa.sa_addr  = cf->cf_loc[VX115_APBCF_ADDR];
    aa.sa_size  = cf->cf_loc[VX115_APBCF_SIZE];
    aa.sa_index = cf->cf_loc[VX115_APBCF_INDEX];
    aa.sa_intr  = cf->cf_loc[VX115_APBCF_INTR];

    if (config_match(parent, cf, &aa))
        config_attach(parent, cf, &aa, vx115_apb_print);

    return 0;
}

