Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
Browse files Browse the repository at this point in the history
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
  [S390] mm: add ZONE_DMA to 31-bit config again
  [S390] mm: add page fault retry handling
  [S390] mm: handle kernel caused page fault oom situations
  [S390] delay: implement ndelay
  [S390] topology,sched: fix cpu_coregroup_mask/cpu_book_mask definitions
  [S390] hwsampler: allow cpu hotplug
  [S390] uaccess: turn __access_ok() into a define
  [S390] irq: merge irq.c and s390_ext.c
  [S390] irq: fix service signal external interrupt handling
  [S390] pfault: always enable service signal interrupt
  • Loading branch information
Linus Torvalds committed May 27, 2011
2 parents 45acab0 + 69dbb2f commit 95948c3
Show file tree
Hide file tree
Showing 24 changed files with 221 additions and 193 deletions.
2 changes: 1 addition & 1 deletion arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ config MMU
def_bool y

config ZONE_DMA
def_bool y if 64BIT
def_bool y

config LOCKDEP_SUPPORT
def_bool y
Expand Down
2 changes: 0 additions & 2 deletions arch/s390/appldata/appldata_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ static void appldata_get_mem_data(void *data)
mem_data->pswpin = ev[PSWPIN];
mem_data->pswpout = ev[PSWPOUT];
mem_data->pgalloc = ev[PGALLOC_NORMAL];
#ifdef CONFIG_ZONE_DMA
mem_data->pgalloc += ev[PGALLOC_DMA];
#endif
mem_data->pgfault = ev[PGFAULT];
mem_data->pgmajfault = ev[PGMAJFAULT];

Expand Down
8 changes: 5 additions & 3 deletions arch/s390/include/asm/delay.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
#ifndef _S390_DELAY_H
#define _S390_DELAY_H

extern void __udelay(unsigned long long usecs);
extern void udelay_simple(unsigned long long usecs);
extern void __delay(unsigned long loops);
void __ndelay(unsigned long long nsecs);
void __udelay(unsigned long long usecs);
void udelay_simple(unsigned long long usecs);
void __delay(unsigned long loops);

#define ndelay(n) __ndelay((unsigned long long) (n))
#define udelay(n) __udelay((unsigned long long) (n))
#define mdelay(n) __udelay((unsigned long long) (n) * 1000)

Expand Down
8 changes: 8 additions & 0 deletions arch/s390/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _ASM_IRQ_H

#include <linux/hardirq.h>
#include <linux/types.h>

enum interruption_class {
EXTERNAL_INTERRUPT,
Expand Down Expand Up @@ -31,4 +32,11 @@ enum interruption_class {
NR_IRQS,
};

typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);

int register_external_interrupt(u16 code, ext_int_handler_t handler);
int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
void service_subclass_irq_register(void);
void service_subclass_irq_unregister(void);

#endif /* _ASM_IRQ_H */
17 changes: 0 additions & 17 deletions arch/s390/include/asm/s390_ext.h

This file was deleted.

4 changes: 2 additions & 2 deletions arch/s390/include/asm/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
extern unsigned char cpu_core_id[NR_CPUS];
extern cpumask_t cpu_core_map[NR_CPUS];

static inline const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
static inline const struct cpumask *cpu_coregroup_mask(int cpu)
{
return &cpu_core_map[cpu];
}
Expand All @@ -21,7 +21,7 @@ static inline const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
extern unsigned char cpu_book_id[NR_CPUS];
extern cpumask_t cpu_book_map[NR_CPUS];

static inline const struct cpumask *cpu_book_mask(unsigned int cpu)
static inline const struct cpumask *cpu_book_mask(int cpu)
{
return &cpu_book_map[cpu];
}
Expand Down
11 changes: 6 additions & 5 deletions arch/s390/include/asm/uaccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@

#define segment_eq(a,b) ((a).ar4 == (b).ar4)

#define __access_ok(addr, size) \
({ \
__chk_user_ptr(addr); \
1; \
})

static inline int __access_ok(const void __user *addr, unsigned long size)
{
return 1;
}
#define access_ok(type,addr,size) __access_ok(addr,size)
#define access_ok(type, addr, size) __access_ok(addr, size)

/*
* The exception table consists of pairs of addresses: the first is the
Expand Down
8 changes: 4 additions & 4 deletions arch/s390/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'

CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w

obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o \
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
vdso.o vtime.o sysinfo.o nmi.o sclp.o jump_label.o
obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \
processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \
debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \
sysinfo.o jump_label.o

obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/dis.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
#include <asm/atomic.h>
#include <asm/mathemu.h>
#include <asm/cpcmd.h>
#include <asm/s390_ext.h>
#include <asm/lowcore.h>
#include <asm/debug.h>
#include <asm/irq.h>

#ifndef CONFIG_64BIT
#define ONELONG "%08lx: "
Expand Down
137 changes: 129 additions & 8 deletions arch/s390/kernel/irq.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
/*
* Copyright IBM Corp. 2004,2010
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Thomas Spatzier (tspat@de.ibm.com)
* Copyright IBM Corp. 2004,2011
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
* Holger Smolinski <Holger.Smolinski@de.ibm.com>,
* Thomas Spatzier <tspat@de.ibm.com>,
*
* This file contains interrupt related functions.
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <linux/cpu.h>
#include <linux/proc_fs.h>
#include <linux/profile.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/cpu.h>
#include <asm/irq_regs.h>
#include <asm/cputime.h>
#include <asm/lowcore.h>
#include <asm/irq.h>
#include "entry.h"

struct irq_class {
char *name;
Expand Down Expand Up @@ -82,8 +91,7 @@ int show_interrupts(struct seq_file *p, void *v)
* For compatibilty only. S/390 specific setup of interrupts et al. is done
* much later in init_channel_subsystem().
*/
void __init
init_IRQ(void)
void __init init_IRQ(void)
{
/* nothing... */
}
Expand Down Expand Up @@ -134,3 +142,116 @@ void init_irq_proc(void)
create_prof_cpu_mask(root_irq_dir);
}
#endif

/*
* ext_int_hash[index] is the start of the list for all external interrupts
* that hash to this index. With the current set of external interrupts
* (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
* iucv and 0x2603 pfault) this is always the first element.
*/

struct ext_int_info {
struct ext_int_info *next;
ext_int_handler_t handler;
u16 code;
};

static struct ext_int_info *ext_int_hash[256];

static inline int ext_hash(u16 code)
{
return (code + (code >> 9)) & 0xff;
}

int register_external_interrupt(u16 code, ext_int_handler_t handler)
{
struct ext_int_info *p;
int index;

p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (!p)
return -ENOMEM;
p->code = code;
p->handler = handler;
index = ext_hash(code);
p->next = ext_int_hash[index];
ext_int_hash[index] = p;
return 0;
}
EXPORT_SYMBOL(register_external_interrupt);

int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
{
struct ext_int_info *p, *q;
int index;

index = ext_hash(code);
q = NULL;
p = ext_int_hash[index];
while (p) {
if (p->code == code && p->handler == handler)
break;
q = p;
p = p->next;
}
if (!p)
return -ENOENT;
if (q)
q->next = p->next;
else
ext_int_hash[index] = p->next;
kfree(p);
return 0;
}
EXPORT_SYMBOL(unregister_external_interrupt);

void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
unsigned int param32, unsigned long param64)
{
struct pt_regs *old_regs;
unsigned short code;
struct ext_int_info *p;
int index;

code = (unsigned short) ext_int_code;
old_regs = set_irq_regs(regs);
s390_idle_check(regs, S390_lowcore.int_clock,
S390_lowcore.async_enter_timer);
irq_enter();
if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
/* Serve timer interrupts first. */
clock_comparator_work();
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
if (code != 0x1004)
__get_cpu_var(s390_idle).nohz_delay = 1;
index = ext_hash(code);
for (p = ext_int_hash[index]; p; p = p->next) {
if (likely(p->code == code))
p->handler(ext_int_code, param32, param64);
}
irq_exit();
set_irq_regs(old_regs);
}

static DEFINE_SPINLOCK(sc_irq_lock);
static int sc_irq_refcount;

void service_subclass_irq_register(void)
{
spin_lock(&sc_irq_lock);
if (!sc_irq_refcount)
ctl_set_bit(0, 9);
sc_irq_refcount++;
spin_unlock(&sc_irq_lock);
}
EXPORT_SYMBOL(service_subclass_irq_register);

void service_subclass_irq_unregister(void)
{
spin_lock(&sc_irq_lock);
sc_irq_refcount--;
if (!sc_irq_refcount)
ctl_clear_bit(0, 9);
spin_unlock(&sc_irq_lock);
}
EXPORT_SYMBOL(service_subclass_irq_unregister);
Loading

0 comments on commit 95948c3

Please sign in to comment.