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