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

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

Merge "mhi: core: remove firmware loader worker thread"

parents 905bbcdf be796937
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */

#include <linux/debugfs.h>
#include <linux/device.h>
@@ -1018,7 +1018,7 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
	if (!mhi_cntrl->mhi_event)
		return -ENOMEM;

	INIT_LIST_HEAD(&mhi_cntrl->lp_ev_rings);
	INIT_LIST_HEAD(&mhi_cntrl->sp_ev_rings);

	/* populate ev ring */
	mhi_event = mhi_cntrl->mhi_event;
@@ -1101,13 +1101,13 @@ static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
							      "mhi,offload");

		/*
		 * low priority events are handled in a separate worker thread
		 * special purpose events are handled in a separate kthread
		 * to allow for sleeping functions to be called.
		 */
		if (!mhi_event->offload_ev) {
			if (IS_MHI_ER_PRIORITY_LOW(mhi_event))
			if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event))
				list_add_tail(&mhi_event->node,
						&mhi_cntrl->lp_ev_rings);
						&mhi_cntrl->sp_ev_rings);
			else
				mhi_event->request_irq = true;
		}
@@ -1393,9 +1393,15 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
	spin_lock_init(&mhi_cntrl->transition_lock);
	spin_lock_init(&mhi_cntrl->wlock);
	INIT_WORK(&mhi_cntrl->st_worker, mhi_pm_st_worker);
	INIT_WORK(&mhi_cntrl->low_priority_worker, mhi_low_priority_worker);
	init_waitqueue_head(&mhi_cntrl->state_event);

	mhi_cntrl->special_wq = alloc_ordered_workqueue("mhi_special_w",
						WQ_MEM_RECLAIM | WQ_HIGHPRI);
	if (!mhi_cntrl->special_wq)
		goto error_alloc_cmd;

	INIT_WORK(&mhi_cntrl->special_work, mhi_special_purpose_work);

	mhi_cmd = mhi_cntrl->mhi_cmd;
	for (i = 0; i < NR_OF_CMD_RINGS; i++, mhi_cmd++)
		spin_lock_init(&mhi_cmd->lock);
@@ -1408,7 +1414,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
		mhi_event->mhi_cntrl = mhi_cntrl;
		spin_lock_init(&mhi_event->lock);

		if (IS_MHI_ER_PRIORITY_LOW(mhi_event))
		if (IS_MHI_ER_PRIORITY_SPECIAL(mhi_event))
			continue;

		if (mhi_event->data_type == MHI_ER_CTRL_ELEMENT_TYPE)
@@ -1516,6 +1522,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)

error_alloc_dev:
	kfree(mhi_cntrl->mhi_cmd);
	destroy_workqueue(mhi_cntrl->special_wq);

error_alloc_cmd:
	vfree(mhi_cntrl->mhi_chan);
+3 −3
Original line number Diff line number Diff line
@@ -550,10 +550,10 @@ enum MHI_ER_TYPE {
enum mhi_er_priority {
	MHI_ER_PRIORITY_HIGH,
	MHI_ER_PRIORITY_MEDIUM,
	MHI_ER_PRIORITY_LOW,
	MHI_ER_PRIORITY_SPECIAL,
};

#define IS_MHI_ER_PRIORITY_LOW(ev) (ev->priority >= MHI_ER_PRIORITY_LOW)
#define IS_MHI_ER_PRIORITY_SPECIAL(ev) (ev->priority >= MHI_ER_PRIORITY_SPECIAL)
#define IS_MHI_ER_PRIORITY_HIGH(ev) (ev->priority == MHI_ER_PRIORITY_HIGH)

enum mhi_er_data_type {
@@ -769,8 +769,8 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl,
			       enum MHI_ST_TRANSITION state);
void mhi_pm_st_worker(struct work_struct *work);
void mhi_fw_load_worker(struct work_struct *work);
void mhi_special_purpose_work(struct work_struct *work);
void mhi_process_sys_err(struct mhi_controller *mhi_cntrl);
void mhi_low_priority_worker(struct work_struct *work);
int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl);
void mhi_ctrl_ev_task(unsigned long data);
int mhi_pm_m0_transition(struct mhi_controller *mhi_cntrl);
+1 −1
Original line number Diff line number Diff line
@@ -1762,7 +1762,7 @@ irqreturn_t mhi_intvec_handlr(int irq_number, void *dev)
	MHI_VERB("Exit\n");

	if (MHI_IN_MISSION_MODE(mhi_cntrl->ee))
		schedule_work(&mhi_cntrl->low_priority_worker);
		queue_work(mhi_cntrl->special_wq, &mhi_cntrl->special_work);

	return IRQ_WAKE_THREAD;
}
+19 −14
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include <linux/mhi.h>
#include "mhi_internal.h"

static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl);

/*
 * Not all MHI states transitions are sync transitions. Linkdown, SSR, and
 * shutdown can happen anytime asynchronously. This function will transition to
@@ -525,6 +527,8 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
	if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
		mhi_timesync_log(mhi_cntrl);

	mhi_special_events_pending(mhi_cntrl);

	MHI_LOG("Adding new devices\n");

	/* add supported devices */
@@ -643,7 +647,7 @@ static void mhi_pm_disable_transition(struct mhi_controller *mhi_cntrl,

	MHI_LOG("Waiting for all pending threads to complete\n");
	wake_up_all(&mhi_cntrl->state_event);
	flush_work(&mhi_cntrl->low_priority_worker);
	flush_work(&mhi_cntrl->special_work);

	mhi_cntrl->force_m3_done = false;

@@ -785,18 +789,19 @@ int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl,
	return 0;
}

static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl)
static void mhi_special_events_pending(struct mhi_controller *mhi_cntrl)
{
	struct mhi_event *mhi_event;

	list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node) {
	list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node) {
		struct mhi_event_ctxt *er_ctxt =
			&mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
		struct mhi_ring *ev_ring = &mhi_event->ring;

		spin_lock_bh(&mhi_event->lock);
		if (ev_ring->rp != mhi_to_virtual(ev_ring, er_ctxt->rp)) {
			schedule_work(&mhi_cntrl->low_priority_worker);
			queue_work(mhi_cntrl->special_wq,
				   &mhi_cntrl->special_work);
			spin_unlock_bh(&mhi_event->lock);
			break;
		}
@@ -804,11 +809,11 @@ static void mhi_low_priority_events_pending(struct mhi_controller *mhi_cntrl)
	}
}

void mhi_low_priority_worker(struct work_struct *work)
void mhi_special_purpose_work(struct work_struct *work)
{
	struct mhi_controller *mhi_cntrl = container_of(work,
							struct mhi_controller,
							low_priority_worker);
							special_work);
	struct mhi_event *mhi_event;

	MHI_VERB("Enter with pm_state:%s MHI_STATE:%s ee:%s\n",
@@ -816,8 +821,8 @@ void mhi_low_priority_worker(struct work_struct *work)
		 TO_MHI_STATE_STR(mhi_cntrl->dev_state),
		 TO_MHI_EXEC_STR(mhi_cntrl->ee));

	/* check low priority event rings and process events */
	list_for_each_entry(mhi_event, &mhi_cntrl->lp_ev_rings, node)
	/* check special purpose event rings and process events */
	list_for_each_entry(mhi_event, &mhi_cntrl->sp_ev_rings, node)
		mhi_event->process_event(mhi_cntrl, mhi_event, U32_MAX);
}

@@ -1380,11 +1385,11 @@ int mhi_pm_resume(struct mhi_controller *mhi_cntrl)

	/*
	 * If MHI on host is in suspending/suspended state, we do not process
	 * any low priority requests, for example, bandwidth scaling events
	 * from the device. Check for low priority event rings and handle the
	 * pending events upon resume.
	 * any special purpose requests, for example, bandwidth scaling events
	 * from the device. Check for special purpose event rings and handle
	 * the pending events upon resume.
	 */
	mhi_low_priority_events_pending(mhi_cntrl);
	mhi_special_events_pending(mhi_cntrl);

	return 0;
}
@@ -1453,8 +1458,8 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client)
		mhi_msi_handlr(0, mhi_event);
	}

	/* schedules worker if any low priority events need to be handled */
	mhi_low_priority_events_pending(mhi_cntrl);
	/* schedules worker if any special purpose events need to be handled */
	mhi_special_events_pending(mhi_cntrl);

	MHI_LOG("Exit with pm_state:%s dev_state:%s\n",
		to_mhi_pm_state_str(mhi_cntrl->pm_state),
+5 −4
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */

#ifndef _MHI_H_
#define _MHI_H_
@@ -306,7 +306,7 @@ struct mhi_controller {
	u32 msi_allocated;
	int *irq; /* interrupt table */
	struct mhi_event *mhi_event;
	struct list_head lp_ev_rings; /* low priority event rings */
	struct list_head sp_ev_rings; /* special purpose event rings */

	/* cmd rings */
	struct mhi_cmd *mhi_cmd;
@@ -346,8 +346,9 @@ struct mhi_controller {

	/* worker for different state transitions */
	struct work_struct st_worker;
	struct work_struct fw_worker;
	struct work_struct low_priority_worker;
	struct work_struct special_work;
	struct workqueue_struct *special_wq;

	wait_queue_head_t state_event;

	/* shadow functions */