18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2002, 2007 48c2ecf20Sopenharmony_ci * Author(s): Ingo Adlung <adlung@de.ibm.com> 58c2ecf20Sopenharmony_ci * Cornelia Huck <cornelia.huck@de.ibm.com> 68c2ecf20Sopenharmony_ci * Arnd Bergmann <arndb@de.ibm.com> 78c2ecf20Sopenharmony_ci * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef _ASM_S390_AIRQ_H 118c2ecf20Sopenharmony_ci#define _ASM_S390_AIRQ_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/bit_spinlock.h> 148c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistruct airq_struct { 178c2ecf20Sopenharmony_ci struct hlist_node list; /* Handler queueing. */ 188c2ecf20Sopenharmony_ci void (*handler)(struct airq_struct *airq, bool floating); 198c2ecf20Sopenharmony_ci u8 *lsi_ptr; /* Local-Summary-Indicator pointer */ 208c2ecf20Sopenharmony_ci u8 lsi_mask; /* Local-Summary-Indicator mask */ 218c2ecf20Sopenharmony_ci u8 isc; /* Interrupt-subclass */ 228c2ecf20Sopenharmony_ci u8 flags; 238c2ecf20Sopenharmony_ci}; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define AIRQ_PTR_ALLOCATED 0x01 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciint register_adapter_interrupt(struct airq_struct *airq); 288c2ecf20Sopenharmony_civoid unregister_adapter_interrupt(struct airq_struct *airq); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* Adapter interrupt bit vector */ 318c2ecf20Sopenharmony_cistruct airq_iv { 328c2ecf20Sopenharmony_ci unsigned long *vector; /* Adapter interrupt bit vector */ 338c2ecf20Sopenharmony_ci dma_addr_t vector_dma; /* Adapter interrupt bit vector dma */ 348c2ecf20Sopenharmony_ci unsigned long *avail; /* Allocation bit mask for the bit vector */ 358c2ecf20Sopenharmony_ci unsigned long *bitlock; /* Lock bit mask for the bit vector */ 368c2ecf20Sopenharmony_ci unsigned long *ptr; /* Pointer associated with each bit */ 378c2ecf20Sopenharmony_ci unsigned int *data; /* 32 bit value associated with each bit */ 388c2ecf20Sopenharmony_ci unsigned long bits; /* Number of bits in the vector */ 398c2ecf20Sopenharmony_ci unsigned long end; /* Number of highest allocated bit + 1 */ 408c2ecf20Sopenharmony_ci unsigned long flags; /* Allocation flags */ 418c2ecf20Sopenharmony_ci spinlock_t lock; /* Lock to protect alloc & free */ 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define AIRQ_IV_ALLOC 1 /* Use an allocation bit mask */ 458c2ecf20Sopenharmony_ci#define AIRQ_IV_BITLOCK 2 /* Allocate the lock bit mask */ 468c2ecf20Sopenharmony_ci#define AIRQ_IV_PTR 4 /* Allocate the ptr array */ 478c2ecf20Sopenharmony_ci#define AIRQ_IV_DATA 8 /* Allocate the data array */ 488c2ecf20Sopenharmony_ci#define AIRQ_IV_CACHELINE 16 /* Cacheline alignment for the vector */ 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cistruct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags); 518c2ecf20Sopenharmony_civoid airq_iv_release(struct airq_iv *iv); 528c2ecf20Sopenharmony_ciunsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num); 538c2ecf20Sopenharmony_civoid airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num); 548c2ecf20Sopenharmony_ciunsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, 558c2ecf20Sopenharmony_ci unsigned long end); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_cistatic inline unsigned long airq_iv_alloc_bit(struct airq_iv *iv) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci return airq_iv_alloc(iv, 1); 608c2ecf20Sopenharmony_ci} 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistatic inline void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci airq_iv_free(iv, bit, 1); 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic inline unsigned long airq_iv_end(struct airq_iv *iv) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci return iv->end; 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic inline void airq_iv_lock(struct airq_iv *iv, unsigned long bit) 738c2ecf20Sopenharmony_ci{ 748c2ecf20Sopenharmony_ci const unsigned long be_to_le = BITS_PER_LONG - 1; 758c2ecf20Sopenharmony_ci bit_spin_lock(bit ^ be_to_le, iv->bitlock); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistatic inline void airq_iv_unlock(struct airq_iv *iv, unsigned long bit) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci const unsigned long be_to_le = BITS_PER_LONG - 1; 818c2ecf20Sopenharmony_ci bit_spin_unlock(bit ^ be_to_le, iv->bitlock); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic inline void airq_iv_set_data(struct airq_iv *iv, unsigned long bit, 858c2ecf20Sopenharmony_ci unsigned int data) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci iv->data[bit] = data; 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic inline unsigned int airq_iv_get_data(struct airq_iv *iv, 918c2ecf20Sopenharmony_ci unsigned long bit) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci return iv->data[bit]; 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistatic inline void airq_iv_set_ptr(struct airq_iv *iv, unsigned long bit, 978c2ecf20Sopenharmony_ci unsigned long ptr) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci iv->ptr[bit] = ptr; 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic inline unsigned long airq_iv_get_ptr(struct airq_iv *iv, 1038c2ecf20Sopenharmony_ci unsigned long bit) 1048c2ecf20Sopenharmony_ci{ 1058c2ecf20Sopenharmony_ci return iv->ptr[bit]; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#endif /* _ASM_S390_AIRQ_H */ 109