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