aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hsi/controllers/omap_ssi.h4
-rw-r--r--drivers/hsi/controllers/omap_ssi_core.c4
-rw-r--r--drivers/hsi/controllers/omap_ssi_port.c18
3 files changed, 25 insertions, 1 deletions
diff --git a/drivers/hsi/controllers/omap_ssi.h b/drivers/hsi/controllers/omap_ssi.h
index 99143f4f8837..32ced0c8f789 100644
--- a/drivers/hsi/controllers/omap_ssi.h
+++ b/drivers/hsi/controllers/omap_ssi.h
@@ -73,6 +73,8 @@ struct omap_ssm_ctx {
73 * @txqueue: TX message queues 73 * @txqueue: TX message queues
74 * @rxqueue: RX message queues 74 * @rxqueue: RX message queues
75 * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode) 75 * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode)
76 * @errqueue: Queue for failed messages
77 * @errqueue_work: Delayed Work for failed messages
76 * @irq: IRQ number 78 * @irq: IRQ number
77 * @wake_irq: IRQ number for incoming wake line (-1 if none) 79 * @wake_irq: IRQ number for incoming wake line (-1 if none)
78 * @wake_gpio: GPIO number for incoming wake line (-1 if none) 80 * @wake_gpio: GPIO number for incoming wake line (-1 if none)
@@ -96,6 +98,8 @@ struct omap_ssi_port {
96 struct list_head txqueue[SSI_MAX_CHANNELS]; 98 struct list_head txqueue[SSI_MAX_CHANNELS];
97 struct list_head rxqueue[SSI_MAX_CHANNELS]; 99 struct list_head rxqueue[SSI_MAX_CHANNELS];
98 struct list_head brkqueue; 100 struct list_head brkqueue;
101 struct list_head errqueue;
102 struct delayed_work errqueue_work;
99 unsigned int irq; 103 unsigned int irq;
100 int wake_irq; 104 int wake_irq;
101 struct gpio_desc *wake_gpio; 105 struct gpio_desc *wake_gpio;
diff --git a/drivers/hsi/controllers/omap_ssi_core.c b/drivers/hsi/controllers/omap_ssi_core.c
index 79562ce65579..506a9f1ef7ad 100644
--- a/drivers/hsi/controllers/omap_ssi_core.c
+++ b/drivers/hsi/controllers/omap_ssi_core.c
@@ -235,7 +235,9 @@ static void ssi_gdd_complete(struct hsi_controller *ssi, unsigned int lch)
235 spin_lock(&omap_port->lock); 235 spin_lock(&omap_port->lock);
236 list_del(&msg->link); /* Dequeue msg */ 236 list_del(&msg->link); /* Dequeue msg */
237 spin_unlock(&omap_port->lock); 237 spin_unlock(&omap_port->lock);
238 msg->complete(msg); 238
239 list_add_tail(&msg->link, &omap_port->errqueue);
240 schedule_delayed_work(&omap_port->errqueue_work, 0);
239 return; 241 return;
240 } 242 }
241 spin_lock(&omap_port->lock); 243 spin_lock(&omap_port->lock);
diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c
index f91c6a4bb1a5..7717c769c4dd 100644
--- a/drivers/hsi/controllers/omap_ssi_port.c
+++ b/drivers/hsi/controllers/omap_ssi_port.c
@@ -193,6 +193,21 @@ static int ssi_debug_add_port(struct omap_ssi_port *omap_port,
193} 193}
194#endif 194#endif
195 195
196static void ssi_process_errqueue(struct work_struct *work)
197{
198 struct omap_ssi_port *omap_port;
199 struct list_head *head, *tmp;
200 struct hsi_msg *msg;
201
202 omap_port = container_of(work, struct omap_ssi_port, errqueue_work.work);
203
204 list_for_each_safe(head, tmp, &omap_port->errqueue) {
205 msg = list_entry(head, struct hsi_msg, link);
206 msg->complete(msg);
207 list_del(head);
208 }
209}
210
196static int ssi_claim_lch(struct hsi_msg *msg) 211static int ssi_claim_lch(struct hsi_msg *msg)
197{ 212{
198 213
@@ -1170,6 +1185,7 @@ static int ssi_port_probe(struct platform_device *pd)
1170 omap_port->pdev = &pd->dev; 1185 omap_port->pdev = &pd->dev;
1171 omap_port->port_id = port_id; 1186 omap_port->port_id = port_id;
1172 1187
1188 INIT_DEFERRABLE_WORK(&omap_port->errqueue_work, ssi_process_errqueue);
1173 INIT_WORK(&omap_port->work, start_tx_work); 1189 INIT_WORK(&omap_port->work, start_tx_work);
1174 1190
1175 /* initialize HSI port */ 1191 /* initialize HSI port */
@@ -1237,6 +1253,8 @@ static int ssi_port_remove(struct platform_device *pd)
1237 ssi_debug_remove_port(port); 1253 ssi_debug_remove_port(port);
1238#endif 1254#endif
1239 1255
1256 cancel_delayed_work_sync(&omap_port->errqueue_work);
1257
1240 hsi_port_unregister_clients(port); 1258 hsi_port_unregister_clients(port);
1241 1259
1242 port->async = hsi_dummy_msg; 1260 port->async = hsi_dummy_msg;