Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e4ac406 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "diag: mhi: Fix error handling for DCI channel failure"

parents 12f97e10 d3ca23df
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
Qualcomm Technologies, Inc. Diag MHI Driver

Required properties:
-compatible : should be "qcom,diag-mhi".
-qcom,mhi : phandle of MHI Device to connect to.

Example:
	qcom,diag {
		compatible = "qcom,diag-mhi";
		qcom,mhi = <&mhi_wlan>;
	};
+1 −0
Original line number Diff line number Diff line
@@ -598,6 +598,7 @@ struct diagchar_dev {
#endif
	int time_sync_enabled;
	uint8_t uses_time_api;
	struct platform_device *pdev;
};

extern struct diagchar_dev *driver;
+38 −8
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include <linux/sched.h>
#include <linux/ratelimit.h>
#include <linux/timer.h>
#include <linux/platform_device.h>
#include <linux/msm_mhi.h>
#ifdef CONFIG_DIAG_OVER_USB
#include <linux/usb/usbdiag.h>
#endif
@@ -3360,6 +3362,41 @@ static int diagchar_cleanup(void)
	return 0;
}

static int diag_mhi_probe(struct platform_device *pdev)
{
	int ret;

	if (!mhi_is_device_ready(&pdev->dev, "qcom,mhi"))
		return -EPROBE_DEFER;
	driver->pdev = pdev;
	ret = diag_remote_init();
	if (ret) {
		diag_remote_exit();
		return ret;
	}
	ret = diagfwd_bridge_init();
	if (ret) {
		diagfwd_bridge_exit();
		return ret;
	}
	pr_debug("diag: mhi device is ready\n");
	return 0;
}

static const struct of_device_id diag_mhi_table[] = {
	{.compatible = "qcom,diag-mhi"},
	{},
};

static struct platform_driver diag_mhi_driver = {
	.probe = diag_mhi_probe,
	.driver = {
		.name = "DIAG MHI Platform",
		.owner = THIS_MODULE,
		.of_match_table = diag_mhi_table,
	},
};

static int __init diagchar_init(void)
{
	dev_t dev;
@@ -3441,9 +3478,6 @@ static int __init diagchar_init(void)
	if (ret)
		goto fail;
	ret = diag_masks_init();
	if (ret)
		goto fail;
	ret = diag_remote_init();
	if (ret)
		goto fail;
	ret = diag_mux_init();
@@ -3482,9 +3516,7 @@ static int __init diagchar_init(void)
		goto fail;

	pr_debug("diagchar initialized now");
	ret = diagfwd_bridge_init();
	if (ret)
		diagfwd_bridge_exit();
	platform_driver_register(&diag_mhi_driver);
	return 0;

fail:
@@ -3498,9 +3530,7 @@ fail:
	diagfwd_cntl_exit();
	diag_dci_exit();
	diag_masks_exit();
	diag_remote_exit();
	return -1;

}

static void diagchar_exit(void)
+23 −11
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -197,7 +197,7 @@ static void mhi_buf_tbl_clear(struct diag_mhi_info *mhi_info)
	struct diag_mhi_buf_tbl_t *item = NULL;
	struct diag_mhi_ch_t *ch = NULL;

	if (!mhi_info || !mhi_info->enabled)
	if (!mhi_info)
		return;

	/* Clear all the pending reads */
@@ -665,7 +665,25 @@ static int diag_mhi_register_ch(int id, struct diag_mhi_ch_t *ch)
	atomic_set(&(ch->opened), 0);
	ctxt = SET_CH_CTXT(id, ch->type);
	ch->client_info.mhi_client_cb = mhi_notifier;
	return mhi_register_channel(&ch->hdl, NULL);
	ch->client_info.chan = ch->chan;
	ch->client_info.dev = &driver->pdev->dev;
	ch->client_info.node_name = "qcom,mhi";
	ch->client_info.user_data = (void *)(uintptr_t)ctxt;
	return mhi_register_channel(&ch->hdl, &ch->client_info);
}

static void diag_mhi_dev_exit(int dev)
{
	struct diag_mhi_info *mhi_info = NULL;

	mhi_info = &diag_mhi[dev];
	if (!mhi_info)
		return;
	if (mhi_info->mhi_wq)
		destroy_workqueue(mhi_info->mhi_wq);
	mhi_close(mhi_info->id);
	if (mhi_info->mempool_init)
		diagmem_exit(driver, mhi_info->mempool);
}

int diag_mhi_init()
@@ -713,22 +731,16 @@ int diag_mhi_init()

	return 0;
fail:
	diag_mhi_exit();
	diag_mhi_dev_exit(i);
	return -ENOMEM;
}

void diag_mhi_exit()
{
	int i;
	struct diag_mhi_info *mhi_info = NULL;

	for (i = 0; i < NUM_MHI_DEV; i++) {
		mhi_info = &diag_mhi[i];
		if (mhi_info->mhi_wq)
			destroy_workqueue(mhi_info->mhi_wq);
		mhi_close(mhi_info->id);
		if (mhi_info->mempool_init)
			diagmem_exit(driver, mhi_info->mempool);
		diag_mhi_dev_exit(i);
	}
}