Commit 0b520647 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/davem/BK/sparc-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 35aa61ec e79e45cb
......@@ -10,6 +10,7 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <asm/page.h>
#include <asm/oplib.h>
......@@ -17,6 +18,11 @@
#include <asm/smp.h>
#include <asm/spitfire.h>
/* Used to synchronize acceses to NatSemi SUPER I/O chip configure
* operations in asm/ns87303.h
*/
spinlock_t ns87303_lock = SPIN_LOCK_UNLOCKED;
struct prom_cpuinfo linux_cpus[NR_CPUS] __initdata = { { 0 } };
unsigned prom_cpu_nodes[NR_CPUS];
int linux_num_cpus = 0;
......
......@@ -45,7 +45,6 @@ cpuinfo_sparc cpu_data[NR_CPUS];
/* Please don't make this stuff initdata!!! --DaveM */
static unsigned char boot_cpu_id;
static int smp_activated;
/* Kernel spinlock */
spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
......@@ -223,85 +222,46 @@ extern unsigned long sparc64_cpu_startup;
*/
static struct thread_info *cpu_new_thread = NULL;
static void __init smp_boot_cpus(unsigned int max_cpus)
static int __devinit smp_boot_one_cpu(unsigned int cpu)
{
int cpucount = 0, i;
unsigned long entry =
(unsigned long)(&sparc64_cpu_startup);
unsigned long cookie =
(unsigned long)(&cpu_new_thread);
struct task_struct *p;
int timeout, no, ret;
printk("Entering UltraSMPenguin Mode...\n");
local_irq_enable();
smp_store_cpu_info(boot_cpu_id);
if (linux_num_cpus == 1)
return;
for (i = 0; i < NR_CPUS; i++) {
if (i == boot_cpu_id)
continue;
if ((cpucount + 1) == max_cpus)
goto ignorecpu;
if (test_bit(i, &phys_cpu_present_map)) {
unsigned long entry =
(unsigned long)(&sparc64_cpu_startup);
unsigned long cookie =
(unsigned long)(&cpu_new_thread);
struct task_struct *p;
int timeout;
int no;
kernel_thread(NULL, NULL, CLONE_IDLETASK);
prom_printf("Starting CPU %d... ", i);
kernel_thread(NULL, NULL, CLONE_IDLETASK);
cpucount++;
p = prev_task(&init_task);
p = prev_task(&init_task);
init_idle(p, cpu);
init_idle(p, i);
unhash_process(p);
unhash_process(p);
callin_flag = 0;
for (no = 0; no < linux_num_cpus; no++)
if (linux_cpus[no].mid == i)
break;
cpu_new_thread = p->thread_info;
set_bit(i, &cpu_callout_map);
prom_startcpu(linux_cpus[no].prom_node,
entry, cookie);
for (timeout = 0; timeout < 5000000; timeout++) {
if (callin_flag)
break;
udelay(100);
}
if (callin_flag) {
prom_cpu_nodes[i] = linux_cpus[no].prom_node;
prom_printf("OK\n");
} else {
cpucount--;
printk("Processor %d is stuck.\n", i);
prom_printf("FAILED\n");
clear_bit(i, &cpu_callout_map);
}
ignorecpu:
}
callin_flag = 0;
for (no = 0; no < linux_num_cpus; no++)
if (linux_cpus[no].mid == cpu)
break;
cpu_new_thread = p->thread_info;
set_bit(cpu, &cpu_callout_map);
prom_startcpu(linux_cpus[no].prom_node, entry, cookie);
for (timeout = 0; timeout < 5000000; timeout++) {
if (callin_flag)
break;
udelay(100);
}
cpu_new_thread = NULL;
if (cpucount == 0) {
if (max_cpus != 1)
printk("Error: only one processor found.\n");
if (callin_flag) {
prom_cpu_nodes[cpu] = linux_cpus[no].prom_node;
ret = 0;
} else {
unsigned long bogosum = 0;
for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i))
bogosum += cpu_data[i].udelay_val;
}
printk("Total of %d processors activated "
"(%lu.%02lu BogoMIPS).\n",
cpucount + 1,
bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);
smp_activated = 1;
printk("Processor %d is stuck.\n", cpu);
clear_bit(cpu, &cpu_callout_map);
ret = -ENODEV;
}
cpu_new_thread = NULL;
return ret;
}
static void spitfire_xcall_helper(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu)
......@@ -1119,8 +1079,6 @@ static void __init smp_setup_percpu_timer(void)
void __init smp_tick_init(void)
{
int i;
boot_cpu_id = hard_smp_processor_id();
current_tick_offset = timer_tick_offset;
......@@ -1129,19 +1087,10 @@ void __init smp_tick_init(void)
prom_halt();
}
atomic_set(&sparc64_num_cpus_online, 1);
memset(&cpu_online_map, 0, sizeof(cpu_online_map));
atomic_inc(&sparc64_num_cpus_online);
set_bit(boot_cpu_id, &cpu_online_map);
prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node;
prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1;
for (i = 0; i < linux_num_cpus; i++) {
if (linux_cpus[i].mid < NR_CPUS) {
set_bit(linux_cpus[i].mid,
&phys_cpu_present_map);
atomic_inc(&sparc64_num_cpus_possible);
}
}
}
cycles_t cacheflush_time;
......@@ -1272,19 +1221,59 @@ int setup_profiling_timer(unsigned int multiplier)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
smp_boot_cpus(max_cpus);
int i;
for (i = 0; i < linux_num_cpus; i++) {
if (linux_cpus[i].mid < max_cpus) {
set_bit(linux_cpus[i].mid,
&phys_cpu_present_map);
atomic_inc(&sparc64_num_cpus_possible);
}
}
if (atomic_read(&sparc64_num_cpus_possible) > max_cpus) {
for (i = linux_num_cpus - 1; i >= 0; i--) {
if (linux_cpus[i].mid != boot_cpu_id) {
clear_bit(linux_cpus[i].mid,
&phys_cpu_present_map);
atomic_dec(&sparc64_num_cpus_possible);
if (atomic_read(&sparc64_num_cpus_possible) <= max_cpus)
break;
}
}
}
smp_store_cpu_info(boot_cpu_id);
}
int __devinit __cpu_up(unsigned int cpu)
{
set_bit(cpu, &smp_commenced_mask);
while (!test_bit(cpu, &cpu_online_map))
mb();
return 0;
int ret = smp_boot_one_cpu(cpu);
if (!ret) {
set_bit(cpu, &smp_commenced_mask);
while (!test_bit(cpu, &cpu_online_map))
mb();
if (!test_bit(cpu, &cpu_online_map))
ret = -ENODEV;
}
return ret;
}
void __init smp_cpus_done(unsigned int max_cpus)
{
unsigned long bogosum = 0;
int i;
for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i))
bogosum += cpu_data[i].udelay_val;
}
printk("Total of %d processors activated "
"(%lu.%02lu BogoMIPS).\n",
num_online_cpus(),
bogosum/(500000/HZ),
(bogosum/(5000/HZ))%100);
/* We want to run this with all the other cpus spinning
* in the kernel.
*/
......
......@@ -52,6 +52,7 @@
#include <asm/isa.h>
#endif
#include <asm/a.out.h>
#include <asm/ns87303.h>
struct poll {
int fd;
......@@ -373,3 +374,6 @@ EXPORT_SYMBOL(kbd_pt_regs);
#ifdef CONFIG_DEBUG_BUGVERBOSE
EXPORT_SYMBOL(do_BUG);
#endif
/* for ns8703 */
EXPORT_SYMBOL(ns87303_lock);
......@@ -250,8 +250,8 @@ solaris_sys_table:
.word solaris_fstatvfs64 /* fstatvfs64 dP 219 */
.word solaris_setrlimit64 /* setrlimit64 dP 220 */
.word solaris_getrlimit64 /* getrlimit64 dP 221 */
.word CHAIN(pread) /* pread64 dpdD 222 */
.word CHAIN(pwrite) /* pwrite64 dpdD 223 */
.word CHAIN(pread64) /* pread64 dpdD 222 */
.word CHAIN(pwrite64) /* pwrite64 dpdD 223 */
.word CHAIN(creat) /* creat64 so 224 */
.word solaris_open /* open64 soo 225 */
.word solaris_unimplemented /* 226 */
......
......@@ -546,8 +546,11 @@ static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct myri_eth *mp = (struct myri_eth *) dev->priv;
unsigned long lregs = mp->lregs;
struct myri_channel *chan = &mp->shmem->channel;
unsigned long flags;
u32 status;
spin_lock_irqsave(&mp->irq_lock, flags);
status = sbus_readl(lregs + LANAI_ISTAT);
DIRQ(("myri_interrupt: status[%08x] ", status));
if (status & ISTAT_HOST) {
......@@ -569,6 +572,8 @@ static void myri_interrupt(int irq, void *dev_id, struct pt_regs *regs)
myri_enable_irq(lregs, mp->cregs);
}
DIRQ(("\n"));
spin_unlock_irqrestore(&mp->irq_lock, flags);
}
static int myri_open(struct net_device *dev)
......@@ -622,7 +627,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
return 1;
}
save_and_cli(flags);
spin_lock_irqsave(&mp->irq_lock, flags);
DHDR(("xmit[skbdata(%p)]\n", skb->data));
#ifdef DEBUG_HEADER
......@@ -669,7 +674,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
DTX(("tbusy=0, returning 0\n"));
netif_start_queue(dev);
restore_flags(flags);
spin_unlock_irqrestore(&mp->irq_lock, flags);
return 0;
}
......@@ -900,6 +905,7 @@ static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev,
printk("%s: MyriCOM MyriNET Ethernet ", dev->name);
mp = (struct myri_eth *) dev->priv;
spin_lock_init(&mp->irq_lock);
mp->myri_sdev = sdev;
/* Clean out skb arrays. */
......
......@@ -269,6 +269,7 @@ struct myri_eth {
/* These are frequently accessed, keep together
* to obtain good cache hit rates.
*/
spinlock_t irq_lock;
struct myri_shmem *shmem; /* Shared data structures. */
unsigned long cregs; /* Control register space. */
struct recvq *rqack; /* Where we ack rx's. */
......
......@@ -147,7 +147,6 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
DATA *data = (DATA *) file->private_data;
char buffer[OPROMMAXPARAM+1], *buf;
struct openpromio *opp;
unsigned long flags;
int bufsize, len, error = 0;
extern char saved_command_line[];
static int cnt;
......@@ -163,18 +162,14 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
switch (cmd) {
case OPROMGETOPT:
case OPROMGETPROP:
save_and_cli(flags);
len = prom_getproplen(node, opp->oprom_array);
restore_flags(flags);
if (len <= 0 || len > bufsize) {
error = copyout((void *)arg, opp, sizeof(int));
break;
}
save_and_cli(flags);
len = prom_getproperty(node, opp->oprom_array, buffer, bufsize);
restore_flags(flags);
memcpy(opp->oprom_array, buffer, len);
opp->oprom_array[len] = '\0';
......@@ -185,9 +180,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
case OPROMNXTOPT:
case OPROMNXTPROP:
save_and_cli(flags);
buf = prom_nextprop(node, opp->oprom_array, buffer);
restore_flags(flags);
len = strlen(buf);
if (len == 0 || len + 1 > bufsize) {
......@@ -207,10 +200,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
buf = opp->oprom_array + strlen(opp->oprom_array) + 1;
len = opp->oprom_array + bufsize - buf;
save_and_cli(flags);
error = prom_setprop(options_node, opp->oprom_array,
buf, len);
restore_flags(flags);
if (error < 0)
error = -EINVAL;
......@@ -226,13 +217,11 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
node = *((int *) opp->oprom_array);
save_and_cli(flags);
switch (cmd) {
case OPROMNEXT: node = __prom_getsibling(node); break;
case OPROMCHILD: node = __prom_getchild(node); break;
case OPROMSETCUR: break;
}
restore_flags(flags);
data->current_node = node;
*((int *)opp->oprom_array) = node;
......@@ -264,9 +253,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
break;
case OPROMPATH2NODE:
save_and_cli(flags);
node = prom_finddevice(opp->oprom_array);
restore_flags(flags);
data->current_node = node;
*((int *)opp->oprom_array) = node;
opp->oprom_size = sizeof(int);
......@@ -361,7 +348,6 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
{
DATA *data = (DATA *) file->private_data;
struct opiocdesc op;
unsigned long flags;
int error, node, len;
char *str, *tmp;
char buffer[64];
......@@ -379,9 +365,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
if (error)
return error;
save_and_cli(flags);
len = prom_getproplen(op.op_nodeid,str);
restore_flags(flags);
if (len > op.op_buflen) {
kfree(str);
......@@ -405,9 +389,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
return -ENOMEM;
}
save_and_cli(flags);
prom_getproperty(op.op_nodeid, str, tmp, len);
restore_flags(flags);
tmp[len] = '\0';
......@@ -431,9 +413,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
if (error)
return error;
save_and_cli(flags);
tmp = prom_nextprop(op.op_nodeid,str,buffer);
restore_flags(flags);
if (tmp) {
len = strlen(tmp);
......@@ -481,9 +461,7 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
return error;
}
save_and_cli(flags);
len = prom_setprop(op.op_nodeid,str,tmp,op.op_buflen+1);
restore_flags(flags);
if (len != op.op_buflen)
return -EINVAL;
......@@ -503,12 +481,10 @@ static int openprom_bsd_ioctl(struct inode * inode, struct file * file,
if (copy_from_user(&node, (void *)arg, sizeof(int)))
return -EFAULT;
save_and_cli(flags);
if (cmd == OPIOCGETNEXT)
node = __prom_getsibling(node);
else
node = __prom_getchild(node);
restore_flags(flags);
if (__copy_to_user((void *)arg, &node, sizeof(int)))
return -EFAULT;
......@@ -624,7 +600,6 @@ static struct miscdevice openprom_dev = {
static int __init openprom_init(void)
{
unsigned long flags;
int error;
error = misc_register(&openprom_dev);
......@@ -633,10 +608,8 @@ static int __init openprom_init(void)
return error;
}
save_and_cli(flags);
options_node = prom_getchild(prom_root_node);
options_node = prom_searchsiblings(options_node,"options");
restore_flags(flags);
if (options_node == 0 || options_node == -1) {
printk(KERN_ERR "openprom: unable to find options node\n");
......
......@@ -318,7 +318,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
risc_code_addr = 0x1000; /* all load addresses are at 0x1000 */
save_flags(flags); cli();
spin_lock_irqsave(&qpti->lock, flags);
sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
......@@ -366,7 +366,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot execute ISP firmware.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -377,7 +377,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: Cannot set initiator SCSI ID.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -392,7 +392,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot init response queue.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -404,7 +404,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot init request queue.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -450,7 +450,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
qlogicpti_mbox_command(qpti, param, 0);
qpti->send_marker = 1;
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 0;
}
......@@ -468,7 +468,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */
risc_code_length = sbus_risc_code_length01;
save_flags(flags); cli();
spin_lock_irqsave(&qpti->lock, flags);
/* Verify the checksum twice, one before loading it, and once
* afterwards via the mailbox commands.
......@@ -476,7 +476,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
for (i = 0; i < risc_code_length; i++)
csum += risc_code[i];
if (csum) {
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
qpti->qpti_id);
return 1;
......@@ -488,7 +488,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
udelay(20);
if (!timeout) {
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
return 1;
}
......@@ -528,7 +528,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -541,7 +541,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
param[0] != MBOX_COMMAND_COMPLETE) {
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
}
......@@ -561,7 +561,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -575,7 +575,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -591,7 +591,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
qpti->qpti_id);
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 1;
}
......@@ -608,7 +608,7 @@ static int __init qlogicpti_load_firmware(struct qlogicpti *qpti)
qlogicpti_mbox_command(qpti, param, 1);
}
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return 0;
}
......@@ -1166,8 +1166,8 @@ static void ourdone(Scsi_Cmnd *Cmnd)
int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
{
unsigned long flags;
struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata;
unsigned long flags;
/*
* done checking this host adapter?
......@@ -1178,12 +1178,13 @@ int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
if (qpti->sbits && qpti->sbits != 0xffff) {
/* See above about in ourdone this ugliness... */
Cmnd->SCp.Message = ((unsigned long)done) & 0xffffffff;
#ifdef __sparc_v9__
#ifdef CONFIG_SPARC64
Cmnd->SCp.Status = ((unsigned long)done >> 32UL) & 0xffffffff;
#endif
return qlogicpti_queuecommand(Cmnd, ourdone);
}
save_flags(flags); cli();
spin_lock_irqsave(&qpti->lock, flags);
/*
* We've peeked at all targets for this bus- time
......@@ -1226,7 +1227,8 @@ int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
if (qpti == NULL)
Cmnd->host->hostt->queuecommand = qlogicpti_queuecommand;
restore_flags(flags);
spin_unlock_irqrestore(&qpti->lock, flags);
return qlogicpti_queuecommand(Cmnd, done);
}
......
This diff is collapsed.
/* $Id: sab82532.h,v 1.7 2001/05/23 23:09:10 ecd Exp $
* sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC
/* sunsab.h: Register Definitions for the Siemens SAB82532 DUSCC
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _SPARC64_SAB82532_H
#define _SPARC64_SAB82532_H
#include <linux/types.h>
#include <linux/serial.h>
#include <linux/circ_buf.h>
#ifndef _SUNSAB_H
#define _SUNSAB_H
struct sab82532_async_rd_regs {
u8 rfifo[0x20]; /* Receive FIFO */
......@@ -120,8 +115,6 @@ union sab82532_async_regs {
__volatile__ struct sab82532_async_rw_regs rw;
};
#define NR_PORTS 2
union sab82532_irq_status {
unsigned short stat;
struct {
......@@ -130,62 +123,10 @@ union sab82532_irq_status {
} sreg;
};
struct sab82532 {
int magic;
int baud_base;
union sab82532_async_regs *regs;
int irq;
int flags; /* defined in tty.h */
int type; /* SAB82532 version */
struct tty_struct *tty;
int read_status_mask;
int ignore_status_mask;
int timeout;
int xmit_fifo_size;
int recv_fifo_size;
int custom_divisor;
int baud;
unsigned int cec_timeout;
unsigned int tec_timeout;
int x_char;
int close_delay;
unsigned short closing_wait;
unsigned short closing_wait2;
unsigned long irqflags;
int is_console;
unsigned char interrupt_mask0;
unsigned char interrupt_mask1;
unsigned char pvr_dtr_bit;
unsigned char pvr_dsr_bit;
unsigned char dcd;
unsigned char cts;
unsigned char dsr;
unsigned long event;
unsigned long last_active;
int line;
int count;
int blocked_open;
long session;
long pgrp;
struct circ_buf xmit;
struct tq_struct tqueue;
struct tq_struct tqueue_hangup;
struct async_icount icount;
struct termios normal_termios;
struct termios callout_termios;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
wait_queue_head_t delta_msr_wait;
struct sab82532 *next;
struct sab82532 *prev;
};
/* irqflags bits */
#define SAB82532_ALLS 0x00000001
#define SAB82532_XPR 0x00000002
/* RFIFO Status Byte */
#define SAB82532_RSTAT_PE 0x80
#define SAB82532_RSTAT_FE 0x40
......@@ -377,4 +318,4 @@ struct sab82532 {
#define SAB82532_CCR4_ICD 0x10
#endif /* !(_SPARC64_SAB82532_H) */
#endif /* !(_SUNSAB_H) */
......@@ -1362,7 +1362,7 @@ static void sunsu_console_write(struct console *co, const char *s,
static kdev_t sunsu_console_device(struct console *co)
{
return mk_kdev(TTY_MAJOR, 64 + co->index);
return mk_kdev(sunsu_reg.major, sunsu_reg.minor + co->index);
}
/*
......@@ -1379,6 +1379,9 @@ static int __init sunsu_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
printk("Console: ttyS%d (SU)\n",
(sunsu_reg.minor - 64) + co->index);
/*
* Check whether an invalid uart number has been specified, and
* if so, search for the first available port that does have
......@@ -1414,15 +1417,23 @@ static struct console sunsu_cons = {
static int __init sunsu_serial_console_init(void)
{
int index;
int i;
if (con_is_present())
return 0;
index = serial_console - 1;
if (sunsu_ports[index].port_node == 0)
for (i = 0; i < UART_NR; i++) {
int this_minor = sunsu_reg.minor + i;
if ((this_minor - 64) == (serial_console - 1))
break;
}
if (i == UART_NR)
return 0;
sunsu_cons.index = index;
if (sunsu_ports[i].port_node == 0)
return 0;
sunsu_cons.index = i;
register_console(&sunsu_cons);
return 0;
}
......
......@@ -1013,7 +1013,6 @@ static struct uart_driver sunzilog_reg = {
.dev_name = "ttyS",
#endif
.major = TTY_MAJOR,
.minor = 64,
};
static void * __init alloc_one_table(unsigned long size)
......@@ -1386,7 +1385,7 @@ sunzilog_console_write(struct console *con, const char *s, unsigned int count)
static kdev_t sunzilog_console_device(struct console *con)
{
return mk_kdev(TTY_MAJOR, 64 + con->index);
return mk_kdev(sunzilog_reg.major, sunzilog_reg.minor + con->index);
}
static int __init sunzilog_console_setup(struct console *con, char *options)
......@@ -1395,7 +1394,8 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
unsigned long flags;
int baud, brg;
printk("Console: ttyS%d (Zilog8530)\n", con->index / 2);
printk("Console: ttyS%d (Zilog8530)\n",
(sunzilog_reg.minor - 64) + con->index);
/* Get firmware console settings. */
sunserial_console_termios(con);
......@@ -1447,10 +1447,21 @@ static struct console sunzilog_console = {
static int __init sunzilog_console_init(void)
{
int i;
if (con_is_present())
return 0;
sunzilog_console.index = serial_console - 1;
for (i = 0; i < NUM_CHANNELS; i++) {
int this_minor = sunzilog_reg.minor + i;
if ((this_minor - 64) == (serial_console - 1))
break;
}
if (i == NUM_CHANNELS)
return 0;
sunzilog_console.index = i;
register_console(&sunzilog_console);
return 0;
}
......@@ -1480,6 +1491,7 @@ static void __init sunzilog_prepare(void)
up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
up[(chip * 2) + 0].port.fifosize = 1;
up[(chip * 2) + 0].port.ops = &sunzilog_pops;
up[(chip * 2) + 0].port.type = PORT_SUNZILOG;
up[(chip * 2) + 0].port.flags = 0;
up[(chip * 2) + 0].port.line = (chip * 2) + 0;
up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
......@@ -1490,6 +1502,7 @@ static void __init sunzilog_prepare(void)
up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
up[(chip * 2) + 1].port.fifosize = 1;
up[(chip * 2) + 1].port.ops = &sunzilog_pops;
up[(chip * 2) + 1].port.type = PORT_SUNZILOG;
up[(chip * 2) + 1].port.flags = 0;
up[(chip * 2) + 1].port.line = (chip * 2) + 1;
up[(chip * 2) + 1].flags |= 0;
......@@ -1607,12 +1620,10 @@ static int __init sunzilog_ports_init(void)
* in the system.
*/
sunzilog_reg.nr = NUM_CHANNELS;
#ifdef CONFIG_SERIAL_CONSOLE
sunzilog_reg.cons = &sunzilog_console;
#else
sunzilog_reg.cons = NULL;
#endif
sunzilog_reg.minor = sunserial_current_minor;
sunserial_current_minor += NUM_CHANNELS;
ret = uart_register_driver(&sunzilog_reg);
if (ret == 0) {
......
......@@ -78,9 +78,13 @@
#ifdef __KERNEL__
#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/io.h>
extern spinlock_t ns87303_lock;
static __inline__ int ns87303_modify(unsigned long port, unsigned int index,
unsigned char clr, unsigned char set)
{
......@@ -96,14 +100,16 @@ static __inline__ int ns87303_modify(unsigned long port, unsigned int index,
if (index > 0x0d)
return -EINVAL;
save_flags(flags); cli();
spin_lock_irqsave(&ns87303_lock, flags);
outb(index, port);
value = inb(port + 1);
value &= ~(reserved[index] | clr);
value |= set;
outb(value, port + 1);
outb(value, port + 1);
restore_flags(flags);
spin_unlock_irqrestore(&ns87303_lock, flags);
return 0;
}
......
......@@ -51,6 +51,10 @@
#define PORT_UART00 35
#define PORT_21285 37
/* Sparc type numbers. */
#define PORT_SUNZILOG 38
#define PORT_SUNSAB 39
#ifdef __KERNEL__
#include <linux/config.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment