Ejemplo n.º 1
0
void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
{
	struct mm_struct *mm = vma->vm_mm;
	int page_id = mm->context.page_id;
	int i;
	unsigned long flags;

	D(printk("tlb: flush page %p in context %d (%p)\n", addr, page_id, mm));

	if(page_id == NO_CONTEXT)
		return;

	addr &= PAGE_MASK; 


	local_irq_save(flags);
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		unsigned long tlb_hi;
		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
		tlb_hi = *R_TLB_HI;
		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
		    (tlb_hi & PAGE_MASK) == addr) {
			*R_TLB_HI = IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
				addr; 

			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
				      IO_STATE(R_TLB_LO, valid, no  ) |
				      IO_STATE(R_TLB_LO, kernel,no  ) |
				      IO_STATE(R_TLB_LO, we,    no  ) |
				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
		}
	}
	local_irq_restore(flags);
}
Ejemplo n.º 2
0
static int __init
i2c_init(void)
{
	int res;

	/* Setup and enable the Port B I2C interface */

#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
	*R_PORT_PB_I2C = port_pb_i2c_shadow |= 
		IO_STATE(R_PORT_PB_I2C, i2c_en,  on) |
		IO_FIELD(R_PORT_PB_I2C, i2c_d,   1)  |
		IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1)  |
		IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);
#endif

	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);
	port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);

	*R_PORT_PB_DIR = (port_pb_dir_shadow |=
			  IO_STATE(R_PORT_PB_DIR, dir0, input)  |
			  IO_STATE(R_PORT_PB_DIR, dir1, output));

	/* register char device */

	res = register_chrdev(I2C_MAJOR, i2c_name, &i2c_fops);
	if(res < 0) {
		printk(KERN_ERR "i2c: couldn't get a major number.\n");
		return res;
	}

	printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
	
	return 0;
}
Ejemplo n.º 3
0
int __init
ds1302_init(void) 
{ 
	if (!ds1302_probe()) {
#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
#if CONFIG_ETRAX_DS1302_RSTBIT == 27
		/*
		 * The only way to set g27 to output is to enable ATA.
		 *
		 * Make sure that R_GEN_CONFIG is setup correct.
		 */
    		genconfig_shadow = ((genconfig_shadow &
				     ~IO_MASK(R_GEN_CONFIG, ata)) | 
				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
    		*R_GEN_CONFIG = genconfig_shadow;
#elif CONFIG_ETRAX_DS1302_RSTBIT == 0
		
		/* Set the direction of this bit to out. */		
    		genconfig_shadow = ((genconfig_shadow &
				     ~IO_MASK(R_GEN_CONFIG, g0dir)) | 
				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));    
    		*R_GEN_CONFIG = genconfig_shadow;
#endif
		if (!ds1302_probe())
      			return -1;
#else
    		return -1;
#endif
  	}
  
	/* Initialise trickle charger */
	ds1302_writereg(RTC_TRICKLECHARGER,
			RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
	return 0;
}
Ejemplo n.º 4
0
void
flush_tlb_all(void)
{
	int i;
	unsigned long flags;

	/* the vpn of i & 0xf is so we dont write similar TLB entries
	 * in the same 4-way entry group. details.. 
	 */

	save_and_cli(flags); /* flush needs to be atomic */
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
		*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
			      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
		
		*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no       ) |
			      IO_STATE(R_TLB_LO, valid, no       ) |
			      IO_STATE(R_TLB_LO, kernel,no	 ) |
			      IO_STATE(R_TLB_LO, we,    no       ) |
			      IO_FIELD(R_TLB_LO, pfn,   0        ) );
	}
	restore_flags(flags);
	D(printk("tlb: flushed all\n"));
}
Ejemplo n.º 5
0
void
flush_tlb_mm(struct mm_struct *mm)
{
	int i;
	int page_id = mm->context;
	unsigned long flags;

	D(printk("tlb: flush mm context %d (%p)\n", page_id, mm));

	if(page_id == NO_CONTEXT)
		return;
	
	/* mark the TLB entries that match the page_id as invalid.
	 * here we could also check the _PAGE_GLOBAL bit and NOT flush
	 * global pages. is it worth the extra I/O ? 
	 */

	save_and_cli(flags);  /* flush needs to be atomic */
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
		if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) {
			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
			
			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
				      IO_STATE(R_TLB_LO, valid, no  ) |
				      IO_STATE(R_TLB_LO, kernel,no  ) |
				      IO_STATE(R_TLB_LO, we,    no  ) |
				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
		}
	}
	restore_flags(flags);
}
Ejemplo n.º 6
0
void
flush_tlb_mm(struct mm_struct *mm)
{
	int i;
	int page_id = mm->context.page_id;
	unsigned long flags;

	D(printk("tlb: flush mm context %d (%p)\n", page_id, mm));

	if(page_id == NO_CONTEXT)
		return;


	local_irq_save(flags);
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
		if (IO_EXTRACT(R_TLB_HI, page_id, *R_TLB_HI) == page_id) {
			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );

			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
				      IO_STATE(R_TLB_LO, valid, no  ) |
				      IO_STATE(R_TLB_LO, kernel,no  ) |
				      IO_STATE(R_TLB_LO, we,    no  ) |
				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
		}
	}
	local_irq_restore(flags);
}
Ejemplo n.º 7
0
void *dma_memcpy(void *pdst,
         const void *psrc,
         unsigned int pn)
{
    static etrax_dma_descr indma, outdma;
    
    D(printk("dma_memcpy %d bytes... ", pn));

#if 0
    *R_GEN_CONFIG = genconfig_shadow = 
        (genconfig_shadow & ~0x3c0000) |
        IO_STATE(R_GEN_CONFIG, dma6, intdma7) |
        IO_STATE(R_GEN_CONFIG, dma7, intdma6);
#endif
    indma.sw_len = outdma.sw_len = pn;
    indma.ctrl = d_eol | d_eop;
    outdma.ctrl = d_eol;
    indma.buf = psrc;
    outdma.buf = pdst;

    *R_DMA_CH6_FIRST = &indma;
    *R_DMA_CH7_FIRST = &outdma;
    *R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
    *R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);
    
    while(*R_DMA_CH7_CMD == 1) /* wait for completion */ ;

    D(printk("done\n"));

}
Ejemplo n.º 8
0
void
enableDebugIRQ(void)
{
	*R_IRQ_MASK1_SET = port->irq;
	/* use R_VECT_MASK directly, since we really bypass Linux normal
	 * IRQ handling in kgdb anyway, we don't need to use enable_irq
	 */
	*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);

	*port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
}
Ejemplo n.º 9
0
int __init
i2c_init(void)
{
    static int res = 0;
    static int first = 1;

    if (!first) {
        return res;
    }
    first = 0;

    /* Setup and enable the Port B I2C interface */

#ifndef CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
    if ((res = cris_request_io_interface(if_i2c, "I2C"))) {
        printk(KERN_CRIT "i2c_init: Failed to get IO interface\n");
        return res;
    }

    *R_PORT_PB_I2C = port_pb_i2c_shadow |=
                         IO_STATE(R_PORT_PB_I2C, i2c_en,  on) |
                         IO_FIELD(R_PORT_PB_I2C, i2c_d,   1)  |
                         IO_FIELD(R_PORT_PB_I2C, i2c_clk, 1)  |
                         IO_STATE(R_PORT_PB_I2C, i2c_oe_, enable);

    port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir0);
    port_pb_dir_shadow &= ~IO_MASK(R_PORT_PB_DIR, dir1);

    *R_PORT_PB_DIR = (port_pb_dir_shadow |=
                          IO_STATE(R_PORT_PB_DIR, dir0, input)  |
                          IO_STATE(R_PORT_PB_DIR, dir1, output));
#else
    if ((res = cris_io_interface_allocate_pins(if_i2c,
               'b',
               CONFIG_ETRAX_I2C_DATA_PORT,
               CONFIG_ETRAX_I2C_DATA_PORT))) {
        printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C data port\n");
        return res;
    } else if ((res = cris_io_interface_allocate_pins(if_i2c,
                      'b',
                      CONFIG_ETRAX_I2C_CLK_PORT,
                      CONFIG_ETRAX_I2C_CLK_PORT))) {
        cris_io_interface_free_pins(if_i2c,
                                    'b',
                                    CONFIG_ETRAX_I2C_DATA_PORT,
                                    CONFIG_ETRAX_I2C_DATA_PORT);
        printk(KERN_WARNING "i2c_init: Failed to get IO pin for I2C clk port\n");
    }
#endif

    return res;
}
Ejemplo n.º 10
0
void
enableDebugIRQ(void)
{
	if (!kgdb_port)
		return;

	*R_IRQ_MASK1_SET = kgdb_port->irq;
	/*                                                              
                                                                
  */
	*R_VECT_MASK_SET = IO_STATE(R_VECT_MASK_SET, serial, set);

	*kgdb_port->rec_ctrl = IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
}
Ejemplo n.º 11
0
int __init
ds1302_init(void) 
{
#ifdef CONFIG_ETRAX_I2C
	i2c_init();
#endif

	if (!ds1302_probe()) {
#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
#if CONFIG_ETRAX_DS1302_RSTBIT == 27
		/*
		 * The only way to set g27 to output is to enable ATA.
		 *
		 * Make sure that R_GEN_CONFIG is setup correct.
		 */
		/* Allocating the ATA interface will grab almost all
		 * pins in I/O groups a, b, c and d.  A consequence of
		 * allocating the ATA interface is that the fixed
		 * interfaces shared RAM, parallel port 0, parallel
		 * port 1, parallel port W, SCSI-8 port 0, SCSI-8 port
		 * 1, SCSI-W, serial port 2, serial port 3,
		 * synchronous serial port 3 and USB port 2 and almost
		 * all GPIO pins on port g cannot be used.
		 */
		if (cris_request_io_interface(if_ata, "ds1302/ATA")) {
			printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
			return -1;
		}

#elif CONFIG_ETRAX_DS1302_RSTBIT == 0
		if (cris_io_interface_allocate_pins(if_gpio_grp_a,
						    'g',
						    CONFIG_ETRAX_DS1302_RSTBIT,
						    CONFIG_ETRAX_DS1302_RSTBIT)) {
			printk(KERN_WARNING "ds1302: Failed to get IO interface\n");
			return -1;
		}

		/* Set the direction of this bit to out. */
		genconfig_shadow = ((genconfig_shadow &
 				     ~IO_MASK(R_GEN_CONFIG, g0dir)) |
 				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));
		*R_GEN_CONFIG = genconfig_shadow;
#endif
		if (!ds1302_probe()) {
			printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
			return -1;
		}
#else
		printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
		return -1;
#endif
  	}
	/* Initialise trickle charger */
	ds1302_writereg(RTC_TRICKLECHARGER,
			RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
        /* Start clock by resetting CLOCK_HALT */
	ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
	return 0;
}
Ejemplo n.º 12
0
void hard_reset_now (void)
{
    /*
     * Don't declare this variable elsewhere.  We don't want any other
     * code to know about it than the watchdog handler in entry.S and
     * this code, implementing hard reset through the watchdog.
     */
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
    extern int cause_of_death;
#endif

    printk("*** HARD RESET ***\n");
    local_irq_disable();

#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
    cause_of_death = 0xbedead;
#else
    /* Since we dont plan to keep on resetting the watchdog,
       the key can be arbitrary hence three */
    *R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
                  IO_STATE(R_WATCHDOG, enable, start);
#endif

    while(1) /* waiting for RETRIBUTION! */ ;
}
Ejemplo n.º 13
0
int __init
ds1302_init(void) 
{ 
	if (!ds1302_probe()) {
#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
		/*
		 * The only way to set g27 to output is to enable ATA.
		 *
		 * Make sure that R_GEN_CONFIG is setup correct.
		 */
    		genconfig_shadow = ((genconfig_shadow &
				     ~IO_MASK(R_GEN_CONFIG, ata))
				   | 
				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
    		*R_GEN_CONFIG = genconfig_shadow;
    		if (!ds1302_probe())
      			return -1;
#else
    		return -1;
#endif
  	}
  
	if (register_chrdev(RTC_MAJOR_NR, ds1302_name, &rtc_fops)) {
		printk(KERN_INFO "%s: unable to get major %d for rtc\n", 
		       ds1302_name, RTC_MAJOR_NR);
		return -1;
	}
	return 0;
}
Ejemplo n.º 14
0
/* Internal methods */
static PyObject *
iobase_unsupported(const char *message)
{
    _PyIO_State *state = IO_STATE();
    if (state != NULL)
        PyErr_SetString(state->unsupported_operation, message);
    return NULL;
}
Ejemplo n.º 15
0
/* Handle multiple IRQs */
void do_multiple_IRQ(struct pt_regs* regs)
{
	int bit;
	unsigned masked;
	unsigned mask;
	unsigned ethmask = 0;

	/* Get interrupts to mask and handle */
	mask = masked = *R_VECT_MASK_RD;

	/* Never mask timer IRQ */
	mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));

	/*
	 * If either ethernet interrupt (rx or tx) is active then block
	 * the other one too. Unblock afterwards also.
	 */
	if (mask &
	    (IO_STATE(R_VECT_MASK_RD, dma0, active) |
	     IO_STATE(R_VECT_MASK_RD, dma1, active))) {
		ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
			   IO_MASK(R_VECT_MASK_RD, dma1));
	}

	/* Block them */
	*R_VECT_MASK_CLR = (mask | ethmask);

	/* An extra irq_enter here to prevent softIRQs to run after
	 * each do_IRQ. This will decrease the interrupt latency.
	 */
	irq_enter();

	/* Handle all IRQs */
	for (bit = 2; bit < 32; bit++) {
		if (masked & (1 << bit)) {
			do_IRQ(bit, regs);
		}
	}

	/* This irq_exit() will trigger the soft IRQs. */
	irq_exit();

	/* Unblock the IRQs again */
	*R_VECT_MASK_SET = (masked | ethmask);
}
Ejemplo n.º 16
0
void do_multiple_IRQ(struct pt_regs* regs)
{
	int bit;
	unsigned masked;
	unsigned mask;
	unsigned ethmask = 0;

	/*                                   */
	mask = masked = *R_VECT_MASK_RD;

	/*                      */
	mask &= ~(IO_MASK(R_VECT_MASK_RD, timer0));

	/*
                                                                
                                               
  */
	if (mask &
	    (IO_STATE(R_VECT_MASK_RD, dma0, active) |
	     IO_STATE(R_VECT_MASK_RD, dma1, active))) {
		ethmask = (IO_MASK(R_VECT_MASK_RD, dma0) |
			   IO_MASK(R_VECT_MASK_RD, dma1));
	}

	/*            */
	*R_VECT_MASK_CLR = (mask | ethmask);

	/*                                                         
                                                          
  */
	irq_enter();

	/*                 */
	for (bit = 2; bit < 32; bit++) {
		if (masked & (1 << bit)) {
			do_IRQ(bit, regs);
		}
	}

	/*                                             */
	irq_exit();

	/*                        */
	*R_VECT_MASK_SET = (masked | ethmask);
}
Ejemplo n.º 17
0
static inline irqreturn_t
timer_interrupt(int irq, void *dev_id)
{
	struct pt_regs *regs = get_irq_regs();
	/* acknowledge the timer irq */

#ifdef USE_CASCADE_TIMERS
	*R_TIMER_CTRL =
		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
		IO_STATE( R_TIMER_CTRL, i1, clr) |
		IO_STATE( R_TIMER_CTRL, tm1, run) |
		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
		IO_STATE( R_TIMER_CTRL, i0, clr) |
		IO_STATE( R_TIMER_CTRL, tm0, run) |
		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
#else
	*R_TIMER_CTRL = r_timer_ctrl_shadow |
		IO_STATE(R_TIMER_CTRL, i0, clr);
#endif

	/* reset watchdog otherwise it resets us! */
	reset_watchdog();

	/* Update statistics. */
	update_process_times(user_mode(regs));

	/* call the real timer interrupt handler */

	do_timer(1);

        cris_do_profile(regs); /* Save profiling information */
        return IRQ_HANDLED;
}
Ejemplo n.º 18
0
void
stop_watchdog(void)
{
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
	watchdog_key ^= 0x7; /* invert key, which is 3 bits */
	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
		IO_STATE(R_WATCHDOG, enable, stop);
#endif
}
Ejemplo n.º 19
0
void
flush_tlb_range(struct mm_struct *mm, 
		unsigned long start,
		unsigned long end)
{
	int page_id = mm->context;
	int i;
	unsigned long flags;

	D(printk("tlb: flush range %p<->%p in context %d (%p)\n",
		 start, end, page_id, mm));

	if(page_id == NO_CONTEXT)
		return;

	start &= PAGE_MASK;  /* probably not necessary */
	end &= PAGE_MASK;    /* dito */

	/* invalidate those TLB entries that match both the mm context
	 * and the virtual address range
	 */

	save_and_cli(flags);  /* flush needs to be atomic */
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		unsigned long tlb_hi, vpn;
		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
		tlb_hi = *R_TLB_HI;
		vpn = tlb_hi & PAGE_MASK;
		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
		    vpn >= start && vpn < end) {
			*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
				      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );
			
			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
				      IO_STATE(R_TLB_LO, valid, no  ) |
				      IO_STATE(R_TLB_LO, kernel,no  ) |
				      IO_STATE(R_TLB_LO, we,    no  ) |
				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
		}
	}
	restore_flags(flags);
}
Ejemplo n.º 20
0
void handle_nmi(struct pt_regs *regs)
{
	if (nmi_handler)
		nmi_handler(regs);

	/* Wait until nmi is no longer active. (We enable NMI immediately after
	   returning from this function, and we don't want it happening while
	   exiting from the NMI interrupt handler.) */
	while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active))
		;
}
Ejemplo n.º 21
0
int __init
ds1302_init(void) 
{
	i2c_init();

	if (!ds1302_probe()) {
#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
#if CONFIG_ETRAX_DS1302_RSTBIT == 27
		/*
		 * The only way to set g27 to output is to enable ATA.
		 *
		 * Make sure that R_GEN_CONFIG is setup correct.
		 */
    		genconfig_shadow = ((genconfig_shadow &
				     ~IO_MASK(R_GEN_CONFIG, ata)) | 
				   (IO_STATE(R_GEN_CONFIG, ata, select)));    
    		*R_GEN_CONFIG = genconfig_shadow;
#elif CONFIG_ETRAX_DS1302_RSTBIT == 0
		
		/* Set the direction of this bit to out. */		
    		genconfig_shadow = ((genconfig_shadow &
				     ~IO_MASK(R_GEN_CONFIG, g0dir)) | 
				   (IO_STATE(R_GEN_CONFIG, g0dir, out)));    
    		*R_GEN_CONFIG = genconfig_shadow;
#endif
		if (!ds1302_probe()) {
			printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
      			return -1;
		}
#else
		printk(KERN_WARNING "%s: RTC not found.\n", ds1302_name);
    		return -1;
#endif
  	}
	/* Initialise trickle charger */
	ds1302_writereg(RTC_TRICKLECHARGER,
			RTC_TCR_PATTERN |(CONFIG_ETRAX_DS1302_TRICKLE_CHARGE & 0x0F));
        /* Start clock by resetting CLOCK_HALT */
	ds1302_writereg(RTC_SECONDS, (ds1302_readreg(RTC_SECONDS) & 0x7F));
	return 0;
}
Ejemplo n.º 22
0
void
flush_tlb_all(void)
{
	int i;
	unsigned long flags;


	local_irq_save(flags);
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		*R_TLB_SELECT = ( IO_FIELD(R_TLB_SELECT, index, i) );
		*R_TLB_HI = ( IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
			      IO_FIELD(R_TLB_HI, vpn,     i & 0xf ) );

		*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no       ) |
			      IO_STATE(R_TLB_LO, valid, no       ) |
			      IO_STATE(R_TLB_LO, kernel,no	 ) |
			      IO_STATE(R_TLB_LO, we,    no       ) |
			      IO_FIELD(R_TLB_LO, pfn,   0        ) );
	}
	local_irq_restore(flags);
	D(printk("tlb: flushed all\n"));
}
Ejemplo n.º 23
0
void
flush_tlb_page(struct vm_area_struct *vma, 
	       unsigned long addr)
{
	struct mm_struct *mm = vma->vm_mm;
	int page_id = mm->context;
	int i;
	unsigned long flags;

	D(printk("tlb: flush page %p in context %d (%p)\n", addr, page_id, mm));

	if(page_id == NO_CONTEXT)
		return;

	addr &= PAGE_MASK; /* perhaps not necessary */

	/* invalidate those TLB entries that match both the mm context
	 * and the virtual address requested 
	 */

	save_and_cli(flags);  /* flush needs to be atomic */
	for(i = 0; i < NUM_TLB_ENTRIES; i++) {
		unsigned long tlb_hi;
		*R_TLB_SELECT = IO_FIELD(R_TLB_SELECT, index, i);
		tlb_hi = *R_TLB_HI;
		if (IO_EXTRACT(R_TLB_HI, page_id, tlb_hi) == page_id &&
		    (tlb_hi & PAGE_MASK) == addr) {
			*R_TLB_HI = IO_FIELD(R_TLB_HI, page_id, INVALID_PAGEID ) |
				addr; /* same addr as before works. */
			
			*R_TLB_LO = ( IO_STATE(R_TLB_LO, global,no  ) |
				      IO_STATE(R_TLB_LO, valid, no  ) |
				      IO_STATE(R_TLB_LO, kernel,no  ) |
				      IO_STATE(R_TLB_LO, we,    no  ) |
				      IO_FIELD(R_TLB_LO, pfn,   0   ) );
		}
	}
	restore_flags(flags);
}
Ejemplo n.º 24
0
void
reset_watchdog(void)
{
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
	/* only keep watchdog happy as long as we have memory left! */
	if(nr_free_pages() > WATCHDOG_MIN_FREE_PAGES) {
		/* reset the watchdog with the inverse of the old key */
		watchdog_key ^= 0x7; /* invert key, which is 3 bits */
		*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, watchdog_key) |
			IO_STATE(R_WATCHDOG, enable, start);
	}
#endif
}
Ejemplo n.º 25
0
static inline irqreturn_t
timer_interrupt(int irq, void *dev_id)
{
	struct pt_regs *regs = get_irq_regs();
	/* acknowledge the timer irq */

#ifdef USE_CASCADE_TIMERS
	*R_TIMER_CTRL =
		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
		IO_STATE( R_TIMER_CTRL, i1, clr) |
		IO_STATE( R_TIMER_CTRL, tm1, run) |
		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
		IO_STATE( R_TIMER_CTRL, i0, clr) |
		IO_STATE( R_TIMER_CTRL, tm0, run) |
		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
#else
	*R_TIMER_CTRL = r_timer_ctrl_shadow | 
		IO_STATE(R_TIMER_CTRL, i0, clr);
#endif

	/* reset watchdog otherwise it resets us! */
	reset_watchdog();
	
	/* Update statistics. */
	update_process_times(user_mode(regs));

	/* call the real timer interrupt handler */

	do_timer(1);
	
        cris_do_profile(regs); /* Save profiling information */

	/*
	 * If we have an externally synchronized Linux clock, then update
	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
	 * called as close as possible to 500 ms before the new second starts.
	 *
	 * The division here is not time critical since it will run once in 
	 * 11 minutes
	 */
	if (ntp_synced() &&
	    xtime.tv_sec > last_rtc_update + 660 &&
	    (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 &&
	    (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) {
		if (set_rtc_mmss(xtime.tv_sec) == 0)
			last_rtc_update = xtime.tv_sec;
		else
			last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
	}
        return IRQ_HANDLED;
}
Ejemplo n.º 26
0
void *dma_memcpy(void *pdst,
		 const void *psrc,
		 unsigned int pn)
{
	static etrax_dma_descr indma, outdma;

	D(printk(KERN_DEBUG "dma_memcpy %d bytes... ", pn));

	indma.sw_len = outdma.sw_len = pn;
	indma.ctrl = d_eol | d_eop;
	outdma.ctrl = d_eol;
	indma.buf = psrc;
	outdma.buf = pdst;

	*R_DMA_CH6_FIRST = &indma;
	*R_DMA_CH7_FIRST = &outdma;
	*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, start);
	*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, start);

	while (*R_DMA_CH7_CMD == 1)
		/* wait for completion */;

	D(printk(KERN_DEBUG "done\n"));
}
Ejemplo n.º 27
0
void __init
init_etrax_debug(void)
{
#if CONFIG_ETRAX_DEBUG_PORT_NULL
    return;
#endif

#if DEBUG_PORT_IDX == 0
    genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma6);
    genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma6, unused);
#elif DEBUG_PORT_IDX == 1
    genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma8);
    genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma8, usb);
#elif DEBUG_PORT_IDX == 2
    genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma2);
    genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma2, par0);
#elif DEBUG_PORT_IDX == 3
    genconfig_shadow &=  ~IO_MASK(R_GEN_CONFIG, dma4);
    genconfig_shadow |= IO_STATE(R_GEN_CONFIG, dma4, par1);
#endif
    *R_GEN_CONFIG = genconfig_shadow;

    register_console(&sercons);
}
Ejemplo n.º 28
0
void hard_reset_now (void)
{
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
	extern int cause_of_death;
#endif

	printk("*** HARD RESET ***\n");
	local_irq_disable();

#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
	cause_of_death = 0xbedead;
#else
	*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
		IO_STATE(R_WATCHDOG, enable, start);
#endif

	while(1)  ;
}
Ejemplo n.º 29
0
void __init
time_init(void)
{
	/* probe for the RTC and read it if it exists
	 * Before the RTC can be probed the loops_per_usec variable needs
	 * to be initialized to make usleep work. A better value for
	 * loops_per_usec is calculated by the kernel later once the
	 * clock has started.
	 */
	loops_per_usec = 50;

	if(RTC_INIT() < 0)
		have_rtc = 0;
	else
		have_rtc = 1;

	/* Setup the etrax timers
	 * Base frequency is 25000 hz, divider 250 -> 100 HZ
	 * In normal mode, we use timer0, so timer1 is free. In cascade
	 * mode (which we sometimes use for debugging) both timers are used.
	 * Remember that linux/timex.h contains #defines that rely on the
	 * timer settings below (hz and divide factor) !!!
	 */

#ifdef USE_CASCADE_TIMERS
	*R_TIMER_CTRL =
		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
		IO_STATE( R_TIMER_CTRL, i1, nop) |
		IO_STATE( R_TIMER_CTRL, tm1, stop_ld) |
		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
		IO_STATE( R_TIMER_CTRL, i0, nop) |
		IO_STATE( R_TIMER_CTRL, tm0, stop_ld) |
		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);

	*R_TIMER_CTRL = r_timer_ctrl_shadow =
		IO_FIELD( R_TIMER_CTRL, timerdiv1, 0) |
		IO_FIELD( R_TIMER_CTRL, timerdiv0, 0) |
		IO_STATE( R_TIMER_CTRL, i1, nop) |
		IO_STATE( R_TIMER_CTRL, tm1, run) |
		IO_STATE( R_TIMER_CTRL, clksel1, cascade0) |
		IO_STATE( R_TIMER_CTRL, i0, nop) |
		IO_STATE( R_TIMER_CTRL, tm0, run) |
		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
#else
	*R_TIMER_CTRL =
		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      |
		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
		IO_STATE(R_TIMER_CTRL, i1,        nop)      |
		IO_STATE(R_TIMER_CTRL, tm1,       stop_ld)  |
		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
		IO_STATE(R_TIMER_CTRL, tm0,       stop_ld)  |
		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);

	*R_TIMER_CTRL = r_timer_ctrl_shadow =
		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      |
		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
		IO_STATE(R_TIMER_CTRL, i1,        nop)      |
		IO_STATE(R_TIMER_CTRL, tm1,       run)      |
		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
		IO_STATE(R_TIMER_CTRL, tm0,       run)      |
		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);

	*R_TIMER_PRESCALE = PRESCALE_VALUE;
#endif

	*R_IRQ_MASK0_SET =
		IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */

	/* now actually register the timer irq handler that calls timer_interrupt() */

	setup_irq(2, &irq2); /* irq 2 is the timer0 irq in etrax */

	/* enable watchdog if we should use one */

#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
	printk("Enabling watchdog...\n");
	start_watchdog();

	/* If we use the hardware watchdog, we want to trap it as an NMI
	   and dump registers before it resets us.  For this to happen, we
	   must set the "m" NMI enable flag (which once set, is unset only
	   when an NMI is taken).

	   The same goes for the external NMI, but that doesn't have any
	   driver or infrastructure support yet.  */
	asm ("setf m");

	*R_IRQ_MASK0_SET =
		IO_STATE(R_IRQ_MASK0_SET, watchdog_nmi, set);
	*R_VECT_MASK_SET =
		IO_STATE(R_VECT_MASK_SET, nmi, set);
#endif
}
Ejemplo n.º 30
0
Archivo: dma.c Proyecto: 1x23/unifi-gpl
void cris_free_dma(unsigned int dmanr, const char * device_id)
{
	unsigned long flags;
	if ((dmanr < 0) || (dmanr >= MAX_DMA_CHANNELS)) {
		printk(KERN_CRIT "cris_free_dma: invalid DMA channel %u\n", dmanr);
		return;
	}

	local_irq_save(flags);
	if (!used_dma_channels[dmanr]) {
		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated\n", dmanr);
	} else if (device_id != used_dma_channels_users[dmanr]) {
		printk(KERN_CRIT "cris_free_dma: DMA channel %u not allocated by device\n", dmanr);
	} else {
		switch(dmanr)
		{
		case 0:
			*R_DMA_CH0_CMD = IO_STATE(R_DMA_CH0_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH0_CMD, cmd, *R_DMA_CH0_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH0_CMD, cmd, reset));
			break;
		case 1:
			*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH1_CMD, cmd, *R_DMA_CH1_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH1_CMD, cmd, reset));
			break;
		case 2:
			*R_DMA_CH2_CMD = IO_STATE(R_DMA_CH2_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH2_CMD, cmd, *R_DMA_CH2_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH2_CMD, cmd, reset));
			break;
		case 3:
			*R_DMA_CH3_CMD = IO_STATE(R_DMA_CH3_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH3_CMD, cmd, *R_DMA_CH3_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH3_CMD, cmd, reset));
			break;
		case 4:
			*R_DMA_CH4_CMD = IO_STATE(R_DMA_CH4_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH4_CMD, cmd, *R_DMA_CH4_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH4_CMD, cmd, reset));
			break;
		case 5:
			*R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH5_CMD, cmd, *R_DMA_CH5_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH5_CMD, cmd, reset));
			break;
		case 6:
			*R_DMA_CH6_CMD = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH6_CMD, cmd, *R_DMA_CH6_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
			break;
		case 7:
			*R_DMA_CH7_CMD = IO_STATE(R_DMA_CH7_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH7_CMD, cmd, *R_DMA_CH7_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH7_CMD, cmd, reset));
			break;
		case 8:
			*R_DMA_CH8_CMD = IO_STATE(R_DMA_CH8_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH8_CMD, cmd, *R_DMA_CH8_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH8_CMD, cmd, reset));
			break;
		case 9:
			*R_DMA_CH9_CMD = IO_STATE(R_DMA_CH9_CMD, cmd, reset);
			while (IO_EXTRACT(R_DMA_CH9_CMD, cmd, *R_DMA_CH9_CMD) ==
			       IO_STATE_VALUE(R_DMA_CH9_CMD, cmd, reset));
			break;
		}
		used_dma_channels[dmanr] = 0;
	}
	local_irq_restore(flags);
}