Example #1
0
/* Retrieve the current date and time from the real time clock. */
static void get_rtc_time(struct rtc_time *t)
{
	void __iomem *regs = mstk48t02_regs;
	u8 tmp;

	spin_lock_irq(&mostek_lock);

	tmp = mostek_read(regs + MOSTEK_CREG);
	tmp |= MSTK_CREG_READ;
	mostek_write(regs + MOSTEK_CREG, tmp);

	t->sec = MSTK_REG_SEC(regs);
	t->min = MSTK_REG_MIN(regs);
	t->hour = MSTK_REG_HOUR(regs);
	t->dow = MSTK_REG_DOW(regs);
	t->dom = MSTK_REG_DOM(regs);
	t->month = MSTK_REG_MONTH(regs);
	t->year = MSTK_CVT_YEAR( MSTK_REG_YEAR(regs) );

	tmp = mostek_read(regs + MOSTEK_CREG);
	tmp &= ~MSTK_CREG_READ;
	mostek_write(regs + MOSTEK_CREG, tmp);

	spin_unlock_irq(&mostek_lock);
}
Example #2
0
/* Retrieve the current date and time from the real time clock. */
void get_rtc_time(struct rtc_time *t)
{
	unsigned long regs = mstk48t02_regs;
	unsigned long flags;
	u8 tmp;

	save_flags(flags);
	cli();

	tmp = mostek_read(regs + MOSTEK_CREG);
	tmp |= MSTK_CREG_READ;
	mostek_write(regs + MOSTEK_CREG, tmp);

	t->sec = MSTK_REG_SEC(regs);
	t->min = MSTK_REG_MIN(regs);
	t->hour = MSTK_REG_HOUR(regs);
	t->dow = MSTK_REG_DOW(regs);
	t->dom = MSTK_REG_DOM(regs);
	t->month = MSTK_REG_MONTH(regs);
	t->year = MSTK_CVT_YEAR( MSTK_REG_YEAR(regs) );

	tmp = mostek_read(regs + MOSTEK_CREG);
	tmp &= ~MSTK_CREG_READ;
	mostek_write(regs + MOSTEK_CREG, tmp);
	restore_flags(flags);
}
Example #3
0
/*
 * BUG: This routine does not handle hour overflow properly; it just
 *      sets the minutes. Usually you won't notice until after reboot!
 */
static int set_rtc_mmss(unsigned long nowtime)
{
	int real_seconds, real_minutes, mostek_minutes;
	struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
	unsigned long flags;
#ifdef CONFIG_SUN4
	struct intersil *iregs = intersil_clock;
	int temp;
#endif

	/* Not having a register set can lead to trouble. */
	if (!regs) {
#ifdef CONFIG_SUN4
		if(!iregs)
		return -1;
	 	else {
			temp = iregs->clk.int_csec;

			mostek_minutes = iregs->clk.int_min;

			real_seconds = nowtime % 60;
			real_minutes = nowtime / 60;
			if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
				real_minutes += 30;	/* correct for half hour time zone */
			real_minutes %= 60;

			if (abs(real_minutes - mostek_minutes) < 30) {
				intersil_stop(iregs);
				iregs->clk.int_sec=real_seconds;
				iregs->clk.int_min=real_minutes;
				intersil_start(iregs);
			} else {
				printk(KERN_WARNING
			       "set_rtc_mmss: can't update from %d to %d\n",
				       mostek_minutes, real_minutes);
				return -1;
			}
			
			return 0;
		}
#endif
	}

	spin_lock_irqsave(&mostek_lock, flags);
	/* Read the current RTC minutes. */
	regs->creg |= MSTK_CREG_READ;
	mostek_minutes = MSTK_REG_MIN(regs);
	regs->creg &= ~MSTK_CREG_READ;

	/*
	 * since we're only adjusting minutes and seconds,
	 * don't interfere with hour overflow. This avoids
	 * messing with unknown time zones but requires your
	 * RTC not to be off by more than 15 minutes
	 */
	real_seconds = nowtime % 60;
	real_minutes = nowtime / 60;
	if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
		real_minutes += 30;	/* correct for half hour time zone */
	real_minutes %= 60;

	if (abs(real_minutes - mostek_minutes) < 30) {
		regs->creg |= MSTK_CREG_WRITE;
		MSTK_SET_REG_SEC(regs,real_seconds);
		MSTK_SET_REG_MIN(regs,real_minutes);
		regs->creg &= ~MSTK_CREG_WRITE;
		spin_unlock_irqrestore(&mostek_lock, flags);
		return 0;
	} else {
		spin_unlock_irqrestore(&mostek_lock, flags);
		return -1;
	}
}
Example #4
0
void __init sbus_time_init(void)
{
	unsigned int year, mon, day, hour, min, sec;
	struct mostek48t02 *mregs;

#ifdef CONFIG_SUN4
	int temp;
	struct intersil *iregs;
#endif

	BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
	btfixup();

	if (ARCH_SUN4)
		sun4_clock_probe();
	else
		clock_probe();

	sparc_init_timers(timer_interrupt);
	
#ifdef CONFIG_SUN4
	if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
#endif
	mregs = (struct mostek48t02 *)mstk48t02_regs;
	if(!mregs) {
		prom_printf("Something wrong, clock regs not mapped yet.\n");
		prom_halt();
	}		
	spin_lock_irq(&mostek_lock);
	mregs->creg |= MSTK_CREG_READ;
	sec = MSTK_REG_SEC(mregs);
	min = MSTK_REG_MIN(mregs);
	hour = MSTK_REG_HOUR(mregs);
	day = MSTK_REG_DOM(mregs);
	mon = MSTK_REG_MONTH(mregs);
	year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
        set_normalized_timespec(&wall_to_monotonic,
                                -xtime.tv_sec, -xtime.tv_nsec);
	mregs->creg &= ~MSTK_CREG_READ;
	spin_unlock_irq(&mostek_lock);
#ifdef CONFIG_SUN4
	} else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) {
		/* initialise the intersil on sun4 */

		iregs=intersil_clock;
		if(!iregs) {
			prom_printf("Something wrong, clock regs not mapped yet.\n");
			prom_halt();
		}

		intersil_intr(intersil_clock,INTERSIL_INT_100HZ);
		disable_pil_irq(10);
		intersil_stop(iregs);
		intersil_read_intr(intersil_clock, temp);

		temp = iregs->clk.int_csec;

		sec = iregs->clk.int_sec;
		min = iregs->clk.int_min;
		hour = iregs->clk.int_hour;
		day = iregs->clk.int_day;
		mon = iregs->clk.int_month;
		year = MSTK_CVT_YEAR(iregs->clk.int_year);

		enable_pil_irq(10);
		intersil_start(iregs);

		xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
	        set_normalized_timespec(&wall_to_monotonic,
 	                               -xtime.tv_sec, -xtime.tv_nsec);
		printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
	}
#endif

	/* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
	local_irq_enable();
}