diff options
| author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-09-06 16:27:37 +0000 | 
|---|---|---|
| committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2007-09-06 16:27:37 +0000 | 
| commit | 17c7b6c3fdc48301e50d22cc6138ede16bd1be24 (patch) | |
| tree | a5d41b991a151e72663527a96fbc6c494565d65c /target/linux/rdc/files/arch/i386/mach-rdc | |
| parent | 5389989abaa52926b22f9f030d1481df1e73d745 (diff) | |
strip the kernel version suffix from target directories, except for brcm-2.4 (the -2.4 will be included in the board name here). CONFIG_LINUX_<ver>_<board> becomes CONFIG_TARGET_<board>, same for profiles.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@8653 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/rdc/files/arch/i386/mach-rdc')
| -rw-r--r-- | target/linux/rdc/files/arch/i386/mach-rdc/Makefile | 5 | ||||
| -rw-r--r-- | target/linux/rdc/files/arch/i386/mach-rdc/gpio.c | 91 | ||||
| -rw-r--r-- | target/linux/rdc/files/arch/i386/mach-rdc/platform.c | 83 | ||||
| -rw-r--r-- | target/linux/rdc/files/arch/i386/mach-rdc/wdt.c | 272 | 
4 files changed, 451 insertions, 0 deletions
diff --git a/target/linux/rdc/files/arch/i386/mach-rdc/Makefile b/target/linux/rdc/files/arch/i386/mach-rdc/Makefile new file mode 100644 index 000000000..5961bc791 --- /dev/null +++ b/target/linux/rdc/files/arch/i386/mach-rdc/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the RDC321x specific parts of the kernel +# +obj-$(CONFIG_X86_RDC)        := gpio.o platform.o wdt.o + diff --git a/target/linux/rdc/files/arch/i386/mach-rdc/gpio.c b/target/linux/rdc/files/arch/i386/mach-rdc/gpio.c new file mode 100644 index 000000000..dbd03270f --- /dev/null +++ b/target/linux/rdc/files/arch/i386/mach-rdc/gpio.c @@ -0,0 +1,91 @@ +/* + *  Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org> + *  	RDC321x architecture specific GPIO support + * + *  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/autoconf.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/delay.h> + +#include <asm/mach-rdc/rdc321x_defs.h> + +static inline int rdc_gpio_is_valid(unsigned gpio) +{ +	return (gpio <= RDC_MAX_GPIO); +} + +static unsigned int rdc_gpio_read(unsigned gpio) +{ +	unsigned int val; + +	val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x84:0x48)); +        outl(val, RDC3210_CFGREG_ADDR); +        udelay(10); +        val = inl(RDC3210_CFGREG_DATA); +        val |= (0x1 << (gpio & 0x1F)); +        outl(val, RDC3210_CFGREG_DATA); +        udelay(10); +        val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x88:0x4C)); +        outl(val, RDC3210_CFGREG_ADDR); +        udelay(10); +        val = inl(RDC3210_CFGREG_DATA); + +	return val; +} + +static void rdc_gpio_write(unsigned int val) +{ +	if (val) { +		outl(val, RDC3210_CFGREG_DATA); +		udelay(10); +	} +} + +int rdc_gpio_get_value(unsigned gpio) +{ +	if (rdc_gpio_is_valid(gpio)) +		return (int)rdc_gpio_read(gpio); +	else +		return -EINVAL; +} +EXPORT_SYMBOL(rdc_gpio_get_value); + +void rdc_gpio_set_value(unsigned gpio, int value) +{ +	unsigned int val; + +	if (!rdc_gpio_is_valid(gpio)) +		return; +	 +	val = rdc_gpio_read(gpio); + +	if (value) +		val &= ~(0x1 << (gpio & 0x1F)); +	else +		val |= (0x1 << (gpio & 0x1F)); + +	rdc_gpio_write(val); +} +EXPORT_SYMBOL(rdc_gpio_set_value); + +int rdc_gpio_direction_input(unsigned gpio) +{ +	return 0; +} +EXPORT_SYMBOL(rdc_gpio_direction_input); + +int rdc_gpio_direction_output(unsigned gpio, int value) +{ +	return 0; +} +EXPORT_SYMBOL(rdc_gpio_direction_output); + + diff --git a/target/linux/rdc/files/arch/i386/mach-rdc/platform.c b/target/linux/rdc/files/arch/i386/mach-rdc/platform.c new file mode 100644 index 000000000..6809dcdd3 --- /dev/null +++ b/target/linux/rdc/files/arch/i386/mach-rdc/platform.c @@ -0,0 +1,83 @@ +/* + *  $Id: platform.c 8331 2007-08-03 15:59:23Z florian $ + * + *  Generic RDC321x platform devices + * + *  Copyright (C) 2007 OpenWrt.org + *  Copyright (C) 2007 Florian Fainelli <florian@openwrt.org> + * + *  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. + * + *  This program is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  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., 51 Franklin Street, Fifth Floor, + *  Boston, MA  02110-1301, USA. + * + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/platform_device.h> + +#include <asm/gpio.h> + +#define PFX "rdc321x: " + +/* FIXME : Flash */ +static struct resource rdc_flash_resource[] = { +	[0] = { +		.start = (u32)-CONFIG_MTD_RDC3210_SIZE, +		.end = (u32)-1, +		.flags = IORESOURCE_MEM, +	}, +}; + +static struct platform_device rdc_flash_device = { +	.name = "rdc321x-flash", +	.id = -1, +	.num_resources = ARRAY_SIZE(rdc_flash_resource), +	.resource = rdc_flash_resource, +}; + +/* LEDS */ +static struct platform_device rdc321x_leds = { +	.name = "rdc321x-leds", +	.id = -1, +	.num_resources = 0, +}; + +static struct platform_device rdc321x_wdt = { +	.name = "rdc321x-wdt", +	.id = -1, +	.num_resources = 0, +}; + +static int __init rdc_board_setup(void) +{ +	int err; + +	err = platform_device_register(&rdc_flash_device); +	if (err) +		printk(KERN_ALERT PFX "failed to register flash\n"); + +	err = platform_device_register(&rdc321x_leds); +	if (err) +		printk(KERN_ALERT PFX "failed to register LEDS\n"); + +	err = platform_device_register(&rdc321x_wdt); +		printk(KERN_ALERT PFX "failed to register watchdog\n"); + +	return err;  +} + +arch_initcall(rdc_board_setup); diff --git a/target/linux/rdc/files/arch/i386/mach-rdc/wdt.c b/target/linux/rdc/files/arch/i386/mach-rdc/wdt.c new file mode 100644 index 000000000..39956f35a --- /dev/null +++ b/target/linux/rdc/files/arch/i386/mach-rdc/wdt.c @@ -0,0 +1,272 @@ +/* + * RDC321x watchdog driver + * + * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org> + * + * This driver is highly inspired from the cpu5_wdt driver + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/miscdevice.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/timer.h> +#include <linux/completion.h> +#include <linux/jiffies.h> +#include <linux/platform_device.h> +#include <linux/watchdog.h> + +#include <asm/io.h> +#include <asm/uaccess.h> + +#include <asm/mach-rdc/rdc321x_defs.h> + +#define RDC_WDT_MASK		0x80000000	/* Mask */ +#define RDC_WDT_EN		0x00800000 	/* Enable bit */ +#define RDC_WDT_WTI		0x00200000	/* Generate a CPU reset/NMI/WDT irq when WDT timeout is reached */ +#define RDC_WDT_RST		0x00100000	/* Reset bit */ +#define RDC_WDT_WIF		0x00040000	/* WDT IRQ Flag */ +#define RDC_WDT_IRT		0x00000100	/* IRQ Routing table */ +#define RDC_WDT_CNT		0x00000001	/* WDT count */ + +#define RDC_CLS_TMR		0x80003844	/* Clear timer */ + +#define RDC_WDT_INTERVAL	(HZ/10+1) + +int nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + +static int ticks = 1000; + +/* some device data */ + +static struct { +	struct completion stop; +	volatile int running; +	struct timer_list timer; +	volatile int queue; +	int default_ticks; +	unsigned long inuse; +} rdc321x_wdt_device; + +/* generic helper functions */ + +static void rdc321x_wdt_trigger(unsigned long unused) +{ +	if( rdc321x_wdt_device.running ) +		ticks--; + +	/* keep watchdog alive */ +	outl(RDC_WDT_EN|inl(RDC3210_CFGREG_DATA), RDC3210_CFGREG_DATA);	 +	 +	/* requeue?? */ +	if (rdc321x_wdt_device.queue && ticks) +		mod_timer(&rdc321x_wdt_device.timer, jiffies + RDC_WDT_INTERVAL); +	else { +		/* ticks doesn't matter anyway */ +		complete(&rdc321x_wdt_device.stop); +	} + +} + +static void rdc321x_wdt_reset(void) +{ +	ticks = rdc321x_wdt_device.default_ticks; +} + +static void rdc321x_wdt_start(void) +{ +	if (!rdc321x_wdt_device.queue) { +		rdc321x_wdt_device.queue = 1; + +		/* Clear the timer */ +		outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR); +		 +		/* Enable watchdog and set the timeout to 81.92 us */ +		outl(RDC_WDT_EN|RDC_WDT_CNT, RDC3210_CFGREG_DATA); + +		mod_timer(&rdc321x_wdt_device.timer, jiffies + RDC_WDT_INTERVAL); +	} + +	/* if process dies, counter is not decremented */ +	rdc321x_wdt_device.running++; +} + +static int rdc321x_wdt_stop(void) +{ +	if (rdc321x_wdt_device.running) +		rdc321x_wdt_device.running = 0; + +	ticks = rdc321x_wdt_device.default_ticks; + +	return -EIO; +} + +/* filesystem operations */ + +static int rdc321x_wdt_open(struct inode *inode, struct file *file) +{ +	if (test_and_set_bit(0, &rdc321x_wdt_device.inuse)) +		return -EBUSY; + +	return nonseekable_open(inode, file); +} + +static int rdc321x_wdt_release(struct inode *inode, struct file *file) +{ +	clear_bit(0, &rdc321x_wdt_device.inuse); +	return 0; +} + +static int rdc321x_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 = "RDC321x WDT", +	}; + +	switch(cmd) { +		case WDIOC_KEEPALIVE: +			rdc321x_wdt_reset(); +			break; +		case WDIOC_GETSTATUS: +			/* Read the value from the DATA register */ +			value = inl(RDC3210_CFGREG_DATA); +			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: +					rdc321x_wdt_start(); +					break; +				case WDIOS_DISABLECARD: +					return rdc321x_wdt_stop(); +				default: +					return -EINVAL; +			} +			break; +		default: +    			return -ENOTTY; +	} +	return 0; +} + +static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) +{ +	if ( !count ) +		return -EIO; + +	rdc321x_wdt_reset(); + +	return count; +} + +static const struct file_operations rdc321x_wdt_fops = { +	.owner		= THIS_MODULE, +	.llseek		= no_llseek, +	.ioctl		= rdc321x_wdt_ioctl, +	.open		= rdc321x_wdt_open, +	.write		= rdc321x_wdt_write, +	.release	= rdc321x_wdt_release, +}; + +static struct miscdevice rdc321x_wdt_misc = { +	.minor	= WATCHDOG_MINOR, +	.name	= "watchdog", +	.fops	= &rdc321x_wdt_fops, +}; + +static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) +{ +	int err; + +	if ( (err = misc_register(&rdc321x_wdt_misc)) < 0 ) { +		printk(KERN_ERR PFX "misc_register failed\n"); +		return err; +	} + +	/* Reset the watchdog */ +	outl(RDC_WDT_RST, RDC3210_CFGREG_DATA); + +	init_completion(&rdc321x_wdt_device.stop); +	rdc321x_wdt_device.queue = 0; + +	clear_bit(0, &rdc321x_wdt_device.inuse); + +	setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0); + +	rdc321x_wdt_device.default_ticks = ticks; + +	printk(KERN_INFO PFX "init success\n"); + +	return 0; +} + +static int rdc321x_wdt_remove(struct platform_device *pdev) +{ +	if (rdc321x_wdt_device.queue) { +		rdc321x_wdt_device.queue = 0; +		wait_for_completion(&rdc321x_wdt_device.stop); +	} + +	misc_deregister(&rdc321x_wdt_misc); + +	return 0; +} + +static struct platform_driver rdc321x_wdt_driver = { +	.probe = rdc321x_wdt_probe, +	.remove = rdc321x_wdt_remove, +	.driver = { +		.owner = THIS_MODULE, +		.name = "rdc321x_wdt", +	}, +}; + +static int __init rdc321x_wdt_init(void) +{ +	return platform_driver_register(&rdc321x_wdt_driver); +} + +static void __exit rdc321x_wdt_exit(void) +{ +	platform_driver_unregister(&rdc321x_wdt_driver); +} + +module_init(rdc321x_wdt_init); +module_exit(rdc321x_wdt_exit); + +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); +MODULE_DESCRIPTION("RDC321x watchdog driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);  | 
