1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Functions for registration of I/O interruption subclasses on s390. |
4 | * |
5 | * Copyright IBM Corp. 2008 |
6 | * Authors: Sebastian Ott <sebott@linux.vnet.ibm.com> |
7 | */ |
8 | |
9 | #include <linux/spinlock.h> |
10 | #include <linux/module.h> |
11 | #include <asm/isc.h> |
12 | |
13 | static unsigned int isc_refs[MAX_ISC + 1]; |
14 | static DEFINE_SPINLOCK(isc_ref_lock); |
15 | |
16 | |
17 | /** |
18 | * isc_register - register an I/O interruption subclass. |
19 | * @isc: I/O interruption subclass to register |
20 | * |
21 | * The number of users for @isc is increased. If this is the first user to |
22 | * register @isc, the corresponding I/O interruption subclass mask is enabled. |
23 | * |
24 | * Context: |
25 | * This function must not be called in interrupt context. |
26 | */ |
27 | void isc_register(unsigned int isc) |
28 | { |
29 | if (isc > MAX_ISC) { |
30 | WARN_ON(1); |
31 | return; |
32 | } |
33 | |
34 | spin_lock(lock: &isc_ref_lock); |
35 | if (isc_refs[isc] == 0) |
36 | system_ctl_set_bit(6, 31 - isc); |
37 | isc_refs[isc]++; |
38 | spin_unlock(lock: &isc_ref_lock); |
39 | } |
40 | EXPORT_SYMBOL_GPL(isc_register); |
41 | |
42 | /** |
43 | * isc_unregister - unregister an I/O interruption subclass. |
44 | * @isc: I/O interruption subclass to unregister |
45 | * |
46 | * The number of users for @isc is decreased. If this is the last user to |
47 | * unregister @isc, the corresponding I/O interruption subclass mask is |
48 | * disabled. |
49 | * Note: This function must not be called if isc_register() hasn't been called |
50 | * before by the driver for @isc. |
51 | * |
52 | * Context: |
53 | * This function must not be called in interrupt context. |
54 | */ |
55 | void isc_unregister(unsigned int isc) |
56 | { |
57 | spin_lock(lock: &isc_ref_lock); |
58 | /* check for misuse */ |
59 | if (isc > MAX_ISC || isc_refs[isc] == 0) { |
60 | WARN_ON(1); |
61 | goto out_unlock; |
62 | } |
63 | if (isc_refs[isc] == 1) |
64 | system_ctl_clear_bit(6, 31 - isc); |
65 | isc_refs[isc]--; |
66 | out_unlock: |
67 | spin_unlock(lock: &isc_ref_lock); |
68 | } |
69 | EXPORT_SYMBOL_GPL(isc_unregister); |
70 | |