18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Functions for registration of I/O interruption subclasses on s390. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2008 68c2ecf20Sopenharmony_ci * Authors: Sebastian Ott <sebott@linux.vnet.ibm.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 108c2ecf20Sopenharmony_ci#include <linux/module.h> 118c2ecf20Sopenharmony_ci#include <asm/isc.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic unsigned int isc_refs[MAX_ISC + 1]; 148c2ecf20Sopenharmony_cistatic DEFINE_SPINLOCK(isc_ref_lock); 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/** 188c2ecf20Sopenharmony_ci * isc_register - register an I/O interruption subclass. 198c2ecf20Sopenharmony_ci * @isc: I/O interruption subclass to register 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * The number of users for @isc is increased. If this is the first user to 228c2ecf20Sopenharmony_ci * register @isc, the corresponding I/O interruption subclass mask is enabled. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Context: 258c2ecf20Sopenharmony_ci * This function must not be called in interrupt context. 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_civoid isc_register(unsigned int isc) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci if (isc > MAX_ISC) { 308c2ecf20Sopenharmony_ci WARN_ON(1); 318c2ecf20Sopenharmony_ci return; 328c2ecf20Sopenharmony_ci } 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci spin_lock(&isc_ref_lock); 358c2ecf20Sopenharmony_ci if (isc_refs[isc] == 0) 368c2ecf20Sopenharmony_ci ctl_set_bit(6, 31 - isc); 378c2ecf20Sopenharmony_ci isc_refs[isc]++; 388c2ecf20Sopenharmony_ci spin_unlock(&isc_ref_lock); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(isc_register); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/** 438c2ecf20Sopenharmony_ci * isc_unregister - unregister an I/O interruption subclass. 448c2ecf20Sopenharmony_ci * @isc: I/O interruption subclass to unregister 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * The number of users for @isc is decreased. If this is the last user to 478c2ecf20Sopenharmony_ci * unregister @isc, the corresponding I/O interruption subclass mask is 488c2ecf20Sopenharmony_ci * disabled. 498c2ecf20Sopenharmony_ci * Note: This function must not be called if isc_register() hasn't been called 508c2ecf20Sopenharmony_ci * before by the driver for @isc. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * Context: 538c2ecf20Sopenharmony_ci * This function must not be called in interrupt context. 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_civoid isc_unregister(unsigned int isc) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci spin_lock(&isc_ref_lock); 588c2ecf20Sopenharmony_ci /* check for misuse */ 598c2ecf20Sopenharmony_ci if (isc > MAX_ISC || isc_refs[isc] == 0) { 608c2ecf20Sopenharmony_ci WARN_ON(1); 618c2ecf20Sopenharmony_ci goto out_unlock; 628c2ecf20Sopenharmony_ci } 638c2ecf20Sopenharmony_ci if (isc_refs[isc] == 1) 648c2ecf20Sopenharmony_ci ctl_clear_bit(6, 31 - isc); 658c2ecf20Sopenharmony_ci isc_refs[isc]--; 668c2ecf20Sopenharmony_ciout_unlock: 678c2ecf20Sopenharmony_ci spin_unlock(&isc_ref_lock); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(isc_unregister); 70