arch/m68k/bvme6000/config.c

Source file repositories/reference/linux-study-clean/arch/m68k/bvme6000/config.c

File Facts

System
Linux kernel
Corpus path
arch/m68k/bvme6000/config.c
Extension
.c
Size
9108 bytes
Lines
323
Domain
Architecture Layer
Bucket
arch/m68k
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!vme_brdtype) {
	if (m68k_cputype == CPU_68060)
	    vme_brdtype = VME_TYPE_BVME6000;
	else
	    vme_brdtype = VME_TYPE_BVME4000;
    }
#if 0
    /* Call bvme6000_set_vectors() so ABORT will work, along with BVMBug
     * debugger.  Note trap_init() will splat the abort vector, but
     * bvme6000_init_IRQ() will put it back again.  Hopefully. */

    bvme6000_set_vectors();
#endif

    mach_sched_init      = bvme6000_sched_init;
    mach_init_IRQ        = bvme6000_init_IRQ;
    mach_hwclk           = bvme6000_hwclk;
    mach_reset		 = bvme6000_reset;
    mach_get_model       = bvme6000_get_model;

    pr_info("Board is %sconfigured as a System Controller\n",
	    *config_reg_ptr & BVME_CONFIG_SW1 ? "" : "not ");

    /* Now do the PIT configuration */

    pit->pgcr	= 0x00;	/* Unidirectional 8 bit, no handshake for now */
    pit->psrr	= 0x18;	/* PIACK and PIRQ functions enabled */
    pit->pacr	= 0x00;	/* Sub Mode 00, H2 i/p, no DMA */
    pit->padr	= 0x00;	/* Just to be tidy! */
    pit->paddr	= 0x00;	/* All inputs for now (safest) */
    pit->pbcr	= 0x80;	/* Sub Mode 1x, H4 i/p, no DMA */
    pit->pbdr	= 0xbc | (*config_reg_ptr & BVME_CONFIG_SW1 ? 0 : 0x40);
			/* PRI, SYSCON?, Level3, SCC clks from xtal */
    pit->pbddr	= 0xf3;	/* Mostly outputs */
    pit->pcdr	= 0x01;	/* PA transceiver disabled */
    pit->pcddr	= 0x03;	/* WDOG disable */

    /* Disable snooping for Ethernet and VME accesses */

    bvme_acr_addrctl = 0;
}


static irqreturn_t bvme6000_abort_int(int irq, void *dev_id)
{
        unsigned long *new = (unsigned long *)vectors;
        unsigned long *old = (unsigned long *)0xf8000000;

        /* Wait for button release */
        while (*(volatile unsigned char *)BVME_LOCAL_IRQ_STAT & BVME_ABORT_STATUS)
                ;

        *(new+4) = *(old+4);            /* Illegal instruction */
        *(new+9) = *(old+9);            /* Trace */
        *(new+47) = *(old+47);          /* Trap #15 */
        *(new+0x1f) = *(old+0x1f);      /* ABORT switch */
	return IRQ_HANDLED;
}

static u64 bvme6000_read_clk(struct clocksource *cs);

static struct clocksource bvme6000_clk = {
	.name   = "rtc",
	.rating = 250,
	.read   = bvme6000_read_clk,
	.mask   = CLOCKSOURCE_MASK(32),
	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
};

static u32 clk_total, clk_offset;

#define RTC_TIMER_CLOCK_FREQ 8000000
#define RTC_TIMER_CYCLES     (RTC_TIMER_CLOCK_FREQ / HZ)
#define RTC_TIMER_COUNT      ((RTC_TIMER_CYCLES / 2) - 1)

static irqreturn_t bvme6000_timer_int (int irq, void *dev_id)
{
    unsigned long flags;
    volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
    unsigned char msr;

    local_irq_save(flags);
    msr = rtc->msr & 0xc0;
    rtc->msr = msr | 0x20;		/* Ack the interrupt */
    clk_total += RTC_TIMER_CYCLES;
    clk_offset = 0;
    legacy_timer_tick(1);
    local_irq_restore(flags);

    return IRQ_HANDLED;

Annotation

Implementation Notes