Commit fcc6ab335ba4d0f2b2548a910466c0dac767e5b1
Committed by
Heiko Carstens
1 parent
da7c5af828
Exists in
master
and in
7 other branches
[S390] cio: introduce isc_(un)register functions.
This interface makes it easy for drivers to register usage of different I/O interruption subclasses without needing to worry about possible other users of the same isc. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Showing 3 changed files with 76 additions and 2 deletions Side-by-side Diff
drivers/s390/cio/Makefile
... | ... | @@ -2,8 +2,8 @@ |
2 | 2 | # Makefile for the S/390 common i/o drivers |
3 | 3 | # |
4 | 4 | |
5 | -obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o scsw.o fcx.o \ | |
6 | - itcw.o | |
5 | +obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o scsw.o \ | |
6 | + fcx.o itcw.o | |
7 | 7 | ccw_device-objs += device.o device_fsm.o device_ops.o |
8 | 8 | ccw_device-objs += device_id.o device_pgid.o device_status.o |
9 | 9 | obj-y += ccw_device.o cmf.o |
drivers/s390/cio/isc.c
1 | +/* | |
2 | + * Functions for registration of I/O interruption subclasses on s390. | |
3 | + * | |
4 | + * Copyright IBM Corp. 2008 | |
5 | + * Authors: Sebastian Ott <sebott@linux.vnet.ibm.com> | |
6 | + */ | |
7 | + | |
8 | +#include <linux/spinlock.h> | |
9 | +#include <linux/module.h> | |
10 | +#include <asm/isc.h> | |
11 | + | |
12 | +static unsigned int isc_refs[MAX_ISC + 1]; | |
13 | +static DEFINE_SPINLOCK(isc_ref_lock); | |
14 | + | |
15 | + | |
16 | +/** | |
17 | + * isc_register - register an I/O interruption subclass. | |
18 | + * @isc: I/O interruption subclass to register | |
19 | + * | |
20 | + * The number of users for @isc is increased. If this is the first user to | |
21 | + * register @isc, the corresponding I/O interruption subclass mask is enabled. | |
22 | + * | |
23 | + * Context: | |
24 | + * This function must not be called in interrupt context. | |
25 | + */ | |
26 | +void isc_register(unsigned int isc) | |
27 | +{ | |
28 | + if (isc > MAX_ISC) { | |
29 | + WARN_ON(1); | |
30 | + return; | |
31 | + } | |
32 | + | |
33 | + spin_lock(&isc_ref_lock); | |
34 | + if (isc_refs[isc] == 0) | |
35 | + ctl_set_bit(6, 31 - isc); | |
36 | + isc_refs[isc]++; | |
37 | + spin_unlock(&isc_ref_lock); | |
38 | +} | |
39 | +EXPORT_SYMBOL_GPL(isc_register); | |
40 | + | |
41 | +/** | |
42 | + * isc_unregister - unregister an I/O interruption subclass. | |
43 | + * @isc: I/O interruption subclass to unregister | |
44 | + * | |
45 | + * The number of users for @isc is decreased. If this is the last user to | |
46 | + * unregister @isc, the corresponding I/O interruption subclass mask is | |
47 | + * disabled. | |
48 | + * Note: This function must not be called if isc_register() hasn't been called | |
49 | + * before by the driver for @isc. | |
50 | + * | |
51 | + * Context: | |
52 | + * This function must not be called in interrupt context. | |
53 | + */ | |
54 | +void isc_unregister(unsigned int isc) | |
55 | +{ | |
56 | + spin_lock(&isc_ref_lock); | |
57 | + /* check for misuse */ | |
58 | + if (isc > MAX_ISC || isc_refs[isc] == 0) { | |
59 | + WARN_ON(1); | |
60 | + goto out_unlock; | |
61 | + } | |
62 | + if (isc_refs[isc] == 1) | |
63 | + ctl_clear_bit(6, 31 - isc); | |
64 | + isc_refs[isc]--; | |
65 | +out_unlock: | |
66 | + spin_unlock(&isc_ref_lock); | |
67 | +} | |
68 | +EXPORT_SYMBOL_GPL(isc_unregister); |
include/asm-s390/isc.h
1 | 1 | #ifndef _ASM_S390_ISC_H |
2 | 2 | #define _ASM_S390_ISC_H |
3 | 3 | |
4 | +#include <linux/types.h> | |
5 | + | |
4 | 6 | /* |
5 | 7 | * I/O interruption subclasses used by drivers. |
6 | 8 | * Please add all used iscs here so that it is possible to distribute |
... | ... | @@ -14,6 +16,10 @@ |
14 | 16 | #define CONSOLE_ISC 1 /* console I/O subchannel */ |
15 | 17 | /* Adapter interrupts. */ |
16 | 18 | #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ |
19 | + | |
20 | +/* Functions for registration of I/O interruption subclasses */ | |
21 | +void isc_register(unsigned int isc); | |
22 | +void isc_unregister(unsigned int isc); | |
17 | 23 | |
18 | 24 | #endif /* _ASM_S390_ISC_H */ |