Merge tag 's390-5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[platform/kernel/linux-starfive.git] / drivers / s390 / cio / qdio_main.c
index 3475317..c890848 100644 (file)
@@ -950,19 +950,14 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
        if (unlikely(irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
                return;
 
-       for_each_input_queue(irq_ptr, q, i) {
-               if (q->u.in.queue_start_poll) {
-                       /* skip if polling is enabled or already in work */
-                       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                                    &q->u.in.queue_irq_state)) {
-                               QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
-                               continue;
-                       }
-                       q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr,
-                                                q->irq_ptr->int_parm);
-               } else {
+       if (irq_ptr->irq_poll) {
+               if (!test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
+                       irq_ptr->irq_poll(irq_ptr->cdev, irq_ptr->int_parm);
+               else
+                       QDIO_PERF_STAT_INC(irq_ptr, int_discarded);
+       } else {
+               for_each_input_queue(irq_ptr, q, i)
                        tasklet_schedule(&q->tasklet);
-               }
        }
 
        if (!pci_out_supported(irq_ptr) || !irq_ptr->scan_threshold)
@@ -1105,9 +1100,8 @@ int qdio_get_ssqd_desc(struct ccw_device *cdev,
 }
 EXPORT_SYMBOL_GPL(qdio_get_ssqd_desc);
 
-static void qdio_shutdown_queues(struct ccw_device *cdev)
+static void qdio_shutdown_queues(struct qdio_irq *irq_ptr)
 {
-       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
        struct qdio_q *q;
        int i;
 
@@ -1155,7 +1149,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 
        tiqdio_remove_device(irq_ptr);
-       qdio_shutdown_queues(cdev);
+       qdio_shutdown_queues(irq_ptr);
        qdio_shutdown_debug_entries(irq_ptr);
 
        /* cleanup subchannel */
@@ -1230,10 +1224,11 @@ EXPORT_SYMBOL_GPL(qdio_free);
  */
 int qdio_allocate(struct qdio_initialize *init_data)
 {
+       struct ccw_device *cdev = init_data->cdev;
        struct subchannel_id schid;
        struct qdio_irq *irq_ptr;
 
-       ccw_device_get_schid(init_data->cdev, &schid);
+       ccw_device_get_schid(cdev, &schid);
        DBF_EVENT("qallocate:%4x", schid.sch_no);
 
        if ((init_data->no_input_qs && !init_data->input_handler) ||
@@ -1253,6 +1248,7 @@ int qdio_allocate(struct qdio_initialize *init_data)
        if (!irq_ptr)
                goto out_err;
 
+       irq_ptr->cdev = cdev;
        mutex_init(&irq_ptr->setup_mutex);
        if (qdio_allocate_dbf(init_data, irq_ptr))
                goto out_rel;
@@ -1277,7 +1273,7 @@ int qdio_allocate(struct qdio_initialize *init_data)
                goto out_rel;
 
        INIT_LIST_HEAD(&irq_ptr->entry);
-       init_data->cdev->private->qdio_data = irq_ptr;
+       cdev->private->qdio_data = irq_ptr;
        qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
        return 0;
 out_rel:
@@ -1316,19 +1312,18 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
 int qdio_establish(struct qdio_initialize *init_data)
 {
        struct ccw_device *cdev = init_data->cdev;
+       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
        struct subchannel_id schid;
-       struct qdio_irq *irq_ptr;
        int rc;
 
        ccw_device_get_schid(cdev, &schid);
        DBF_EVENT("qestablish:%4x", schid.sch_no);
 
-       irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
 
        mutex_lock(&irq_ptr->setup_mutex);
-       qdio_setup_irq(init_data);
+       qdio_setup_irq(irq_ptr, init_data);
 
        rc = qdio_establish_thinint(irq_ptr);
        if (rc) {
@@ -1374,8 +1369,8 @@ int qdio_establish(struct qdio_initialize *init_data)
        qdio_init_buf_states(irq_ptr);
 
        mutex_unlock(&irq_ptr->setup_mutex);
-       qdio_print_subchannel_info(irq_ptr, cdev);
-       qdio_setup_debug_entries(irq_ptr, cdev);
+       qdio_print_subchannel_info(irq_ptr);
+       qdio_setup_debug_entries(irq_ptr);
        return 0;
 }
 EXPORT_SYMBOL_GPL(qdio_establish);
@@ -1386,14 +1381,13 @@ EXPORT_SYMBOL_GPL(qdio_establish);
  */
 int qdio_activate(struct ccw_device *cdev)
 {
+       struct qdio_irq *irq_ptr = cdev->private->qdio_data;
        struct subchannel_id schid;
-       struct qdio_irq *irq_ptr;
        int rc;
 
        ccw_device_get_schid(cdev, &schid);
        DBF_EVENT("qactivate:%4x", schid.sch_no);
 
-       irq_ptr = cdev->private->qdio_data;
        if (!irq_ptr)
                return -ENODEV;
 
@@ -1610,24 +1604,26 @@ EXPORT_SYMBOL_GPL(do_QDIO);
 /**
  * qdio_start_irq - process input buffers
  * @cdev: associated ccw_device for the qdio subchannel
- * @nr: input queue number
  *
  * Return codes
  *   0 - success
  *   1 - irqs not started since new data is available
  */
-int qdio_start_irq(struct ccw_device *cdev, int nr)
+int qdio_start_irq(struct ccw_device *cdev)
 {
        struct qdio_q *q;
        struct qdio_irq *irq_ptr = cdev->private->qdio_data;
+       unsigned int i;
 
        if (!irq_ptr)
                return -ENODEV;
-       q = irq_ptr->input_qs[nr];
 
        clear_nonshared_ind(irq_ptr);
-       qdio_stop_polling(q);
-       clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
+
+       for_each_input_queue(irq_ptr, q, i)
+               qdio_stop_polling(q);
+
+       clear_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state);
 
        /*
         * We need to check again to not lose initiative after
@@ -1635,13 +1631,16 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
         */
        if (test_nonshared_ind(irq_ptr))
                goto rescan;
-       if (!qdio_inbound_q_done(q, q->first_to_check))
-               goto rescan;
+
+       for_each_input_queue(irq_ptr, q, i) {
+               if (!qdio_inbound_q_done(q, q->first_to_check))
+                       goto rescan;
+       }
+
        return 0;
 
 rescan:
-       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                            &q->u.in.queue_irq_state))
+       if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
                return 0;
        else
                return 1;
@@ -1729,23 +1728,19 @@ EXPORT_SYMBOL(qdio_get_next_buffers);
 /**
  * qdio_stop_irq - disable interrupt processing for the device
  * @cdev: associated ccw_device for the qdio subchannel
- * @nr: input queue number
  *
  * Return codes
  *   0 - interrupts were already disabled
  *   1 - interrupts successfully disabled
  */
-int qdio_stop_irq(struct ccw_device *cdev, int nr)
+int qdio_stop_irq(struct ccw_device *cdev)
 {
-       struct qdio_q *q;
        struct qdio_irq *irq_ptr = cdev->private->qdio_data;
 
        if (!irq_ptr)
                return -ENODEV;
-       q = irq_ptr->input_qs[nr];
 
-       if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
-                            &q->u.in.queue_irq_state))
+       if (test_and_set_bit(QDIO_IRQ_DISABLED, &irq_ptr->poll_state))
                return 0;
        else
                return 1;