rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Freeing function list\n");
 
-       mutex_lock(&data->irq_mutex);
-
        devm_kfree(&rmi_dev->dev, data->irq_memory);
        data->irq_memory = NULL;
        data->irq_status = NULL;
                list_del(&fn->node);
                rmi_unregister_function(fn);
        }
-
-       mutex_unlock(&data->irq_mutex);
 }
 EXPORT_SYMBOL_GPL(rmi_free_function_list);
 
        if (!data)
                return 0;
 
-       mutex_lock(&data->irq_mutex);
-       if (!data->irq_status || !data->f01_container) {
-               mutex_unlock(&data->irq_mutex);
-               return 0;
-       }
-
        if (!rmi_dev->xport->attn_data) {
                error = rmi_read_block(rmi_dev,
                                data->f01_container->fd.data_base_addr + 1,
                                data->irq_status, data->num_of_irq_regs);
                if (error < 0) {
                        dev_err(dev, "Failed to read irqs, code=%d\n", error);
-                       mutex_unlock(&data->irq_mutex);
                        return error;
                }
        }
 
+       mutex_lock(&data->irq_mutex);
        bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask,
               data->irq_count);
+       /*
+        * At this point, irq_status has all bits that are set in the
+        * interrupt status register and are enabled.
+        */
+       mutex_unlock(&data->irq_mutex);
 
        /*
         * It would be nice to be able to use irq_chip to handle these
        if (data->input)
                input_sync(data->input);
 
-       mutex_unlock(&data->irq_mutex);
-
        return 0;
 }
 
        struct rmi_function *entry;
        int retval;
 
-       mutex_lock(&data->irq_mutex);
-
        list_for_each_entry(entry, &data->function_list, node) {
                retval = suspend_one_function(entry);
-               if (retval < 0) {
-                       mutex_unlock(&data->irq_mutex);
+               if (retval < 0)
                        return retval;
-               }
        }
 
-       mutex_unlock(&data->irq_mutex);
-
        return 0;
 }
 
        struct rmi_function *entry;
        int retval;
 
-       mutex_lock(&data->irq_mutex);
-
        list_for_each_entry(entry, &data->function_list, node) {
                retval = resume_one_function(entry);
-               if (retval < 0) {
-                       mutex_unlock(&data->irq_mutex);
+               if (retval < 0)
                        return retval;
-               }
        }
 
-       mutex_unlock(&data->irq_mutex);
-
        return 0;
 }
 
        int irq_count;
        int retval;
 
-       mutex_lock(&data->irq_mutex);
-
        irq_count = 0;
        rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Creating functions.\n", __func__);
        retval = rmi_scan_pdt(rmi_dev, &irq_count, rmi_create_function);
                goto err_destroy_functions;
        }
 
-       mutex_unlock(&data->irq_mutex);
-
        return 0;
 
 err_destroy_functions:
        rmi_free_function_list(rmi_dev);
-       mutex_unlock(&data->irq_mutex);
        return retval;
 }
 EXPORT_SYMBOL_GPL(rmi_init_functions);
 
 static int rmi_firmware_update(struct rmi_driver_data *data,
                               const struct firmware *fw)
 {
-       struct device *dev = &data->rmi_dev->dev;
+       struct rmi_device *rmi_dev = data->rmi_dev;
+       struct device *dev = &rmi_dev->dev;
        struct f34_data *f34;
        int ret;
 
        if (ret)
                return ret;
 
+       rmi_disable_irq(rmi_dev, false);
+
        /* Tear down functions and re-probe */
-       rmi_free_function_list(data->rmi_dev);
+       rmi_free_function_list(rmi_dev);
 
        ret = rmi_probe_interrupts(data);
        if (ret)
                return -EINVAL;
        }
 
+       rmi_enable_irq(rmi_dev, false);
+
        f34 = dev_get_drvdata(&data->f34_container->dev);
 
        /* Perform firmware update */
 
        dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret);
 
+       rmi_disable_irq(rmi_dev, false);
+
        /* Re-probe */
        rmi_dbg(RMI_DEBUG_FN, dev, "Re-probing device\n");
-       rmi_free_function_list(data->rmi_dev);
+       rmi_free_function_list(rmi_dev);
 
-       ret = rmi_scan_pdt(data->rmi_dev, NULL, rmi_initial_reset);
+       ret = rmi_scan_pdt(rmi_dev, NULL, rmi_initial_reset);
        if (ret < 0)
                dev_warn(dev, "RMI reset failed!\n");
 
        if (ret)
                return ret;
 
+       rmi_enable_irq(rmi_dev, false);
+
        if (data->f01_container->dev.driver)
                /* Driver already bound, so enable ATTN now. */
-               return rmi_enable_sensor(data->rmi_dev);
+               return rmi_enable_sensor(rmi_dev);
 
        rmi_dbg(RMI_DEBUG_FN, dev, "%s complete\n", __func__);