Commit f02dc825 authored by Stephen Boyd's avatar Stephen Boyd Committed by Andy Gross

soc: qcom: smd: Represent channel layout in structures

The rx and tx channel info are laid out in memory next to each
other, and there are two types of channel info structures, byte
based and word based. We have 4 pointers to these info
structures, when we really only need two to point to the
different types of structures. Encapsulate the byte based and
word based tx/rx structures in a "channel pair" structure that
describes the layout of memory and reduces the number of pointers
in the smd channel structure by two.
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@sonymobile.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarAndy Gross <agross@codeaurora.org>
parent 9806884d
...@@ -65,7 +65,9 @@ ...@@ -65,7 +65,9 @@
*/ */
struct smd_channel_info; struct smd_channel_info;
struct smd_channel_info_pair;
struct smd_channel_info_word; struct smd_channel_info_word;
struct smd_channel_info_word_pair;
#define SMD_ALLOC_TBL_COUNT 2 #define SMD_ALLOC_TBL_COUNT 2
#define SMD_ALLOC_TBL_SIZE 64 #define SMD_ALLOC_TBL_SIZE 64
...@@ -151,10 +153,8 @@ enum smd_channel_state { ...@@ -151,10 +153,8 @@ enum smd_channel_state {
* @name: name of the channel * @name: name of the channel
* @state: local state of the channel * @state: local state of the channel
* @remote_state: remote state of the channel * @remote_state: remote state of the channel
* @tx_info: byte aligned outgoing channel info * @info: byte aligned outgoing/incoming channel info
* @rx_info: byte aligned incoming channel info * @info_word: word aligned outgoing/incoming channel info
* @tx_info_word: word aligned outgoing channel info
* @rx_info_word: word aligned incoming channel info
* @tx_lock: lock to make writes to the channel mutually exclusive * @tx_lock: lock to make writes to the channel mutually exclusive
* @fblockread_event: wakeup event tied to tx fBLOCKREADINTR * @fblockread_event: wakeup event tied to tx fBLOCKREADINTR
* @tx_fifo: pointer to the outgoing ring buffer * @tx_fifo: pointer to the outgoing ring buffer
...@@ -175,11 +175,8 @@ struct qcom_smd_channel { ...@@ -175,11 +175,8 @@ struct qcom_smd_channel {
enum smd_channel_state state; enum smd_channel_state state;
enum smd_channel_state remote_state; enum smd_channel_state remote_state;
struct smd_channel_info *tx_info; struct smd_channel_info_pair *info;
struct smd_channel_info *rx_info; struct smd_channel_info_word_pair *info_word;
struct smd_channel_info_word *tx_info_word;
struct smd_channel_info_word *rx_info_word;
struct mutex tx_lock; struct mutex tx_lock;
wait_queue_head_t fblockread_event; wait_queue_head_t fblockread_event;
...@@ -228,6 +225,11 @@ struct smd_channel_info { ...@@ -228,6 +225,11 @@ struct smd_channel_info {
u32 head; u32 head;
}; };
struct smd_channel_info_pair {
struct smd_channel_info tx;
struct smd_channel_info rx;
};
/* /*
* Format of the smd_info smem items, for word aligned channels. * Format of the smd_info smem items, for word aligned channels.
*/ */
...@@ -245,25 +247,30 @@ struct smd_channel_info_word { ...@@ -245,25 +247,30 @@ struct smd_channel_info_word {
u32 head; u32 head;
}; };
struct smd_channel_info_word_pair {
struct smd_channel_info_word tx;
struct smd_channel_info_word rx;
};
#define GET_RX_CHANNEL_INFO(channel, param) \ #define GET_RX_CHANNEL_INFO(channel, param) \
(channel->rx_info_word ? \ (channel->info_word ? \
channel->rx_info_word->param : \ channel->info_word->rx.param : \
channel->rx_info->param) channel->info->rx.param)
#define SET_RX_CHANNEL_INFO(channel, param, value) \ #define SET_RX_CHANNEL_INFO(channel, param, value) \
(channel->rx_info_word ? \ (channel->info_word ? \
(channel->rx_info_word->param = value) : \ (channel->info_word->rx.param = value) : \
(channel->rx_info->param = value)) (channel->info->rx.param = value))
#define GET_TX_CHANNEL_INFO(channel, param) \ #define GET_TX_CHANNEL_INFO(channel, param) \
(channel->tx_info_word ? \ (channel->info_word ? \
channel->tx_info_word->param : \ channel->info_word->tx.param : \
channel->tx_info->param) channel->info->tx.param)
#define SET_TX_CHANNEL_INFO(channel, param, value) \ #define SET_TX_CHANNEL_INFO(channel, param, value) \
(channel->tx_info_word ? \ (channel->info_word ? \
(channel->tx_info_word->param = value) : \ (channel->info_word->tx.param = value) : \
(channel->tx_info->param = value)) (channel->info->tx.param = value))
/** /**
* struct qcom_smd_alloc_entry - channel allocation entry * struct qcom_smd_alloc_entry - channel allocation entry
...@@ -412,7 +419,7 @@ static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel, ...@@ -412,7 +419,7 @@ static size_t qcom_smd_channel_peek(struct qcom_smd_channel *channel,
unsigned tail; unsigned tail;
size_t len; size_t len;
word_aligned = channel->rx_info_word != NULL; word_aligned = channel->info_word;
tail = GET_RX_CHANNEL_INFO(channel, tail); tail = GET_RX_CHANNEL_INFO(channel, tail);
len = min_t(size_t, count, channel->fifo_size - tail); len = min_t(size_t, count, channel->fifo_size - tail);
...@@ -627,7 +634,7 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel, ...@@ -627,7 +634,7 @@ static int qcom_smd_write_fifo(struct qcom_smd_channel *channel,
unsigned head; unsigned head;
size_t len; size_t len;
word_aligned = channel->tx_info_word != NULL; word_aligned = channel->info_word;
head = GET_TX_CHANNEL_INFO(channel, head); head = GET_TX_CHANNEL_INFO(channel, head);
len = min_t(size_t, count, channel->fifo_size - head); len = min_t(size_t, count, channel->fifo_size - head);
...@@ -670,7 +677,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len) ...@@ -670,7 +677,7 @@ int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len)
int ret; int ret;
/* Word aligned channels only accept word size aligned data */ /* Word aligned channels only accept word size aligned data */
if (channel->rx_info_word != NULL && len % 4) if (channel->info_word && len % 4)
return -EINVAL; return -EINVAL;
ret = mutex_lock_interruptible(&channel->tx_lock); ret = mutex_lock_interruptible(&channel->tx_lock);
...@@ -1000,11 +1007,9 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed ...@@ -1000,11 +1007,9 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
* use. * use.
*/ */
if (info_size == 2 * sizeof(struct smd_channel_info_word)) { if (info_size == 2 * sizeof(struct smd_channel_info_word)) {
channel->tx_info_word = info; channel->info_word = info;
channel->rx_info_word = info + sizeof(struct smd_channel_info_word);
} else if (info_size == 2 * sizeof(struct smd_channel_info)) { } else if (info_size == 2 * sizeof(struct smd_channel_info)) {
channel->tx_info = info; channel->info = info;
channel->rx_info = info + sizeof(struct smd_channel_info);
} else { } else {
dev_err(smd->dev, dev_err(smd->dev,
"channel info of size %zu not supported\n", info_size); "channel info of size %zu not supported\n", info_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment