msm: ipc: Update to support multiple SMD links
Refactor the IPC Router to SMD Transport Abstraction Layer so that
multiple SMD links can be registered with IPC Router.
Change-Id: I6e26d91a49643dfd978959d1297d1a59da526976
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index 15ea8ba..538dbbe 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -756,7 +756,7 @@
pkt->length = pkt_size;
mutex_lock(&xprt_info->tx_lock);
- ret = xprt_info->xprt->write(pkt, pkt_size, 0);
+ ret = xprt_info->xprt->write(pkt, pkt_size, xprt_info->xprt);
mutex_unlock(&xprt_info->tx_lock);
release_pkt(pkt);
@@ -933,7 +933,8 @@
list_for_each_entry(fwd_xprt_info, &xprt_info_list, list) {
mutex_lock(&fwd_xprt_info->tx_lock);
if (xprt_info->xprt->link_id != fwd_xprt_info->xprt->link_id)
- fwd_xprt_info->xprt->write(pkt, pkt->length, 0);
+ fwd_xprt_info->xprt->write(pkt, pkt->length,
+ fwd_xprt_info->xprt);
mutex_unlock(&fwd_xprt_info->tx_lock);
}
mutex_unlock(&xprt_info_list_lock);
@@ -984,7 +985,7 @@
pr_err("%s: DST in the same cluster\n", __func__);
return 0;
}
- fwd_xprt_info->xprt->write(pkt, pkt->length, 0);
+ fwd_xprt_info->xprt->write(pkt, pkt->length, fwd_xprt_info->xprt);
mutex_unlock(&fwd_xprt_info->tx_lock);
mutex_unlock(&rt_entry->lock);
mutex_unlock(&routing_table_lock);
@@ -1713,7 +1714,7 @@
mutex_lock(&rt_entry->lock);
xprt_info = rt_entry->xprt_info;
mutex_lock(&xprt_info->tx_lock);
- ret = xprt_info->xprt->write(pkt, pkt->length, 0);
+ ret = xprt_info->xprt->write(pkt, pkt->length, xprt_info->xprt);
mutex_unlock(&xprt_info->tx_lock);
mutex_unlock(&rt_entry->lock);
mutex_unlock(&routing_table_lock);
@@ -2070,7 +2071,7 @@
mutex_lock(&xprt_info_list_lock);
list_for_each_entry_safe(xprt_info, tmp_xprt_info,
&xprt_info_list, list) {
- xprt_info->xprt->close();
+ xprt_info->xprt->close(xprt_info->xprt);
list_del(&xprt_info->list);
kfree(xprt_info);
}
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index b125185..bd10ea7 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -150,11 +150,13 @@
uint32_t link_id;
void *priv;
- int (*read_avail)(void);
- int (*read)(void *data, uint32_t len);
- int (*write_avail)(void);
- int (*write)(void *data, uint32_t len, enum write_data_type type);
- int (*close)(void);
+ int (*read_avail)(struct msm_ipc_router_xprt *xprt);
+ int (*read)(void *data, uint32_t len,
+ struct msm_ipc_router_xprt *xprt);
+ int (*write_avail)(struct msm_ipc_router_xprt *xprt);
+ int (*write)(void *data, uint32_t len,
+ struct msm_ipc_router_xprt *xprt);
+ int (*close)(struct msm_ipc_router_xprt *xprt);
};
extern struct completion msm_ipc_remote_router_up;
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index 997d4b5..6960d2e 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,14 +38,21 @@
#define MIN_FRAG_SZ (IPC_ROUTER_HDR_SIZE + sizeof(union rr_control_msg))
+#define NUM_SMD_XPRTS 2
+#define XPRT_NAME_LEN (SMD_MAX_CH_NAME_LEN + 12)
+
struct msm_ipc_router_smd_xprt {
struct msm_ipc_router_xprt xprt;
-
smd_channel_t *channel;
+ struct workqueue_struct *smd_xprt_wq;
+ wait_queue_head_t write_avail_wait_q;
+ struct rr_packet *in_pkt;
+ int is_partial_in_pkt;
+ struct delayed_work read_work;
+ spinlock_t ss_reset_lock; /*Subsystem reset lock*/
+ int ss_reset;
};
-static struct msm_ipc_router_smd_xprt smd_remote_xprt;
-
struct msm_ipc_router_smd_xprt_work {
struct msm_ipc_router_xprt *xprt;
struct work_struct work;
@@ -54,24 +61,45 @@
static void smd_xprt_read_data(struct work_struct *work);
static void smd_xprt_open_event(struct work_struct *work);
static void smd_xprt_close_event(struct work_struct *work);
-static DECLARE_DELAYED_WORK(work_read_data, smd_xprt_read_data);
-static struct workqueue_struct *smd_xprt_workqueue;
-static wait_queue_head_t write_avail_wait_q;
-static struct rr_packet *in_pkt;
-static int is_partial_in_pkt;
+struct msm_ipc_router_smd_xprt_config {
+ char ch_name[SMD_MAX_CH_NAME_LEN];
+ char xprt_name[XPRT_NAME_LEN];
+ uint32_t edge;
+ uint32_t link_id;
+};
-static DEFINE_SPINLOCK(modem_reset_lock);
-static int modem_reset;
+struct msm_ipc_router_smd_xprt_config smd_xprt_cfg[] = {
+ {"RPCRPY_CNTL", "ipc_rtr_smd_rpcrpy_cntl", SMD_APPS_MODEM, 1},
+ {"IPCRTR", "ipc_rtr_smd_ipcrtr", SMD_APPS_MODEM, 1},
+};
-static int msm_ipc_router_smd_remote_write_avail(void)
+static struct msm_ipc_router_smd_xprt smd_remote_xprt[NUM_SMD_XPRTS];
+
+static int find_smd_xprt_cfg(const char *name)
{
- return smd_write_avail(smd_remote_xprt.channel);
+ int i;
+
+ for (i = 0; i < NUM_SMD_XPRTS; i++) {
+ if (!strncmp(name, smd_xprt_cfg[i].ch_name, 20))
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+static int msm_ipc_router_smd_remote_write_avail(
+ struct msm_ipc_router_xprt *xprt)
+{
+ struct msm_ipc_router_smd_xprt *smd_xprtp =
+ container_of(xprt, struct msm_ipc_router_smd_xprt, xprt);
+
+ return smd_write_avail(smd_xprtp->channel);
}
static int msm_ipc_router_smd_remote_write(void *data,
uint32_t len,
- uint32_t type)
+ struct msm_ipc_router_xprt *xprt)
{
struct rr_packet *pkt = (struct rr_packet *)data;
struct sk_buff *ipc_rtr_pkt;
@@ -79,6 +107,8 @@
int offset, sz_written = 0;
int ret, num_retries = 0;
unsigned long flags;
+ struct msm_ipc_router_smd_xprt *smd_xprtp =
+ container_of(xprt, struct msm_ipc_router_smd_xprt, xprt);
if (!pkt)
return -EINVAL;
@@ -87,81 +117,92 @@
return -EINVAL;
align_sz = ALIGN_SIZE(pkt->length);
- while ((ret = smd_write_start(smd_remote_xprt.channel,
+ while ((ret = smd_write_start(smd_xprtp->channel,
(len + align_sz))) < 0) {
- spin_lock_irqsave(&modem_reset_lock, flags);
- if (modem_reset) {
- spin_unlock_irqrestore(&modem_reset_lock, flags);
- pr_err("%s: Modem reset\n", __func__);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ if (smd_xprtp->ss_reset) {
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock,
+ flags);
+ pr_err("%s: %s chnl reset\n", __func__, xprt->name);
return -ENETRESET;
}
- spin_unlock_irqrestore(&modem_reset_lock, flags);
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock, flags);
if (num_retries >= 5) {
- pr_err("%s: Error %d @ smd_write_start\n",
- __func__, ret);
+ pr_err("%s: Error %d @smd_write_start for %s\n",
+ __func__, ret, xprt->name);
return ret;
}
msleep(50);
+ num_retries++;
}
D("%s: Ready to write\n", __func__);
skb_queue_walk(pkt->pkt_fragment_q, ipc_rtr_pkt) {
offset = 0;
while (offset < ipc_rtr_pkt->len) {
- if (!smd_write_avail(smd_remote_xprt.channel))
- smd_enable_read_intr(smd_remote_xprt.channel);
+ if (!smd_write_avail(smd_xprtp->channel))
+ smd_enable_read_intr(smd_xprtp->channel);
- wait_event(write_avail_wait_q,
- (smd_write_avail(smd_remote_xprt.channel) ||
- modem_reset));
- smd_disable_read_intr(smd_remote_xprt.channel);
- spin_lock_irqsave(&modem_reset_lock, flags);
- if (modem_reset) {
- spin_unlock_irqrestore(&modem_reset_lock,
- flags);
- pr_err("%s: Modem reset\n", __func__);
+ wait_event(smd_xprtp->write_avail_wait_q,
+ (smd_write_avail(smd_xprtp->channel) ||
+ smd_xprtp->ss_reset));
+ smd_disable_read_intr(smd_xprtp->channel);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ if (smd_xprtp->ss_reset) {
+ spin_unlock_irqrestore(
+ &smd_xprtp->ss_reset_lock, flags);
+ pr_err("%s: %s chnl reset\n",
+ __func__, xprt->name);
return -ENETRESET;
}
- spin_unlock_irqrestore(&modem_reset_lock, flags);
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock,
+ flags);
- sz_written = smd_write_segment(smd_remote_xprt.channel,
- ipc_rtr_pkt->data + offset,
- (ipc_rtr_pkt->len - offset), 0);
+ sz_written = smd_write_segment(smd_xprtp->channel,
+ ipc_rtr_pkt->data + offset,
+ (ipc_rtr_pkt->len - offset), 0);
offset += sz_written;
sz_written = 0;
}
- D("%s: Wrote %d bytes\n", __func__, offset);
+ D("%s: Wrote %d bytes over %s\n",
+ __func__, offset, xprt->name);
}
if (align_sz) {
- if (smd_write_avail(smd_remote_xprt.channel) < align_sz)
- smd_enable_read_intr(smd_remote_xprt.channel);
+ if (smd_write_avail(smd_xprtp->channel) < align_sz)
+ smd_enable_read_intr(smd_xprtp->channel);
- wait_event(write_avail_wait_q,
- ((smd_write_avail(smd_remote_xprt.channel) >=
- align_sz) || modem_reset));
- smd_disable_read_intr(smd_remote_xprt.channel);
- spin_lock_irqsave(&modem_reset_lock, flags);
- if (modem_reset) {
- spin_unlock_irqrestore(&modem_reset_lock, flags);
- pr_err("%s: Modem reset\n", __func__);
+ wait_event(smd_xprtp->write_avail_wait_q,
+ ((smd_write_avail(smd_xprtp->channel) >=
+ align_sz) || smd_xprtp->ss_reset));
+ smd_disable_read_intr(smd_xprtp->channel);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ if (smd_xprtp->ss_reset) {
+ spin_unlock_irqrestore(
+ &smd_xprtp->ss_reset_lock, flags);
+ pr_err("%s: %s chnl reset\n",
+ __func__, xprt->name);
return -ENETRESET;
}
- spin_unlock_irqrestore(&modem_reset_lock, flags);
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock,
+ flags);
- smd_write_segment(smd_remote_xprt.channel,
+ smd_write_segment(smd_xprtp->channel,
&align_data, align_sz, 0);
- D("%s: Wrote %d align bytes\n", __func__, align_sz);
+ D("%s: Wrote %d align bytes over %s\n",
+ __func__, align_sz, xprt->name);
}
- if (!smd_write_end(smd_remote_xprt.channel))
+ if (!smd_write_end(smd_xprtp->channel))
D("%s: Finished writing\n", __func__);
return len;
}
-static int msm_ipc_router_smd_remote_close(void)
+static int msm_ipc_router_smd_remote_close(struct msm_ipc_router_xprt *xprt)
{
- smsm_change_state(SMSM_APPS_STATE, SMSM_RPCINIT, 0);
- return smd_close(smd_remote_xprt.channel);
+ struct msm_ipc_router_smd_xprt *smd_xprtp =
+ container_of(xprt, struct msm_ipc_router_smd_xprt, xprt);
+
+ return smd_close(smd_xprtp->channel);
}
static void smd_xprt_read_data(struct work_struct *work)
@@ -170,90 +211,97 @@
struct sk_buff *ipc_rtr_pkt;
void *data;
unsigned long flags;
+ struct delayed_work *rwork = to_delayed_work(work);
+ struct msm_ipc_router_smd_xprt *smd_xprtp =
+ container_of(rwork, struct msm_ipc_router_smd_xprt, read_work);
- spin_lock_irqsave(&modem_reset_lock, flags);
- if (modem_reset) {
- spin_unlock_irqrestore(&modem_reset_lock, flags);
- release_pkt(in_pkt);
- is_partial_in_pkt = 0;
- pr_err("%s: Modem reset\n", __func__);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ if (smd_xprtp->ss_reset) {
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock, flags);
+ if (smd_xprtp->in_pkt)
+ release_pkt(smd_xprtp->in_pkt);
+ smd_xprtp->is_partial_in_pkt = 0;
+ pr_err("%s: %s channel reset\n",
+ __func__, smd_xprtp->xprt.name);
return;
}
- spin_unlock_irqrestore(&modem_reset_lock, flags);
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock, flags);
D("%s pkt_size: %d, read_avail: %d\n", __func__,
- smd_cur_packet_size(smd_remote_xprt.channel),
- smd_read_avail(smd_remote_xprt.channel));
- while ((pkt_size = smd_cur_packet_size(smd_remote_xprt.channel)) &&
- smd_read_avail(smd_remote_xprt.channel)) {
- if (!is_partial_in_pkt) {
- in_pkt = kzalloc(sizeof(struct rr_packet), GFP_KERNEL);
- if (!in_pkt) {
+ smd_cur_packet_size(smd_xprtp->channel),
+ smd_read_avail(smd_xprtp->channel));
+ while ((pkt_size = smd_cur_packet_size(smd_xprtp->channel)) &&
+ smd_read_avail(smd_xprtp->channel)) {
+ if (!smd_xprtp->is_partial_in_pkt) {
+ smd_xprtp->in_pkt = kzalloc(sizeof(struct rr_packet),
+ GFP_KERNEL);
+ if (!smd_xprtp->in_pkt) {
pr_err("%s: Couldn't alloc rr_packet\n",
__func__);
return;
}
- in_pkt->pkt_fragment_q = kmalloc(
- sizeof(struct sk_buff_head),
- GFP_KERNEL);
- if (!in_pkt->pkt_fragment_q) {
+ smd_xprtp->in_pkt->pkt_fragment_q =
+ kmalloc(sizeof(struct sk_buff_head),
+ GFP_KERNEL);
+ if (!smd_xprtp->in_pkt->pkt_fragment_q) {
pr_err("%s: Couldn't alloc pkt_fragment_q\n",
__func__);
- kfree(in_pkt);
+ kfree(smd_xprtp->in_pkt);
return;
}
- skb_queue_head_init(in_pkt->pkt_fragment_q);
- is_partial_in_pkt = 1;
+ skb_queue_head_init(smd_xprtp->in_pkt->pkt_fragment_q);
+ smd_xprtp->is_partial_in_pkt = 1;
D("%s: Allocated rr_packet\n", __func__);
}
if (((pkt_size >= MIN_FRAG_SZ) &&
- (smd_read_avail(smd_remote_xprt.channel) < MIN_FRAG_SZ)) ||
+ (smd_read_avail(smd_xprtp->channel) < MIN_FRAG_SZ)) ||
((pkt_size < MIN_FRAG_SZ) &&
- (smd_read_avail(smd_remote_xprt.channel) < pkt_size)))
+ (smd_read_avail(smd_xprtp->channel) < pkt_size)))
return;
- sz = smd_read_avail(smd_remote_xprt.channel);
+ sz = smd_read_avail(smd_xprtp->channel);
do {
ipc_rtr_pkt = alloc_skb(sz, GFP_KERNEL);
if (!ipc_rtr_pkt) {
if (sz <= (PAGE_SIZE/2)) {
- queue_delayed_work(smd_xprt_workqueue,
- &work_read_data,
- msecs_to_jiffies(100));
+ queue_delayed_work(
+ smd_xprtp->smd_xprt_wq,
+ &smd_xprtp->read_work,
+ msecs_to_jiffies(100));
return;
}
sz = sz / 2;
}
} while (!ipc_rtr_pkt);
- D("%s: Allocated the sk_buff of size %d\n",
- __func__, sz);
+ D("%s: Allocated the sk_buff of size %d\n", __func__, sz);
data = skb_put(ipc_rtr_pkt, sz);
- sz_read = smd_read(smd_remote_xprt.channel, data, sz);
+ sz_read = smd_read(smd_xprtp->channel, data, sz);
if (sz_read != sz) {
- pr_err("%s: Couldn't read completely\n", __func__);
+ pr_err("%s: Couldn't read %s completely\n",
+ __func__, smd_xprtp->xprt.name);
kfree_skb(ipc_rtr_pkt);
- release_pkt(in_pkt);
- is_partial_in_pkt = 0;
+ release_pkt(smd_xprtp->in_pkt);
+ smd_xprtp->is_partial_in_pkt = 0;
return;
}
- skb_queue_tail(in_pkt->pkt_fragment_q, ipc_rtr_pkt);
- in_pkt->length += sz_read;
+ skb_queue_tail(smd_xprtp->in_pkt->pkt_fragment_q, ipc_rtr_pkt);
+ smd_xprtp->in_pkt->length += sz_read;
if (sz_read != pkt_size)
- is_partial_in_pkt = 1;
+ smd_xprtp->is_partial_in_pkt = 1;
else
- is_partial_in_pkt = 0;
+ smd_xprtp->is_partial_in_pkt = 0;
- if (!is_partial_in_pkt) {
+ if (!smd_xprtp->is_partial_in_pkt) {
D("%s: Packet size read %d\n",
- __func__, in_pkt->length);
- msm_ipc_router_xprt_notify(&smd_remote_xprt.xprt,
- IPC_ROUTER_XPRT_EVENT_DATA,
- (void *)in_pkt);
- release_pkt(in_pkt);
- in_pkt = NULL;
+ __func__, smd_xprtp->in_pkt->length);
+ msm_ipc_router_xprt_notify(&smd_xprtp->xprt,
+ IPC_ROUTER_XPRT_EVENT_DATA,
+ (void *)smd_xprtp->in_pkt);
+ release_pkt(smd_xprtp->in_pkt);
+ smd_xprtp->in_pkt = NULL;
}
}
}
@@ -265,7 +313,8 @@
msm_ipc_router_xprt_notify(xprt_work->xprt,
IPC_ROUTER_XPRT_EVENT_OPEN, NULL);
- D("%s: Notified IPC Router of OPEN Event\n", __func__);
+ D("%s: Notified IPC Router of %s OPEN\n",
+ __func__, xprt_work->xprt->name);
kfree(xprt_work);
}
@@ -276,28 +325,34 @@
msm_ipc_router_xprt_notify(xprt_work->xprt,
IPC_ROUTER_XPRT_EVENT_CLOSE, NULL);
- D("%s: Notified IPC Router of CLOSE Event\n", __func__);
+ D("%s: Notified IPC Router of %s CLOSE\n",
+ __func__, xprt_work->xprt->name);
kfree(xprt_work);
}
static void msm_ipc_router_smd_remote_notify(void *_dev, unsigned event)
{
unsigned long flags;
+ struct msm_ipc_router_smd_xprt *smd_xprtp;
struct msm_ipc_router_smd_xprt_work *xprt_work;
+ smd_xprtp = (struct msm_ipc_router_smd_xprt *)_dev;
+ if (!smd_xprtp)
+ return;
+
switch (event) {
case SMD_EVENT_DATA:
- if (smd_read_avail(smd_remote_xprt.channel))
- queue_delayed_work(smd_xprt_workqueue,
- &work_read_data, 0);
- if (smd_write_avail(smd_remote_xprt.channel))
- wake_up(&write_avail_wait_q);
+ if (smd_read_avail(smd_xprtp->channel))
+ queue_delayed_work(smd_xprtp->smd_xprt_wq,
+ &smd_xprtp->read_work, 0);
+ if (smd_write_avail(smd_xprtp->channel))
+ wake_up(&smd_xprtp->write_avail_wait_q);
break;
case SMD_EVENT_OPEN:
- spin_lock_irqsave(&modem_reset_lock, flags);
- modem_reset = 0;
- spin_unlock_irqrestore(&modem_reset_lock, flags);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ smd_xprtp->ss_reset = 0;
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock, flags);
xprt_work = kmalloc(sizeof(struct msm_ipc_router_smd_xprt_work),
GFP_ATOMIC);
if (!xprt_work) {
@@ -305,16 +360,16 @@
__func__, event);
return;
}
- xprt_work->xprt = &smd_remote_xprt.xprt;
+ xprt_work->xprt = &smd_xprtp->xprt;
INIT_WORK(&xprt_work->work, smd_xprt_open_event);
- queue_work(smd_xprt_workqueue, &xprt_work->work);
+ queue_work(smd_xprtp->smd_xprt_wq, &xprt_work->work);
break;
case SMD_EVENT_CLOSE:
- spin_lock_irqsave(&modem_reset_lock, flags);
- modem_reset = 1;
- spin_unlock_irqrestore(&modem_reset_lock, flags);
- wake_up(&write_avail_wait_q);
+ spin_lock_irqsave(&smd_xprtp->ss_reset_lock, flags);
+ smd_xprtp->ss_reset = 1;
+ spin_unlock_irqrestore(&smd_xprtp->ss_reset_lock, flags);
+ wake_up(&smd_xprtp->write_avail_wait_q);
xprt_work = kmalloc(sizeof(struct msm_ipc_router_smd_xprt_work),
GFP_ATOMIC);
if (!xprt_work) {
@@ -322,9 +377,9 @@
__func__, event);
return;
}
- xprt_work->xprt = &smd_remote_xprt.xprt;
+ xprt_work->xprt = &smd_xprtp->xprt;
INIT_WORK(&xprt_work->work, smd_xprt_close_event);
- queue_work(smd_xprt_workqueue, &xprt_work->work);
+ queue_work(smd_xprtp->smd_xprt_wq, &xprt_work->work);
break;
}
}
@@ -332,50 +387,93 @@
static int msm_ipc_router_smd_remote_probe(struct platform_device *pdev)
{
int rc;
+ int id; /*Index into the smd_xprt_cfg table*/
- smd_xprt_workqueue = create_singlethread_workqueue("smd_xprt");
- if (!smd_xprt_workqueue)
- return -ENOMEM;
+ id = find_smd_xprt_cfg(pdev->name);
+ if (id < 0) {
+ pr_err("%s: called for unknown ch %s\n",
+ __func__, pdev->name);
+ return id;
+ }
- smd_remote_xprt.xprt.name = "msm_ipc_router_smd_xprt";
- smd_remote_xprt.xprt.link_id = 1;
- smd_remote_xprt.xprt.read_avail = NULL;
- smd_remote_xprt.xprt.read = NULL;
- smd_remote_xprt.xprt.write_avail =
+ smd_remote_xprt[id].smd_xprt_wq =
+ create_singlethread_workqueue(pdev->name);
+ if (!smd_remote_xprt[id].smd_xprt_wq) {
+ pr_err("%s: WQ creation failed for %s\n",
+ __func__, pdev->name);
+ return -EFAULT;
+ }
+
+ smd_remote_xprt[id].xprt.name = smd_xprt_cfg[id].xprt_name;
+ smd_remote_xprt[id].xprt.link_id = smd_xprt_cfg[id].link_id;
+ smd_remote_xprt[id].xprt.read_avail = NULL;
+ smd_remote_xprt[id].xprt.read = NULL;
+ smd_remote_xprt[id].xprt.write_avail =
msm_ipc_router_smd_remote_write_avail;
- smd_remote_xprt.xprt.write = msm_ipc_router_smd_remote_write;
- smd_remote_xprt.xprt.close = msm_ipc_router_smd_remote_close;
- smd_remote_xprt.xprt.priv = NULL;
+ smd_remote_xprt[id].xprt.write = msm_ipc_router_smd_remote_write;
+ smd_remote_xprt[id].xprt.close = msm_ipc_router_smd_remote_close;
+ smd_remote_xprt[id].xprt.priv = NULL;
- init_waitqueue_head(&write_avail_wait_q);
+ init_waitqueue_head(&smd_remote_xprt[id].write_avail_wait_q);
+ smd_remote_xprt[id].in_pkt = NULL;
+ smd_remote_xprt[id].is_partial_in_pkt = 0;
+ INIT_DELAYED_WORK(&smd_remote_xprt[id].read_work, smd_xprt_read_data);
+ spin_lock_init(&smd_remote_xprt[id].ss_reset_lock);
+ smd_remote_xprt[id].ss_reset = 0;
- rc = smd_open("RPCRPY_CNTL", &smd_remote_xprt.channel, NULL,
- msm_ipc_router_smd_remote_notify);
+ rc = smd_named_open_on_edge(smd_xprt_cfg[id].ch_name,
+ smd_xprt_cfg[id].edge,
+ &smd_remote_xprt[id].channel,
+ &smd_remote_xprt[id],
+ msm_ipc_router_smd_remote_notify);
if (rc < 0) {
- destroy_workqueue(smd_xprt_workqueue);
+ pr_err("%s: Channel open failed for %s\n",
+ __func__, smd_xprt_cfg[id].ch_name);
+ destroy_workqueue(smd_remote_xprt[id].smd_xprt_wq);
return rc;
}
- smd_disable_read_intr(smd_remote_xprt.channel);
+ smd_disable_read_intr(smd_remote_xprt[id].channel);
smsm_change_state(SMSM_APPS_STATE, 0, SMSM_RPCINIT);
return 0;
}
-static struct platform_driver msm_ipc_router_smd_remote_driver = {
- .probe = msm_ipc_router_smd_remote_probe,
- .driver = {
- .name = "RPCRPY_CNTL",
- .owner = THIS_MODULE,
+static struct platform_driver msm_ipc_router_smd_remote_driver[] = {
+ {
+ .probe = msm_ipc_router_smd_remote_probe,
+ .driver = {
+ .name = "RPCRPY_CNTL",
+ .owner = THIS_MODULE,
+ },
+ },
+ {
+ .probe = msm_ipc_router_smd_remote_probe,
+ .driver = {
+ .name = "IPCRTR",
+ .owner = THIS_MODULE,
+ },
},
};
static int __init msm_ipc_router_smd_init(void)
{
- return platform_driver_register(&msm_ipc_router_smd_remote_driver);
+ int i, ret, rc = 0;
+ BUG_ON(ARRAY_SIZE(msm_ipc_router_smd_remote_driver) != NUM_SMD_XPRTS);
+ BUG_ON(ARRAY_SIZE(smd_xprt_cfg) != NUM_SMD_XPRTS);
+ for (i = 0; i < NUM_SMD_XPRTS; i++) {
+ ret = platform_driver_register(
+ &msm_ipc_router_smd_remote_driver[i]);
+ if (ret) {
+ pr_err("%s: Failed to register platform driver for"
+ " xprt%d. Continuing...\n", __func__, i);
+ rc = ret;
+ }
+ }
+ return rc;
}
module_init(msm_ipc_router_smd_init);
-MODULE_DESCRIPTION("RPC Router SMD XPRT");
+MODULE_DESCRIPTION("IPC Router SMD XPRT");
MODULE_LICENSE("GPL v2");