Browse Source

brcm63xx cleanups; add a watchdog driver, indent serial console driver, add support for another sst flash

SVN-Revision: 6985
Florian Fainelli 19 years ago
parent
commit
2bf49e010b

+ 1 - 1
target/linux/brcm63xx-2.6/files/arch/mips/bcm963xx/Makefile

@@ -3,7 +3,7 @@
 #
 # Copyright (C) 2004 Broadcom Corporation
 #
-obj-y           := irq.o prom.o setup.o time.o ser_init.o int-handler.o info.o
+obj-y           := irq.o prom.o setup.o time.o ser_init.o int-handler.o info.o wdt.o
 
 SRCBASE         := $(TOPDIR)
 EXTRA_CFLAGS    += -I$(SRCBASE)/include

+ 20 - 4
target/linux/brcm63xx-2.6/files/arch/mips/bcm963xx/info.c

@@ -25,7 +25,8 @@
 static char *boot_loader_names[BOOT_LOADER_LAST+1] = {
         [BOOT_LOADER_UNKNOWN]   = "Unknown",
         [BOOT_LOADER_CFE]       = "CFE",
-        [BOOT_LOADER_REDBOOT]	= "RedBoot"
+        [BOOT_LOADER_REDBOOT]	= "RedBoot",
+	[BOOT_LOADER_CFE2]	= "CFEv2"
 };
 
 /* boot loaders specific definitions */
@@ -73,14 +74,29 @@ void __init detect_bootloader(void)
 {
 	if (detect_cfe()) {
 		boot_loader_type = BOOT_LOADER_CFE;
-		printk("Boot loader is : %s\n", boot_loader_names[boot_loader_type]);
 	}
 
 	if (detect_redboot()) {
 		boot_loader_type = BOOT_LOADER_REDBOOT;
 	}
-	else
-		boot_loader_type = BOOT_LOADER_UNKNOWN;
+	else {
+		/* Some devices are using CFE, but it is not detected as is */
+		boot_loader_type = BOOT_LOADER_CFE2;
+	}
+	printk("Boot loader is : %s\n", boot_loader_names[boot_loader_type]);
+}
+
+void __init detect_board(void)
+{
+	switch (boot_loader_type)
+	{
+		case BOOT_LOADER_CFE:
+			break;
+		case BOOT_LOADER_REDBOOT:
+			break;
+		default:
+			break;
+	}
 }
 
 EXPORT_SYMBOL(boot_loader_type);

+ 5 - 5
target/linux/brcm63xx-2.6/files/arch/mips/bcm963xx/irq.c

@@ -237,14 +237,14 @@ unsigned int BcmHalMapInterrupt(FN_HANDLER pfunc, unsigned int param,
 	irq_desc[interruptId].chip = &brcm_irq_no_end_type;
 
 	if( interruptId >= INTERNAL_ISR_TABLE_OFFSET )
-	{
-		nRet = request_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT,
-			devname, (void *) param );
+	{	
+		printk("BcmHalMapInterrupt : internal IRQ\n");
+		nRet = request_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT, devname, (void *) param );
 	}
 	else if (interruptId >= INTERRUPT_ID_EXTERNAL_0 && interruptId <= INTERRUPT_ID_EXTERNAL_3)
 	{
-		nRet = request_external_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT,
-			devname, (void *) param );
+		printk("BcmHalMapInterrupt : external IRQ\n");
+		nRet = request_external_irq( interruptId, pfunc, SA_SAMPLE_RANDOM | SA_INTERRUPT, devname, (void *) param );
 	}
 
 	return( nRet );

+ 11 - 10
target/linux/brcm63xx-2.6/files/arch/mips/bcm963xx/prom.c

@@ -1,6 +1,6 @@
 /*
-<:copyright-gpl
  Copyright 2004 Broadcom Corp. All Rights Reserved.
+ Copyright 2007 OpenWrt,org, Florian Fainelli <[email protected]>
 
  This program is free software; you can distribute it and/or modify it
  under the terms of the GNU General Public License (Version 2) as
@@ -14,7 +14,6 @@
  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-:>
 */
 /*
  * prom.c: PROM library initialization code.
@@ -50,24 +49,26 @@ void __init prom_init(void)
 {
     	serial_init();
 
-    	printk( "%s prom init\n", get_system_type() );
+    	printk("%s prom init\n", get_system_type() );
 
     	PERF->IrqMask = 0;
-
+	
+	/* Detect the bootloader */
 	detect_bootloader();
 
-	if (boot_loader_type == BOOT_LOADER_CFE) {
+	/* Do further initialisations depending on the bootloader */
+	if (boot_loader_type == BOOT_LOADER_CFE || boot_loader_type == BOOT_LOADER_CFE2) {
 		cfe_setup(fw_arg0, fw_arg1, fw_arg2, fw_arg3);
-		add_memory_region(0, (boot_mem_map.map[0].size - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
 	}
-	else
-		add_memory_region(0, (0x01000000 - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
-	
+	/* Register 16MB RAM minus the ADSL SDRAM by default */
+	add_memory_region(0, (0x01000000 - ADSL_SDRAM_IMAGE_SIZE), BOOT_MEM_RAM);
+
 	mips_machgroup = MACH_GROUP_BRCM;
 	mips_machtype = MACH_BCM;
 }
 
-void __init prom_free_prom_memory(void)
+unsigned long __init prom_free_prom_memory(void)
 {
 	/* We do not have any memory to free */
+	return 0;
 }

+ 246 - 0
target/linux/brcm63xx-2.6/files/arch/mips/bcm963xx/wdt.c

@@ -0,0 +1,246 @@
+/*
+ * Watchdog driver for the BCM963xx devices
+ * 
+ * Copyright (C) 2007 OpenWrt.org
+ *			Florian Fainelli <[email protected]>
+ * 
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/notifier.h>
+#include <linux/watchdog.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+#include <linux/completion.h>
+#include <linux/ioport.h>
+
+typedef struct bcm963xx_timer {
+	unsigned short unused0;
+	unsigned char  timer_mask;
+#define TIMER0EN        0x01
+#define TIMER1EN        0x02
+#define TIMER2EN        0x04
+  	unsigned char  timer_ints;
+#define TIMER0          0x01
+#define TIMER1          0x02
+#define TIMER2          0x04
+#define WATCHDOG        0x08
+ 	unsigned long	timer_ctl0;
+  	unsigned long	timer_ctl1;
+  	unsigned long	timer_ctl2;
+#define TIMERENABLE     0x80000000
+#define RSTCNTCLR       0x40000000      
+  	unsigned long	timer_cnt0;
+  	unsigned long	timer_cnt1;
+  	unsigned long	timer_cnt2;
+  	unsigned long	wdt_def_count;
+
+  	/* Write 0xff00 0x00ff to Start timer
+   	* Write 0xee00 0x00ee to Stop and re-load default count
+   	* Read from this register returns current watch dog count
+   	*/
+  	unsigned long	wdt_ctl;
+
+  	/* Number of 40-MHz ticks for WD Reset pulse to last */
+  	unsigned long	wdt_rst_count;
+} bcm963xx_timer;
+
+static struct bcm963xx_wdt_device {
+	struct completion stop;
+	volatile int running;
+	struct timer_list timer;
+	volatile int queue;
+	int default_ticks;
+	unsigned long inuse;
+} bcm963xx_wdt_device;
+
+static int ticks = 1000;
+
+#define WDT_BASE	0xfffe0200
+#define WDT 		((volatile bcm963xx_timer * const) WDT_BASE)
+
+#define BCM963XX_INTERVAL        (HZ/10+1)
+
+static void bcm963xx_wdt_trigger(unsigned long unused)
+{
+	if (bcm963xx_wdt_device.running)
+		ticks--;
+
+	/* Load the default ticking value into the reset counter register */	
+	WDT->wdt_rst_count = bcm963xx_wdt_device.default_ticks;
+	
+	if (bcm963xx_wdt_device.queue && ticks) {
+		bcm963xx_wdt_device.timer.expires = jiffies + BCM963XX_INTERVAL;
+		add_timer(&bcm963xx_wdt_device.timer);
+	}
+	else {
+		complete(&bcm963xx_wdt_device.stop);
+	}
+}
+
+static void bcm963xx_wdt_reset(void)
+{
+	ticks = bcm963xx_wdt_device.default_ticks;
+	/* Also reload default count */
+	WDT->wdt_def_count = ticks;
+	WDT->wdt_ctl = 0xee00;
+	WDT->wdt_ctl = 0x00ee;
+}
+
+static void bcm963xx_wdt_start(void)
+{
+	if (!bcm963xx_wdt_device.queue) {
+		bcm963xx_wdt_device.queue;
+		/* Enable the watchdog by writing 0xff00 ,then 0x00ff to the control register */
+		WDT->wdt_ctl = 0xff00;
+		WDT->wdt_ctl = 0x00ff;
+		bcm963xx_wdt_device.timer.expires = jiffies + BCM963XX_INTERVAL;
+		add_timer(&bcm963xx_wdt_device.timer);
+	}
+	bcm963xx_wdt_device.running++;
+}
+
+static int bcm963xx_wdt_stop(void)
+{
+	if (bcm963xx_wdt_device.running)
+		bcm963xx_wdt_device.running = 0;
+	
+	ticks = bcm963xx_wdt_device.default_ticks;
+
+	/* Stop the watchdog by writing 0xee00 then 0x00ee to the control register */
+	WDT->wdt_ctl = 0xee00;
+	WDT->wdt_ctl = 0x00ee;
+
+	return -EIO;
+}
+
+static int bcm963xx_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(0, &bcm963xx_wdt_device.inuse))
+		return -EBUSY;
+	return nonseekable_open(inode, file);
+}
+
+static int bcm963xx_wdt_release(struct inode *inode, struct file *file)
+{
+	clear_bit(0, &bcm963xx_wdt_device.inuse);
+	return 0;
+}
+
+static int bcm963xx_wdt_ioctl(struct inode *inode, struct file *file,
+				unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	unsigned int value;
+
+	static struct watchdog_info ident = {
+		.options = WDIOF_CARDRESET,
+		.identity = "BCM963xx WDT",
+	};
+
+	switch (cmd) {
+		case WDIOC_KEEPALIVE:
+			bcm963xx_wdt_reset();
+			break;
+		case WDIOC_GETSTATUS:
+			/* Reading from the control register will return the current value */
+			value = WDT->wdt_ctl;
+			if ( copy_to_user(argp, &value, sizeof(int)) )
+				return -EFAULT;
+			break;
+		case WDIOC_GETSUPPORT:
+			if ( copy_to_user(argp, &ident, sizeof(ident)) )
+				return -EFAULT;
+			break;
+		case WDIOC_SETOPTIONS:
+			if ( copy_from_user(&value, argp, sizeof(int)) )
+				return -EFAULT;
+			switch(value) {
+				case WDIOS_ENABLECARD:
+					bcm963xx_wdt_start();
+					break;
+				case WDIOS_DISABLECARD:
+					bcm963xx_wdt_stop();
+					break;
+				default:
+					return -EINVAL;
+			}
+			break;
+		default:
+			return -ENOTTY;
+	}
+	return 0;		
+}
+
+static int bcm963xx_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{
+	if (!count)
+		return -EIO;
+	bcm963xx_wdt_reset();
+	return count;
+}
+
+static const struct file_operations bcm963xx_wdt_fops = {
+	.owner 		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.write		= bcm963xx_wdt_write,
+	.ioctl		= bcm963xx_wdt_ioctl,
+	.open		= bcm963xx_wdt_open,
+	.release 	= bcm963xx_wdt_release,
+};	
+
+static struct miscdevice bcm963xx_wdt_miscdev = {
+	.minor 	= WATCHDOG_MINOR,
+	.name 	= "watchdog",
+	.fops	= &bcm963xx_wdt_fops,
+};
+
+static void __exit bcm963xx_wdt_exit(void)
+{
+	if (bcm963xx_wdt_device.queue ){
+		bcm963xx_wdt_device.queue = 0;
+		wait_for_completion(&bcm963xx_wdt_device.stop);
+	}	
+	misc_deregister(&bcm963xx_wdt_miscdev);
+}
+
+static int __init bcm963xx_wdt_init(void)
+{
+	int ret = 0;
+	
+	printk("Broadcom BCM963xx Watchdog timer\n");
+
+	ret = misc_register(&bcm963xx_wdt_miscdev);
+	if (ret) {
+		printk(KERN_CRIT "Cannot register miscdev on minor=%d (err=%d)\n", WATCHDOG_MINOR, ret);
+		return ret;
+	}
+	init_completion(&bcm963xx_wdt_device.stop);
+	bcm963xx_wdt_device.queue = 0;
+	
+	clear_bit(0, &bcm963xx_wdt_device.inuse);
+	
+	init_timer(&bcm963xx_wdt_device.timer);
+	bcm963xx_wdt_device.timer.function = bcm963xx_wdt_trigger;
+	bcm963xx_wdt_device.timer.data = 0;
+
+	bcm963xx_wdt_device.default_ticks = ticks;	
+	return ret;
+}
+
+	
+module_init(bcm963xx_wdt_init);
+module_exit(bcm963xx_wdt_exit);
+
+MODULE_AUTHOR("Florian Fainelli <[email protected]>");
+MODULE_DESCRIPTION("Broadcom BCM963xx Watchdog driver");
+MODULE_LICENSE("GPL");

File diff suppressed because it is too large
+ 449 - 447
target/linux/brcm63xx-2.6/files/drivers/serial/bcm63xx_cons.c


+ 5 - 4
target/linux/brcm63xx-2.6/files/include/asm-mips/mach-bcm963xx/bootloaders.h

@@ -1,6 +1,7 @@
 #define ADSL_SDRAM_IMAGE_SIZE (384*1024)
 
-#define BOOT_LOADER_UNKNOWN 0
-#define BOOT_LOADER_CFE 1
-#define BOOT_LOADER_REDBOOT 2
-#define BOOT_LOADER_LAST 2
+#define BOOT_LOADER_UNKNOWN 	0
+#define BOOT_LOADER_CFE 	1
+#define BOOT_LOADER_REDBOOT 	2
+#define BOOT_LOADER_CFE2	3
+#define BOOT_LOADER_LAST 	3

+ 36 - 0
target/linux/brcm63xx-2.6/patches/150-sst_flash.patch

@@ -0,0 +1,36 @@
+diff -urN linux-2.6.19.2/drivers/mtd/chips/jedec_probe.c linux-2.6.19.2.new/drivers/mtd/chips/jedec_probe.c
+--- linux-2.6.19.2/drivers/mtd/chips/jedec_probe.c	2007-01-10 20:10:37.000000000 +0100
++++ linux-2.6.19.2.new/drivers/mtd/chips/jedec_probe.c	2007-04-09 22:33:05.000000000 +0200
+@@ -158,6 +158,7 @@
+ #define SST49LF030A	0x001C
+ #define SST49LF040A	0x0051
+ #define SST49LF080A	0x005B
++#define SST39VF6402B   	0x236C
+ 
+ /* Toshiba */
+ #define TC58FVT160	0x00C2
+@@ -1494,7 +1495,23 @@
+                        ERASEINFO(0x1000,256),
+                        ERASEINFO(0x1000,256)
+                }
+-
++	}, {
++		.mfr_id         = MANUFACTURER_SST,
++		.dev_id         = SST39VF6402B,
++		.name           = "SST 39VF6402B",
++		.uaddr          = {
++			[0] = MTD_UADDR_0x5555_0x2AAA,  /* x8 */
++			[1] = MTD_UADDR_0x5555_0x2AAA   /* x16 */
++		},
++		.DevSize        = SIZE_8MiB,
++		.CmdSet         = P_ID_AMD_STD,
++		.NumEraseRegions= 4,
++		.regions        = {
++			ERASEINFO(0x2000,256),
++			ERASEINFO(0x2000,256),
++			ERASEINFO(0x2000,256),
++			ERASEINFO(0x2000,256)
++		}
+        }, {
+ 		.mfr_id		= MANUFACTURER_ST,	/* FIXME - CFI device? */
+ 		.dev_id		= M29W800DT,

Some files were not shown because too many files changed in this diff