diff options
-rw-r--r-- | drivers/hsi/controllers/omap_ssi.h | 4 | ||||
-rw-r--r-- | drivers/hsi/controllers/omap_ssi_core.c | 4 | ||||
-rw-r--r-- | drivers/hsi/controllers/omap_ssi_port.c | 18 |
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 | ||
196 | static 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 | |||
196 | static int ssi_claim_lch(struct hsi_msg *msg) | 211 | static 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; |