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

Commit 3932056d authored by Sujeev Dias's avatar Sujeev Dias Committed by Gerrit - the friendly Code Review server
Browse files

mhi: controller: qcom: add a boot monitor



Repurpose existing async boot log thread as a general purpose boot
monitor for boot status.

CRs-Fixed: 2418347
Change-Id: I7c1391ae9506c13c5f1a17457a2c9c0582089546
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 0a53ea29
Loading
Loading
Loading
Loading
+54 −51
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/

#include <asm/dma-iommu.h>
#include <linux/async.h>
@@ -28,12 +28,9 @@ struct arch_info {
	struct pci_saved_state *pcie_state;
	struct pci_saved_state *ref_pcie_state;
	struct dma_iommu_mapping *mapping;
};

struct mhi_bl_info {
	struct mhi_device *mhi_device;
	async_cookie_t cookie;
	void *ipc_log;
	void *boot_ipc_log;
	struct mhi_device *boot_dev;
};

/* ipc log markings */
@@ -129,6 +126,7 @@ void mhi_arch_esoc_ops_power_off(void *priv, bool mdm_state)
{
	struct mhi_controller *mhi_cntrl = priv;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;

	MHI_LOG("Enter: mdm_crashed:%d\n", mdm_state);
	if (!mhi_dev->powered_on) {
@@ -142,21 +140,27 @@ void mhi_arch_esoc_ops_power_off(void *priv, bool mdm_state)
	/* turn the link off */
	mhi_deinit_pci_dev(mhi_cntrl);
	mhi_arch_link_off(mhi_cntrl, false);

	/* wait for boot monitor to exit */
	async_synchronize_cookie(arch_info->cookie + 1);

	mhi_arch_iommu_deinit(mhi_cntrl);
	mhi_arch_pcie_deinit(mhi_cntrl);
	mhi_dev->powered_on = false;
}

static void mhi_bl_dl_cb(struct mhi_device *mhi_dev,
static void mhi_bl_dl_cb(struct mhi_device *mhi_device,
			 struct mhi_result *mhi_result)
{
	struct mhi_bl_info *mhi_bl_info = mhi_device_get_devdata(mhi_dev);
	struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;
	char *buf = mhi_result->buf_addr;

	/* force a null at last character */
	buf[mhi_result->bytes_xferd - 1] = 0;

	ipc_log_string(mhi_bl_info->ipc_log, "%s %s", DLOG, buf);
	ipc_log_string(arch_info->boot_ipc_log, "%s %s", DLOG, buf);
}

static void mhi_bl_dummy_cb(struct mhi_device *mhi_dev,
@@ -164,21 +168,23 @@ static void mhi_bl_dummy_cb(struct mhi_device *mhi_dev,
{
}

static void mhi_bl_remove(struct mhi_device *mhi_dev)
static void mhi_bl_remove(struct mhi_device *mhi_device)
{
	struct mhi_bl_info *mhi_bl_info = mhi_device_get_devdata(mhi_dev);

	ipc_log_string(mhi_bl_info->ipc_log, HLOG "Received Remove notif.\n");
	struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;

	/* wait for boot monitor to exit */
	async_synchronize_cookie(mhi_bl_info->cookie + 1);
	arch_info->boot_dev = NULL;
	ipc_log_string(arch_info->boot_ipc_log,
		       HLOG "Received Remove notif.\n");
}

static void mhi_bl_boot_monitor(void *data, async_cookie_t cookie)
static void mhi_boot_monitor(void *data, async_cookie_t cookie)
{
	struct mhi_bl_info *mhi_bl_info = data;
	struct mhi_device *mhi_device = mhi_bl_info->mhi_device;
	struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
	struct mhi_controller *mhi_cntrl = data;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;
	struct mhi_device *boot_dev;
	/* 15 sec timeout for booting device */
	const u32 timeout = msecs_to_jiffies(15000);

@@ -187,46 +193,43 @@ static void mhi_bl_boot_monitor(void *data, async_cookie_t cookie)
			   || mhi_cntrl->ee == MHI_EE_DISABLE_TRANSITION,
			   timeout);

	if (mhi_cntrl->ee == MHI_EE_AMSS) {
		ipc_log_string(mhi_bl_info->ipc_log, HLOG
			       "Device successfully booted to mission mode\n");

		mhi_unprepare_from_transfer(mhi_device);
	} else {
		ipc_log_string(mhi_bl_info->ipc_log, HLOG
			       "Device failed to boot to mission mode, ee = %s\n",
	ipc_log_string(arch_info->boot_ipc_log, HLOG "Device current ee = %s\n",
		       TO_MHI_EXEC_STR(mhi_cntrl->ee));

	/* if we successfully booted to amss disable boot log channel */
	boot_dev = arch_info->boot_dev;
	if (boot_dev && mhi_cntrl->ee == MHI_EE_AMSS)
		mhi_unprepare_from_transfer(boot_dev);
}

int mhi_arch_power_up(struct mhi_controller *mhi_cntrl)
{
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;

	/* start a boot monitor */
	arch_info->cookie = async_schedule(mhi_boot_monitor, mhi_cntrl);

	return 0;
}

static int mhi_bl_probe(struct mhi_device *mhi_dev,
static int mhi_bl_probe(struct mhi_device *mhi_device,
			const struct mhi_device_id *id)
{
	char node_name[32];
	struct mhi_bl_info *mhi_bl_info;

	mhi_bl_info = devm_kzalloc(&mhi_dev->dev, sizeof(*mhi_bl_info),
				   GFP_KERNEL);
	if (!mhi_bl_info)
		return -ENOMEM;
	struct mhi_controller *mhi_cntrl = mhi_device->mhi_cntrl;
	struct mhi_dev *mhi_dev = mhi_controller_get_devdata(mhi_cntrl);
	struct arch_info *arch_info = mhi_dev->arch_info;

	snprintf(node_name, sizeof(node_name), "mhi_bl_%04x_%02u.%02u.%02u",
		 mhi_dev->dev_id, mhi_dev->domain, mhi_dev->bus, mhi_dev->slot);
		 mhi_device->dev_id, mhi_device->domain, mhi_device->bus,
		 mhi_device->slot);

	mhi_bl_info->ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES,
	arch_info->boot_dev = mhi_device;
	arch_info->boot_ipc_log = ipc_log_context_create(MHI_IPC_LOG_PAGES,
							 node_name, 0);
	if (!mhi_bl_info->ipc_log)
		return -EINVAL;

	mhi_bl_info->mhi_device = mhi_dev;
	mhi_device_set_devdata(mhi_dev, mhi_bl_info);

	ipc_log_string(mhi_bl_info->ipc_log, HLOG
		       "Entered SBL, Session ID:0x%x\n",
		       mhi_dev->mhi_cntrl->session_id);

	/* start a thread to monitor entering mission mode */
	mhi_bl_info->cookie = async_schedule(mhi_bl_boot_monitor, mhi_bl_info);
	ipc_log_string(arch_info->boot_ipc_log, HLOG
		       "Entered SBL, Session ID:0x%x\n", mhi_cntrl->session_id);

	return 0;
}
+7 −0
Original line number Diff line number Diff line
@@ -409,6 +409,13 @@ static int mhi_qcom_power_up(struct mhi_controller *mhi_cntrl)
			return -EIO;
	}

	/* when coming out of SSR, initial ee state is not valid */
	mhi_cntrl->ee = 0;

	ret = mhi_arch_power_up(mhi_cntrl);
	if (ret)
		return ret;

	ret = mhi_async_power_up(mhi_cntrl);

	/* power up create the dentry */
+7 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.*/
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.*/

#ifndef _MHI_QCOM_
#define _MHI_QCOM_
@@ -38,6 +38,7 @@ int mhi_pci_probe(struct pci_dev *pci_dev,

#ifdef CONFIG_ARCH_QCOM

int mhi_arch_power_up(struct mhi_controller *mhi_cntrl);
int mhi_arch_pcie_init(struct mhi_controller *mhi_cntrl);
void mhi_arch_pcie_deinit(struct mhi_controller *mhi_cntrl);
int mhi_arch_iommu_init(struct mhi_controller *mhi_cntrl);
@@ -80,6 +81,11 @@ static inline int mhi_arch_link_on(struct mhi_controller *mhi_cntrl)
	return 0;
}

static inline int mhi_arch_power_up(struct mhi_controller *mhi_cntrl)
{
	return 0;
}

#endif

#endif /* _MHI_QCOM_ */