config.c

来自「linux 内核源代码」· C语言 代码 · 共 355 行

C
355
字号
/* *  arch/m68k/q40/config.c * *  Copyright (C) 1999 Richard Zidlicky * * originally based on: * *  linux/bvme/config.c * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file README.legal in the main directory of this archive * for more details. */#include <linux/types.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/console.h>#include <linux/linkage.h>#include <linux/init.h>#include <linux/major.h>#include <linux/serial_reg.h>#include <linux/rtc.h>#include <linux/vt_kern.h>#include <asm/io.h>#include <asm/rtc.h>#include <asm/bootinfo.h>#include <asm/system.h>#include <asm/pgtable.h>#include <asm/setup.h>#include <asm/irq.h>#include <asm/traps.h>#include <asm/machdep.h>#include <asm/q40_master.h>extern irqreturn_t q40_process_int(int level, struct pt_regs *regs);extern void q40_init_IRQ(void);static void q40_get_model(char *model);static int  q40_get_hardware_list(char *buffer);extern void q40_sched_init(irq_handler_t handler);extern unsigned long q40_gettimeoffset(void);extern int q40_hwclk(int, struct rtc_time *);extern unsigned int q40_get_ss(void);extern int q40_set_clock_mmss(unsigned long);static int q40_get_rtc_pll(struct rtc_pll_info *pll);static int q40_set_rtc_pll(struct rtc_pll_info *pll);extern void q40_reset(void);void q40_halt(void);extern void q40_waitbut(void);void q40_set_vectors(void);extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/);static void q40_mem_console_write(struct console *co, const char *b,				  unsigned int count);extern int ql_ticks;static struct console q40_console_driver = {	.name	= "debug",	.write	= q40_mem_console_write,	.flags	= CON_PRINTBUFFER,	.index	= -1,};/* early debugging function:*/extern char *q40_mem_cptr; /*=(char *)0xff020000;*/static int _cpleft;static void q40_mem_console_write(struct console *co, const char *s,				  unsigned int count){	const char *p = s;	if (count < _cpleft) {		while (count-- > 0) {			*q40_mem_cptr = *p++;			q40_mem_cptr += 4;			_cpleft--;		}	}}static int __init q40_debug_setup(char *arg){	/* useful for early debugging stages - writes kernel messages into SRAM */	if (MACH_IS_Q40 && !strncmp(arg, "mem", 3)) {		/*printk("using NVRAM debug, q40_mem_cptr=%p\n",q40_mem_cptr);*/		_cpleft = 2000 - ((long)q40_mem_cptr-0xff020000) / 4;		register_console(&q40_console_driver);	}	return 0;}early_param("debug", q40_debug_setup);#if 0void printq40(char *str){	int l = strlen(str);	char *p = q40_mem_cptr;	while (l-- > 0 && _cpleft-- > 0) {		*p = *str++;		p += 4;	}	q40_mem_cptr = p;}#endifstatic int halted;#ifdef CONFIG_HEARTBEATstatic void q40_heartbeat(int on){	if (halted)		return;	if (on)		Q40_LED_ON();	else		Q40_LED_OFF();}#endifvoid q40_reset(void){        halted = 1;        printk("\n\n*******************************************\n"		"Called q40_reset : press the RESET button!! \n"		"*******************************************\n");	Q40_LED_ON();	while (1)		;}void q40_halt(void){        halted = 1;        printk("\n\n*******************\n"		   "  Called q40_halt\n"		   "*******************\n");	Q40_LED_ON();	while (1)		;}static void q40_get_model(char *model){	sprintf(model, "Q40");}/* No hardware options on Q40? */static int q40_get_hardware_list(char *buffer){	*buffer = '\0';	return 0;}static unsigned int serports[] ={	0x3f8,0x2f8,0x3e8,0x2e8,0};void q40_disable_irqs(void){	unsigned i, j;	j = 0;	while ((i = serports[j++]))		outb(0, i + UART_IER);	master_outb(0, EXT_ENABLE_REG);	master_outb(0, KEY_IRQ_ENABLE_REG);}void __init config_q40(void){	mach_sched_init = q40_sched_init;	mach_init_IRQ = q40_init_IRQ;	mach_gettimeoffset = q40_gettimeoffset;	mach_hwclk = q40_hwclk;	mach_get_ss = q40_get_ss;	mach_get_rtc_pll = q40_get_rtc_pll;	mach_set_rtc_pll = q40_set_rtc_pll;	mach_set_clock_mmss = q40_set_clock_mmss;	mach_reset = q40_reset;	mach_get_model = q40_get_model;	mach_get_hardware_list = q40_get_hardware_list;#if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)	mach_beep = q40_mksound;#endif#ifdef CONFIG_HEARTBEAT	mach_heartbeat = q40_heartbeat;#endif	mach_halt = q40_halt;	/* disable a few things that SMSQ might have left enabled */	q40_disable_irqs();	/* no DMA at all, but ide-scsi requires it.. make sure	 * all physical RAM fits into the boundary - otherwise	 * allocator may play costly and useless tricks */	mach_max_dma_address = 1024*1024*1024;}int q40_parse_bootinfo(const struct bi_record *rec){	return 1;}static inline unsigned char bcd2bin(unsigned char b){	return (b >> 4) * 10 + (b & 15);}static inline unsigned char bin2bcd(unsigned char b){	return (b / 10) * 16 + (b % 10);}unsigned long q40_gettimeoffset(void){	return 5000 * (ql_ticks != 0);}/* * Looks like op is non-zero for setting the clock, and zero for * reading the clock. * *  struct hwclk_time { *         unsigned        sec;       0..59 *         unsigned        min;       0..59 *         unsigned        hour;      0..23 *         unsigned        day;       1..31 *         unsigned        mon;       0..11 *         unsigned        year;      00... *         int             wday;      0..6, 0 is Sunday, -1 means unknown/don't set * }; */int q40_hwclk(int op, struct rtc_time *t){	if (op) {		/* Write.... */		Q40_RTC_CTRL |= Q40_RTC_WRITE;		Q40_RTC_SECS = bin2bcd(t->tm_sec);		Q40_RTC_MINS = bin2bcd(t->tm_min);		Q40_RTC_HOUR = bin2bcd(t->tm_hour);		Q40_RTC_DATE = bin2bcd(t->tm_mday);		Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1);		Q40_RTC_YEAR = bin2bcd(t->tm_year%100);		if (t->tm_wday >= 0)			Q40_RTC_DOW = bin2bcd(t->tm_wday+1);		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);	} else {		/* Read....  */		Q40_RTC_CTRL |= Q40_RTC_READ;		t->tm_year = bcd2bin (Q40_RTC_YEAR);		t->tm_mon  = bcd2bin (Q40_RTC_MNTH)-1;		t->tm_mday = bcd2bin (Q40_RTC_DATE);		t->tm_hour = bcd2bin (Q40_RTC_HOUR);		t->tm_min  = bcd2bin (Q40_RTC_MINS);		t->tm_sec  = bcd2bin (Q40_RTC_SECS);		Q40_RTC_CTRL &= ~(Q40_RTC_READ);		if (t->tm_year < 70)			t->tm_year += 100;		t->tm_wday = bcd2bin(Q40_RTC_DOW)-1;	}	return 0;}unsigned int q40_get_ss(void){	return bcd2bin(Q40_RTC_SECS);}/* * Set the minutes and seconds from seconds value 'nowtime'.  Fail if * clock is out by > 30 minutes.  Logic lifted from atari code. */int q40_set_clock_mmss(unsigned long nowtime){	int retval = 0;	short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;	int rtc_minutes;	rtc_minutes = bcd2bin(Q40_RTC_MINS);	if ((rtc_minutes < real_minutes ?	     real_minutes - rtc_minutes :	     rtc_minutes - real_minutes) < 30) {		Q40_RTC_CTRL |= Q40_RTC_WRITE;		Q40_RTC_MINS = bin2bcd(real_minutes);		Q40_RTC_SECS = bin2bcd(real_seconds);		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);	} else		retval = -1;	return retval;}/* get and set PLL calibration of RTC clock */#define Q40_RTC_PLL_MASK ((1<<5)-1)#define Q40_RTC_PLL_SIGN (1<<5)static int q40_get_rtc_pll(struct rtc_pll_info *pll){	int tmp = Q40_RTC_CTRL;	pll->pll_value = tmp & Q40_RTC_PLL_MASK;	if (tmp & Q40_RTC_PLL_SIGN)		pll->pll_value = -pll->pll_value;	pll->pll_max = 31;	pll->pll_min = -31;	pll->pll_posmult = 512;	pll->pll_negmult = 256;	pll->pll_clock = 125829120;	return 0;}static int q40_set_rtc_pll(struct rtc_pll_info *pll){	if (!pll->pll_ctrl) {		/* the docs are a bit unclear so I am doublesetting */		/* RTC_WRITE here ... */		int tmp = (pll->pll_value & 31) | (pll->pll_value<0 ? 32 : 0) |			  Q40_RTC_WRITE;		Q40_RTC_CTRL |= Q40_RTC_WRITE;		Q40_RTC_CTRL = tmp;		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);		return 0;	} else		return -EINVAL;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?