diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2001-04-05 04:55:58 +0000 |
commit | 74a9f2e1b4d3ab45a9f72cb5b556c9f521524ab3 (patch) | |
tree | 7c4cdb103ab1b388c9852a88bd6fb1e73eba0b5c /drivers/sbus/char | |
parent | ee6374c8b0d333c08061c6a97bc77090d7461225 (diff) |
Merge with Linux 2.4.3.
Note that mingetty does no longer work with serial console, you have to
switch to another getty like getty_ps. This commit also includes a
fix for a setitimer bug which did prevent getty_ps from working on
older kernels.
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r-- | drivers/sbus/char/Makefile | 1 | ||||
-rw-r--r-- | drivers/sbus/char/aurora.c | 4 | ||||
-rw-r--r-- | drivers/sbus/char/cpwatchdog.c | 59 | ||||
-rw-r--r-- | drivers/sbus/char/envctrl.c | 13 | ||||
-rw-r--r-- | drivers/sbus/char/flash.c | 11 | ||||
-rw-r--r-- | drivers/sbus/char/pcikbd.c | 44 | ||||
-rw-r--r-- | drivers/sbus/char/riowatchdog.c | 275 | ||||
-rw-r--r-- | drivers/sbus/char/rtc.c | 10 | ||||
-rw-r--r-- | drivers/sbus/char/sab82532.c | 40 | ||||
-rw-r--r-- | drivers/sbus/char/su.c | 52 | ||||
-rw-r--r-- | drivers/sbus/char/sunserial.c | 45 | ||||
-rw-r--r-- | drivers/sbus/char/vfc_dev.c | 2 |
12 files changed, 483 insertions, 73 deletions
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile index 437f2d28c..9513fac9f 100644 --- a/drivers/sbus/char/Makefile +++ b/drivers/sbus/char/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_SAB82532) += sab82532.o obj-$(CONFIG_ENVCTRL) += envctrl.o obj-$(CONFIG_DISPLAY7SEG) += display7seg.o obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwatchdog.o +obj-$(CONFIG_WATCHDOG_RIO) += riowatchdog.o obj-$(CONFIG_OBP_FLASH) += flash.o obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c index c640c9fe8..669d157b4 100644 --- a/drivers/sbus/char/aurora.c +++ b/drivers/sbus/char/aurora.c @@ -1,4 +1,4 @@ -/* $Id: aurora.c,v 1.10 2000/12/07 04:35:38 anton Exp $ +/* $Id: aurora.c,v 1.11 2001/03/08 01:43:30 davem Exp $ * linux/drivers/sbus/char/aurora.c -- Aurora multiport driver * * Copyright (c) 1999 by Oliver Aldulea (oli@bv.ro) @@ -1942,7 +1942,7 @@ static int aurora_set_serial_info(struct Aurora_port * port, change_speed = ((port->flags & ASYNC_SPD_MASK) != (tmp.flags & ASYNC_SPD_MASK)); - if (!suser()) { + if (!capable(CAP_SYS_ADMIN)) { if ((tmp.close_delay != port->close_delay) || (tmp.closing_wait != port->closing_wait) || ((tmp.flags & ~ASYNC_USR_MASK) != diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c index c319b4d33..e53ce669d 100644 --- a/drivers/sbus/char/cpwatchdog.c +++ b/drivers/sbus/char/cpwatchdog.c @@ -173,7 +173,7 @@ static struct wd_device wd_dev = { 0, SPIN_LOCK_UNLOCKED, 0, 0, 0, 0, }; -struct timer_list wd_timer; +static struct timer_list wd_timer; static int wd0_timeout = 0; static int wd1_timeout = 0; @@ -199,20 +199,20 @@ MODULE_SUPPORTED_DEVICE /* Forward declarations of internal methods */ -void wd_dumpregs(void); -void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs); -void wd_toggleintr(struct wd_timer* pTimer, int enable); -void wd_pingtimer(struct wd_timer* pTimer); -void wd_starttimer(struct wd_timer* pTimer); -void wd_resetbrokentimer(struct wd_timer* pTimer); -void wd_stoptimer(struct wd_timer* pTimer); -void wd_brokentimer(unsigned long data); -int wd_getstatus(struct wd_timer* pTimer); +static void wd_dumpregs(void); +static void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void wd_toggleintr(struct wd_timer* pTimer, int enable); +static void wd_pingtimer(struct wd_timer* pTimer); +static void wd_starttimer(struct wd_timer* pTimer); +static void wd_resetbrokentimer(struct wd_timer* pTimer); +static void wd_stoptimer(struct wd_timer* pTimer); +static void wd_brokentimer(unsigned long data); +static int wd_getstatus(struct wd_timer* pTimer); /* PLD expects words to be written in LSB format, * so we must flip all words prior to writing them to regs */ -inline unsigned short flip_word(unsigned short word) +static inline unsigned short flip_word(unsigned short word) { return ((word & 0xff) << 8) | ((word >> 8) & 0xff); } @@ -355,10 +355,15 @@ static int wd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETSUPPORT: if(copy_to_user((struct watchdog_info *)arg, (struct watchdog_info *)&info, - sizeof(struct watchdog_info *))) { + sizeof(struct watchdog_info))) { return(-EFAULT); } break; + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + if (put_user(0, (int *) arg)) + return -EFAULT; + break; case WDIOC_KEEPALIVE: wd_pingtimer(pTimer); break; @@ -417,8 +422,14 @@ static ssize_t wd_write( struct file *file, return(-EINVAL); } - wd_pingtimer(pTimer); - return(count); + if (ppos != &file->f_pos) + return -ESPIPE; + + if (count) { + wd_pingtimer(pTimer); + return 1; + } + return 0; } static ssize_t wd_read(struct file * file, char * buffer, @@ -432,7 +443,7 @@ static ssize_t wd_read(struct file * file, char * buffer, #endif /* ifdef WD_DEBUG */ } -void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { /* Only WD0 will interrupt-- others are NMI and we won't * see them here.... @@ -460,7 +471,7 @@ static struct miscdevice wd0_miscdev = { WD0_MINOR, WD0_DEVNAME, &wd_fops }; static struct miscdevice wd1_miscdev = { WD1_MINOR, WD1_DEVNAME, &wd_fops }; static struct miscdevice wd2_miscdev = { WD2_MINOR, WD2_DEVNAME, &wd_fops }; -void wd_dumpregs(void) +static void wd_dumpregs(void) { /* Reading from downcounters initiates watchdog countdown-- * Example is included below for illustration purposes. @@ -504,7 +515,7 @@ void wd_dumpregs(void) * pTimer - pointer to timer device, or NULL to indicate all timers * enable - non-zero to enable interrupts, zero to disable */ -void wd_toggleintr(struct wd_timer* pTimer, int enable) +static void wd_toggleintr(struct wd_timer* pTimer, int enable) { unsigned char curregs = wd_readb(&wd_dev.regs->pld_regs.intr_mask); unsigned char setregs = @@ -525,7 +536,7 @@ void wd_toggleintr(struct wd_timer* pTimer, int enable) * * pTimer - pointer to timer device */ -void wd_pingtimer(struct wd_timer* pTimer) +static void wd_pingtimer(struct wd_timer* pTimer) { if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) { wd_readb(&pTimer->regs->dcntr); @@ -538,7 +549,7 @@ void wd_pingtimer(struct wd_timer* pTimer) * * pTimer - pointer to timer device */ -void wd_stoptimer(struct wd_timer* pTimer) +static void wd_stoptimer(struct wd_timer* pTimer) { if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) { wd_toggleintr(pTimer, WD_INTR_OFF); @@ -560,7 +571,7 @@ void wd_stoptimer(struct wd_timer* pTimer) * pTimer - pointer to timer device * limit - limit (countdown) value in 1/10th seconds */ -void wd_starttimer(struct wd_timer* pTimer) +static void wd_starttimer(struct wd_timer* pTimer) { if(wd_dev.isbaddoggie) { pTimer->runstatus &= ~WD_STAT_BSTOP; @@ -574,7 +585,7 @@ void wd_starttimer(struct wd_timer* pTimer) /* Restarts timer with maximum limit value and * does not unset 'brokenstop' value. */ -void wd_resetbrokentimer(struct wd_timer* pTimer) +static void wd_resetbrokentimer(struct wd_timer* pTimer) { wd_toggleintr(pTimer, WD_INTR_ON); wd_writew(WD_BLIMIT, &pTimer->regs->limit); @@ -583,7 +594,7 @@ void wd_resetbrokentimer(struct wd_timer* pTimer) /* Timer device initialization helper. * Returns 0 on success, other on failure */ -int wd_inittimer(int whichdog) +static int wd_inittimer(int whichdog) { struct miscdevice *whichmisc; volatile struct wd_timer_regblk *whichregs; @@ -650,7 +661,7 @@ int wd_inittimer(int whichdog) * interrupts within the PLD so me must continually * reset the timers ad infinitum. */ -void wd_brokentimer(unsigned long data) +static void wd_brokentimer(unsigned long data) { struct wd_device* pDev = (struct wd_device*)data; int id, tripped = 0; @@ -676,7 +687,7 @@ void wd_brokentimer(unsigned long data) } } -int wd_getstatus(struct wd_timer* pTimer) +static int wd_getstatus(struct wd_timer* pTimer) { unsigned char stat = wd_readb(&pTimer->regs->status); unsigned char intr = wd_readb(&wd_dev.regs->pld_regs.intr_mask); diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index ea42ce5f3..0ed684afc 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c @@ -1,4 +1,4 @@ -/* $Id: envctrl.c,v 1.21 2001/02/13 04:07:38 davem Exp $ +/* $Id: envctrl.c,v 1.22 2001/03/25 09:12:15 davem Exp $ * envctrl.c: Temperature and Fan monitoring on Machines providing it. * * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) @@ -984,6 +984,17 @@ static int __init envctrl_init(void) struct linux_ebus_child *edev_child = NULL; int i = 0; + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "bbc")) { + /* If we find a boot-bus controller node, + * then this envctrl driver is not for us. + */ + return -ENODEV; + } + } + } + /* Traverse through ebus and ebus device list for i2c device and * adc and gpio nodes. */ diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index f144cca3f..f002bc4af 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -1,4 +1,4 @@ -/* $Id: flash.c,v 1.22 2001/02/13 01:17:00 davem Exp $ +/* $Id: flash.c,v 1.23 2001/03/02 06:32:40 davem Exp $ * flash.c: Allow mmap access to the OBP Flash, for OBP updates. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -106,12 +106,17 @@ flash_read(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned long p = file->f_pos; + int i; if (count > flash.read_size - p) count = flash.read_size - p; - if (copy_to_user(buf, flash.read_base + p, count) < 0) - return -EFAULT; + for (i = 0; i < count; i++) { + u8 data = readb(flash.read_base + p + i); + if (put_user(data, buf)) + return -EFAULT; + buf++; + } file->f_pos += count; return count; diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index 68b8905c0..5513053dc 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.51 2001/02/13 01:17:00 davem Exp $ +/* $Id: pcikbd.c,v 1.53 2001/03/21 00:28:33 davem Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -369,9 +369,10 @@ out_ack: void pcikbd_leds(unsigned char leds) { - if(!send_data(KBD_CMD_SET_LEDS) || !send_data(leds)) + if (!pcikbd_iobase) + return; + if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds)) send_data(KBD_CMD_ENABLE); - } static int __init pcikbd_wait_for_input(void) @@ -414,7 +415,10 @@ static unsigned long pcibeep_iobase = 0; /* Timer routine to turn off the beep after the interval expires. */ static void pcikbd_kd_nosound(unsigned long __unused) { - outl(0, pcibeep_iobase); + if (pcibeep_iobase & 0x2UL) + outb(0, pcibeep_iobase); + else + outl(0, pcibeep_iobase); } /* @@ -431,13 +435,20 @@ static void pcikbd_kd_mksound(unsigned int hz, unsigned int ticks) save_flags(flags); cli(); del_timer(&sound_timer); if (hz) { - outl(1, pcibeep_iobase); + if (pcibeep_iobase & 0x2UL) + outb(1, pcibeep_iobase); + else + outl(1, pcibeep_iobase); if (ticks) { sound_timer.expires = jiffies + ticks; add_timer(&sound_timer); } - } else - outl(0, pcibeep_iobase); + } else { + if (pcibeep_iobase & 0x2UL) + outb(0, pcibeep_iobase); + else + outl(0, pcibeep_iobase); + } restore_flags(flags); } #endif @@ -523,6 +534,25 @@ void __init pcikbd_init_hw(void) } } } +#ifdef CONFIG_USB + /* We are being called for the sake of USB keyboard + * state initialization. So we should check for beeper + * device in this case. + */ + edev = 0; + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "beep")) { + pcibeep_iobase = edev->resource[0].start; + kd_mksound = pcikbd_kd_mksound; + printk("8042(speaker): iobase[%016lx]\n", pcibeep_iobase); + return; + } + } + } + + /* No beeper found, ok complain. */ +#endif printk("pcikbd_init_hw: no 8042 found\n"); return; diff --git a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c new file mode 100644 index 000000000..70e8d6198 --- /dev/null +++ b/drivers/sbus/char/riowatchdog.c @@ -0,0 +1,275 @@ +/* $Id: riowatchdog.c,v 1.1 2001/03/24 06:04:24 davem Exp $ + * riowatchdog.c - driver for hw watchdog inside Super I/O of RIO + * + * Copyright (C) 2001 David S. Miller (davem@redhat.com) + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/miscdevice.h> + +#include <asm/io.h> +#include <asm/ebus.h> +#include <asm/bbc.h> +#include <asm/oplib.h> +#include <asm/uaccess.h> + +#include <asm/watchdog.h> + +/* RIO uses the NatSemi Super I/O power management logical device + * as its' watchdog. + * + * When the watchdog triggers, it asserts a line to the BBC (Boot Bus + * Controller) of the machine. The BBC can be configured to treat the + * assertion of this signal in different ways. It can trigger an XIR + * (external CPU reset) to all the processors or it can trigger a true + * power-on reset which triggers the RST signal of all devices in the machine. + * + * The only Super I/O device register we care about is at index + * 0x05 (WDTO_INDEX) which is the watchdog time-out in minutes (1-255). + * If set to zero, this disables the watchdog. When set, the system + * must periodically (before watchdog expires) clear (set to zero) and + * re-set the watchdog else it will trigger. + * + * There are two other indexed watchdog registers inside this Super I/O + * logical device, but they are unused. The first, at index 0x06 is + * the watchdog control and can be used to make the watchdog timer re-set + * when the PS/2 mouse or serial lines show activity. The second, at + * index 0x07 is merely a sampling of the line from the watchdog to the + * BBC. + * + * The watchdog device generates no interrupts. + */ + +MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); +MODULE_DESCRIPTION("Hardware watchdog driver for Sun RIO"); +MODULE_SUPPORTED_DEVICE("watchdog"); + +#define RIOWD_NAME "pmc" +#define RIOWD_MINOR 215 + +static spinlock_t riowd_lock = SPIN_LOCK_UNLOCKED; + +static void *riowd_regs; +#define WDTO_INDEX 0x05 + +static int riowd_timeout = 1; /* in minutes */ +static int riowd_xir = 1; /* watchdog generates XIR? */ +MODULE_PARM(riowd_timeout,"i"); +MODULE_PARM_DESC(riowd_timeout, "Watchdog timeout in minutes"); +MODULE_PARM(riowd_xir,"i"); +MODULE_PARM_DESC(riowd_xir, "Watchdog generates XIR reset if non-zero"); + +#if 0 /* Currently unused. */ +static u8 riowd_readreg(int index) +{ + unsigned long flags; + u8 ret; + + spin_lock_irqsave(&riowd_lock, flags); + writeb(index, riowd_regs + 0); + ret = readb(riowd_regs + 1); + spin_unlock_irqrestore(&riowd_lock, flags); + + return ret; +} +#endif + +static void riowd_writereg(u8 val, int index) +{ + unsigned long flags; + + spin_lock_irqsave(&riowd_lock, flags); + writeb(index, riowd_regs + 0); + writeb(val, riowd_regs + 1); + spin_unlock_irqrestore(&riowd_lock, flags); +} + +static void riowd_pingtimer(void) +{ + riowd_writereg(riowd_timeout, WDTO_INDEX); +} + +static void riowd_stoptimer(void) +{ + riowd_writereg(0, WDTO_INDEX); +} + +static void riowd_starttimer(void) +{ + riowd_writereg(riowd_timeout, WDTO_INDEX); +} + +static int riowd_open(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int riowd_release(struct inode *inode, struct file *filp) +{ + return 0; +} + +static int riowd_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + static struct watchdog_info info = { 0, 0, "Natl. Semiconductor PC97317" }; + unsigned int options; + + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user((struct watchdog_info *) arg, &info, sizeof(info))) + return -EFAULT; + break; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + if (put_user(0, (int *) arg)) + return -EFAULT; + break; + + case WDIOC_KEEPALIVE: + riowd_pingtimer(); + break; + + case WDIOC_SETOPTIONS: + if (copy_from_user(&options, (void *) arg, sizeof(options))) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) + riowd_stoptimer(); + else if (options & WDIOS_ENABLECARD) + riowd_starttimer(); + else + return -EINVAL; + + break; + + default: + return -EINVAL; + }; + + return 0; +} + +static ssize_t riowd_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + if (ppos != &file->f_pos) + return -ESPIPE; + + if (count) { + riowd_pingtimer(); + return 1; + } + + return 0; +} + +static ssize_t riowd_read(struct file *file, char *buffer, size_t count, loff_t *ppos) +{ + return -EINVAL; +} + +static struct file_operations riowd_fops = { + owner: THIS_MODULE, + ioctl: riowd_ioctl, + open: riowd_open, + write: riowd_write, + read: riowd_read, + release: riowd_release, +}; + +static struct miscdevice riowd_miscdev = { RIOWD_MINOR, RIOWD_NAME, &riowd_fops }; + +static int __init riowd_bbc_init(void) +{ + struct linux_ebus *ebus = NULL; + struct linux_ebus_device *edev = NULL; + void *bbc_regs; + u8 val; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, "bbc")) + goto found_bbc; + } + } + +found_bbc: + if (!edev) + return -ENODEV; + bbc_regs = ioremap(edev->resource[0].start, BBC_REGS_SIZE); + if (!bbc_regs) + return -ENODEV; + + val = readb(bbc_regs + BBC_WDACTION); + if (riowd_xir != 0) + val &= ~BBC_WDACTION_RST; + else + val |= BBC_WDACTION_RST; + writeb(val, bbc_regs + BBC_WDACTION); + + iounmap(bbc_regs); + return 0; +} + +static int __init riowd_init(void) +{ + struct linux_ebus *ebus = NULL; + struct linux_ebus_device *edev = NULL; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, RIOWD_NAME)) + goto ebus_done; + } + } + +ebus_done: + if (!edev) + goto fail; + + riowd_regs = ioremap(edev->resource[0].start, 2); + if (riowd_regs == NULL) { + printk(KERN_ERR "pmc: Cannot map registers.\n"); + return -ENODEV; + } + + if (riowd_bbc_init()) { + printk(KERN_ERR "pmc: Failure initializing BBC config.\n"); + goto fail; + } + + if (misc_register(&riowd_miscdev)) { + printk(KERN_ERR "pmc: Cannot register watchdog misc device.\n"); + goto fail; + } + + printk(KERN_INFO "pmc: Hardware watchdog [%i minutes, %s reset], " + "regs at %p\n", + riowd_timeout, (riowd_xir ? "XIR" : "POR"), + riowd_regs); + + return 0; + +fail: + if (riowd_regs) { + iounmap(riowd_regs); + riowd_regs = NULL; + } + return -ENODEV; +} + +static void __exit riowd_cleanup(void) +{ + misc_deregister(&riowd_miscdev); + iounmap(riowd_regs); + riowd_regs = NULL; +} + +module_init(riowd_init); +module_exit(riowd_cleanup); diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c index b862b3538..c1fc98b06 100644 --- a/drivers/sbus/char/rtc.c +++ b/drivers/sbus/char/rtc.c @@ -1,4 +1,4 @@ -/* $Id: rtc.c,v 1.25 2001/02/13 01:17:00 davem Exp $ +/* $Id: rtc.c,v 1.26 2001/03/14 09:30:31 davem Exp $ * * Linux/SPARC Real Time Clock Driver * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -157,11 +157,11 @@ static int __init rtc_sun_init(void) { int error; - if (mstk48t02_regs == 0) { - /* This diagnostic is a debugging aid... But a useful one. */ - printk(KERN_ERR "rtc: no Mostek in this computer\n"); + /* It is possible we are being driven by some other RTC chip + * and thus another RTC driver is handling things. + */ + if (mstk48t02_regs == 0) return -ENODEV; - } error = misc_register(&rtc_dev); if (error) { diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c index 6f62d5f1b..4a4a65d13 100644 --- a/drivers/sbus/char/sab82532.c +++ b/drivers/sbus/char/sab82532.c @@ -1,4 +1,4 @@ -/* $Id: sab82532.c,v 1.55 2001/02/13 01:17:00 davem Exp $ +/* $Id: sab82532.c,v 1.56 2001/03/15 02:11:10 davem Exp $ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -2084,6 +2084,23 @@ static int __init get_sab82532(unsigned long *memory_start) for_each_ebusdev(edev, ebus) { if (!strcmp(edev->prom_name, "se")) goto ebus_done; + + if (!strcmp(edev->prom_name, "serial")) { + char compat[32]; + int clen; + + /* On RIO this can be an SE, check it. We could + * just check ebus->is_rio, but this is more portable. + */ + clen = prom_getproperty(edev->prom_node, "compatible", + compat, sizeof(compat)); + if (clen > 0) { + if (strncmp(compat, "sab82532", 8) == 0) { + /* Yep. */ + goto ebus_done; + } + } + } } } ebus_done: @@ -2134,7 +2151,7 @@ static void __init sab82532_kgdb_hook(int line) static inline void __init show_serial_version(void) { - char *revision = "$Revision: 1.55 $"; + char *revision = "$Revision: 1.56 $"; char *version, *p; version = strchr(revision, ' '); @@ -2316,11 +2333,26 @@ int __init sab82532_probe(void) * For each EBus on this PCI... */ while (enode) { - snode = prom_getchild(enode); - snode = prom_searchsiblings(snode, "se"); + int child; + + child = prom_getchild(enode); + snode = prom_searchsiblings(child, "se"); if (snode) goto found; + snode = prom_searchsiblings(child, "serial"); + if (snode) { + char compat[32]; + int clen; + + clen = prom_getproperty(snode, "compatible", + compat, sizeof(compat)); + if (clen > 0) { + if (strncmp(compat, "sab82532", 8) == 0) + goto found; + } + } + enode = prom_getsibling(enode); enode = prom_searchsiblings(enode, "ebus"); } diff --git a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c index f45ef22d2..631c0f00d 100644 --- a/drivers/sbus/char/su.c +++ b/drivers/sbus/char/su.c @@ -1,4 +1,4 @@ -/* $Id: su.c,v 1.44 2001/02/13 01:17:00 davem Exp $ +/* $Id: su.c,v 1.45 2001/03/15 02:11:10 davem Exp $ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -352,16 +352,16 @@ receive_kbd_ms_chars(struct su_struct *info, struct pt_regs *regs, int is_brk) do { ch = serial_inp(info, UART_RX); if (info->port_type == SU_PORT_KBD) { - if(ch == SUNKBD_RESET) { + if (ch == SUNKBD_RESET) { l1a_state.kbd_id = 1; l1a_state.l1_down = 0; - } else if(l1a_state.kbd_id) { + } else if (l1a_state.kbd_id) { l1a_state.kbd_id = 0; - } else if(ch == SUNKBD_L1) { + } else if (ch == SUNKBD_L1) { l1a_state.l1_down = 1; - } else if(ch == (SUNKBD_L1|SUNKBD_UP)) { + } else if (ch == (SUNKBD_L1|SUNKBD_UP)) { l1a_state.l1_down = 0; - } else if(ch == SUNKBD_A && l1a_state.l1_down) { + } else if (ch == SUNKBD_A && l1a_state.l1_down) { /* whee... */ batten_down_hatches(); /* Continue execution... */ @@ -1166,7 +1166,7 @@ su_change_mouse_baud(int baud) return; info->cflag &= ~(CBAUDEX | CBAUD); - switch(baud) { + switch (baud) { case 1200: info->cflag |= B1200; break; @@ -2220,7 +2220,7 @@ done: */ static __inline__ void __init show_su_version(void) { - char *revision = "$Revision: 1.44 $"; + char *revision = "$Revision: 1.45 $"; char *version, *p; version = strchr(revision, ' '); @@ -2578,6 +2578,30 @@ int __init su_kbd_ms_init(void) return 0; } +static int su_node_ok(int node, char *name, int namelen) +{ + if (strncmp(name, "su", namelen) == 0 || + strncmp(name, "su_pnp", namelen) == 0) + return 1; + + if (strncmp(name, "serial", namelen) == 0) { + char compat[32]; + int clen; + + /* Is it _really_ a 'su' device? */ + clen = prom_getproperty(node, "compatible", compat, sizeof(compat)); + if (clen > 0) { + if (strncmp(compat, "sab82532", 8) == 0) { + /* Nope, Siemens serial, not for us. */ + return 0; + } + } + return 1; + } + + return 0; +} + /* * We got several platforms which present 'su' in different parts * of device tree. 'su' may be found under obio, ebus, isa and pci. @@ -2593,9 +2617,7 @@ void __init su_probe_any(struct su_probe_scan *t, int sunode) for (; sunode != 0; sunode = prom_getsibling(sunode)) { len = prom_getproperty(sunode, "name", t->prop, SU_PROPSIZE); if (len <= 1) continue; /* Broken PROM node */ - if (strncmp(t->prop, "su", len) == 0 || - strncmp(t->prop, "serial", len) == 0 || - strncmp(t->prop, "su_pnp", len) == 0) { + if (su_node_ok(sunode, t->prop, len)) { info = &su_table[t->devices]; if (t->kbnode != 0 && sunode == t->kbnode) { t->kbx = t->devices; @@ -2844,7 +2866,7 @@ static int __init serial_console_setup(struct console *co, char *options) if (options) { baud = simple_strtoul(options, NULL, 10); s = options; - while(*s >= '0' && *s <= '9') + while (*s >= '0' && *s <= '9') s++; if (*s) parity = *s++; if (*s) bits = *s - '0'; @@ -2853,7 +2875,7 @@ static int __init serial_console_setup(struct console *co, char *options) /* * Now construct a cflag setting. */ - switch(baud) { + switch (baud) { case 1200: cflag |= B1200; break; @@ -2880,7 +2902,7 @@ static int __init serial_console_setup(struct console *co, char *options) cflag |= B9600; break; } - switch(bits) { + switch (bits) { case 7: cflag |= CS7; break; @@ -2889,7 +2911,7 @@ static int __init serial_console_setup(struct console *co, char *options) cflag |= CS8; break; } - switch(parity) { + switch (parity) { case 'o': case 'O': cflag |= PARODD; break; diff --git a/drivers/sbus/char/sunserial.c b/drivers/sbus/char/sunserial.c index e58eb1ef7..fe3638596 100644 --- a/drivers/sbus/char/sunserial.c +++ b/drivers/sbus/char/sunserial.c @@ -1,4 +1,4 @@ -/* $Id: sunserial.c,v 1.75 2000/03/22 02:45:36 davem Exp $ +/* $Id: sunserial.c,v 1.78 2001/03/21 22:43:11 davem Exp $ * serial.c: Serial port driver infrastructure for the Sparc. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -54,21 +54,23 @@ struct sunserial_operations rs_ops = { nop_rs_read_proc }; -int rs_init(void) +void rs_init(void) { - struct initfunc *init; - int err = -ENODEV; + static int invoked = 0; - init = rs_ops.rs_init; - while (init) { - err = init->init(); - init = init->next; + if (!invoked) { + struct initfunc *init; + + invoked = 1; + + init = rs_ops.rs_init; + while (init) { + (void) init->init(); + init = init->next; + } } - return err; } -__initcall(rs_init); - void __init rs_kgdb_hook(int channel) { rs_ops.rs_kgdb_hook(channel); @@ -137,6 +139,15 @@ struct sunkbd_operations kbd_ops = { nop_getkeycode }; +#ifdef CONFIG_USB +extern void pci_compute_shiftstate(void); +extern int pci_setkeycode(unsigned int, unsigned int); +extern int pci_getkeycode(unsigned int); +extern void pci_setledstate(struct kbd_struct *, unsigned int); +extern unsigned char pci_getledstate(void); +extern int pcikbd_init(void); +#endif + int kbd_init(void) { struct initfunc *init; @@ -147,6 +158,18 @@ int kbd_init(void) err = init->init(); init = init->next; } +#ifdef CONFIG_USB + if (!serial_console && + kbd_ops.compute_shiftstate == nop_compute_shiftstate) { + printk("kbd_init: Assuming USB keyboard.\n"); + kbd_ops.compute_shiftstate = pci_compute_shiftstate; + kbd_ops.setledstate = pci_setledstate; + kbd_ops.getledstate = pci_getledstate; + kbd_ops.setkeycode = pci_setkeycode; + kbd_ops.getkeycode = pci_getkeycode; + pcikbd_init(); + } +#endif return err; } diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index c395c018a..e9a84a6d8 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -362,7 +362,7 @@ static int vfc_set_control_ioctl(struct inode *inode, struct file *file, vfc_capture_poll(dev); break; case DIAGMODE: - if(suser()) { + if(capable(CAP_SYS_ADMIN)) { vfc_lock_device(dev); dev->control_reg |= VFC_CONTROL_DIAGMODE; sbus_writel(dev->control_reg, &dev->regs->control); |