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

Commit 79e5906c authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: mhi_dev: Fix broadcast check for uevents"

parents 755d9a0a c2575e9d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ Optional Properties:
  - qcom,phy-status-reg: Register offset for PHY status.
  - qcom,dbi-base-reg: Register offset for DBI base address.
  - qcom,slv-space-reg: Register offset for slave address space size.
  - qcom,pcie-vendor-id: Vendor id to be written to the Vendor ID register.
  - qcom,pcie-device-id: Device id to be written to the Device ID register.
  - qcom,pcie-link-speed: generation of PCIe link speed. The value could be
    1, 2 or 3.
  - qcom,pcie-active-config: boolean type; active configuration of PCIe
+4 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@
#define PCIE20_ELBI_CS2_ENABLE         0xA4

#define PCIE20_DEVICE_ID_VENDOR_ID     0x00
#define PCIE20_MASK_DEVICE_ID          GENMASK(31, 16)
#define PCIE20_MASK_VENDOR_ID          GENMASK(15, 0)
#define PCIE20_COMMAND_STATUS          0x04
#define PCIE20_CLASS_CODE_REVISION_ID  0x08
#define PCIE20_BIST_HDR_TYPE           0x0C
@@ -328,6 +330,8 @@ struct ep_pcie_dev_t {

	struct msm_bus_scale_pdata   *bus_scale_table;
	u32                          bus_client;
	u16                          vendor_id;
	u16                          device_id;
	u32                          link_speed;
	bool                         active_config;
	bool                         aggregated_irq;
+35 −0
Original line number Diff line number Diff line
@@ -659,6 +659,17 @@ static void ep_pcie_core_init(struct ep_pcie_dev_t *dev, bool configured)
		ep_pcie_write_mask(dev->dm_core + PCIE20_MISC_CONTROL_1, 0,
			BIT(0));

		/* Set Vendor ID and Device ID */
		if (ep_pcie_dev.device_id != 0xFFFF)
			ep_pcie_write_reg_field(dev->dm_core,
						PCIE20_DEVICE_ID_VENDOR_ID,
						PCIE20_MASK_DEVICE_ID,
						ep_pcie_dev.device_id);
		if (ep_pcie_dev.vendor_id != 0xFFFF)
			ep_pcie_write_reg_field(dev->dm_core,
						PCIE20_DEVICE_ID_VENDOR_ID,
						PCIE20_MASK_VENDOR_ID,
						ep_pcie_dev.vendor_id);
		/* Set class code and revision ID */
		ep_pcie_write_reg(dev->dm_core, PCIE20_CLASS_CODE_REVISION_ID,
			0xff000000);
@@ -2512,6 +2523,30 @@ static int ep_pcie_probe(struct platform_device *pdev)
		EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-link-speed:%d\n",
			ep_pcie_dev.rev, ep_pcie_dev.link_speed);

	ep_pcie_dev.vendor_id = 0xFFFF;
	ret = of_property_read_u16((&pdev->dev)->of_node,
				"qcom,pcie-vendor-id",
				&ep_pcie_dev.vendor_id);
	if (ret)
		EP_PCIE_DBG(&ep_pcie_dev,
				"PCIe V%d: pcie-vendor-id does not exist.\n",
				ep_pcie_dev.rev);
	else
		EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-vendor-id:%d.\n",
				ep_pcie_dev.rev, ep_pcie_dev.vendor_id);

	ep_pcie_dev.device_id = 0xFFFF;
	ret = of_property_read_u16((&pdev->dev)->of_node,
				"qcom,pcie-device-id",
				&ep_pcie_dev.device_id);
	if (ret)
		EP_PCIE_DBG(&ep_pcie_dev,
				"PCIe V%d: pcie-device-id does not exist.\n",
				ep_pcie_dev.rev);
	else
		EP_PCIE_DBG(&ep_pcie_dev, "PCIe V%d: pcie-device-id:%d.\n",
				ep_pcie_dev.rev, ep_pcie_dev.device_id);

	ret = of_property_read_u32((&pdev->dev)->of_node,
				"qcom,dbi-base-reg",
				&ep_pcie_dev.dbi_base_reg);
+62 −35
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@
#define TR_RING_ELEMENT_SZ	sizeof(struct mhi_dev_transfer_ring_element)
#define RING_ELEMENT_TYPE_SZ	sizeof(union mhi_dev_ring_element_type)

uint32_t bhi_imgtxdb;
enum mhi_msg_level mhi_msg_lvl = MHI_MSG_ERROR;
enum mhi_msg_level mhi_ipc_msg_lvl = MHI_MSG_VERBOSE;
void *mhi_ipc_log;
@@ -1243,8 +1244,6 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
	struct mhi_addr host_addr;
	struct mhi_dev_channel *ch;
	struct mhi_dev_ring *ring;
	char *connected[2] = { "MHI_CHANNEL_STATE_12=CONNECTED", NULL};
	char *disconnected[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL};
	union mhi_dev_ring_ctx *evt_ctx;

	ch_id = el->generic.chid;
@@ -1349,9 +1348,7 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
		mhi_update_state_info(ch_id, MHI_STATE_CONNECTED);
		/* Trigger callback to clients */
		mhi_dev_trigger_cb(ch_id);
		if (ch_id == MHI_CLIENT_MBIM_OUT)
			kobject_uevent_env(&mhi_ctx->dev->kobj,
						KOBJ_CHANGE, connected);
		mhi_uci_chan_state_notify(mhi, ch_id, MHI_STATE_CONNECTED);
		break;
	case MHI_DEV_RING_EL_STOP:
		if (ch_id >= HW_CHANNEL_BASE) {
@@ -1405,9 +1402,10 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,

			mutex_unlock(&ch->ch_lock);
			mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED);
			if (ch_id == MHI_CLIENT_MBIM_OUT)
				kobject_uevent_env(&mhi_ctx->dev->kobj,
						KOBJ_CHANGE, disconnected);
			/* Trigger callback to clients */
			mhi_dev_trigger_cb(ch_id);
			mhi_uci_chan_state_notify(mhi, ch_id,
					MHI_STATE_DISCONNECTED);
		}
		break;
	case MHI_DEV_RING_EL_RESET:
@@ -1481,9 +1479,9 @@ static void mhi_dev_process_cmd_ring(struct mhi_dev *mhi,
				pr_err("Error sending command completion event\n");
			mutex_unlock(&ch->ch_lock);
			mhi_update_state_info(ch_id, MHI_STATE_DISCONNECTED);
			if (ch_id == MHI_CLIENT_MBIM_OUT)
				kobject_uevent_env(&mhi_ctx->dev->kobj,
						KOBJ_CHANGE, disconnected);
			mhi_dev_trigger_cb(ch_id);
			mhi_uci_chan_state_notify(mhi, ch_id,
					MHI_STATE_DISCONNECTED);
		}
		break;
	default:
@@ -1646,13 +1644,28 @@ static void mhi_dev_check_channel_interrupt(struct mhi_dev *mhi)
	}
}

static void mhi_update_state_info_all(enum mhi_ctrl_info info)
{
	int i;
	struct mhi_dev_client_cb_reason reason;

	mhi_ctx->ctrl_info = info;
	for (i = 0; i < MHI_MAX_CHANNELS; ++i) {
		channel_state_info[i].ctrl_info = info;
		/* Notify kernel clients */
		mhi_dev_trigger_cb(i);
	}

	/* For legacy reasons for QTI client */
	reason.reason = MHI_DEV_CTRL_UPDATE;
	uci_ctrl_update(&reason);
}

static int mhi_dev_abort(struct mhi_dev *mhi)
{
	struct mhi_dev_channel *ch;
	struct mhi_dev_ring *ring;
	int ch_id = 0, rc = 0;
	char *disconnected_12[2] = { "MHI_CHANNEL_STATE_12=DISCONNECTED", NULL};
	char *disconnected_14[2] = { "MHI_CHANNEL_STATE_14=DISCONNECTED", NULL};

	/* Hard stop all the channels */
	for (ch_id = 0; ch_id < mhi->cfg.channels; ch_id++) {
@@ -1666,19 +1679,9 @@ static int mhi_dev_abort(struct mhi_dev *mhi)
		mutex_unlock(&ch->ch_lock);
	}

	/* Update ctrl node */
	mhi_update_state_info(MHI_DEV_UEVENT_CTRL, MHI_STATE_DISCONNECTED);
	mhi_update_state_info(MHI_CLIENT_MBIM_OUT, MHI_STATE_DISCONNECTED);
	mhi_update_state_info(MHI_CLIENT_QMI_OUT, MHI_STATE_DISCONNECTED);
	rc = kobject_uevent_env(&mhi_ctx->dev->kobj,
				KOBJ_CHANGE, disconnected_12);
	if (rc)
		pr_err("Error sending uevent:%d\n", rc);

	rc = kobject_uevent_env(&mhi_ctx->dev->kobj,
				KOBJ_CHANGE, disconnected_14);
	if (rc)
		pr_err("Error sending uevent:%d\n", rc);
	/* Update channel state and notify clients */
	mhi_update_state_info_all(MHI_STATE_DISCONNECTED);
	mhi_uci_chan_state_notify_all(mhi, MHI_STATE_DISCONNECTED);

	flush_workqueue(mhi->ring_init_wq);
	flush_workqueue(mhi->pending_ring_wq);
@@ -1818,8 +1821,7 @@ static void mhi_dev_scheduler(struct work_struct *work)
	struct mhi_dev_ring *ring;
	enum mhi_dev_state state;
	enum mhi_dev_event event = 0;
	bool mhi_reset = false;
	uint32_t bhi_imgtxdb = 0;
	u32 mhi_reset;

	mutex_lock(&mhi_ctx->mhi_lock);
	/* Check for interrupts */
@@ -1828,6 +1830,10 @@ static void mhi_dev_scheduler(struct work_struct *work)
	if (int_value & MHI_MMIO_CTRL_INT_STATUS_A7_MSK) {
		mhi_log(MHI_MSG_VERBOSE,
			"processing ctrl interrupt with %d\n", int_value);

		rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb);
		mhi_log(MHI_MSG_DBG, "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb);

		rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset);
		if (rc) {
			pr_err("%s: get mhi state failed\n", __func__);
@@ -1857,10 +1863,6 @@ static void mhi_dev_scheduler(struct work_struct *work)
			pr_err("error sending SM event\n");
			goto fail;
		}

		rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb);
		mhi_log(MHI_MSG_VERBOSE,
			"BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb);
	}

	if (int_value & MHI_MMIO_CTRL_CRDB_STATUS_MSK) {
@@ -2677,7 +2679,7 @@ static int mhi_dev_recover(struct mhi_dev *mhi)
{
	int rc = 0;
	uint32_t syserr, max_cnt = 0, bhi_intvec = 0;
	bool mhi_reset;
	u32 mhi_reset;
	enum mhi_dev_state state;

	/* Check if MHI is in syserr */
@@ -2687,6 +2689,16 @@ static int mhi_dev_recover(struct mhi_dev *mhi)

	mhi_log(MHI_MSG_VERBOSE, "mhi_syserr = 0x%X\n", syserr);
	if (syserr) {
		/* Poll for the host to set the reset bit */
		rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset);
		if (rc) {
			pr_err("%s: get mhi state failed\n", __func__);
			return rc;
		}

		mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n",
				state, mhi_reset);

		rc = mhi_dev_mmio_read(mhi, BHI_INTVEC, &bhi_intvec);
		if (rc)
			return rc;
@@ -2706,7 +2718,11 @@ static int mhi_dev_recover(struct mhi_dev *mhi)
			pr_err("%s: get mhi state failed\n", __func__);
			return rc;
		}
		while (mhi_reset != true && max_cnt < MHI_SUSPEND_TIMEOUT) {

		mhi_log(MHI_MSG_VERBOSE, "mhi_state = 0x%X, reset = %d\n",
				state, mhi_reset);

		while (mhi_reset != 0x1 && max_cnt < MHI_SUSPEND_TIMEOUT) {
			/* Wait for Host to set the reset */
			msleep(MHI_SUSPEND_MIN);
			rc = mhi_dev_mmio_get_mhi_state(mhi, &state,
@@ -2737,7 +2753,7 @@ static void mhi_dev_enable(struct work_struct *work)
	struct ep_pcie_msi_config msi_cfg;
	struct mhi_dev *mhi = container_of(work,
				struct mhi_dev, ring_init_cb_work);
	bool mhi_reset;
	u32 mhi_reset;
	enum mhi_dev_state state;
	uint32_t max_cnt = 0, bhi_intvec = 0;

@@ -3215,6 +3231,15 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx)
	struct platform_device *pdev;
	int rc = 0;

	/*
	 * There could be multiple calls to this function if device gets
	 * multiple link-up events (bme irqs).
	 */
	if (mhi_ctx->init_done) {
		mhi_log(MHI_MSG_INFO, "mhi init already done, returning\n");
		return 0;
	}

	pdev = mhi_ctx->pdev;

	INIT_WORK(&mhi_ctx->chdb_ctrl_work, mhi_dev_scheduler);
@@ -3346,6 +3371,8 @@ static int mhi_dev_resume_mmio_mhi_init(struct mhi_dev *mhi_ctx)
	if (mhi_ctx->use_edma)
		mhi_ring_init_cb(mhi_ctx);

	mhi_ctx->init_done = true;

	return 0;
}

+18 −2
Original line number Diff line number Diff line
@@ -567,6 +567,9 @@ struct mhi_dev {
	/* iATU is required to map control and data region */
	bool				config_iatu;

	/* Indicates if mhi init is done */
	bool				init_done;

	/* MHI state info */
	enum mhi_ctrl_info		ctrl_info;

@@ -606,6 +609,7 @@ enum mhi_msg_level {
	MHI_MSG_reserved = 0x80000000
};

extern uint32_t bhi_imgtxdb;
extern enum mhi_msg_level mhi_msg_lvl;
extern enum mhi_msg_level mhi_ipc_msg_lvl;
extern void *mhi_ipc_log;
@@ -616,7 +620,7 @@ extern void *mhi_ipc_log;
	} \
	if (mhi_ipc_log && (_msg_lvl >= mhi_ipc_msg_lvl)) { \
		ipc_log_string(mhi_ipc_log,                     \
			"[%s] " _msg, __func__, ##__VA_ARGS__);     \
		"[0x%x %s] " _msg, bhi_imgtxdb, __func__, ##__VA_ARGS__);     \
	} \
} while (0)

@@ -959,7 +963,7 @@ int mhi_dev_get_mhi_addr(struct mhi_dev *dev);
 * @mhi_reset:	MHI device reset from host.
 */
int mhi_dev_mmio_get_mhi_state(struct mhi_dev *dev, enum mhi_dev_state *state,
						bool *mhi_reset);
						u32 *mhi_reset);

/**
 * mhi_dev_mmio_init() - Initializes the MMIO and reads the Number of event
@@ -1069,5 +1073,17 @@ int mhi_dev_net_interface_init(void);
void mhi_dev_notify_a7_event(struct mhi_dev *mhi);

void uci_ctrl_update(struct mhi_dev_client_cb_reason *reason);
/**
 * mhi_uci_chan_state_notify_all - Notifies channel state updates for
 *				all clients who have uevents enabled.
 */
void mhi_uci_chan_state_notify_all(struct mhi_dev *mhi,
		enum mhi_ctrl_info ch_state);
/**
 * mhi_uci_chan_state_notify - Notifies channel state update to the client
 *				if uevents are enabled.
 */
void mhi_uci_chan_state_notify(struct mhi_dev *mhi,
		enum mhi_client_channel ch_id, enum mhi_ctrl_info ch_state);

#endif /* _MHI_H */
Loading