Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HSI: omap_ssi: call msg->complete() from process context

msg->complete() should always be called from process context once
irq_safe runtime pm flag is no longer set for omap-ssi.

Signed-off-by: Sebastian Reichel <sre@kernel.org>
Tested-by: Pavel Machek <pavel@ucw.cz>

+25 -1
+4
drivers/hsi/controllers/omap_ssi.h
··· 73 73 * @txqueue: TX message queues 74 74 * @rxqueue: RX message queues 75 75 * @brkqueue: Queue of incoming HWBREAK requests (FRAME mode) 76 + * @errqueue: Queue for failed messages 77 + * @errqueue_work: Delayed Work for failed messages 76 78 * @irq: IRQ number 77 79 * @wake_irq: IRQ number for incoming wake line (-1 if none) 78 80 * @wake_gpio: GPIO number for incoming wake line (-1 if none) ··· 98 96 struct list_head txqueue[SSI_MAX_CHANNELS]; 99 97 struct list_head rxqueue[SSI_MAX_CHANNELS]; 100 98 struct list_head brkqueue; 99 + struct list_head errqueue; 100 + struct delayed_work errqueue_work; 101 101 unsigned int irq; 102 102 int wake_irq; 103 103 struct gpio_desc *wake_gpio;
+3 -1
drivers/hsi/controllers/omap_ssi_core.c
··· 235 235 spin_lock(&omap_port->lock); 236 236 list_del(&msg->link); /* Dequeue msg */ 237 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 241 return; 240 242 } 241 243 spin_lock(&omap_port->lock);
+18
drivers/hsi/controllers/omap_ssi_port.c
··· 193 193 } 194 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 211 static int ssi_claim_lch(struct hsi_msg *msg) 197 212 { 198 213 ··· 1185 1170 omap_port->pdev = &pd->dev; 1186 1171 omap_port->port_id = port_id; 1187 1172 1173 + INIT_DEFERRABLE_WORK(&omap_port->errqueue_work, ssi_process_errqueue); 1188 1174 INIT_WORK(&omap_port->work, start_tx_work); 1189 1175 1190 1176 /* initialize HSI port */ ··· 1252 1236 #ifdef CONFIG_DEBUG_FS 1253 1237 ssi_debug_remove_port(port); 1254 1238 #endif 1239 + 1240 + cancel_delayed_work_sync(&omap_port->errqueue_work); 1255 1241 1256 1242 hsi_port_unregister_clients(port); 1257 1243