Skip to content

Commit 1f44a22

Browse files
author
Martin Schwidefsky
committed
s390: convert interrupt handling to use generic hardirq
With the introduction of PCI it became apparent that s390 should convert to generic hardirqs as too many drivers do not have the correct dependency for GENERIC_HARDIRQS. On the architecture level s390 does not have irq lines. It has external interrupts, I/O interrupts and adapter interrupts. This patch hard-codes all external interrupts as irq #1, all I/O interrupts as irq #2 and all adapter interrupts as irq #3. The additional information from the lowcore associated with the interrupt is stored in the pt_regs of the interrupt frame, where the interrupt handler can pick it up. For PCI/MSI interrupts the adapter interrupt handler scans the relevant bit fields and calls generic_handle_irq with the virtual irq number for the MSI interrupt. Reviewed-by: Sebastian Ott <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 5d0d8f4 commit 1f44a22

File tree

15 files changed

+249
-483
lines changed

15 files changed

+249
-483
lines changed

arch/s390/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ config S390
116116
select HAVE_FUNCTION_GRAPH_TRACER
117117
select HAVE_FUNCTION_TRACER
118118
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
119+
select HAVE_GENERIC_HARDIRQS
119120
select HAVE_KERNEL_BZIP2
120121
select HAVE_KERNEL_GZIP
121122
select HAVE_KERNEL_LZ4
@@ -445,6 +446,16 @@ config PCI_NR_FUNCTIONS
445446
This allows you to specify the maximum number of PCI functions which
446447
this kernel will support.
447448

449+
config PCI_NR_MSI
450+
int "Maximum number of MSI interrupts (64-32768)"
451+
range 64 32768
452+
default "256"
453+
help
454+
This defines the number of virtual interrupts the kernel will
455+
provide for MSI interrupts. If you configure your system to have
456+
too few drivers will fail to allocate MSI interrupts for all
457+
PCI devices.
458+
448459
source "drivers/pci/Kconfig"
449460
source "drivers/pci/pcie/Kconfig"
450461
source "drivers/pci/hotplug/Kconfig"

arch/s390/include/asm/hardirq.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@
2020

2121
#define HARDIRQ_BITS 8
2222

23+
static inline void ack_bad_irq(unsigned int irq)
24+
{
25+
printk(KERN_CRIT "unexpected IRQ trap at vector %02x\n", irq);
26+
}
27+
2328
#endif /* __ASM_HARDIRQ_H */

arch/s390/include/asm/hw_irq.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,8 @@
44
#include <linux/msi.h>
55
#include <linux/pci.h>
66

7-
static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
8-
{
9-
return __irq_get_msi_desc(irq);
10-
}
11-
12-
/* Must be called with msi map lock held */
13-
static inline int irq_set_msi_desc(unsigned int irq, struct msi_desc *msi)
14-
{
15-
if (!msi)
16-
return -EINVAL;
17-
18-
msi->irq = irq;
19-
return 0;
20-
}
7+
void __init init_airq_interrupts(void);
8+
void __init init_cio_interrupts(void);
9+
void __init init_ext_interrupts(void);
2110

2211
#endif

arch/s390/include/asm/irq.h

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
#ifndef _ASM_IRQ_H
22
#define _ASM_IRQ_H
33

4+
#define EXT_INTERRUPT 1
5+
#define IO_INTERRUPT 2
6+
#define THIN_INTERRUPT 3
7+
8+
#define NR_IRQS_BASE 4
9+
10+
#ifdef CONFIG_PCI_NR_MSI
11+
# define NR_IRQS (NR_IRQS_BASE + CONFIG_PCI_NR_MSI)
12+
#else
13+
# define NR_IRQS NR_IRQS_BASE
14+
#endif
15+
16+
/* This number is used when no interrupt has been assigned */
17+
#define NO_IRQ 0
18+
19+
#ifndef __ASSEMBLY__
20+
421
#include <linux/hardirq.h>
522
#include <linux/percpu.h>
623
#include <linux/cache.h>
724
#include <linux/types.h>
825

9-
enum interruption_main_class {
10-
EXTERNAL_INTERRUPT,
11-
IO_INTERRUPT,
12-
NR_IRQS
13-
};
14-
1526
enum interruption_class {
1627
IRQEXT_CLK,
1728
IRQEXT_EXC,
@@ -72,14 +83,8 @@ void service_subclass_irq_unregister(void);
7283
void measurement_alert_subclass_register(void);
7384
void measurement_alert_subclass_unregister(void);
7485

75-
#ifdef CONFIG_LOCKDEP
76-
# define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq)
77-
# define disable_irq_nosync_lockdep_irqsave(irq, flags) \
78-
disable_irq_nosync(irq)
79-
# define disable_irq_lockdep(irq) disable_irq(irq)
80-
# define enable_irq_lockdep(irq) enable_irq(irq)
81-
# define enable_irq_lockdep_irqrestore(irq, flags) \
82-
enable_irq(irq)
83-
#endif
86+
#define irq_canonicalize(irq) (irq)
87+
88+
#endif /* __ASSEMBLY__ */
8489

8590
#endif /* _ASM_IRQ_H */

arch/s390/include/asm/pci.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,6 @@ struct zpci_fmb {
5353
atomic64_t unmapped_pages;
5454
} __packed __aligned(16);
5555

56-
struct msi_map {
57-
unsigned long irq;
58-
struct msi_desc *msi;
59-
struct hlist_node msi_chain;
60-
};
61-
6256
#define ZPCI_MSI_VEC_BITS 11
6357
#define ZPCI_MSI_VEC_MAX (1 << ZPCI_MSI_VEC_BITS)
6458
#define ZPCI_MSI_VEC_MASK (ZPCI_MSI_VEC_MAX - 1)
@@ -92,8 +86,6 @@ struct zpci_dev {
9286

9387
/* IRQ stuff */
9488
u64 msi_addr; /* MSI address */
95-
struct zdev_irq_map *irq_map;
96-
struct msi_map *msi_map;
9789
struct airq_iv *aibv; /* adapter interrupt bit vector */
9890
unsigned int aisb; /* number of the summary bit */
9991

@@ -153,14 +145,6 @@ int clp_add_pci_device(u32, u32, int);
153145
int clp_enable_fh(struct zpci_dev *, u8);
154146
int clp_disable_fh(struct zpci_dev *);
155147

156-
/* MSI */
157-
struct msi_desc *__irq_get_msi_desc(unsigned int);
158-
int zpci_msi_set_mask_bits(struct msi_desc *, u32, u32);
159-
int zpci_setup_msi_irq(struct zpci_dev *, struct msi_desc *, unsigned int, int);
160-
void zpci_teardown_msi_irq(struct zpci_dev *, struct msi_desc *);
161-
int zpci_msihash_init(void);
162-
void zpci_msihash_exit(void);
163-
164148
#ifdef CONFIG_PCI
165149
/* Error handling and recovery */
166150
void zpci_event_error(void *);

arch/s390/include/asm/serial.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef _ASM_S390_SERIAL_H
2+
#define _ASM_S390_SERIAL_H
3+
4+
#define BASE_BAUD 0
5+
6+
#endif /* _ASM_S390_SERIAL_H */

arch/s390/kernel/entry.S

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <asm/unistd.h>
1919
#include <asm/page.h>
2020
#include <asm/sigp.h>
21+
#include <asm/irq.h>
2122

2223
__PT_R0 = __PT_GPRS
2324
__PT_R1 = __PT_GPRS + 4
@@ -435,6 +436,11 @@ io_skip:
435436
io_loop:
436437
l %r1,BASED(.Ldo_IRQ)
437438
lr %r2,%r11 # pass pointer to pt_regs
439+
lhi %r3,IO_INTERRUPT
440+
tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ?
441+
jz io_call
442+
lhi %r3,THIN_INTERRUPT
443+
io_call:
438444
basr %r14,%r1 # call do_IRQ
439445
tm __LC_MACHINE_FLAGS+2,0x10 # MACHINE_FLAG_LPAR
440446
jz io_return
@@ -584,9 +590,10 @@ ext_skip:
584590
mvc __PT_INT_CODE(4,%r11),__LC_EXT_CPU_ADDR
585591
mvc __PT_INT_PARM(4,%r11),__LC_EXT_PARAMS
586592
TRACE_IRQS_OFF
593+
l %r1,BASED(.Ldo_IRQ)
587594
lr %r2,%r11 # pass pointer to pt_regs
588-
l %r1,BASED(.Ldo_extint)
589-
basr %r14,%r1 # call do_extint
595+
lhi %r3,EXT_INTERRUPT
596+
basr %r14,%r1 # call do_IRQ
590597
j io_return
591598

592599
/*
@@ -902,7 +909,6 @@ cleanup_idle_wait:
902909
.Ldo_machine_check: .long s390_do_machine_check
903910
.Lhandle_mcck: .long s390_handle_mcck
904911
.Ldo_IRQ: .long do_IRQ
905-
.Ldo_extint: .long do_extint
906912
.Ldo_signal: .long do_signal
907913
.Ldo_notify_resume: .long do_notify_resume
908914
.Ldo_per_trap: .long do_per_trap

arch/s390/kernel/entry64.S

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <asm/unistd.h>
2020
#include <asm/page.h>
2121
#include <asm/sigp.h>
22+
#include <asm/irq.h>
2223

2324
__PT_R0 = __PT_GPRS
2425
__PT_R1 = __PT_GPRS + 8
@@ -468,6 +469,11 @@ io_skip:
468469
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
469470
io_loop:
470471
lgr %r2,%r11 # pass pointer to pt_regs
472+
lghi %r3,IO_INTERRUPT
473+
tm __PT_INT_CODE+8(%r11),0x80 # adapter interrupt ?
474+
jz io_call
475+
lghi %r3,THIN_INTERRUPT
476+
io_call:
471477
brasl %r14,do_IRQ
472478
tm __LC_MACHINE_FLAGS+6,0x10 # MACHINE_FLAG_LPAR
473479
jz io_return
@@ -623,7 +629,8 @@ ext_skip:
623629
TRACE_IRQS_OFF
624630
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
625631
lgr %r2,%r11 # pass pointer to pt_regs
626-
brasl %r14,do_extint
632+
lghi %r3,EXT_INTERRUPT
633+
brasl %r14,do_IRQ
627634
j io_return
628635

629636
/*

0 commit comments

Comments
 (0)