MHI Host
-------- Support for new modems: - Quectel EM120 FCCL based on SDX24. This product MHI configuration is same as EM120R-GL modem. - Foxconn Cinterion MV31-W. This product is same as the existing MV31-W modem but sold as a separate product as it uses a different firmware baseline. - Foxconn T99W175 based on SDX55. Core changes: - Moved the IRQ allocation to MHI controller registration phase. Since the MHI endpoint may be powered up/down several times during runtime, it makes sense to move the IRQ allocation to registration phase and just enable/disable IRQs during endpoint power up/down. MHI endpoint ------------ Core changes: - Added error check for dev_set_name() -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEZ6VDKoFIy9ikWCeXVZ8R5v6RzvUFAmLLwEwACgkQVZ8R5v6R zvVduQf9F8w3t8PP06i7Lo2gUoKARhGZUKFwK/ZRv2JdpFfVgC7BHas4/yAdljDQ gsmUbqpge8GaidyFk8Zlo5MBOKJK5C85TWKAWVI4pmB5r1iFMFP+YI/3TXNUP3yg nlMabWg05RdYU89c4Db3rpZVl6S+FfADwDilrE6BN9TA+T/z91zweb2VmD1AoAgP XqHX5pS60LaybIBk6hNPdhLfSk3un94tibNFfgbzY1F48t0+K+3Z1CeHszqoArwt vEKoTCDBJc1K4LmpGm388W9HXVJl46/xhxlxj6fq24jL1cWcB9/b6puKO4bmvYwl 7DT9kBVssrBNucKIsZRVZafTALNK3w== =GxUB -----END PGP SIGNATURE----- Merge tag 'mhi-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi into char-misc-next Manivannan writes: MHI Host -------- Support for new modems: - Quectel EM120 FCCL based on SDX24. This product MHI configuration is same as EM120R-GL modem. - Foxconn Cinterion MV31-W. This product is same as the existing MV31-W modem but sold as a separate product as it uses a different firmware baseline. - Foxconn T99W175 based on SDX55. Core changes: - Moved the IRQ allocation to MHI controller registration phase. Since the MHI endpoint may be powered up/down several times during runtime, it makes sense to move the IRQ allocation to registration phase and just enable/disable IRQs during endpoint power up/down. MHI endpoint ------------ Core changes: - Added error check for dev_set_name() * tag 'mhi-for-v5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/mani/mhi: bus: mhi: ep: Check dev_set_name() return value bus: mhi: host: pci_generic: Add another Foxconn T99W175 bus: mhi: host: Move IRQ allocation to controller registration phase bus: mhi: host: pci_generic: Add Cinterion MV31-W with new baseline bus: mhi: host: pci_generic: Add support for Quectel EM120 FCCL modem
This commit is contained in:
commit
f5fd903b31
4 changed files with 46 additions and 9 deletions
|
@ -1242,9 +1242,13 @@ static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id)
|
||||||
|
|
||||||
/* Channel name is same for both UL and DL */
|
/* Channel name is same for both UL and DL */
|
||||||
mhi_dev->name = mhi_chan->name;
|
mhi_dev->name = mhi_chan->name;
|
||||||
dev_set_name(&mhi_dev->dev, "%s_%s",
|
ret = dev_set_name(&mhi_dev->dev, "%s_%s",
|
||||||
dev_name(&mhi_cntrl->mhi_dev->dev),
|
dev_name(&mhi_cntrl->mhi_dev->dev),
|
||||||
mhi_dev->name);
|
mhi_dev->name);
|
||||||
|
if (ret) {
|
||||||
|
put_device(&mhi_dev->dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = device_add(&mhi_dev->dev);
|
ret = device_add(&mhi_dev->dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1408,7 +1412,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
|
||||||
goto err_free_irq;
|
goto err_free_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_set_name(&mhi_dev->dev, "mhi_ep%u", mhi_cntrl->index);
|
ret = dev_set_name(&mhi_dev->dev, "mhi_ep%u", mhi_cntrl->index);
|
||||||
|
if (ret)
|
||||||
|
goto err_put_dev;
|
||||||
|
|
||||||
mhi_dev->name = dev_name(&mhi_dev->dev);
|
mhi_dev->name = dev_name(&mhi_dev->dev);
|
||||||
mhi_cntrl->mhi_dev = mhi_dev;
|
mhi_cntrl->mhi_dev = mhi_dev;
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,12 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
|
||||||
"bhi", mhi_cntrl);
|
"bhi", mhi_cntrl);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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++) {
|
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
|
||||||
if (mhi_event->offload_ev)
|
if (mhi_event->offload_ev)
|
||||||
|
@ -199,6 +205,8 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
|
||||||
mhi_cntrl->irq[mhi_event->irq], i);
|
mhi_cntrl->irq[mhi_event->irq], i);
|
||||||
goto error_request;
|
goto error_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disable_irq(mhi_cntrl->irq[mhi_event->irq]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -978,12 +986,16 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
|
||||||
goto err_destroy_wq;
|
goto err_destroy_wq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = mhi_init_irq_setup(mhi_cntrl);
|
||||||
|
if (ret)
|
||||||
|
goto err_ida_free;
|
||||||
|
|
||||||
/* Register controller with MHI bus */
|
/* Register controller with MHI bus */
|
||||||
mhi_dev = mhi_alloc_device(mhi_cntrl);
|
mhi_dev = mhi_alloc_device(mhi_cntrl);
|
||||||
if (IS_ERR(mhi_dev)) {
|
if (IS_ERR(mhi_dev)) {
|
||||||
dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate MHI device\n");
|
dev_err(mhi_cntrl->cntrl_dev, "Failed to allocate MHI device\n");
|
||||||
ret = PTR_ERR(mhi_dev);
|
ret = PTR_ERR(mhi_dev);
|
||||||
goto err_ida_free;
|
goto error_setup_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
mhi_dev->dev_type = MHI_DEVICE_CONTROLLER;
|
mhi_dev->dev_type = MHI_DEVICE_CONTROLLER;
|
||||||
|
@ -1006,6 +1018,8 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
|
||||||
|
|
||||||
err_release_dev:
|
err_release_dev:
|
||||||
put_device(&mhi_dev->dev);
|
put_device(&mhi_dev->dev);
|
||||||
|
error_setup_irq:
|
||||||
|
mhi_deinit_free_irq(mhi_cntrl);
|
||||||
err_ida_free:
|
err_ida_free:
|
||||||
ida_free(&mhi_controller_ida, mhi_cntrl->index);
|
ida_free(&mhi_controller_ida, mhi_cntrl->index);
|
||||||
err_destroy_wq:
|
err_destroy_wq:
|
||||||
|
@ -1026,6 +1040,7 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
|
||||||
struct mhi_chan *mhi_chan = mhi_cntrl->mhi_chan;
|
struct mhi_chan *mhi_chan = mhi_cntrl->mhi_chan;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
mhi_deinit_free_irq(mhi_cntrl);
|
||||||
mhi_destroy_debugfs(mhi_cntrl);
|
mhi_destroy_debugfs(mhi_cntrl);
|
||||||
|
|
||||||
destroy_workqueue(mhi_cntrl->hiprio_wq);
|
destroy_workqueue(mhi_cntrl->hiprio_wq);
|
||||||
|
|
|
@ -557,6 +557,8 @@ static const struct pci_device_id mhi_pci_id_table[] = {
|
||||||
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
|
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
|
||||||
{ PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */
|
{ PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */
|
||||||
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
|
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
|
||||||
|
{ PCI_DEVICE(0x1eac, 0x2001), /* EM120R-GL for FCCL (sdx24) */
|
||||||
|
.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
|
||||||
/* T99W175 (sdx55), Both for eSIM and Non-eSIM */
|
/* T99W175 (sdx55), Both for eSIM and Non-eSIM */
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),
|
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),
|
||||||
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
|
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
|
||||||
|
@ -569,6 +571,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
|
||||||
/* T99W175 (sdx55), Based on Qualcomm new baseline */
|
/* T99W175 (sdx55), Based on Qualcomm new baseline */
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0bf),
|
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0bf),
|
||||||
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
|
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
|
||||||
|
/* T99W175 (sdx55) */
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0c3),
|
||||||
|
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx55_info },
|
||||||
/* T99W368 (sdx65) */
|
/* T99W368 (sdx65) */
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d8),
|
{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d8),
|
||||||
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
|
.driver_data = (kernel_ulong_t) &mhi_foxconn_sdx65_info },
|
||||||
|
@ -578,6 +583,9 @@ static const struct pci_device_id mhi_pci_id_table[] = {
|
||||||
/* MV31-W (Cinterion) */
|
/* MV31-W (Cinterion) */
|
||||||
{ PCI_DEVICE(0x1269, 0x00b3),
|
{ PCI_DEVICE(0x1269, 0x00b3),
|
||||||
.driver_data = (kernel_ulong_t) &mhi_mv31_info },
|
.driver_data = (kernel_ulong_t) &mhi_mv31_info },
|
||||||
|
/* MV31-W (Cinterion), based on new baseline */
|
||||||
|
{ PCI_DEVICE(0x1269, 0x00b4),
|
||||||
|
.driver_data = (kernel_ulong_t) &mhi_mv31_info },
|
||||||
/* MV32-WA (Cinterion) */
|
/* MV32-WA (Cinterion) */
|
||||||
{ PCI_DEVICE(0x1269, 0x00ba),
|
{ PCI_DEVICE(0x1269, 0x00ba),
|
||||||
.driver_data = (kernel_ulong_t) &mhi_mv32_info },
|
.driver_data = (kernel_ulong_t) &mhi_mv32_info },
|
||||||
|
|
|
@ -500,7 +500,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl)
|
||||||
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
|
for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
|
||||||
if (mhi_event->offload_ev)
|
if (mhi_event->offload_ev)
|
||||||
continue;
|
continue;
|
||||||
free_irq(mhi_cntrl->irq[mhi_event->irq], mhi_event);
|
disable_irq(mhi_cntrl->irq[mhi_event->irq]);
|
||||||
tasklet_kill(&mhi_event->task);
|
tasklet_kill(&mhi_event->task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1060,12 +1060,13 @@ static void mhi_deassert_dev_wake(struct mhi_controller *mhi_cntrl,
|
||||||
|
|
||||||
int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
|
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_state state;
|
||||||
enum mhi_ee_type current_ee;
|
enum mhi_ee_type current_ee;
|
||||||
enum dev_st_transition next_state;
|
enum dev_st_transition next_state;
|
||||||
struct device *dev = &mhi_cntrl->mhi_dev->dev;
|
struct device *dev = &mhi_cntrl->mhi_dev->dev;
|
||||||
u32 interval_us = 25000; /* poll register field every 25 milliseconds */
|
u32 interval_us = 25000; /* poll register field every 25 milliseconds */
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
dev_info(dev, "Requested to power ON\n");
|
dev_info(dev, "Requested to power ON\n");
|
||||||
|
|
||||||
|
@ -1117,9 +1118,15 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl)
|
||||||
mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
|
mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mhi_init_irq_setup(mhi_cntrl);
|
/* IRQs have been requested during probe, so we just need to enable them. */
|
||||||
if (ret)
|
enable_irq(mhi_cntrl->irq[0]);
|
||||||
goto error_exit;
|
|
||||||
|
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 */
|
/* Transition to next state */
|
||||||
next_state = MHI_IN_PBL(current_ee) ?
|
next_state = MHI_IN_PBL(current_ee) ?
|
||||||
|
@ -1182,7 +1189,7 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
|
||||||
/* Wait for shutdown to complete */
|
/* Wait for shutdown to complete */
|
||||||
flush_work(&mhi_cntrl->st_worker);
|
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);
|
EXPORT_SYMBOL_GPL(mhi_power_down);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue