Commit 1d0b87e8 authored by Keith M. Wesolowski's avatar Keith M. Wesolowski

[SPARC32]: Remove cli/sti from all arch code.

parent f199c752
This diff is collapsed.
...@@ -940,8 +940,8 @@ static void pcic_load_profile_irq(int cpu, unsigned int limit) ...@@ -940,8 +940,8 @@ static void pcic_load_profile_irq(int cpu, unsigned int limit)
printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
} }
/* We assume the caller is local cli()'d when these are called, or else /* We assume the caller has disabled local interrupts when these are called,
* very bizarre behavior will result. * or else very bizarre behavior will result.
*/ */
static void pcic_disable_pil_irq(unsigned int pil) static void pcic_disable_pil_irq(unsigned int pil)
{ {
......
...@@ -74,7 +74,7 @@ void prom_sync_me(void) ...@@ -74,7 +74,7 @@ void prom_sync_me(void)
unsigned long prom_tbr, flags; unsigned long prom_tbr, flags;
/* XXX Badly broken. FIX! - Anton */ /* XXX Badly broken. FIX! - Anton */
save_and_cli(flags); local_irq_save(flags);
__asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr)); __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr));
__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t" __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
"nop\n\t" "nop\n\t"
...@@ -86,9 +86,9 @@ void prom_sync_me(void) ...@@ -86,9 +86,9 @@ void prom_sync_me(void)
prom_printf("PROM SYNC COMMAND...\n"); prom_printf("PROM SYNC COMMAND...\n");
show_free_areas(); show_free_areas();
if(current->pid != 0) { if(current->pid != 0) {
sti(); local_irq_enable();
sys_sync(); sys_sync();
cli(); local_irq_disable();
} }
prom_printf("Returning to prom\n"); prom_printf("Returning to prom\n");
...@@ -96,7 +96,7 @@ void prom_sync_me(void) ...@@ -96,7 +96,7 @@ void prom_sync_me(void)
"nop\n\t" "nop\n\t"
"nop\n\t" "nop\n\t"
"nop\n\t" : : "r" (prom_tbr)); "nop\n\t" : : "r" (prom_tbr));
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/oplib.h> #include <asm/oplib.h>
#include <asm/hardirq.h> #include <asm/hardirq.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
#include <linux/unistd.h> #include <linux/unistd.h>
...@@ -261,6 +263,9 @@ unsigned int prof_multiplier[NR_CPUS]; ...@@ -261,6 +263,9 @@ unsigned int prof_multiplier[NR_CPUS];
unsigned int prof_counter[NR_CPUS]; unsigned int prof_counter[NR_CPUS];
extern unsigned int lvl14_resolution; extern unsigned int lvl14_resolution;
/* /proc/profile writes can call this, don't __init it please. */
static spinlock_t prof_setup_lock = SPIN_LOCK_UNLOCKED;
int setup_profiling_timer(unsigned int multiplier) int setup_profiling_timer(unsigned int multiplier)
{ {
int i; int i;
...@@ -270,14 +275,14 @@ int setup_profiling_timer(unsigned int multiplier) ...@@ -270,14 +275,14 @@ int setup_profiling_timer(unsigned int multiplier)
if((!multiplier) || (lvl14_resolution / multiplier) < 500) if((!multiplier) || (lvl14_resolution / multiplier) < 500)
return -EINVAL; return -EINVAL;
save_and_cli(flags); spin_lock_irqsave(&prof_setup_lock, flags);
for(i = 0; i < NR_CPUS; i++) { for(i = 0; i < NR_CPUS; i++) {
if(cpu_present_map & (1 << i)) { if(cpu_present_map & (1 << i)) {
load_profile_irq(mid_xlate[i], lvl14_resolution / multiplier); load_profile_irq(mid_xlate[i], lvl14_resolution / multiplier);
prof_multiplier[i] = multiplier; prof_multiplier[i] = multiplier;
} }
} }
restore_flags(flags); spin_unlock_irqrestore(&prof_setup_lock, flags);
return 0; return 0;
} }
......
...@@ -68,7 +68,7 @@ static void sun4c_disable_irq(unsigned int irq_nr) ...@@ -68,7 +68,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)
unsigned long flags; unsigned long flags;
unsigned char current_mask, new_mask; unsigned char current_mask, new_mask;
save_and_cli(flags); local_irq_save(flags);
irq_nr &= (NR_IRQS - 1); irq_nr &= (NR_IRQS - 1);
current_mask = *interrupt_enable; current_mask = *interrupt_enable;
switch(irq_nr) { switch(irq_nr) {
...@@ -85,11 +85,11 @@ static void sun4c_disable_irq(unsigned int irq_nr) ...@@ -85,11 +85,11 @@ static void sun4c_disable_irq(unsigned int irq_nr)
new_mask = ((current_mask) & (~(SUN4C_INT_E14))); new_mask = ((current_mask) & (~(SUN4C_INT_E14)));
break; break;
default: default:
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
*interrupt_enable = new_mask; *interrupt_enable = new_mask;
restore_flags(flags); local_irq_restore(flags);
} }
static void sun4c_enable_irq(unsigned int irq_nr) static void sun4c_enable_irq(unsigned int irq_nr)
...@@ -97,7 +97,7 @@ static void sun4c_enable_irq(unsigned int irq_nr) ...@@ -97,7 +97,7 @@ static void sun4c_enable_irq(unsigned int irq_nr)
unsigned long flags; unsigned long flags;
unsigned char current_mask, new_mask; unsigned char current_mask, new_mask;
save_and_cli(flags); local_irq_save(flags);
irq_nr &= (NR_IRQS - 1); irq_nr &= (NR_IRQS - 1);
current_mask = *interrupt_enable; current_mask = *interrupt_enable;
switch(irq_nr) { switch(irq_nr) {
...@@ -114,11 +114,11 @@ static void sun4c_enable_irq(unsigned int irq_nr) ...@@ -114,11 +114,11 @@ static void sun4c_enable_irq(unsigned int irq_nr)
new_mask = ((current_mask) | SUN4C_INT_E14); new_mask = ((current_mask) | SUN4C_INT_E14);
break; break;
default: default:
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
*interrupt_enable = new_mask; *interrupt_enable = new_mask;
restore_flags(flags); local_irq_restore(flags);
} }
#define TIMER_IRQ 10 /* Also at level 14, but we ignore that one. */ #define TIMER_IRQ 10 /* Also at level 14, but we ignore that one. */
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/sbus.h> #include <asm/sbus.h>
#include <asm/sbi.h> #include <asm/sbi.h>
#include <asm/cacheflush.h>
/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ /* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */
/* #define DISTRIBUTE_IRQS */ /* #define DISTRIBUTE_IRQS */
...@@ -54,6 +55,7 @@ unsigned char sbus_tid[32]; ...@@ -54,6 +55,7 @@ unsigned char sbus_tid[32];
#endif #endif
extern struct irqaction *irq_action[]; extern struct irqaction *irq_action[];
extern spinlock_t irq_action_lock;
struct sbus_action { struct sbus_action {
struct irqaction *action; struct irqaction *action;
...@@ -77,30 +79,32 @@ int show_sun4d_interrupts(struct seq_file *p, void *v) ...@@ -77,30 +79,32 @@ int show_sun4d_interrupts(struct seq_file *p, void *v)
{ {
int i = *(loff_t *) v, j = 0, k = 0, sbusl; int i = *(loff_t *) v, j = 0, k = 0, sbusl;
struct irqaction * action; struct irqaction * action;
unsigned long flags;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
int x; int x;
#endif #endif
spin_lock_irqsave(&irq_action_lock, flags);
if (i < NR_IRQS) { if (i < NR_IRQS) {
sbusl = pil_to_sbus[i]; sbusl = pil_to_sbus[i];
if (!sbusl) { if (!sbusl) {
action = *(i + irq_action); action = *(i + irq_action);
if (!action) if (!action)
goto out; goto out_unlock;
} else { } else {
for (j = 0; j < nsbi; j++) { for (j = 0; j < nsbi; j++) {
for (k = 0; k < 4; k++) for (k = 0; k < 4; k++)
if ((action = sbus_actions [(j << 5) + (sbusl << 2) + k].action)) if ((action = sbus_actions [(j << 5) + (sbusl << 2) + k].action))
goto found_it; goto found_it;
} }
goto out; goto out_unlock;
} }
found_it: seq_printf(p, "%3d: ", i); found_it: seq_printf(p, "%3d: ", i);
#ifndef CONFIG_SMP #ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i)); seq_printf(p, "%10u ", kstat_irqs(i));
#else #else
for (x = 0; x < NR_CPUS; x++) { for (x = 0; x < NR_CPUS; x++) {
if (cpu_online) if (cpu_online(x))
seq_printf(p, "%10u ", seq_printf(p, "%10u ",
kstat_cpu(cpu_logical_map(x)).irqs[i]); kstat_cpu(cpu_logical_map(x)).irqs[i]);
} }
...@@ -128,7 +132,8 @@ found_it: seq_printf(p, "%3d: ", i); ...@@ -128,7 +132,8 @@ found_it: seq_printf(p, "%3d: ", i);
} }
seq_putc(p, '\n'); seq_putc(p, '\n');
} }
out: out_unlock:
spin_unlock_irqrestore(&irq_action_lock, flags);
return 0; return 0;
} }
...@@ -137,7 +142,8 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) ...@@ -137,7 +142,8 @@ void sun4d_free_irq(unsigned int irq, void *dev_id)
struct irqaction *action, **actionp; struct irqaction *action, **actionp;
struct irqaction *tmp = NULL; struct irqaction *tmp = NULL;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&irq_action_lock, flags);
if (irq < 15) if (irq < 15)
actionp = irq + irq_action; actionp = irq + irq_action;
else else
...@@ -145,7 +151,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) ...@@ -145,7 +151,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id)
action = *actionp; action = *actionp;
if (!action) { if (!action) {
printk("Trying to free free IRQ%d\n",irq); printk("Trying to free free IRQ%d\n",irq);
return; goto out_unlock;
} }
if (dev_id) { if (dev_id) {
for (; action; action = action->next) { for (; action; action = action->next) {
...@@ -155,34 +161,40 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) ...@@ -155,34 +161,40 @@ void sun4d_free_irq(unsigned int irq, void *dev_id)
} }
if (!action) { if (!action) {
printk("Trying to free free shared IRQ%d\n",irq); printk("Trying to free free shared IRQ%d\n",irq);
return; goto out_unlock;
} }
} else if (action->flags & SA_SHIRQ) { } else if (action->flags & SA_SHIRQ) {
printk("Trying to free shared IRQ%d with NULL device ID\n", irq); printk("Trying to free shared IRQ%d with NULL device ID\n", irq);
return; goto out_unlock;
} }
if (action->flags & SA_STATIC_ALLOC) if (action->flags & SA_STATIC_ALLOC)
{ {
/* This interrupt is marked as specially allocated /* This interrupt is marked as specially allocated
* so it is a bad idea to free it. * so it is a bad idea to free it.
*/ */
printk("Attempt to free statically allocated IRQ%d (%s)\n", printk("Attempt to free statically allocated IRQ%d (%s)\n",
irq, action->name); irq, action->name);
return; goto out_unlock;
} }
save_and_cli(flags);
if (action && tmp) if (action && tmp)
tmp->next = action->next; tmp->next = action->next;
else else
*actionp = action->next; *actionp = action->next;
spin_unlock_irqrestore(&irq_action_lock, flags);
synchronize_irq(irq);
spin_lock_irqsave(&irq_action_lock, flags);
kfree(action); kfree(action);
if (!(*actionp)) if (!(*actionp))
disable_irq(irq); disable_irq(irq);
restore_flags(flags); out_unlock:
spin_unlock_irqrestore(&irq_action_lock, flags);
} }
extern void unexpected_irq(int, void *, struct pt_regs *); extern void unexpected_irq(int, void *, struct pt_regs *);
...@@ -268,12 +280,19 @@ int sun4d_request_irq(unsigned int irq, ...@@ -268,12 +280,19 @@ int sun4d_request_irq(unsigned int irq,
{ {
struct irqaction *action, *tmp = NULL, **actionp; struct irqaction *action, *tmp = NULL, **actionp;
unsigned long flags; unsigned long flags;
int ret;
if(irq > 14 && irq < (1 << 5)) if(irq > 14 && irq < (1 << 5)) {
return -EINVAL; ret = -EINVAL;
goto out;
}
if (!handler) if (!handler) {
return -EINVAL; ret = -EINVAL;
goto out;
}
spin_lock_irqsave(&irq_action_lock, flags);
if (irq >= (1 << 5)) if (irq >= (1 << 5))
actionp = &(sbus_actions[irq - (1 << 5)].action); actionp = &(sbus_actions[irq - (1 << 5)].action);
...@@ -285,34 +304,34 @@ int sun4d_request_irq(unsigned int irq, ...@@ -285,34 +304,34 @@ int sun4d_request_irq(unsigned int irq,
if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {
for (tmp = action; tmp->next; tmp = tmp->next); for (tmp = action; tmp->next; tmp = tmp->next);
} else { } else {
return -EBUSY; ret = -EBUSY;
goto out_unlock;
} }
if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) { if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {
printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);
return -EBUSY; ret = -EBUSY;
} goto out_unlock;
}
action = NULL; /* Or else! */ action = NULL; /* Or else! */
} }
save_and_cli(flags);
/* If this is flagged as statically allocated then we use our /* If this is flagged as statically allocated then we use our
* private struct which is never freed. * private struct which is never freed.
*/ */
if (irqflags & SA_STATIC_ALLOC) { if (irqflags & SA_STATIC_ALLOC) {
if (static_irq_count < MAX_STATIC_ALLOC) if (static_irq_count < MAX_STATIC_ALLOC)
action = &static_irqaction[static_irq_count++]; action = &static_irqaction[static_irq_count++];
else else
printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",irq, devname); printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", irq, devname);
} }
if (action == NULL) if (action == NULL)
action = (struct irqaction *)kmalloc(sizeof(struct irqaction), action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
GFP_KERNEL); GFP_ATOMIC);
if (!action) { if (!action) {
restore_flags(flags); ret = -ENOMEM;
return -ENOMEM; goto out_unlock;
} }
action->handler = handler; action->handler = handler;
...@@ -328,8 +347,12 @@ int sun4d_request_irq(unsigned int irq, ...@@ -328,8 +347,12 @@ int sun4d_request_irq(unsigned int irq,
*actionp = action; *actionp = action;
enable_irq(irq); enable_irq(irq);
restore_flags(flags);
return 0; ret = 0;
out_unlock:
spin_unlock_irqrestore(&irq_action_lock, flags);
out:
return ret;
} }
static void sun4d_disable_irq(unsigned int irq) static void sun4d_disable_irq(unsigned int irq)
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/sbus.h> #include <asm/sbus.h>
#include <asm/cacheflush.h>
static unsigned long dummy; static unsigned long dummy;
...@@ -116,12 +117,12 @@ static void sun4m_disable_irq(unsigned int irq_nr) ...@@ -116,12 +117,12 @@ static void sun4m_disable_irq(unsigned int irq_nr)
int cpu = smp_processor_id(); int cpu = smp_processor_id();
mask = sun4m_get_irqmask(irq_nr); mask = sun4m_get_irqmask(irq_nr);
save_and_cli(flags); local_irq_save(flags);
if (irq_nr > 15) if (irq_nr > 15)
sun4m_interrupts->set = mask; sun4m_interrupts->set = mask;
else else
sun4m_interrupts->cpu_intregs[cpu].set = mask; sun4m_interrupts->cpu_intregs[cpu].set = mask;
restore_flags(flags); local_irq_restore(flags);
} }
static void sun4m_enable_irq(unsigned int irq_nr) static void sun4m_enable_irq(unsigned int irq_nr)
...@@ -135,16 +136,16 @@ static void sun4m_enable_irq(unsigned int irq_nr) ...@@ -135,16 +136,16 @@ static void sun4m_enable_irq(unsigned int irq_nr)
*/ */
if (irq_nr != 0x0b) { if (irq_nr != 0x0b) {
mask = sun4m_get_irqmask(irq_nr); mask = sun4m_get_irqmask(irq_nr);
save_and_cli(flags); local_irq_save(flags);
if (irq_nr > 15) if (irq_nr > 15)
sun4m_interrupts->clear = mask; sun4m_interrupts->clear = mask;
else else
sun4m_interrupts->cpu_intregs[cpu].clear = mask; sun4m_interrupts->cpu_intregs[cpu].clear = mask;
restore_flags(flags); local_irq_restore(flags);
} else { } else {
save_and_cli(flags); local_irq_save(flags);
sun4m_interrupts->clear = SUN4M_INT_FLOPPY; sun4m_interrupts->clear = SUN4M_INT_FLOPPY;
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -167,8 +168,8 @@ static unsigned long cpu_pil_to_imask[16] = { ...@@ -167,8 +168,8 @@ static unsigned long cpu_pil_to_imask[16] = {
/*15*/ 0x00000000 /*15*/ 0x00000000
}; };
/* We assume the caller is local cli()'d when these are called, or else /* We assume the caller has disabled local interrupts when these are called,
* very bizarre behavior will result. * or else very bizarre behavior will result.
*/ */
static void sun4m_disable_pil_irq(unsigned int pil) static void sun4m_disable_pil_irq(unsigned int pil)
{ {
......
...@@ -311,15 +311,19 @@ __asm__ __volatile__ ( \ ...@@ -311,15 +311,19 @@ __asm__ __volatile__ ( \
store_common(dst_addr, size, src_val, errh); \ store_common(dst_addr, size, src_val, errh); \
}) })
/* XXX Need to capture/release other cpu's for SMP around this. */ extern void smp_capture(void);
extern void smp_release(void);
#define do_atomic(srcdest_reg, mem, errh) ({ \ #define do_atomic(srcdest_reg, mem, errh) ({ \
unsigned long flags, tmp; \ unsigned long flags, tmp; \
\ \
save_and_cli(flags); \ smp_capture(); \
local_irq_save(flags); \
tmp = *srcdest_reg; \ tmp = *srcdest_reg; \
do_integer_load(srcdest_reg, 4, mem, 0, errh); \ do_integer_load(srcdest_reg, 4, mem, 0, errh); \
store_common(mem, 4, &tmp, errh); \ store_common(mem, 4, &tmp, errh); \
restore_flags(flags); \ local_irq_restore(flags); \
smp_release(); \
}) })
static inline void advance(struct pt_regs *regs) static inline void advance(struct pt_regs *regs)
......
...@@ -441,13 +441,13 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, ...@@ -441,13 +441,13 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
_SUN4C_PAGE_VALID | _SUN4C_PAGE_VALID |
_SUN4C_PAGE_DIRTY); _SUN4C_PAGE_DIRTY);
save_and_cli(flags); local_irq_save(flags);
if (sun4c_get_segmap(address) != invalid_segment) { if (sun4c_get_segmap(address) != invalid_segment) {
sun4c_put_pte(address, pte_val(*ptep)); sun4c_put_pte(address, pte_val(*ptep));
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
restore_flags(flags); local_irq_restore(flags);
} }
} else { } else {
if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT)) if ((pte_val(*ptep) & (_SUN4C_PAGE_READ|_SUN4C_PAGE_PRESENT))
...@@ -457,13 +457,13 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write, ...@@ -457,13 +457,13 @@ asmlinkage void do_sun4c_fault(struct pt_regs *regs, int text_fault, int write,
*ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED | *ptep = __pte(pte_val(*ptep) | _SUN4C_PAGE_ACCESSED |
_SUN4C_PAGE_VALID); _SUN4C_PAGE_VALID);
save_and_cli(flags); local_irq_save(flags);
if (sun4c_get_segmap(address) != invalid_segment) { if (sun4c_get_segmap(address) != invalid_segment) {
sun4c_put_pte(address, pte_val(*ptep)); sun4c_put_pte(address, pte_val(*ptep));
restore_flags(flags); local_irq_restore(flags);
return; return;
} }
restore_flags(flags); local_irq_restore(flags);
} }
} }
} }
......
...@@ -836,7 +836,7 @@ static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx) ...@@ -836,7 +836,7 @@ static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx)
struct sun4c_mmu_entry *head = &crp->ringhd; struct sun4c_mmu_entry *head = &crp->ringhd;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
if (head->next != head) { if (head->next != head) {
struct sun4c_mmu_entry *entry = head->next; struct sun4c_mmu_entry *entry = head->next;
int savectx = sun4c_get_context(); int savectx = sun4c_get_context();
...@@ -854,7 +854,7 @@ static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx) ...@@ -854,7 +854,7 @@ static void sun4c_demap_context(struct sun4c_mmu_ring *crp, unsigned char ctx)
} while (entry != head); } while (entry != head);
sun4c_set_context(savectx); sun4c_set_context(savectx);
} }
restore_flags(flags); local_irq_restore(flags);
} }
static int sun4c_user_taken_entries; /* This is how much we have. */ static int sun4c_user_taken_entries; /* This is how much we have. */
...@@ -978,14 +978,14 @@ static void get_locked_segment(unsigned long addr) ...@@ -978,14 +978,14 @@ static void get_locked_segment(unsigned long addr)
struct sun4c_mmu_entry *stolen; struct sun4c_mmu_entry *stolen;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
addr &= SUN4C_REAL_PGDIR_MASK; addr &= SUN4C_REAL_PGDIR_MASK;
stolen = sun4c_user_strategy(); stolen = sun4c_user_strategy();
max_user_taken_entries--; max_user_taken_entries--;
stolen->vaddr = addr; stolen->vaddr = addr;
flush_user_windows(); flush_user_windows();
sun4c_kernel_map(stolen); sun4c_kernel_map(stolen);
restore_flags(flags); local_irq_restore(flags);
} }
static void free_locked_segment(unsigned long addr) static void free_locked_segment(unsigned long addr)
...@@ -994,7 +994,7 @@ static void free_locked_segment(unsigned long addr) ...@@ -994,7 +994,7 @@ static void free_locked_segment(unsigned long addr)
unsigned long flags; unsigned long flags;
unsigned char pseg; unsigned char pseg;
save_and_cli(flags); local_irq_save(flags);
addr &= SUN4C_REAL_PGDIR_MASK; addr &= SUN4C_REAL_PGDIR_MASK;
pseg = sun4c_get_segmap(addr); pseg = sun4c_get_segmap(addr);
entry = &mmu_entry_pool[pseg]; entry = &mmu_entry_pool[pseg];
...@@ -1004,7 +1004,7 @@ static void free_locked_segment(unsigned long addr) ...@@ -1004,7 +1004,7 @@ static void free_locked_segment(unsigned long addr)
sun4c_kernel_unmap(entry); sun4c_kernel_unmap(entry);
add_ring(&sun4c_ufree_ring, entry); add_ring(&sun4c_ufree_ring, entry);
max_user_taken_entries++; max_user_taken_entries++;
restore_flags(flags); local_irq_restore(flags);
} }
static inline void garbage_collect(int entry) static inline void garbage_collect(int entry)
...@@ -1123,7 +1123,7 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size) ...@@ -1123,7 +1123,7 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size)
size + (PAGE_SIZE-1)) >> PAGE_SHIFT; size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
scan = 0; scan = 0;
save_and_cli(flags); local_irq_save(flags);
for (;;) { for (;;) {
scan = find_next_zero_bit(sun4c_iobuffer_map, scan = find_next_zero_bit(sun4c_iobuffer_map,
iobuffer_map_size, scan); iobuffer_map_size, scan);
...@@ -1157,12 +1157,12 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size) ...@@ -1157,12 +1157,12 @@ static char *sun4c_lockarea(char *vaddr, unsigned long size)
sun4c_put_pte(apage, pte); sun4c_put_pte(apage, pte);
vpage += PAGE_SIZE; vpage += PAGE_SIZE;
} }
restore_flags(flags); local_irq_restore(flags);
return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start + return (char *) ((base << PAGE_SHIFT) + sun4c_iobuffer_start +
(((unsigned long) vaddr) & ~PAGE_MASK)); (((unsigned long) vaddr) & ~PAGE_MASK));
abend: abend:
restore_flags(flags); local_irq_restore(flags);
printk("DMA vaddr=0x%p size=%08lx\n", vaddr, size); printk("DMA vaddr=0x%p size=%08lx\n", vaddr, size);
panic("Out of iobuffer table"); panic("Out of iobuffer table");
return 0; return 0;
...@@ -1178,7 +1178,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size) ...@@ -1178,7 +1178,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size)
npages = (((unsigned long)vaddr & ~PAGE_MASK) + npages = (((unsigned long)vaddr & ~PAGE_MASK) +
size + (PAGE_SIZE-1)) >> PAGE_SHIFT; size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
save_and_cli(flags); local_irq_save(flags);
while (npages != 0) { while (npages != 0) {
--npages; --npages;
...@@ -1200,7 +1200,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size) ...@@ -1200,7 +1200,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size)
sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE; sun4c_iobuffer_high -= SUN4C_REAL_PGDIR_SIZE;
free_locked_segment(sun4c_iobuffer_high); free_locked_segment(sun4c_iobuffer_high);
} }
restore_flags(flags); local_irq_restore(flags);
} }
/* Note the scsi code at init time passes to here buffers /* Note the scsi code at init time passes to here buffers
...@@ -1349,7 +1349,7 @@ static void sun4c_flush_cache_mm(struct mm_struct *mm) ...@@ -1349,7 +1349,7 @@ static void sun4c_flush_cache_mm(struct mm_struct *mm)
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
if (head->next != head) { if (head->next != head) {
struct sun4c_mmu_entry *entry = head->next; struct sun4c_mmu_entry *entry = head->next;
int savectx = sun4c_get_context(); int savectx = sun4c_get_context();
...@@ -1366,7 +1366,7 @@ static void sun4c_flush_cache_mm(struct mm_struct *mm) ...@@ -1366,7 +1366,7 @@ static void sun4c_flush_cache_mm(struct mm_struct *mm)
} while (entry != head); } while (entry != head);
sun4c_set_context(savectx); sun4c_set_context(savectx);
} }
restore_flags(flags); local_irq_restore(flags);
} }
} }
} }
...@@ -1383,7 +1383,7 @@ static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long st ...@@ -1383,7 +1383,7 @@ static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long st
flush_user_windows(); flush_user_windows();
save_and_cli(flags); local_irq_save(flags);
/* All user segmap chains are ordered on entry->vaddr. */ /* All user segmap chains are ordered on entry->vaddr. */
for (entry = head->next; for (entry = head->next;
(entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
...@@ -1427,7 +1427,7 @@ static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long st ...@@ -1427,7 +1427,7 @@ static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long st
} while ((entry != head) && (entry->vaddr < end)); } while ((entry != head) && (entry->vaddr < end));
sun4c_set_context(octx); sun4c_set_context(octx);
} }
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -1444,11 +1444,11 @@ static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long pag ...@@ -1444,11 +1444,11 @@ static void sun4c_flush_cache_page(struct vm_area_struct *vma, unsigned long pag
unsigned long flags; unsigned long flags;
flush_user_windows(); flush_user_windows();
save_and_cli(flags); local_irq_save(flags);
sun4c_set_context(new_ctx); sun4c_set_context(new_ctx);
sun4c_flush_page(page); sun4c_flush_page(page);
sun4c_set_context(octx); sun4c_set_context(octx);
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -1456,9 +1456,9 @@ static void sun4c_flush_page_to_ram(unsigned long page) ...@@ -1456,9 +1456,9 @@ static void sun4c_flush_page_to_ram(unsigned long page)
{ {
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
sun4c_flush_page(page); sun4c_flush_page(page);
restore_flags(flags); local_irq_restore(flags);
} }
/* Sun4c cache is unified, both instructions and data live there, so /* Sun4c cache is unified, both instructions and data live there, so
...@@ -1479,7 +1479,7 @@ static void sun4c_flush_tlb_all(void) ...@@ -1479,7 +1479,7 @@ static void sun4c_flush_tlb_all(void)
unsigned long flags; unsigned long flags;
int savectx, ctx; int savectx, ctx;
save_and_cli(flags); local_irq_save(flags);
this_entry = sun4c_kernel_ring.ringhd.next; this_entry = sun4c_kernel_ring.ringhd.next;
savectx = sun4c_get_context(); savectx = sun4c_get_context();
flush_user_windows(); flush_user_windows();
...@@ -1494,7 +1494,7 @@ static void sun4c_flush_tlb_all(void) ...@@ -1494,7 +1494,7 @@ static void sun4c_flush_tlb_all(void)
this_entry = next_entry; this_entry = next_entry;
} }
sun4c_set_context(savectx); sun4c_set_context(savectx);
restore_flags(flags); local_irq_restore(flags);
} }
static void sun4c_flush_tlb_mm(struct mm_struct *mm) static void sun4c_flush_tlb_mm(struct mm_struct *mm)
...@@ -1505,7 +1505,7 @@ static void sun4c_flush_tlb_mm(struct mm_struct *mm) ...@@ -1505,7 +1505,7 @@ static void sun4c_flush_tlb_mm(struct mm_struct *mm)
struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd; struct sun4c_mmu_entry *head = &sun4c_context_ring[new_ctx].ringhd;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
if (head->next != head) { if (head->next != head) {
struct sun4c_mmu_entry *entry = head->next; struct sun4c_mmu_entry *entry = head->next;
int savectx = sun4c_get_context(); int savectx = sun4c_get_context();
...@@ -1522,7 +1522,7 @@ static void sun4c_flush_tlb_mm(struct mm_struct *mm) ...@@ -1522,7 +1522,7 @@ static void sun4c_flush_tlb_mm(struct mm_struct *mm)
} while (entry != head); } while (entry != head);
sun4c_set_context(savectx); sun4c_set_context(savectx);
} }
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -1536,7 +1536,7 @@ static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long star ...@@ -1536,7 +1536,7 @@ static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long star
struct sun4c_mmu_entry *entry; struct sun4c_mmu_entry *entry;
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
/* See commentary in sun4c_flush_cache_range(). */ /* See commentary in sun4c_flush_cache_range(). */
for (entry = head->next; for (entry = head->next;
(entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start); (entry != head) && ((entry->vaddr+SUN4C_REAL_PGDIR_SIZE) < start);
...@@ -1558,7 +1558,7 @@ static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long star ...@@ -1558,7 +1558,7 @@ static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long star
} while ((entry != head) && (entry->vaddr < end)); } while ((entry != head) && (entry->vaddr < end));
sun4c_set_context(octx); sun4c_set_context(octx);
} }
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -1571,13 +1571,13 @@ static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) ...@@ -1571,13 +1571,13 @@ static void sun4c_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
int savectx = sun4c_get_context(); int savectx = sun4c_get_context();
unsigned long flags; unsigned long flags;
save_and_cli(flags); local_irq_save(flags);
sun4c_set_context(new_ctx); sun4c_set_context(new_ctx);
page &= PAGE_MASK; page &= PAGE_MASK;
sun4c_flush_page(page); sun4c_flush_page(page);
sun4c_put_pte(page, 0); sun4c_put_pte(page, 0);
sun4c_set_context(savectx); sun4c_set_context(savectx);
restore_flags(flags); local_irq_restore(flags);
} }
} }
...@@ -1974,7 +1974,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p ...@@ -1974,7 +1974,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
unsigned long flags; unsigned long flags;
int pseg; int pseg;
save_and_cli(flags); local_irq_save(flags);
address &= PAGE_MASK; address &= PAGE_MASK;
if ((pseg = sun4c_get_segmap(address)) == invalid_segment) { if ((pseg = sun4c_get_segmap(address)) == invalid_segment) {
struct sun4c_mmu_entry *entry = sun4c_user_strategy(); struct sun4c_mmu_entry *entry = sun4c_user_strategy();
...@@ -2010,7 +2010,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p ...@@ -2010,7 +2010,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
#ifndef SUN4C_PRELOAD_PSEG #ifndef SUN4C_PRELOAD_PSEG
sun4c_put_pte(address, pte_val(pte)); sun4c_put_pte(address, pte_val(pte));
#endif #endif
restore_flags(flags); local_irq_restore(flags);
return; return;
} else { } else {
struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg]; struct sun4c_mmu_entry *entry = &mmu_entry_pool[pseg];
...@@ -2020,7 +2020,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p ...@@ -2020,7 +2020,7 @@ void sun4c_update_mmu_cache(struct vm_area_struct *vma, unsigned long address, p
} }
sun4c_put_pte(address, pte_val(pte)); sun4c_put_pte(address, pte_val(pte));
restore_flags(flags); local_irq_restore(flags);
} }
extern void sparc_context_init(int); extern void sparc_context_init(int);
......
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