"bhi", mhi_cntrl);
if (ret)
return ret;
+ /*
+ * IRQs should be enabled during mhi_async_power_up(), so disable them explicitly here.
+ * Due to the use of IRQF_SHARED flag as default while requesting IRQs, we assume that
+ * IRQ_NOAUTOEN is not applicable.
+ */
+ disable_irq(mhi_cntrl->irq[0]);
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
if (mhi_event->offload_ev)
mhi_cntrl->irq[mhi_event->irq], i);
goto error_request;
}
+
+ disable_irq(mhi_cntrl->irq[mhi_event->irq]);
}
return 0;
goto err_destroy_wq;
}
+ ret = mhi_init_irq_setup(mhi_cntrl);
+ if (ret)
+ goto err_ida_free;
+
/* Register controller with MHI bus */
mhi_dev = mhi_alloc_device(mhi_cntrl);
if (IS_ERR(mhi_dev)) {
dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate MHI device\n");
ret = PTR_ERR(mhi_dev);
- goto err_ida_free;
+ goto error_setup_irq;
}
mhi_dev->dev_type = MHI_DEVICE_CONTROLLER;
err_release_dev:
put_device(&mhi_dev->dev);
+error_setup_irq:
+ mhi_deinit_free_irq(mhi_cntrl);
err_ida_free:
ida_free(&mhi_controller_ida, mhi_cntrl->index);
err_destroy_wq:
struct mhi_chan *mhi_chan = mhi_cntrl->mhi_chan;
unsigned int i;
+ mhi_deinit_free_irq(mhi_cntrl);
mhi_destroy_debugfs(mhi_cntrl);
destroy_workqueue(mhi_cntrl->hiprio_wq);
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
if (mhi_event->offload_ev)
continue;
- free_irq(mhi_cntrl->irq[mhi_event->irq], mhi_event);
+ disable_irq(mhi_cntrl->irq[mhi_event->irq]);
tasklet_kill(&mhi_event->task);
}
int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
{
+ struct mhi_event *mhi_event = mhi_cntrl->mhi_event;
enum mhi_state state;
enum mhi_ee_type current_ee;
enum dev_st_transition next_state;
struct device *dev = &mhi_cntrl->mhi_dev->dev;
u32 interval_us = 25000; /* poll register field every 25 milliseconds */
- int ret;
+ int ret, i;
dev_info(dev, "Requested to power ON\n");
mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
}
- ret = mhi_init_irq_setup(mhi_cntrl);
- if (ret)
- goto error_exit;
+ /* IRQs have been requested during probe, so we just need to enable them. */
+ enable_irq(mhi_cntrl->irq[0]);
+
+ for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
+ if (mhi_event->offload_ev)
+ continue;
+
+ enable_irq(mhi_cntrl->irq[mhi_event->irq]);
+ }
/* Transition to next state */
next_state = MHI_IN_PBL(current_ee) ?
/* Wait for shutdown to complete */
flush_work(&mhi_cntrl->st_worker);
- free_irq(mhi_cntrl->irq[0], mhi_cntrl);
+ disable_irq(mhi_cntrl->irq[0]);
}
EXPORT_SYMBOL_GPL(mhi_power_down);