Commit f5fd903b authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'mhi-for-v5.20' of...

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
parents 14facbc1 2ebb36ea
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -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 */
	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),
		     mhi_dev->name);
	if (ret) {
		put_device(&mhi_dev->dev);
		return ret;
	}

	ret = device_add(&mhi_dev->dev);
	if (ret)
@@ -1408,7 +1412,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
		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_cntrl->mhi_dev = mhi_dev;

+16 −1
Original line number Diff line number Diff line
@@ -178,6 +178,12 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
				   "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)
@@ -199,6 +205,8 @@ int mhi_init_irq_setup(struct mhi_controller *mhi_cntrl)
				mhi_cntrl->irq[mhi_event->irq], i);
			goto error_request;
		}

		disable_irq(mhi_cntrl->irq[mhi_event->irq]);
	}

	return 0;
@@ -978,12 +986,16 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,
		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;
@@ -1006,6 +1018,8 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl,

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:
@@ -1026,6 +1040,7 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl)
	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);
+8 −0
Original line number Diff line number Diff line
@@ -557,6 +557,8 @@ static const struct pci_device_id mhi_pci_id_table[] = {
		.driver_data = (kernel_ulong_t) &mhi_quectel_em1xx_info },
	{ PCI_DEVICE(0x1eac, 0x1002), /* EM160R-GL (sdx24) */
		.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 */
	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0ab),
		.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 */
	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0bf),
		.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) */
	{ PCI_DEVICE(PCI_VENDOR_ID_FOXCONN, 0xe0d8),
		.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) */
	{ PCI_DEVICE(0x1269, 0x00b3),
		.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) */
	{ PCI_DEVICE(0x1269, 0x00ba),
		.driver_data = (kernel_ulong_t) &mhi_mv32_info },
+13 −6
Original line number Diff line number Diff line
@@ -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++) {
		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);
	}

@@ -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)
{
	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");

@@ -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);
	}

	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) ?
@@ -1182,7 +1189,7 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful)
	/* 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);