#define _ASM_S390_AIRQ_H
 
 #include <linux/bit_spinlock.h>
+#include <linux/dma-mapping.h>
 
 struct airq_struct {
        struct hlist_node list;         /* Handler queueing. */
 /* Adapter interrupt bit vector */
 struct airq_iv {
        unsigned long *vector;  /* Adapter interrupt bit vector */
+       dma_addr_t vector_dma; /* Adapter interrupt bit vector dma */
        unsigned long *avail;   /* Allocation bit mask for the bit vector */
        unsigned long *bitlock; /* Lock bit mask for the bit vector */
        unsigned long *ptr;     /* Pointer associated with each bit */
 
 #include <linux/mutex.h>
 #include <linux/rculist.h>
 #include <linux/slab.h>
+#include <linux/dmapool.h>
 
 #include <asm/airq.h>
 #include <asm/isc.h>
+#include <asm/cio.h>
 
 #include "cio.h"
 #include "cio_debug.h"
 static DEFINE_SPINLOCK(airq_lists_lock);
 static struct hlist_head airq_lists[MAX_ISC+1];
 
-static struct kmem_cache *airq_iv_cache;
+static struct dma_pool *airq_iv_cache;
 
 /**
  * register_adapter_interrupt() - register adapter interrupt handler
        setup_irq(THIN_INTERRUPT, &airq_interrupt);
 }
 
+static inline unsigned long iv_size(unsigned long bits)
+{
+       return BITS_TO_LONGS(bits) * sizeof(unsigned long);
+}
+
 /**
  * airq_iv_create - create an interrupt vector
  * @bits: number of bits in the interrupt vector
                goto out;
        iv->bits = bits;
        iv->flags = flags;
-       size = BITS_TO_LONGS(bits) * sizeof(unsigned long);
+       size = iv_size(bits);
 
        if (flags & AIRQ_IV_CACHELINE) {
-               if ((cache_line_size() * BITS_PER_BYTE) < bits)
+               if ((cache_line_size() * BITS_PER_BYTE) < bits
+                               || !airq_iv_cache)
                        goto out_free;
 
-               iv->vector = kmem_cache_zalloc(airq_iv_cache, GFP_KERNEL);
+               iv->vector = dma_pool_zalloc(airq_iv_cache, GFP_KERNEL,
+                                            &iv->vector_dma);
                if (!iv->vector)
                        goto out_free;
        } else {
-               iv->vector = kzalloc(size, GFP_KERNEL);
+               iv->vector = cio_dma_zalloc(size);
                if (!iv->vector)
                        goto out_free;
        }
        kfree(iv->ptr);
        kfree(iv->bitlock);
        kfree(iv->avail);
-       if (iv->flags & AIRQ_IV_CACHELINE)
-               kmem_cache_free(airq_iv_cache, iv->vector);
+       if (iv->flags & AIRQ_IV_CACHELINE && iv->vector)
+               dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma);
        else
-               kfree(iv->vector);
+               cio_dma_free(iv->vector, size);
        kfree(iv);
 out:
        return NULL;
        kfree(iv->ptr);
        kfree(iv->bitlock);
        if (iv->flags & AIRQ_IV_CACHELINE)
-               kmem_cache_free(airq_iv_cache, iv->vector);
+               dma_pool_free(airq_iv_cache, iv->vector, iv->vector_dma);
        else
-               kfree(iv->vector);
+               cio_dma_free(iv->vector, iv_size(iv->bits));
        kfree(iv->avail);
        kfree(iv);
 }
 }
 EXPORT_SYMBOL(airq_iv_scan);
 
-static int __init airq_init(void)
+int __init airq_init(void)
 {
-       airq_iv_cache = kmem_cache_create("airq_iv_cache", cache_line_size(),
-                                         cache_line_size(), 0, NULL);
+       airq_iv_cache = dma_pool_create("airq_iv_cache", cio_get_dma_css_dev(),
+                                       cache_line_size(),
+                                       cache_line_size(), PAGE_SIZE);
        if (!airq_iv_cache)
                return -ENOMEM;
        return 0;
 }
-subsys_initcall(airq_init);