Commit b853cb96 authored by Bjorn Andersson's avatar Bjorn Andersson Committed by Andy Gross

soc: qcom: smd: Make callback pass channel reference

By passing the smd channel reference to the callback, rather than the
smd device, we can open additional smd channels from sub-devices of smd
devices.

Also updates the two smd clients today found in mainline.
Signed-off-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarAndy Gross <andy.gross@linaro.org>
parent afd356df
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
*/ */
struct qcom_smd_rpm { struct qcom_smd_rpm {
struct qcom_smd_channel *rpm_channel; struct qcom_smd_channel *rpm_channel;
struct device *dev;
struct completion ack; struct completion ack;
struct mutex lock; struct mutex lock;
...@@ -149,14 +150,14 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm, ...@@ -149,14 +150,14 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
} }
EXPORT_SYMBOL(qcom_rpm_smd_write); EXPORT_SYMBOL(qcom_rpm_smd_write);
static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev, static int qcom_smd_rpm_callback(struct qcom_smd_channel *channel,
const void *data, const void *data,
size_t count) size_t count)
{ {
const struct qcom_rpm_header *hdr = data; const struct qcom_rpm_header *hdr = data;
size_t hdr_length = le32_to_cpu(hdr->length); size_t hdr_length = le32_to_cpu(hdr->length);
const struct qcom_rpm_message *msg; const struct qcom_rpm_message *msg;
struct qcom_smd_rpm *rpm = dev_get_drvdata(&qsdev->dev); struct qcom_smd_rpm *rpm = qcom_smd_get_drvdata(channel);
const u8 *buf = data + sizeof(struct qcom_rpm_header); const u8 *buf = data + sizeof(struct qcom_rpm_header);
const u8 *end = buf + hdr_length; const u8 *end = buf + hdr_length;
char msgbuf[32]; char msgbuf[32];
...@@ -165,7 +166,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev, ...@@ -165,7 +166,7 @@ static int qcom_smd_rpm_callback(struct qcom_smd_device *qsdev,
if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST || if (le32_to_cpu(hdr->service_type) != RPM_SERVICE_TYPE_REQUEST ||
hdr_length < sizeof(struct qcom_rpm_message)) { hdr_length < sizeof(struct qcom_rpm_message)) {
dev_err(&qsdev->dev, "invalid request\n"); dev_err(rpm->dev, "invalid request\n");
return 0; return 0;
} }
...@@ -206,7 +207,9 @@ static int qcom_smd_rpm_probe(struct qcom_smd_device *sdev) ...@@ -206,7 +207,9 @@ static int qcom_smd_rpm_probe(struct qcom_smd_device *sdev)
mutex_init(&rpm->lock); mutex_init(&rpm->lock);
init_completion(&rpm->ack); init_completion(&rpm->ack);
rpm->dev = &sdev->dev;
rpm->rpm_channel = sdev->channel; rpm->rpm_channel = sdev->channel;
qcom_smd_set_drvdata(sdev->channel, rpm);
dev_set_drvdata(&sdev->dev, rpm); dev_set_drvdata(&sdev->dev, rpm);
......
...@@ -194,6 +194,8 @@ struct qcom_smd_channel { ...@@ -194,6 +194,8 @@ struct qcom_smd_channel {
int pkt_size; int pkt_size;
void *drvdata;
struct list_head list; struct list_head list;
struct list_head dev_list; struct list_head dev_list;
}; };
...@@ -513,7 +515,6 @@ static void qcom_smd_channel_advance(struct qcom_smd_channel *channel, ...@@ -513,7 +515,6 @@ static void qcom_smd_channel_advance(struct qcom_smd_channel *channel,
*/ */
static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel)
{ {
struct qcom_smd_device *qsdev = channel->qsdev;
unsigned tail; unsigned tail;
size_t len; size_t len;
void *ptr; void *ptr;
...@@ -533,7 +534,7 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel) ...@@ -533,7 +534,7 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel)
len = channel->pkt_size; len = channel->pkt_size;
} }
ret = channel->cb(qsdev, ptr, len); ret = channel->cb(channel, ptr, len);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1034,6 +1035,18 @@ int qcom_smd_driver_register(struct qcom_smd_driver *qsdrv) ...@@ -1034,6 +1035,18 @@ int qcom_smd_driver_register(struct qcom_smd_driver *qsdrv)
} }
EXPORT_SYMBOL(qcom_smd_driver_register); EXPORT_SYMBOL(qcom_smd_driver_register);
void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel)
{
return channel->drvdata;
}
EXPORT_SYMBOL(qcom_smd_get_drvdata);
void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data)
{
channel->drvdata = data;
}
EXPORT_SYMBOL(qcom_smd_set_drvdata);
/** /**
* qcom_smd_driver_unregister - unregister a smd driver * qcom_smd_driver_unregister - unregister a smd driver
* @qsdrv: qcom_smd_driver struct * @qsdrv: qcom_smd_driver struct
...@@ -1079,12 +1092,13 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name) ...@@ -1079,12 +1092,13 @@ qcom_smd_find_channel(struct qcom_smd_edge *edge, const char *name)
* Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't * Returns a channel handle on success, or -EPROBE_DEFER if the channel isn't
* ready. * ready.
*/ */
struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev, struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *parent,
const char *name, const char *name,
qcom_smd_cb_t cb) qcom_smd_cb_t cb)
{ {
struct qcom_smd_channel *channel; struct qcom_smd_channel *channel;
struct qcom_smd_edge *edge = sdev->channel->edge; struct qcom_smd_device *sdev = parent->qsdev;
struct qcom_smd_edge *edge = parent->edge;
int ret; int ret;
/* Wait up to HZ for the channel to appear */ /* Wait up to HZ for the channel to appear */
......
...@@ -100,17 +100,17 @@ struct wcnss_download_nv_resp { ...@@ -100,17 +100,17 @@ struct wcnss_download_nv_resp {
/** /**
* wcnss_ctrl_smd_callback() - handler from SMD responses * wcnss_ctrl_smd_callback() - handler from SMD responses
* @qsdev: smd device handle * @channel: smd channel handle
* @data: pointer to the incoming data packet * @data: pointer to the incoming data packet
* @count: size of the incoming data packet * @count: size of the incoming data packet
* *
* Handles any incoming packets from the remote WCNSS_CTRL service. * Handles any incoming packets from the remote WCNSS_CTRL service.
*/ */
static int wcnss_ctrl_smd_callback(struct qcom_smd_device *qsdev, static int wcnss_ctrl_smd_callback(struct qcom_smd_channel *channel,
const void *data, const void *data,
size_t count) size_t count)
{ {
struct wcnss_ctrl *wcnss = dev_get_drvdata(&qsdev->dev); struct wcnss_ctrl *wcnss = qcom_smd_get_drvdata(channel);
const struct wcnss_download_nv_resp *nvresp; const struct wcnss_download_nv_resp *nvresp;
const struct wcnss_version_resp *version; const struct wcnss_version_resp *version;
const struct wcnss_msg_hdr *hdr = data; const struct wcnss_msg_hdr *hdr = data;
...@@ -246,7 +246,7 @@ static int wcnss_ctrl_probe(struct qcom_smd_device *sdev) ...@@ -246,7 +246,7 @@ static int wcnss_ctrl_probe(struct qcom_smd_device *sdev)
init_completion(&wcnss->ack); init_completion(&wcnss->ack);
INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv); INIT_WORK(&wcnss->download_nv_work, wcnss_download_nv);
dev_set_drvdata(&sdev->dev, wcnss); qcom_smd_set_drvdata(sdev->channel, wcnss);
return wcnss_request_version(wcnss); return wcnss_request_version(wcnss);
} }
......
...@@ -26,7 +26,7 @@ struct qcom_smd_device { ...@@ -26,7 +26,7 @@ struct qcom_smd_device {
struct qcom_smd_channel *channel; struct qcom_smd_channel *channel;
}; };
typedef int (*qcom_smd_cb_t)(struct qcom_smd_device *, const void *, size_t); typedef int (*qcom_smd_cb_t)(struct qcom_smd_channel *, const void *, size_t);
/** /**
* struct qcom_smd_driver - smd driver struct * struct qcom_smd_driver - smd driver struct
...@@ -50,13 +50,16 @@ struct qcom_smd_driver { ...@@ -50,13 +50,16 @@ struct qcom_smd_driver {
int qcom_smd_driver_register(struct qcom_smd_driver *drv); int qcom_smd_driver_register(struct qcom_smd_driver *drv);
void qcom_smd_driver_unregister(struct qcom_smd_driver *drv); void qcom_smd_driver_unregister(struct qcom_smd_driver *drv);
void *qcom_smd_get_drvdata(struct qcom_smd_channel *channel);
void qcom_smd_set_drvdata(struct qcom_smd_channel *channel, void *data);
#define module_qcom_smd_driver(__smd_driver) \ #define module_qcom_smd_driver(__smd_driver) \
module_driver(__smd_driver, qcom_smd_driver_register, \ module_driver(__smd_driver, qcom_smd_driver_register, \
qcom_smd_driver_unregister) qcom_smd_driver_unregister)
int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len); int qcom_smd_send(struct qcom_smd_channel *channel, const void *data, int len);
struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_device *sdev, struct qcom_smd_channel *qcom_smd_open_channel(struct qcom_smd_channel *channel,
const char *name, const char *name,
qcom_smd_cb_t cb); qcom_smd_cb_t cb);
......
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