@@ -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,
@@ -92,11+92,6 @@ parport_atari_read_status(struct parport *p) }
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 --------------------------------- */
#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
#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();
#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
--- /dev/null
+/*
+ * 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) */
#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(¤t->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(¤t->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.
--- /dev/null
+/* $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 @@ still_running_back: } 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;