aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_thinint.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-24 04:30:41 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 15:10:28 -0400
commitf4eae94f71372ea5ec1ba17a85f3aebedc516ca8 (patch)
treeec3d6a527bf276a92e8befd559d9a0f0866ab7bd /drivers/s390/cio/qdio_thinint.c
parent386aa051fb4b6298c23996e68b7c92f186e484b6 (diff)
s390/airq: simplify adapter interrupt code
There are three users of adapter interrupts: AP, QDIO and PCI. Each registers a single adapter interrupt with independent ISCs. Define a "struct airq" with the interrupt handler, a pointer and a mask for the local summary indicator and the ISC for the adapter interrupt source. Convert the indicator array with its fixed number of adapter interrupt sources per ISE to an array of hlists. This removes the limitation to 32 adapter interrupts per ISC and allows for arbitrary memory locations for the local summary indicator. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio_thinint.c')
-rw-r--r--drivers/s390/cio/qdio_thinint.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 417b2557d83e..5d06253c2a7a 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -36,8 +36,13 @@ struct indicator_t {
36static LIST_HEAD(tiq_list); 36static LIST_HEAD(tiq_list);
37static DEFINE_MUTEX(tiq_list_lock); 37static DEFINE_MUTEX(tiq_list_lock);
38 38
39/* adapter local summary indicator */ 39/* Adapter interrupt definitions */
40static u8 *tiqdio_alsi; 40static void tiqdio_thinint_handler(struct airq_struct *airq);
41
42static struct airq_struct tiqdio_airq = {
43 .handler = tiqdio_thinint_handler,
44 .isc = QDIO_AIRQ_ISC,
45};
41 46
42static struct indicator_t *q_indicators; 47static struct indicator_t *q_indicators;
43 48
@@ -176,7 +181,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
176 * @alsi: pointer to adapter local summary indicator 181 * @alsi: pointer to adapter local summary indicator
177 * @data: NULL 182 * @data: NULL
178 */ 183 */
179static void tiqdio_thinint_handler(void *alsi, void *data) 184static void tiqdio_thinint_handler(struct airq_struct *airq)
180{ 185{
181 u32 si_used = clear_shared_ind(); 186 u32 si_used = clear_shared_ind();
182 struct qdio_q *q; 187 struct qdio_q *q;
@@ -216,7 +221,7 @@ static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
216 summary_indicator_addr = 0; 221 summary_indicator_addr = 0;
217 subchannel_indicator_addr = 0; 222 subchannel_indicator_addr = 0;
218 } else { 223 } else {
219 summary_indicator_addr = virt_to_phys(tiqdio_alsi); 224 summary_indicator_addr = virt_to_phys(tiqdio_airq.lsi_ptr);
220 subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci); 225 subchannel_indicator_addr = virt_to_phys(irq_ptr->dsci);
221 } 226 }
222 227
@@ -252,14 +257,12 @@ void tiqdio_free_memory(void)
252 257
253int __init tiqdio_register_thinints(void) 258int __init tiqdio_register_thinints(void)
254{ 259{
255 isc_register(QDIO_AIRQ_ISC); 260 int rc;
256 tiqdio_alsi = s390_register_adapter_interrupt(&tiqdio_thinint_handler, 261
257 NULL, QDIO_AIRQ_ISC); 262 rc = register_adapter_interrupt(&tiqdio_airq);
258 if (IS_ERR(tiqdio_alsi)) { 263 if (rc) {
259 DBF_EVENT("RTI:%lx", PTR_ERR(tiqdio_alsi)); 264 DBF_EVENT("RTI:%x", rc);
260 tiqdio_alsi = NULL; 265 return rc;
261 isc_unregister(QDIO_AIRQ_ISC);
262 return -ENOMEM;
263 } 266 }
264 return 0; 267 return 0;
265} 268}
@@ -292,9 +295,5 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
292void __exit tiqdio_unregister_thinints(void) 295void __exit tiqdio_unregister_thinints(void)
293{ 296{
294 WARN_ON(!list_empty(&tiq_list)); 297 WARN_ON(!list_empty(&tiq_list));
295 298 unregister_adapter_interrupt(&tiqdio_airq);
296 if (tiqdio_alsi) {
297 s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
298 isc_unregister(QDIO_AIRQ_ISC);
299 }
300} 299}