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

Commit 48d09ea3 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mhi: core: provide an API to retrieve device failure reason"

parents 45618faf e282b99d
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -73,6 +73,19 @@ static const char * const mhi_pm_state_str[] = {

struct mhi_bus mhi_bus;

struct mhi_controller *find_mhi_controller_by_name(const char *name)
{
	struct mhi_controller *mhi_cntrl, *tmp_cntrl;

	list_for_each_entry_safe(mhi_cntrl, tmp_cntrl, &mhi_bus.controller_list,
				 node) {
		if (mhi_cntrl->name && (!strcmp(name, mhi_cntrl->name)))
			return mhi_cntrl;
	}

	return NULL;
}

const char *to_mhi_pm_state_str(enum MHI_PM_STATE state)
{
	int index = find_last_bit((unsigned long *)&state, 32);
@@ -666,6 +679,9 @@ int mhi_init_sfr(struct mhi_controller *mhi_cntrl)
	if (!sfr_info)
		return ret;

	/* do a clean-up if we reach here post SSR */
	memset(sfr_info->str, 0, sfr_info->len);

	sfr_info->buf_addr = mhi_alloc_coherent(mhi_cntrl, sfr_info->len,
					&sfr_info->dma_addr, GFP_KERNEL);
	if (!sfr_info->buf_addr) {
@@ -1330,6 +1346,8 @@ static int of_parse_dt(struct mhi_controller *mhi_cntrl,
	if (!ret)
		mhi_cntrl->bhie = mhi_cntrl->regs + bhie_offset;

	of_property_read_string(of_node, "mhi,name", &mhi_cntrl->name);

	return 0;

error_ev_cfg:
@@ -1469,6 +1487,12 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
			goto error_add_dev;
		}

		sfr_info->str = kzalloc(mhi_cntrl->sfr_len, GFP_KERNEL);
		if (!sfr_info->str) {
			ret = -ENOMEM;
			goto error_alloc_sfr;
		}

		sfr_info->len = mhi_cntrl->sfr_len;
		mhi_cntrl->mhi_sfr = sfr_info;
	}
@@ -1483,6 +1507,9 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)

	return 0;

error_alloc_sfr:
	kfree(sfr_info);

error_add_dev:
	mhi_dealloc_device(mhi_cntrl, mhi_dev);

@@ -1500,12 +1527,17 @@ EXPORT_SYMBOL(of_register_mhi_controller);
void mhi_unregister_mhi_controller(struct mhi_controller *mhi_cntrl)
{
	struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
	struct mhi_sfr_info *sfr_info = mhi_cntrl->mhi_sfr;

	kfree(mhi_cntrl->mhi_cmd);
	kfree(mhi_cntrl->mhi_event);
	vfree(mhi_cntrl->mhi_chan);
	kfree(mhi_cntrl->mhi_tsync);
	kfree(mhi_cntrl->mhi_sfr);

	if (sfr_info) {
		kfree(sfr_info->str);
		kfree(sfr_info);
	}

	device_del(&mhi_dev->dev);
	put_device(&mhi_dev->dev);
+3 −0
Original line number Diff line number Diff line
@@ -728,6 +728,7 @@ struct mhi_sfr_info {
	void *buf_addr;
	dma_addr_t dma_addr;
	size_t len;
	char *str;
	enum MHI_EV_CCS ccs;
	struct completion completion;
};
@@ -741,6 +742,8 @@ struct mhi_bus {
#define MHI_TIMEOUT_MS (1000)
extern struct mhi_bus mhi_bus;

struct mhi_controller *find_mhi_controller_by_name(const char *name);

/* debug fs related functions */
int mhi_debugfs_mhi_chan_show(struct seq_file *m, void *d);
int mhi_debugfs_mhi_event_show(struct seq_file *m, void *d);
+19 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
#include <linux/mhi.h>
#include "mhi_internal.h"

static char *mhi_generic_sfr = "unknown reason";

static void __mhi_unprepare_channel(struct mhi_controller *mhi_cntrl,
				    struct mhi_chan *mhi_chan);

@@ -2558,3 +2560,20 @@ void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl)
	}
}
EXPORT_SYMBOL(mhi_debug_reg_dump);

char *mhi_get_restart_reason(const char *name)
{
	struct mhi_controller *mhi_cntrl;
	struct mhi_sfr_info *sfr_info;

	mhi_cntrl = find_mhi_controller_by_name(name);
	if (!mhi_cntrl)
		return ERR_PTR(-ENODEV);

	sfr_info = mhi_cntrl->mhi_sfr;
	if (!sfr_info)
		return ERR_PTR(-EINVAL);

	return strlen(sfr_info->str) ? sfr_info->str : mhi_generic_sfr;
}
EXPORT_SYMBOL(mhi_get_restart_reason);
+5 −2
Original line number Diff line number Diff line
@@ -992,8 +992,11 @@ void mhi_control_error(struct mhi_controller *mhi_cntrl)
		TO_MHI_STATE_STR(mhi_cntrl->dev_state));

	/* copy subsystem failure reason string if supported */
	if (sfr_info && sfr_info->buf_addr)
		pr_err("mhi: sfr: %s\n", sfr_info->buf_addr);
	if (sfr_info && sfr_info->buf_addr) {
		memcpy(sfr_info->str, sfr_info->buf_addr, sfr_info->len);
		pr_err("mhi: %s sfr: %s\n", mhi_cntrl->name,
		       sfr_info->buf_addr);
	}

	/* link is not down if device is in RDDM */
	transition_state = (mhi_cntrl->ee == MHI_EE_RDDM) ?
+7 −0
Original line number Diff line number Diff line
@@ -378,6 +378,7 @@ struct mhi_controller {
	enum MHI_DEBUG_LEVEL log_lvl;

	/* controller specific data */
	const char *name;
	bool power_down;
	void *priv_data;
	void *log_buf;
@@ -799,6 +800,12 @@ void mhi_control_error(struct mhi_controller *mhi_cntrl);
 */
void mhi_debug_reg_dump(struct mhi_controller *mhi_cntrl);

/**
 * mhi_get_restart_reason - retrieve the subsystem failure reason
 * @name: controller name
 */
char *mhi_get_restart_reason(const char *name);

#ifndef CONFIG_ARCH_QCOM

#ifdef CONFIG_MHI_DEBUG