Commit 6ae9dd08 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.12pre8

parent 197e67c5
......@@ -1146,7 +1146,7 @@ sys_call_table:
.quad sys_timer_create
.quad sys_timer_settime
.quad sys_timer_gettime
.quad sys_timer_setoverrun
.quad sys_timer_getoverrun
.quad sys_timer_delete /* 375 */
.quad sys_clock_gettime
.quad sys_clock_settime
......
......@@ -1580,8 +1580,7 @@ static inline void send_IPI_single(int dest, int vector)
* bad as in the early days of SMP, so we might ease some of the
* paranoia here.
*/
void smp_flush_tlb(void)
static void flush_tlb_others(void)
{
int cpu = smp_processor_id();
int stuck;
......@@ -1634,12 +1633,59 @@ void smp_flush_tlb(void)
}
__restore_flags(flags);
}
}
/*
* Flush the local TLB
*/
/*
* Smarter SMP flushing macros.
* c/o Linus Torvalds.
*
* These mean you can really definitely utterly forget about
* writing to user space from interrupts. (Its not allowed anyway).
*/
void flush_tlb_current_task(void)
{
unsigned long vm_mask = 1 << current->processor;
struct mm_struct *mm = current->mm;
if (mm->cpu_vm_mask != vm_mask)
flush_tlb_others();
mm->cpu_vm_mask = vm_mask;
local_flush_tlb();
}
void flush_tlb_mm(struct mm_struct * mm)
{
unsigned long vm_mask = 1 << current->processor;
if (mm->cpu_vm_mask & ~vm_mask)
flush_tlb_others();
if (current->active_mm == mm) {
local_flush_tlb();
mm->cpu_vm_mask = vm_mask;
return;
}
mm->cpu_vm_mask = 0;
}
void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
{
unsigned long vm_mask = 1 << current->processor;
struct mm_struct *mm = vma->vm_mm;
if (mm->cpu_vm_mask & ~vm_mask)
flush_tlb_others();
if (current->active_mm == mm) {
__flush_tlb_one(va);
mm->cpu_vm_mask = vm_mask;
return;
}
mm->cpu_vm_mask = 0;
}
void flush_tlb_all(void)
{
flush_tlb_others();
local_flush_tlb();
}
......
......@@ -36,13 +36,6 @@ ifeq ($(CONFIG_PARPORT),y)
M_OBJS += parport_pc.o
endif
endif
ifeq ($(CONFIG_PARPORT_AX),y)
LX_OBJS += parport_ax.o
else
ifeq ($(CONFIG_PARPORT_AX),m)
M_OBJS += parport_ax.o
endif
endif
ifeq ($(CONFIG_PARPORT_AMIGA),y)
LX_OBJS += parport_amiga.o
else
......
......@@ -25,7 +25,6 @@ static int irq[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_IRQ_P
static int dma[PARPORT_MAX] __initdata = { [0 ... PARPORT_MAX-1] = PARPORT_DMA_NONE };
extern int parport_pc_init(int *io, int *io_hi, int *irq, int *dma);
extern int parport_ax_init(void);
static int parport_setup_ptr __initdata = 0;
......@@ -126,9 +125,6 @@ __initfunc(int parport_init(void))
#ifdef CONFIG_PARPORT_PC
parport_pc_init(io, io_hi, irq, dma);
#endif
#ifdef CONFIG_PARPORT_AX
parport_ax_init();
#endif
#ifdef CONFIG_PARPORT_AMIGA
parport_amiga_init();
#endif
......
......@@ -199,16 +199,6 @@ static void amiga_dec_use_count(void)
MOD_DEC_USE_COUNT;
}
static void amiga_fill_inode(struct inode *inode, int fill)
{
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations pp_amiga_ops = {
amiga_write_data,
amiga_read_data,
......@@ -217,42 +207,35 @@ static struct parport_operations pp_amiga_ops = {
amiga_read_control,
amiga_frob_control,
NULL, /* write_econtrol */
NULL, /* read_econtrol */
NULL, /* frob_econtrol */
amiga_write_status,
amiga_read_status,
NULL, /* write fifo */
NULL, /* read fifo */
amiga_change_mode,
NULL, /* epp_write_data */
NULL, /* epp_read_data */
NULL, /* epp_write_addr */
NULL, /* epp_read_addr */
NULL, /* epp_check_timeout */
amiga_enable_irq,
amiga_disable_irq,
NULL, /* epp_write_block */
NULL, /* epp_read_block */
NULL, /* data_forward */
NULL, /* data_reverse */
NULL, /* ecp_write_block */
NULL, /* ecp_read_block */
amiga_interrupt,
amiga_init_state,
amiga_save_state,
amiga_restore_state,
amiga_enable_irq,
amiga_disable_irq,
amiga_interrupt,
amiga_inc_use_count,
amiga_dec_use_count,
amiga_fill_inode
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data, /* impossible? */
parport_ieee1284_epp_write_addr,
parport_ieee1284_epp_read_addr, /* impossible? */
parport_ieee1284_ecp_write_data,
parport_ieee1284_ecp_read_data, /* impossible? */
parport_ieee1284_ecp_write_addr,
parport_ieee1284_write_compat, /* FIXME - need to write amiga one */
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte, /* impossible? */
};
/* ----------- Initialisation code --------------------------------- */
......
......@@ -79,16 +79,6 @@ static void arc_dec_use_count(void)
#endif
}
static void arc_fill_inode(struct inode *inode, int fill)
{
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_arc_ops =
{
arc_write_data,
......@@ -114,7 +104,6 @@ static struct parport_operations parport_arc_ops =
arc_inc_use_count,
arc_dec_use_count,
arc_fill_inode,
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
......
......@@ -91,11 +91,6 @@ parport_atari_read_status(struct parport *p)
PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
}
static void
parport_atari_write_status(struct parport *p, unsigned char status)
{
}
static void
parport_atari_init_state(struct parport_state *s)
{
......@@ -129,17 +124,6 @@ parport_atari_dec_use_count(void)
MOD_DEC_USE_COUNT;
}
static void
parport_atari_fill_inode(struct inode *inode, int fill)
{
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_atari_ops = {
parport_atari_write_data,
parport_atari_read_data,
......@@ -148,41 +132,35 @@ static struct parport_operations parport_atari_ops = {
parport_atari_read_control,
parport_atari_frob_control,
NULL, /* write_econtrol */
NULL, /* read_econtrol */
NULL, /* frob_econtrol */
parport_atari_write_status,
parport_atari_read_status,
NULL, /* write fifo */
NULL, /* read fifo */
NULL, /* change_mode */
NULL, /* enable_irq - FIXME */
NULL, /* disable_irq - FIXME */
NULL, /* epp_write_data */
NULL, /* epp_read_data */
NULL, /* epp_write_addr */
NULL, /* epp_read_addr */
NULL, /* epp_check_timeout */
NULL, /* data_forward - FIXME */
NULL, /* data_reverse - FIXME */
NULL, /* epp_write_block */
NULL, /* epp_read_block */
NULL, /* ecp_write_block */
NULL, /* ecp_read_block */
parport_atari_interrupt,
parport_atari_init_state,
parport_atari_save_state,
parport_atari_restore_state,
NULL, /* enable_irq */
NULL, /* disable_irq */
parport_atari_interrupt,
parport_atari_inc_use_count,
parport_atari_dec_use_count,
parport_atari_fill_inode
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
parport_ieee1284_epp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data,
parport_ieee1284_ecp_read_data,
parport_ieee1284_ecp_write_addr,
parport_ieee1284_write_compat,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
};
......
......@@ -254,16 +254,6 @@ parport_ax_dec_use_count(void)
#endif
}
static void parport_ax_fill_inode(struct inode *inode, int fill)
{
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations parport_ax_ops =
{
parport_ax_write_data,
......@@ -289,7 +279,6 @@ static struct parport_operations parport_ax_ops =
parport_ax_inc_use_count,
parport_ax_dec_use_count,
parport_ax_fill_inode,
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
......
......@@ -274,16 +274,6 @@ static void mfc3_dec_use_count(void)
MOD_DEC_USE_COUNT;
}
static void mfc3_fill_inode(struct inode *inode, int fill)
{
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
static struct parport_operations pp_mfc3_ops = {
mfc3_write_data,
mfc3_read_data,
......@@ -292,46 +282,35 @@ static struct parport_operations pp_mfc3_ops = {
mfc3_read_control,
mfc3_frob_control,
NULL, /* write_econtrol */
NULL, /* read_econtrol */
NULL, /* frob_econtrol */
mfc3_write_status,
mfc3_read_status,
NULL, /* write fifo */
NULL, /* read fifo */
mfc3_change_mode,
mfc3_release_resources,
mfc3_claim_resources,
NULL, /* epp_write_data */
NULL, /* epp_read_data */
NULL, /* epp_write_addr */
NULL, /* epp_read_addr */
NULL, /* epp_check_timeout */
mfc3_enable_irq,
mfc3_disable_irq,
NULL, /* epp_write_block */
NULL, /* epp_read_block */
NULL, /* data_forward - FIXME */
NULL, /* data_reverse - FIXME */
NULL, /* ecp_write_block */
NULL, /* ecp_read_block */
mfc3_interrupt,
mfc3_init_state,
mfc3_save_state,
mfc3_restore_state,
mfc3_enable_irq,
mfc3_disable_irq,
mfc3_interrupt,
mfc3_inc_use_count,
mfc3_dec_use_count,
mfc3_fill_inode
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
parport_ieee1284_epp_write_addr,
parport_ieee1284_epp_read_addr,
parport_ieee1284_ecp_write_data,
parport_ieee1284_ecp_read_data,
parport_ieee1284_ecp_write_addr,
parport_ieee1284_write_compat,
parport_ieee1284_read_nibble,
parport_ieee1284_read_byte,
};
/* ----------- Initialisation code --------------------------------- */
......
......@@ -55,10 +55,7 @@
#include <linux/parport.h>
#include <linux/parport_pc.h>
/* Maximum number of ports to support. It is useless to set this greater
than PARPORT_MAX (in <linux/parport.h>). */
#define PARPORT_PC_MAX_PORTS 8
#include <asm/parport.h>
/* ECR modes */
#define ECR_SPP 00
......@@ -70,8 +67,6 @@
#define ECR_TST 06
#define ECR_CNF 07
static int user_specified __initdata = 0;
/* frob_control, but for ECR */
static void frob_econtrol (struct parport *pb, unsigned char m,
unsigned char v)
......@@ -927,17 +922,6 @@ void parport_pc_dec_use_count(void)
#endif
}
static void parport_pc_fill_inode(struct inode *inode, int fill)
{
/* Is this still needed? -tim */
#ifdef MODULE
if (fill)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
#endif
}
struct parport_operations parport_pc_ops =
{
parport_pc_write_data,
......@@ -962,7 +946,6 @@ struct parport_operations parport_pc_ops =
parport_pc_inc_use_count,
parport_pc_dec_use_count,
parport_pc_fill_inode,
parport_ieee1284_epp_write_data,
parport_ieee1284_epp_read_data,
......@@ -1712,8 +1695,8 @@ static int __init parport_pc_init_pci (int irq, int dma)
unsigned int device;
unsigned int numports;
struct {
unsigned int lo;
unsigned int hi; /* -ve if not there */
unsigned long lo;
unsigned long hi; /* -ve if not there */
} addr[4];
} cards[] = {
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550, 1,
......@@ -1776,15 +1759,20 @@ static int __init parport_pc_init_pci (int irq, int dma)
pcidev)) != NULL) {
int n;
for (n = 0; n < cards[i].numports; n++) {
int lo = cards[i].addr[n].lo;
int hi = cards[i].addr[n].hi;
int io_lo = pcidev->base_address[lo];
int io_hi = ((hi < 0) ? 0 :
pcidev->base_address[hi]);
unsigned long lo = cards[i].addr[n].lo;
unsigned long hi = cards[i].addr[n].hi;
unsigned long io_lo = pcidev->base_address[lo];
unsigned long io_hi = ((hi < 0) ? 0 :
pcidev->base_address[hi]);
io_lo &= PCI_BASE_ADDRESS_IO_MASK;
io_hi &= PCI_BASE_ADDRESS_IO_MASK;
count += probe_one_port (io_lo, io_hi,
irq, dma);
if (irq == PARPORT_IRQ_AUTO)
count += probe_one_port (io_lo, io_hi,
pcidev->irq,
dma);
else
count += probe_one_port (io_lo, io_hi,
irq, dma);
}
}
}
......@@ -1792,28 +1780,6 @@ static int __init parport_pc_init_pci (int irq, int dma)
return count;
}
int __init parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
{
int count = 0, i = 0;
if (io && *io) {
/* Only probe the ports we were given. */
user_specified = 1;
do {
if (!*io_hi) *io_hi = 0x400 + *io;
count += probe_one_port(*(io++), *(io_hi++),
*(irq++), *(dma++));
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
count += probe_one_port(0x3bc, 0x7bc, irq[0], dma[0]);
count += probe_one_port(0x378, 0x778, irq[0], dma[0]);
count += probe_one_port(0x278, 0x678, irq[0], dma[0]);
count += parport_pc_init_pci (irq[0], dma[0]);
}
return count;
}
#ifdef MODULE
static int io[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
static int io_hi[PARPORT_PC_MAX_PORTS+1] = { [0 ... PARPORT_PC_MAX_PORTS] = 0 };
......
......@@ -128,12 +128,7 @@ static int do_hardware(ctl_table *table, int write, struct file *filp,
if (port->irq == PARPORT_IRQ_NONE) {
len += sprintf(buffer+len, "irq:\tnone\n");
} else {
#ifdef __sparc__
len += sprintf(buffer+len, "irq:\t%s\n",
__irq_itoa(port->irq));
#else
len += sprintf(buffer+len, "irq:\t%d\n", port->irq);
#endif
}
if (port->dma == PARPORT_DMA_NONE)
......
......@@ -52,7 +52,6 @@ static void dead_irq (int i, void *p, struct pt_regs *r) { }
static void dead_initstate (struct pardevice *d, struct parport_state *s) { }
static void dead_state (struct parport *p, struct parport_state *s) { }
static void dead_noargs (void) { }
static void dead_fill (struct inode *i, int f) { }
static size_t dead_write (struct parport *p, const void *b, size_t l, int f)
{ return 0; }
static size_t dead_read (struct parport *p, void *b, size_t l, int f)
......@@ -74,7 +73,6 @@ static struct parport_operations dead_ops = {
dead_state,
dead_noargs, /* xxx_use_count */
dead_noargs,
dead_fill, /* fill_inode */
dead_write, /* epp */
dead_read,
dead_write,
......
......@@ -371,7 +371,6 @@ static int exec_mmap(void)
if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
flush_cache_mm(old_mm);
mm_release();
release_segments(old_mm);
exit_mmap(old_mm);
flush_tlb_mm(old_mm);
return 0;
......@@ -381,10 +380,9 @@ static int exec_mmap(void)
if (mm) {
struct mm_struct *active_mm = current->active_mm;
mm->cpu_vm_mask = (1UL << smp_processor_id());
current->mm = mm;
current->active_mm = mm;
switch_mm(active_mm, mm);
switch_mm(active_mm, mm, smp_processor_id());
mm_release();
if (old_mm) {
if (active_mm != old_mm) BUG();
......
......@@ -9,8 +9,10 @@
#define destroy_context(mm) do { } while(0)
#define init_new_context(tsk,mm) do { } while (0)
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next)
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, unsigned cpu)
{
unsigned long vm_mask;
/*
* Re-load LDT if necessary
*/
......@@ -19,6 +21,10 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next)
/* Re-load page tables */
asm volatile("movl %0,%%cr3": :"r" (__pa(next->pgd)));
vm_mask = 1UL << cpu;
next->cpu_vm_mask |= vm_mask;
prev->cpu_vm_mask &= ~vm_mask;
}
#endif
/*
* parport.h: ia32-specific parport initialisation
*
* Copyright (C) 1999 Tim Waugh <tim@cyberelk.demon.co.uk>
*
* This file should only be included by drivers/parport/parport_pc.c.
*/
#ifndef _ASM_I386_PARPORT_H
#define _ASM_I386_PARPORT_H 1
/* Maximum number of ports to support. It is useless to set this greater
than PARPORT_MAX (in <linux/parport.h>). */
#define PARPORT_PC_MAX_PORTS 8
static int __init probe_one_port(unsigned long int base,
unsigned long int base_hi,
int irq, int dma);
static int __init parport_pc_init_pci(int irq, int dma);
static int user_specified __initdata = 0;
int __init
parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
{
int count = 0, i = 0;
if (io && *io) {
/* Only probe the ports we were given. */
user_specified = 1;
do {
if (!*io_hi) *io_hi = 0x400 + *io;
count += probe_one_port(*(io++), *(io_hi++),
*(irq++), *(dma++));
} while (*io && (++i < PARPORT_PC_MAX_PORTS));
} else {
/* Probe all the likely ports. */
count += probe_one_port(0x3bc, 0x7bc, irq[0], dma[0]);
count += probe_one_port(0x378, 0x778, irq[0], dma[0]);
count += probe_one_port(0x278, 0x678, irq[0], dma[0]);
count += parport_pc_init_pci (irq[0], dma[0]);
}
return count;
}
#endif /* !(_ASM_I386_PARPORT_H) */
......@@ -17,6 +17,8 @@
#include <asm/fixmap.h>
#include <linux/threads.h>
extern pgd_t swapper_pg_dir[1024];
/* Caches aren't brain-dead on the intel. */
#define flush_cache_all() do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
......@@ -86,79 +88,19 @@ static inline void flush_tlb_range(struct mm_struct *mm,
#define local_flush_tlb() \
__flush_tlb()
extern void flush_tlb_all(void);
extern void flush_tlb_current_task(void);
extern void flush_tlb_mm(struct mm_struct *);
extern void flush_tlb_page(struct vm_area_struct *, unsigned long);
#define CLEVER_SMP_INVALIDATE
#ifdef CLEVER_SMP_INVALIDATE
/*
* Smarter SMP flushing macros.
* c/o Linus Torvalds.
*
* These mean you can really definitely utterly forget about
* writing to user space from interrupts. (Its not allowed anyway).
*/
static inline void flush_tlb_current_task(void)
{
/* just one copy of this mm? */
if (atomic_read(&current->mm->mm_users) == 1)
local_flush_tlb(); /* and that's us, so.. */
else
smp_flush_tlb();
}
#define flush_tlb() flush_tlb_current_task()
#define flush_tlb_all() smp_flush_tlb()
static inline void flush_tlb_mm(struct mm_struct * mm)
{
if (mm == current->mm && atomic_read(&mm->mm_users) == 1)
local_flush_tlb();
else
smp_flush_tlb();
}
static inline void flush_tlb_page(struct vm_area_struct * vma,
unsigned long va)
{
if (vma->vm_mm == current->mm && atomic_read(&current->mm->mm_users) == 1)
__flush_tlb_one(va);
else
smp_flush_tlb();
}
#define flush_tlb() flush_tlb_current_task()
static inline void flush_tlb_range(struct mm_struct * mm,
unsigned long start, unsigned long end)
static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end)
{
flush_tlb_mm(mm);
}
#else
#define flush_tlb() \
smp_flush_tlb()
#define flush_tlb_all() flush_tlb()
static inline void flush_tlb_mm(struct mm_struct *mm)
{
flush_tlb();
}
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr)
{
flush_tlb();
}
static inline void flush_tlb_range(struct mm_struct *mm,
unsigned long start, unsigned long end)
{
flush_tlb();
}
#endif
#endif
#endif /* !__ASSEMBLY__ */
......@@ -392,13 +334,11 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
extern __inline__ pgd_t *get_pgd_slow(void)
{
pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL), *init;
pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
if (ret) {
init = pgd_offset(&init_mm, 0);
memset (ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
(PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy(ret + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
}
return ret;
}
......@@ -407,9 +347,9 @@ extern __inline__ pgd_t *get_pgd_fast(void)
{
unsigned long *ret;
if((ret = pgd_quicklist) != NULL) {
if ((ret = pgd_quicklist) != NULL) {
pgd_quicklist = (unsigned long *)(*ret);
ret[0] = ret[1];
ret[0] = 0;
pgtable_cache_size--;
} else
ret = (unsigned long *)get_pgd_slow();
......@@ -563,8 +503,6 @@ extern inline void set_pgdir(unsigned long address, pgd_t entry)
#endif
}
extern pgd_t swapper_pg_dir[1024];
/*
* The i386 doesn't have any external MMU info: the kernel page
* tables contain all the necessary information.
......
/* $Id$
* parport.h: sparc64 specific parport initialization and dma.
*
* Copyright (C) 1999 Eddie C. Dost (ecd@skynet.be)
*/
#ifndef _ASM_SPARC64_PARPORT_H
#define _ASM_SPARC64_PARPORT_H 1
#include <asm/ebus.h>
#include <asm/ns87303.h>
static struct linux_ebus_dma *sparc_ebus_dmas[PARPORT_MAX];
static __inline__ void
reset_dma(unsigned int dmanr)
{
unsigned int dcsr;
dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr) & EBUS_DCSR_INT_EN;
writel(EBUS_DCSR_RESET, &sparc_ebus_dmas[dmanr]->dcsr);
dcsr |= EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
EBUS_DCSR_EN_CNT;
writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
}
static __inline__ void
enable_dma(unsigned int dmanr)
{
unsigned int dcsr;
dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
dcsr |= EBUS_DCSR_EN_DMA;
writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
}
static __inline__ void
disable_dma(unsigned int dmanr)
{
unsigned int dcsr;
dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
while (dcsr & EBUS_DCSR_DRAIN)
dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
dcsr &= ~(EBUS_DCSR_EN_DMA);
if (dcsr & EBUS_DCSR_ERR_PEND) {
reset_dma(dmanr);
dcsr &= ~(EBUS_DCSR_ERR_PEND);
}
writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
}
static __inline__ void
clear_dma_ff(unsigned int dmanr)
{
/* nothing */
}
static __inline__ void
set_dma_mode(unsigned int dmanr, char mode)
{
unsigned int dcsr;
dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
if (mode == DMA_MODE_WRITE)
dcsr &= ~(EBUS_DCSR_WRITE);
else
dcsr |= EBUS_DCSR_WRITE;
writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
}
static __inline__ void
set_dma_addr(unsigned int dmanr, unsigned int addr)
{
writel(addr, &sparc_ebus_dmas[dmanr]->dacr);
}
static __inline__ void
set_dma_count(unsigned int dmanr, unsigned int count)
{
writel(count, &sparc_ebus_dmas[dmanr]->dbcr);
}
static __inline__ int
get_dma_residue(unsigned int dmanr)
{
return readl(&sparc_ebus_dmas[dmanr]->dbcr);
}
static int __init probe_one_port(unsigned long int base,
unsigned long int base_hi,
int irq, int dma);
static int __init parport_pc_init_pci(int irq, int dma);
int __init
parport_pc_init(int *io, int *io_hi, int *irq, int *dma)
{
struct linux_ebus *ebus;
struct linux_ebus_device *edev;
int count = 0;
if (!pci_present())
return 0;
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
if (!strcmp(edev->prom_name, "ecpp")) {
unsigned long base = edev->base_address[0];
unsigned long config = edev->base_address[1];
unsigned char cfg;
sparc_ebus_dmas[count] =
(struct linux_ebus_dma *)
edev->base_address[2];
/* Enable ECP, set bit 2 of the CTR first */
outb(0x04, base + 0x02);
cfg = ns87303_readb(config, PCR);
cfg |= (PCR_ECP_ENABLE | PCR_ECP_CLK_ENA);
ns87303_writeb(config, PCR, cfg);
/* CTR bit 5 controls direction of port */
cfg = ns87303_readb(config, PTR);
cfg |= PTR_LPT_REG_DIR;
ns87303_writeb(config, PTR, cfg);
/* Configure IRQ to Push Pull, Level Low */
cfg = ns87303_readb(config, PCR);
cfg &= ~(PCR_IRQ_ODRAIN);
cfg |= PCR_IRQ_POLAR;
ns87303_writeb(config, PCR, cfg);
#ifndef HAVE_SLOW_DEVICES
/* Enable Zero Wait State for ECP */
cfg = ns87303_readb(config, FCR);
cfg |= FCR_ZWS_ENA;
ns87303_writeb(config, FCR, cfg);
#endif
count += probe_one_port(base, base + 0x400,
edev->irqs[0], count);
}
}
}
count += parport_pc_init_pci(PARPORT_IRQ_AUTO, PARPORT_DMA_NONE);
return count;
}
#endif /* !(_ASM_SPARC64_PARPORT_H */
......@@ -304,7 +304,6 @@ extern void show_free_areas(void);
extern unsigned long put_dirty_page(struct task_struct * tsk,unsigned long page,
unsigned long address);
extern void free_page_tables(struct mm_struct * mm);
extern void clear_page_tables(struct mm_struct *, unsigned long, int);
extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
......
......@@ -144,7 +144,7 @@ struct parport_operations {
void (*data_reverse) (struct parport *);
/* For core parport code. */
void (*interrupt)(int, void *, struct pt_regs *); /* ? */
void (*interrupt)(int, void *, struct pt_regs *);
void (*init_state)(struct pardevice *, struct parport_state *);
void (*save_state)(struct parport *, struct parport_state *);
......@@ -152,7 +152,6 @@ struct parport_operations {
void (*inc_use_count)(void);
void (*dec_use_count)(void);
void (*fill_inode)(struct inode *inode, int fill); /* ? */
/* Block read/write */
size_t (*epp_write_data) (struct parport *port, const void *buf,
......
......@@ -283,7 +283,7 @@ void end_lazy_tlb(struct mm_struct *mm)
current->mm = mm;
if (mm != active_mm) {
current->active_mm = mm;
switch_mm(active_mm, mm);
switch_mm(active_mm, mm, current->processor);
}
mmdrop(active_mm);
}
......
......@@ -312,6 +312,29 @@ struct mm_struct * mm_alloc(void)
return NULL;
}
/*
* Called when the last reference to the mm
* is dropped: either by a lazy thread or by
* mmput. Free the page directory and the mm.
*/
inline void __mmdrop(struct mm_struct *mm)
{
if (mm == &init_mm) BUG();
pgd_free(mm->pgd);
kmem_cache_free(mm_cachep, mm);
}
/*
* Decrement the use count and release all resources for an mm.
*/
void mmput(struct mm_struct *mm)
{
if (atomic_dec_and_test(&mm->mm_users)) {
exit_mmap(mm);
mmdrop(mm);
}
}
/* Please note the differences between mmput and mm_release.
* mmput is called whenever we stop holding onto a mm_struct,
* error success whatever.
......@@ -336,30 +359,6 @@ void mm_release(void)
}
}
/*
* Called when the last reference to the mm
* is dropped: either by a lazy thread or by
* mmput
*/
inline void __mmdrop(struct mm_struct *mm)
{
if (mm == &init_mm) BUG();
free_page_tables(mm);
kmem_cache_free(mm_cachep, mm);
}
/*
* Decrement the use count and release all resources for an mm.
*/
void mmput(struct mm_struct *mm)
{
if (atomic_dec_and_test(&mm->mm_users)) {
release_segments(mm);
exit_mmap(mm);
mmdrop(mm);
}
}
static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
{
struct mm_struct * mm;
......
......@@ -621,15 +621,6 @@ signed long schedule_timeout(signed long timeout)
*/
static inline void __schedule_tail(struct task_struct *prev)
{
if (!current->active_mm) BUG();
if (!prev->mm) {
struct mm_struct *mm = prev->active_mm;
if (mm) {
prev->active_mm = NULL;
mmdrop(mm);
}
}
#ifdef __SMP__
if ((prev->state == TASK_RUNNING) &&
(prev != idle_task(smp_processor_id())))
......@@ -798,7 +789,12 @@ asmlinkage void schedule(void)
} else {
if (next->active_mm != mm) BUG();
if (mm != oldmm)
switch_mm(oldmm, mm);
switch_mm(oldmm, mm, this_cpu);
}
if (!prev->mm) {
prev->active_mm = NULL;
mmdrop(oldmm);
}
}
......
......@@ -143,28 +143,6 @@ void clear_page_tables(struct mm_struct *mm, unsigned long first, int nr)
check_pgt_cache();
}
/*
* This function just free's the page directory - the
* pages tables themselves have been freed earlier by
* clear_page_tables().
*/
void free_page_tables(struct mm_struct * mm)
{
pgd_t * page_dir = mm->pgd;
if (page_dir) {
if (page_dir == swapper_pg_dir)
goto out_bad;
pgd_free(page_dir);
}
return;
out_bad:
printk(KERN_ERR
"free_page_tables: Trying to free kernel pgd\n");
return;
}
#define PTE_TABLE_MASK ((PTRS_PER_PTE-1) * sizeof(pte_t))
#define PMD_TABLE_MASK ((PTRS_PER_PMD-1) * sizeof(pmd_t))
......
......@@ -813,6 +813,7 @@ void exit_mmap(struct mm_struct * mm)
{
struct vm_area_struct * mpnt;
release_segments(mm);
mpnt = mm->mmap;
mm->mmap = mm->mmap_avl = mm->mmap_cache = NULL;
mm->rss = 0;
......
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