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

Commit f1870b71 authored by Prasadarao Durvasula's avatar Prasadarao Durvasula Committed by Gerrit - the friendly Code Review server
Browse files

drivers: soc: qcom: Port bam dmux driver



Port bam dmux driver to use qcom smem state mechanism.
Driver uses get/update/register/unregister api from
qcom smem state mechanism.

Change-Id: I3ca53e8624ac3bd3cb7f3144b0995b5be89efefe
Signed-off-by: default avatarPrasadarao Durvasula <pdurvasu@codeaurora.org>
Signed-off-by: default avatarSivasri Kumar Vanka <sivasri@codeaurora.org>
Signed-off-by: default avatarSwetha Chikkaboraiah <schikk@codeaurora.org>
Signed-off-by: default avatarChetan C R <cchinnad@codeaurora.org>
parent d60566d6
Loading
Loading
Loading
Loading
+58 −33
Original line number Diff line number Diff line
@@ -33,12 +33,16 @@
#include <linux/msm-sps.h>
#include <linux/sizes.h>
#include <soc/qcom/bam_dmux.h>
#include <soc/qcom/smsm.h>
#include <linux/soc/qcom/smem.h>
#include <linux/soc/qcom/smem_state.h>
#include <soc/qcom/subsystem_restart.h>
#include <soc/qcom/subsystem_notif.h>

#include "bam_dmux_private.h"

#define SMSM_A2_POWER_CONTROL		0x00000002
#define SMSM_A2_POWER_CONTROL_ACK	0x00000800

#define BAM_CH_LOCAL_OPEN       0x1
#define BAM_CH_REMOTE_OPEN      0x2
#define BAM_CH_IN_RESET         0x4
@@ -68,10 +72,10 @@ module_param_named(adaptive_timer_enabled,

static struct bam_ops_if bam_default_ops = {
	/* smsm */
	.smsm_change_state_ptr = &smsm_change_state,
	.smsm_get_state_ptr = &smsm_get_state,
	.smsm_state_cb_register_ptr = &smsm_state_cb_register,
	.smsm_state_cb_deregister_ptr = &smsm_state_cb_deregister,
	.smsm_change_state_ptr = &qcom_smem_state_update_bits,
	.smsm_get_state_ptr = &qcom_smem_state_get,
	.smsm_state_cb_register_ptr = &qcom_smem_state_register,
	.smsm_state_cb_deregister_ptr = &qcom_smem_state_unregister,

	/* sps */
	.sps_connect_ptr = &sps_connect,
@@ -90,6 +94,10 @@ static struct bam_ops_if bam_default_ops = {

	.dma_to = DMA_TO_DEVICE,
	.dma_from = DMA_FROM_DEVICE,
	.node = NULL,
	.smem_state = NULL,
	.pwr_state = NULL,
	.pwr_ack_state = NULL,
};
static struct bam_ops_if *bam_ops = &bam_default_ops;

@@ -1716,10 +1724,10 @@ static void power_vote(int vote)

	bam_dmux_uplink_vote = vote;
	if (vote)
		bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
		bam_ops->smsm_change_state_ptr(bam_ops->pwr_state,
			0, SMSM_A2_POWER_CONTROL);
	else
		bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
		bam_ops->smsm_change_state_ptr(bam_ops->pwr_state,
			SMSM_A2_POWER_CONTROL, 0);
}

@@ -2465,14 +2473,14 @@ static void toggle_apps_ack(void)

	BAM_DMUX_LOG("%s: apps ack %d->%d\n", __func__,
			clear_bit & 0x1, ~clear_bit & 0x1);
	bam_ops->smsm_change_state_ptr(SMSM_APPS_STATE,
	bam_ops->smsm_change_state_ptr(bam_ops->pwr_ack_state,
				clear_bit & SMSM_A2_POWER_CONTROL_ACK,
				~clear_bit & SMSM_A2_POWER_CONTROL_ACK);
	clear_bit = ~clear_bit;
	DBG_INC_ACK_OUT_CNT();
}

static void bam_dmux_smsm_cb(void *priv, uint32_t old_state, uint32_t new_state)
static int bam_dmux_smsm_cb(void *state, u32 old_state, u32 new_state)
{
	static int last_processed_state;
	int rcu_id;
@@ -2487,7 +2495,7 @@ static void bam_dmux_smsm_cb(void *priv, uint32_t old_state, uint32_t new_state)
		BAM_DMUX_LOG("%s: already processed this state\n", __func__);
		mutex_unlock(&smsm_cb_lock);
		srcu_read_unlock(&bam_dmux_srcu, rcu_id);
		return;
		return 1;
	}

	last_processed_state = new_state & SMSM_A2_POWER_CONTROL;
@@ -2511,10 +2519,10 @@ static void bam_dmux_smsm_cb(void *priv, uint32_t old_state, uint32_t new_state)
	}
	mutex_unlock(&smsm_cb_lock);
	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
	return 0;
}

static void bam_dmux_smsm_ack_cb(void *priv, uint32_t old_state,
						uint32_t new_state)
static int bam_dmux_smsm_ack_cb(void *state, u32 old_state, u32 new_state)
{
	int rcu_id;

@@ -2524,8 +2532,17 @@ static void bam_dmux_smsm_ack_cb(void *priv, uint32_t old_state,
			new_state);
	complete_all(&ul_wakeup_ack_completion);
	srcu_read_unlock(&bam_dmux_srcu, rcu_id);
	return 0;
}

static const struct qcom_smem_state_ops dmux_smsm_state_ops = {
	.update_bits = bam_dmux_smsm_cb,
};

static const struct qcom_smem_state_ops dmux_smsm_state_ack_ops = {
	.update_bits = bam_dmux_smsm_ack_cb,
};

/**
 * msm_bam_dmux_set_bam_ops() - sets the bam_ops
 * @ops: bam_ops_if to set
@@ -2564,12 +2581,10 @@ EXPORT_SYMBOL(msm_bam_dmux_deinit);
void msm_bam_dmux_reinit(void)
{
	bam_mux_initialized = 0;
	bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
			SMSM_A2_POWER_CONTROL,
			bam_dmux_smsm_cb, NULL);
	bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
			SMSM_A2_POWER_CONTROL_ACK,
			bam_dmux_smsm_ack_cb, NULL);
	bam_ops->smsm_state_cb_register_ptr(bam_ops->node,
					&dmux_smsm_state_ops, NULL);
	bam_ops->smsm_state_cb_register_ptr(bam_ops->node,
					&dmux_smsm_state_ack_ops, NULL);
}
EXPORT_SYMBOL(msm_bam_dmux_reinit);

@@ -2785,11 +2800,11 @@ static int bam_dmux_probe(struct platform_device *pdev)
		return rc;
	}

	rc = bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
			SMSM_A2_POWER_CONTROL,
			bam_dmux_smsm_cb, NULL);
	bam_ops->pwr_state = bam_ops->smsm_state_cb_register_ptr(
			pdev->dev.of_node,
			&dmux_smsm_state_ops, NULL);

	if (rc) {
	if (IS_ERR(bam_ops->pwr_state)) {
		subsys_notif_unregister_notifier(subsys_h, &restart_notifier);
		destroy_workqueue(bam_mux_rx_workqueue);
		destroy_workqueue(bam_mux_tx_workqueue);
@@ -2797,17 +2812,15 @@ static int bam_dmux_probe(struct platform_device *pdev)
		return -ENOMEM;
	}

	rc = bam_ops->smsm_state_cb_register_ptr(SMSM_MODEM_STATE,
			SMSM_A2_POWER_CONTROL_ACK,
			bam_dmux_smsm_ack_cb, NULL);
	bam_ops->pwr_ack_state = bam_ops->smsm_state_cb_register_ptr(
			pdev->dev.of_node,
			&dmux_smsm_state_ack_ops, NULL);

	if (rc) {
	if (IS_ERR(bam_ops->pwr_ack_state)) {
		subsys_notif_unregister_notifier(subsys_h, &restart_notifier);
		destroy_workqueue(bam_mux_rx_workqueue);
		destroy_workqueue(bam_mux_tx_workqueue);
		bam_ops->smsm_state_cb_deregister_ptr(SMSM_MODEM_STATE,
					SMSM_A2_POWER_CONTROL,
					bam_dmux_smsm_cb, NULL);
		bam_ops->smsm_state_cb_deregister_ptr(bam_ops->pwr_state);
		pr_err("%s: smsm ack cb register failed, rc: %d\n", __func__,
				rc);
		for (rc = 0; rc < BAM_DMUX_NUM_CHANNELS; ++rc)
@@ -2815,10 +2828,22 @@ static int bam_dmux_probe(struct platform_device *pdev)
		return -ENOMEM;
	}

	if (bam_ops->smsm_get_state_ptr(SMSM_MODEM_STATE) &
			SMSM_A2_POWER_CONTROL)
		bam_dmux_smsm_cb(NULL, 0,
			bam_ops->smsm_get_state_ptr(SMSM_MODEM_STATE));
	bam_ops->smem_state = qcom_smem_get(QCOM_SMEM_HOST_ANY,
						SMSM_A2_POWER_CONTROL, NULL);
	if (IS_ERR(bam_ops->smem_state)) {
		subsys_notif_unregister_notifier(subsys_h, &restart_notifier);
		destroy_workqueue(bam_mux_rx_workqueue);
		destroy_workqueue(bam_mux_tx_workqueue);
		bam_ops->smsm_state_cb_deregister_ptr(bam_ops->pwr_state);
		bam_ops->smsm_state_cb_deregister_ptr(bam_ops->pwr_ack_state);
		dev_err(&pdev->dev, "Unable to acquire smem state entry\n");
		for (rc = 0; rc < BAM_DMUX_NUM_CHANNELS; ++rc)
			platform_device_put(bam_ch[rc].pdev);
		return PTR_ERR(bam_ops->smem_state);
	}
	bam_ops->node = pdev->dev.of_node;

	bam_dmux_smsm_cb(NULL, 0, *bam_ops->smem_state);

	return 0;
}
+18 −8
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/dma-mapping.h>

#include <linux/msm-sps.h>
#include <linux/soc/qcom/smem_state.h>

#define BAM_MUX_HDR_MAGIC_NO			0x33fc
#define BAM_MUX_HDR_CMD_DATA			0
@@ -61,17 +62,17 @@
 */
struct bam_ops_if {
	/* smsm */
	int (*smsm_change_state_ptr)(uint32_t smsm_entry,
		uint32_t clear_mask, uint32_t set_mask);
	int (*smsm_change_state_ptr)(struct qcom_smem_state *state, u32 mask,
		u32 value);

	uint32_t (*smsm_get_state_ptr)(uint32_t smsm_entry);
	struct qcom_smem_state *(*smsm_get_state_ptr)(struct device *dev,
		const char *con_id, unsigned int *bit);

	int (*smsm_state_cb_register_ptr)(uint32_t smsm_entry, uint32_t mask,
		void (*notify)(void *, uint32_t old_state, uint32_t new_state),
		void *data);
	struct qcom_smem_state *(*smsm_state_cb_register_ptr)(
		struct device_node *of_node,
		const struct qcom_smem_state_ops *ops, void *priv);

	int (*smsm_state_cb_deregister_ptr)(uint32_t smsm_entry, uint32_t mask,
		void (*notify)(void *, uint32_t, uint32_t), void *data);
	void (*smsm_state_cb_deregister_ptr)(struct qcom_smem_state *state);

	/* sps */
	int (*sps_connect_ptr)(struct sps_pipe *h, struct sps_connect *connect);
@@ -112,6 +113,15 @@ struct bam_ops_if {
	enum dma_data_direction dma_to;

	enum dma_data_direction dma_from;


	struct device_node *node;

	u32 *smem_state;

	void *pwr_state;

	void *pwr_ack_state;
};

/**