+static int i8259_host_match(struct irq_host *h, struct device_node *node)
+{
+ return i8259_node == NULL || i8259_node == node;
+}
+
+static int i8259_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
+
+ /* We block the internal cascade */
+ if (hw == 2)
+ get_irq_desc(virq)->status |= IRQ_NOREQUEST;
+
+ /* We use the level handler only for now, we might want to
+ * be more cautious here but that works for now
+ */
+ get_irq_desc(virq)->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(virq, &i8259_pic, handle_level_irq);
+ return 0;
+}
+
+static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
+{
+ /* Make sure irq is masked in hardware */
+ i8259_mask_irq(virq);
+
+ /* remove chip and handler */
+ set_irq_chip_and_handler(virq, NULL, NULL);
+
+ /* Make sure it's completed */
+ synchronize_irq(virq);
+}
+
+static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
+ u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+ static unsigned char map_isa_senses[4] = {
+ IRQ_TYPE_LEVEL_LOW,
+ IRQ_TYPE_LEVEL_HIGH,
+ IRQ_TYPE_EDGE_FALLING,
+ IRQ_TYPE_EDGE_RISING,
+ };
+
+ *out_hwirq = intspec[0];
+ if (intsize > 1 && intspec[1] < 4)
+ *out_flags = map_isa_senses[intspec[1]];
+ else
+ *out_flags = IRQ_TYPE_NONE;
+
+ return 0;
+}
+
+static struct irq_host_ops i8259_host_ops = {
+ .match = i8259_host_match,
+ .map = i8259_host_map,
+ .unmap = i8259_host_unmap,
+ .xlate = i8259_host_xlate,