Commit 9085423f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull char/misc driver fixes from Greg KH:
 "Here are some small driver fixes for 5.14-rc7.

  They consist of:

   - revert for an interconnect patch that was found to have problems

   - ipack tpci200 driver fixes for reported problems

   - slimbus messaging and ngd fixes for reported problems

  All are small and have been in linux-next for a while with no reported
  issues"

* tag 'char-misc-5.14-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  ipack: tpci200: fix memory leak in the tpci200_register
  ipack: tpci200: fix many double free issues in tpci200_pci_probe
  slimbus: ngd: reset dma setup during runtime pm
  slimbus: ngd: set correct device for pm
  slimbus: messaging: check for valid transaction id
  slimbus: messaging: start transaction ids from 1 instead of zero
  Revert "interconnect: qcom: icc-rpmh: Add BCMs to commit list in pre_aggregate"
parents f4ff9e6b d30836a9
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -20,18 +20,13 @@ void qcom_icc_pre_aggregate(struct icc_node *node)
{
	size_t i;
	struct qcom_icc_node *qn;
	struct qcom_icc_provider *qp;

	qn = node->data;
	qp = to_qcom_provider(node->provider);

	for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) {
		qn->sum_avg[i] = 0;
		qn->max_peak[i] = 0;
	}

	for (i = 0; i < qn->num_bcms; i++)
		qcom_icc_bcm_voter_add(qp->voter, qn->bcms[i]);
}
EXPORT_SYMBOL_GPL(qcom_icc_pre_aggregate);

@@ -49,8 +44,10 @@ int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
{
	size_t i;
	struct qcom_icc_node *qn;
	struct qcom_icc_provider *qp;

	qn = node->data;
	qp = to_qcom_provider(node->provider);

	if (!tag)
		tag = QCOM_ICC_TAG_ALWAYS;
@@ -70,6 +67,9 @@ int qcom_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
	*agg_avg += avg_bw;
	*agg_peak = max_t(u32, *agg_peak, peak_bw);

	for (i = 0; i < qn->num_bcms; i++)
		qcom_icc_bcm_voter_add(qp->voter, qn->bcms[i]);

	return 0;
}
EXPORT_SYMBOL_GPL(qcom_icc_aggregate);
+32 −28
Original line number Diff line number Diff line
@@ -89,16 +89,13 @@ static void tpci200_unregister(struct tpci200_board *tpci200)
	free_irq(tpci200->info->pdev->irq, (void *) tpci200);

	pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);

	pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
	pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
	pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
	pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
	pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);

	pci_disable_device(tpci200->info->pdev);
	pci_dev_put(tpci200->info->pdev);
}

static void tpci200_enable_irq(struct tpci200_board *tpci200,
@@ -257,7 +254,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 2 !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto out_disable_pci;
		goto err_disable_device;
	}

	/* Request IO ID INT space (Bar 3) */
@@ -269,7 +266,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 3 !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto out_release_ip_space;
		goto err_ip_interface_bar;
	}

	/* Request MEM8 space (Bar 5) */
@@ -280,7 +277,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 5!",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto out_release_ioid_int_space;
		goto err_io_id_int_spaces_bar;
	}

	/* Request MEM16 space (Bar 4) */
@@ -291,7 +288,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
			"(bn 0x%X, sn 0x%X) failed to allocate PCI resource for BAR 4!",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto out_release_mem8_space;
		goto err_mem8_space_bar;
	}

	/* Map internal tpci200 driver user space */
@@ -305,7 +302,7 @@ static int tpci200_register(struct tpci200_board *tpci200)
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		res = -ENOMEM;
		goto out_release_mem8_space;
		goto err_mem16_space_bar;
	}

	/* Initialize lock that protects interface_regs */
@@ -344,18 +341,22 @@ static int tpci200_register(struct tpci200_board *tpci200)
			"(bn 0x%X, sn 0x%X) unable to register IRQ !",
			tpci200->info->pdev->bus->number,
			tpci200->info->pdev->devfn);
		goto out_release_ioid_int_space;
		goto err_interface_regs;
	}

	return 0;

out_release_mem8_space:
err_interface_regs:
	pci_iounmap(tpci200->info->pdev, tpci200->info->interface_regs);
err_mem16_space_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_MEM16_SPACE_BAR);
err_mem8_space_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_MEM8_SPACE_BAR);
out_release_ioid_int_space:
err_io_id_int_spaces_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_IO_ID_INT_SPACES_BAR);
out_release_ip_space:
err_ip_interface_bar:
	pci_release_region(tpci200->info->pdev, TPCI200_IP_INTERFACE_BAR);
out_disable_pci:
err_disable_device:
	pci_disable_device(tpci200->info->pdev);
	return res;
}
@@ -527,7 +528,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
	tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL);
	if (!tpci200->info) {
		ret = -ENOMEM;
		goto out_err_info;
		goto err_tpci200;
	}

	pci_dev_get(pdev);
@@ -538,7 +539,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
	if (ret) {
		dev_err(&pdev->dev, "Failed to allocate PCI Configuration Memory");
		ret = -EBUSY;
		goto out_err_pci_request;
		goto err_tpci200_info;
	}
	tpci200->info->cfg_regs = ioremap(
			pci_resource_start(pdev, TPCI200_CFG_MEM_BAR),
@@ -546,7 +547,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
	if (!tpci200->info->cfg_regs) {
		dev_err(&pdev->dev, "Failed to map PCI Configuration Memory");
		ret = -EFAULT;
		goto out_err_ioremap;
		goto err_request_region;
	}

	/* Disable byte swapping for 16 bit IP module access. This will ensure
@@ -569,7 +570,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
	if (ret) {
		dev_err(&pdev->dev, "error during tpci200 install\n");
		ret = -ENODEV;
		goto out_err_install;
		goto err_cfg_regs;
	}

	/* Register the carrier in the industry pack bus driver */
@@ -581,7 +582,7 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
		dev_err(&pdev->dev,
			"error registering the carrier on ipack driver\n");
		ret = -EFAULT;
		goto out_err_bus_register;
		goto err_tpci200_install;
	}

	/* save the bus number given by ipack to logging purpose */
@@ -592,19 +593,16 @@ static int tpci200_pci_probe(struct pci_dev *pdev,
		tpci200_create_device(tpci200, i);
	return 0;

out_err_bus_register:
err_tpci200_install:
	tpci200_uninstall(tpci200);
	/* tpci200->info->cfg_regs is unmapped in tpci200_uninstall */
	tpci200->info->cfg_regs = NULL;
out_err_install:
	if (tpci200->info->cfg_regs)
		iounmap(tpci200->info->cfg_regs);
out_err_ioremap:
err_cfg_regs:
	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);
err_request_region:
	pci_release_region(pdev, TPCI200_CFG_MEM_BAR);
out_err_pci_request:
	pci_dev_put(pdev);
err_tpci200_info:
	kfree(tpci200->info);
out_err_info:
	pci_dev_put(pdev);
err_tpci200:
	kfree(tpci200);
	return ret;
}
@@ -614,6 +612,12 @@ static void __tpci200_pci_remove(struct tpci200_board *tpci200)
	ipack_bus_unregister(tpci200->info->ipack_bus);
	tpci200_uninstall(tpci200);

	pci_iounmap(tpci200->info->pdev, tpci200->info->cfg_regs);

	pci_release_region(tpci200->info->pdev, TPCI200_CFG_MEM_BAR);

	pci_dev_put(tpci200->info->pdev);

	kfree(tpci200->info);
	kfree(tpci200);
}
+4 −3
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ int slim_alloc_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn)
	int ret = 0;

	spin_lock_irqsave(&ctrl->txn_lock, flags);
	ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 0,
	ret = idr_alloc_cyclic(&ctrl->tid_idr, txn, 1,
				SLIM_MAX_TIDS, GFP_ATOMIC);
	if (ret < 0) {
		spin_unlock_irqrestore(&ctrl->txn_lock, flags);
@@ -131,7 +131,8 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
			goto slim_xfer_err;
		}
	}

	/* Initialize tid to invalid value */
	txn->tid = 0;
	need_tid = slim_tid_txn(txn->mt, txn->mc);

	if (need_tid) {
@@ -163,7 +164,7 @@ int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn)
			txn->mt, txn->mc, txn->la, ret);

slim_xfer_err:
	if (!clk_pause_msg && (!need_tid  || ret == -ETIMEDOUT)) {
	if (!clk_pause_msg && (txn->tid == 0  || ret == -ETIMEDOUT)) {
		/*
		 * remove runtime-pm vote if this was TX only, or
		 * if there was error during this transaction
+13 −9
Original line number Diff line number Diff line
@@ -618,7 +618,7 @@ static void qcom_slim_ngd_rx(struct qcom_slim_ngd_ctrl *ctrl, u8 *buf)
		(mc == SLIM_USR_MC_GENERIC_ACK &&
		 mt == SLIM_MSG_MT_SRC_REFERRED_USER)) {
		slim_msg_response(&ctrl->ctrl, &buf[4], buf[3], len - 4);
		pm_runtime_mark_last_busy(ctrl->dev);
		pm_runtime_mark_last_busy(ctrl->ctrl.dev);
	}
}

@@ -1080,7 +1080,8 @@ static void qcom_slim_ngd_setup(struct qcom_slim_ngd_ctrl *ctrl)
{
	u32 cfg = readl_relaxed(ctrl->ngd->base);

	if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN)
	if (ctrl->state == QCOM_SLIM_NGD_CTRL_DOWN ||
		ctrl->state == QCOM_SLIM_NGD_CTRL_ASLEEP)
		qcom_slim_ngd_init_dma(ctrl);

	/* By default enable message queues */
@@ -1131,6 +1132,7 @@ static int qcom_slim_ngd_power_up(struct qcom_slim_ngd_ctrl *ctrl)
			dev_info(ctrl->dev, "Subsys restart: ADSP active framer\n");
			return 0;
		}
		qcom_slim_ngd_setup(ctrl);
		return 0;
	}

@@ -1257,13 +1259,14 @@ static int qcom_slim_ngd_enable(struct qcom_slim_ngd_ctrl *ctrl, bool enable)
		}
		/* controller state should be in sync with framework state */
		complete(&ctrl->qmi.qmi_comp);
		if (!pm_runtime_enabled(ctrl->dev) ||
				!pm_runtime_suspended(ctrl->dev))
			qcom_slim_ngd_runtime_resume(ctrl->dev);
		if (!pm_runtime_enabled(ctrl->ctrl.dev) ||
			 !pm_runtime_suspended(ctrl->ctrl.dev))
			qcom_slim_ngd_runtime_resume(ctrl->ctrl.dev);
		else
			pm_runtime_resume(ctrl->dev);
		pm_runtime_mark_last_busy(ctrl->dev);
		pm_runtime_put(ctrl->dev);
			pm_runtime_resume(ctrl->ctrl.dev);

		pm_runtime_mark_last_busy(ctrl->ctrl.dev);
		pm_runtime_put(ctrl->ctrl.dev);

		ret = slim_register_controller(&ctrl->ctrl);
		if (ret) {
@@ -1389,7 +1392,7 @@ static int qcom_slim_ngd_ssr_pdr_notify(struct qcom_slim_ngd_ctrl *ctrl,
		/* Make sure the last dma xfer is finished */
		mutex_lock(&ctrl->tx_lock);
		if (ctrl->state != QCOM_SLIM_NGD_CTRL_DOWN) {
			pm_runtime_get_noresume(ctrl->dev);
			pm_runtime_get_noresume(ctrl->ctrl.dev);
			ctrl->state = QCOM_SLIM_NGD_CTRL_DOWN;
			qcom_slim_ngd_down(ctrl);
			qcom_slim_ngd_exit_dma(ctrl);
@@ -1617,6 +1620,7 @@ static int __maybe_unused qcom_slim_ngd_runtime_suspend(struct device *dev)
	struct qcom_slim_ngd_ctrl *ctrl = dev_get_drvdata(dev);
	int ret = 0;

	qcom_slim_ngd_exit_dma(ctrl);
	if (!ctrl->qmi.handle)
		return 0;