1 /*
2  * Copyright (C) 2012 Texas Instruments
3  * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 as published by
7  * the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #define DSS_SUBSYS_NAME "APPLY"
19 
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/spinlock.h>
24 #include <linux/jiffies.h>
25 #include <linux/delay.h>
26 #include <linux/interrupt.h>
27 #include <linux/seq_file.h>
28 
29 #include <video/omapfb_dss.h>
30 
31 #include "dss.h"
32 #include "dss_features.h"
33 #include "dispc-compat.h"
34 
35 #define DISPC_IRQ_MASK_ERROR            (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
36 					 DISPC_IRQ_OCP_ERR | \
37 					 DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
38 					 DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
39 					 DISPC_IRQ_SYNC_LOST | \
40 					 DISPC_IRQ_SYNC_LOST_DIGIT)
41 
42 #define DISPC_MAX_NR_ISRS		8
43 
44 struct omap_dispc_isr_data {
45 	omap_dispc_isr_t	isr;
46 	void			*arg;
47 	u32			mask;
48 };
49 
50 struct dispc_irq_stats {
51 	unsigned long last_reset;
52 	unsigned irq_count;
53 	unsigned irqs[32];
54 };
55 
56 static struct {
57 	spinlock_t irq_lock;
58 	u32 irq_error_mask;
59 	struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
60 	u32 error_irqs;
61 	struct work_struct error_work;
62 
63 #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
64 	spinlock_t irq_stats_lock;
65 	struct dispc_irq_stats irq_stats;
66 #endif
67 } dispc_compat;
68 
69 
70 #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
71 static void dispc_dump_irqs(struct seq_file *s)
72 {
73 	unsigned long flags;
74 	struct dispc_irq_stats stats;
75 
76 	spin_lock_irqsave(&dispc_compat.irq_stats_lock, flags);
77 
78 	stats = dispc_compat.irq_stats;
79 	memset(&dispc_compat.irq_stats, 0, sizeof(dispc_compat.irq_stats));
80 	dispc_compat.irq_stats.last_reset = jiffies;
81 
82 	spin_unlock_irqrestore(&dispc_compat.irq_stats_lock, flags);
83 
84 	seq_printf(s, "period %u ms\n",
85 			jiffies_to_msecs(jiffies - stats.last_reset));
86 
87 	seq_printf(s, "irqs %d\n", stats.irq_count);
88 #define PIS(x) \
89 	seq_printf(s, "%-20s %10d\n", #x, stats.irqs[ffs(DISPC_IRQ_##x)-1]);
90 
91 	PIS(FRAMEDONE);
92 	PIS(VSYNC);
93 	PIS(EVSYNC_EVEN);
94 	PIS(EVSYNC_ODD);
95 	PIS(ACBIAS_COUNT_STAT);
96 	PIS(PROG_LINE_NUM);
97 	PIS(GFX_FIFO_UNDERFLOW);
98 	PIS(GFX_END_WIN);
99 	PIS(PAL_GAMMA_MASK);
100 	PIS(OCP_ERR);
101 	PIS(VID1_FIFO_UNDERFLOW);
102 	PIS(VID1_END_WIN);
103 	PIS(VID2_FIFO_UNDERFLOW);
104 	PIS(VID2_END_WIN);
105 	if (dss_feat_get_num_ovls() > 3) {
106 		PIS(VID3_FIFO_UNDERFLOW);
107 		PIS(VID3_END_WIN);
108 	}
109 	PIS(SYNC_LOST);
110 	PIS(SYNC_LOST_DIGIT);
111 	PIS(WAKEUP);
112 	if (dss_has_feature(FEAT_MGR_LCD2)) {
113 		PIS(FRAMEDONE2);
114 		PIS(VSYNC2);
115 		PIS(ACBIAS_COUNT_STAT2);
116 		PIS(SYNC_LOST2);
117 	}
118 	if (dss_has_feature(FEAT_MGR_LCD3)) {
119 		PIS(FRAMEDONE3);
120 		PIS(VSYNC3);
121 		PIS(ACBIAS_COUNT_STAT3);
122 		PIS(SYNC_LOST3);
123 	}
124 #undef PIS
125 }
126 #endif
127 
128 /* dispc.irq_lock has to be locked by the caller */
129 static void _omap_dispc_set_irqs(void)
130 {
131 	u32 mask;
132 	int i;
133 	struct omap_dispc_isr_data *isr_data;
134 
135 	mask = dispc_compat.irq_error_mask;
136 
137 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
138 		isr_data = &dispc_compat.registered_isr[i];
139 
140 		if (isr_data->isr == NULL)
141 			continue;
142 
143 		mask |= isr_data->mask;
144 	}
145 
146 	dispc_write_irqenable(mask);
147 }
148 
149 int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
150 {
151 	int i;
152 	int ret;
153 	unsigned long flags;
154 	struct omap_dispc_isr_data *isr_data;
155 
156 	if (isr == NULL)
157 		return -EINVAL;
158 
159 	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
160 
161 	/* check for duplicate entry */
162 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
163 		isr_data = &dispc_compat.registered_isr[i];
164 		if (isr_data->isr == isr && isr_data->arg == arg &&
165 				isr_data->mask == mask) {
166 			ret = -EINVAL;
167 			goto err;
168 		}
169 	}
170 
171 	isr_data = NULL;
172 	ret = -EBUSY;
173 
174 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
175 		isr_data = &dispc_compat.registered_isr[i];
176 
177 		if (isr_data->isr != NULL)
178 			continue;
179 
180 		isr_data->isr = isr;
181 		isr_data->arg = arg;
182 		isr_data->mask = mask;
183 		ret = 0;
184 
185 		break;
186 	}
187 
188 	if (ret)
189 		goto err;
190 
191 	_omap_dispc_set_irqs();
192 
193 	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
194 
195 	return 0;
196 err:
197 	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
198 
199 	return ret;
200 }
201 EXPORT_SYMBOL(omap_dispc_register_isr);
202 
203 int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
204 {
205 	int i;
206 	unsigned long flags;
207 	int ret = -EINVAL;
208 	struct omap_dispc_isr_data *isr_data;
209 
210 	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
211 
212 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
213 		isr_data = &dispc_compat.registered_isr[i];
214 		if (isr_data->isr != isr || isr_data->arg != arg ||
215 				isr_data->mask != mask)
216 			continue;
217 
218 		/* found the correct isr */
219 
220 		isr_data->isr = NULL;
221 		isr_data->arg = NULL;
222 		isr_data->mask = 0;
223 
224 		ret = 0;
225 		break;
226 	}
227 
228 	if (ret == 0)
229 		_omap_dispc_set_irqs();
230 
231 	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
232 
233 	return ret;
234 }
235 EXPORT_SYMBOL(omap_dispc_unregister_isr);
236 
237 static void print_irq_status(u32 status)
238 {
239 	if ((status & dispc_compat.irq_error_mask) == 0)
240 		return;
241 
242 #define PIS(x) (status & DISPC_IRQ_##x) ? (#x " ") : ""
243 
244 	pr_debug("DISPC IRQ: 0x%x: %s%s%s%s%s%s%s%s%s\n",
245 		status,
246 		PIS(OCP_ERR),
247 		PIS(GFX_FIFO_UNDERFLOW),
248 		PIS(VID1_FIFO_UNDERFLOW),
249 		PIS(VID2_FIFO_UNDERFLOW),
250 		dss_feat_get_num_ovls() > 3 ? PIS(VID3_FIFO_UNDERFLOW) : "",
251 		PIS(SYNC_LOST),
252 		PIS(SYNC_LOST_DIGIT),
253 		dss_has_feature(FEAT_MGR_LCD2) ? PIS(SYNC_LOST2) : "",
254 		dss_has_feature(FEAT_MGR_LCD3) ? PIS(SYNC_LOST3) : "");
255 #undef PIS
256 }
257 
258 /* Called from dss.c. Note that we don't touch clocks here,
259  * but we presume they are on because we got an IRQ. However,
260  * an irq handler may turn the clocks off, so we may not have
261  * clock later in the function. */
262 static irqreturn_t omap_dispc_irq_handler(int irq, void *arg)
263 {
264 	int i;
265 	u32 irqstatus, irqenable;
266 	u32 handledirqs = 0;
267 	u32 unhandled_errors;
268 	struct omap_dispc_isr_data *isr_data;
269 	struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
270 
271 	spin_lock(&dispc_compat.irq_lock);
272 
273 	irqstatus = dispc_read_irqstatus();
274 	irqenable = dispc_read_irqenable();
275 
276 	/* IRQ is not for us */
277 	if (!(irqstatus & irqenable)) {
278 		spin_unlock(&dispc_compat.irq_lock);
279 		return IRQ_NONE;
280 	}
281 
282 #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
283 	spin_lock(&dispc_compat.irq_stats_lock);
284 	dispc_compat.irq_stats.irq_count++;
285 	dss_collect_irq_stats(irqstatus, dispc_compat.irq_stats.irqs);
286 	spin_unlock(&dispc_compat.irq_stats_lock);
287 #endif
288 
289 	print_irq_status(irqstatus);
290 
291 	/* Ack the interrupt. Do it here before clocks are possibly turned
292 	 * off */
293 	dispc_clear_irqstatus(irqstatus);
294 	/* flush posted write */
295 	dispc_read_irqstatus();
296 
297 	/* make a copy and unlock, so that isrs can unregister
298 	 * themselves */
299 	memcpy(registered_isr, dispc_compat.registered_isr,
300 			sizeof(registered_isr));
301 
302 	spin_unlock(&dispc_compat.irq_lock);
303 
304 	for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
305 		isr_data = &registered_isr[i];
306 
307 		if (!isr_data->isr)
308 			continue;
309 
310 		if (isr_data->mask & irqstatus) {
311 			isr_data->isr(isr_data->arg, irqstatus);
312 			handledirqs |= isr_data->mask;
313 		}
314 	}
315 
316 	spin_lock(&dispc_compat.irq_lock);
317 
318 	unhandled_errors = irqstatus & ~handledirqs & dispc_compat.irq_error_mask;
319 
320 	if (unhandled_errors) {
321 		dispc_compat.error_irqs |= unhandled_errors;
322 
323 		dispc_compat.irq_error_mask &= ~unhandled_errors;
324 		_omap_dispc_set_irqs();
325 
326 		schedule_work(&dispc_compat.error_work);
327 	}
328 
329 	spin_unlock(&dispc_compat.irq_lock);
330 
331 	return IRQ_HANDLED;
332 }
333 
334 static void dispc_error_worker(struct work_struct *work)
335 {
336 	int i;
337 	u32 errors;
338 	unsigned long flags;
339 	static const unsigned fifo_underflow_bits[] = {
340 		DISPC_IRQ_GFX_FIFO_UNDERFLOW,
341 		DISPC_IRQ_VID1_FIFO_UNDERFLOW,
342 		DISPC_IRQ_VID2_FIFO_UNDERFLOW,
343 		DISPC_IRQ_VID3_FIFO_UNDERFLOW,
344 	};
345 
346 	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
347 	errors = dispc_compat.error_irqs;
348 	dispc_compat.error_irqs = 0;
349 	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
350 
351 	dispc_runtime_get();
352 
353 	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
354 		struct omap_overlay *ovl;
355 		unsigned bit;
356 
357 		ovl = omap_dss_get_overlay(i);
358 		bit = fifo_underflow_bits[i];
359 
360 		if (bit & errors) {
361 			DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
362 					ovl->name);
363 			ovl->disable(ovl);
364 			msleep(50);
365 		}
366 	}
367 
368 	for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
369 		struct omap_overlay_manager *mgr;
370 		unsigned bit;
371 
372 		mgr = omap_dss_get_overlay_manager(i);
373 		bit = dispc_mgr_get_sync_lost_irq(i);
374 
375 		if (bit & errors) {
376 			int j;
377 
378 			DSSERR("SYNC_LOST on channel %s, restarting the output "
379 					"with video overlays disabled\n",
380 					mgr->name);
381 
382 			dss_mgr_disable(mgr);
383 
384 			for (j = 0; j < omap_dss_get_num_overlays(); ++j) {
385 				struct omap_overlay *ovl;
386 				ovl = omap_dss_get_overlay(j);
387 
388 				if (ovl->id != OMAP_DSS_GFX &&
389 						ovl->manager == mgr)
390 					ovl->disable(ovl);
391 			}
392 
393 			dss_mgr_enable(mgr);
394 		}
395 	}
396 
397 	if (errors & DISPC_IRQ_OCP_ERR) {
398 		DSSERR("OCP_ERR\n");
399 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
400 			struct omap_overlay_manager *mgr;
401 
402 			mgr = omap_dss_get_overlay_manager(i);
403 			dss_mgr_disable(mgr);
404 		}
405 	}
406 
407 	spin_lock_irqsave(&dispc_compat.irq_lock, flags);
408 	dispc_compat.irq_error_mask |= errors;
409 	_omap_dispc_set_irqs();
410 	spin_unlock_irqrestore(&dispc_compat.irq_lock, flags);
411 
412 	dispc_runtime_put();
413 }
414 
415 int dss_dispc_initialize_irq(void)
416 {
417 	int r;
418 
419 #ifdef CONFIG_FB_OMAP2_DSS_COLLECT_IRQ_STATS
420 	spin_lock_init(&dispc_compat.irq_stats_lock);
421 	dispc_compat.irq_stats.last_reset = jiffies;
422 	dss_debugfs_create_file("dispc_irq", dispc_dump_irqs);
423 #endif
424 
425 	spin_lock_init(&dispc_compat.irq_lock);
426 
427 	memset(dispc_compat.registered_isr, 0,
428 			sizeof(dispc_compat.registered_isr));
429 
430 	dispc_compat.irq_error_mask = DISPC_IRQ_MASK_ERROR;
431 	if (dss_has_feature(FEAT_MGR_LCD2))
432 		dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST2;
433 	if (dss_has_feature(FEAT_MGR_LCD3))
434 		dispc_compat.irq_error_mask |= DISPC_IRQ_SYNC_LOST3;
435 	if (dss_feat_get_num_ovls() > 3)
436 		dispc_compat.irq_error_mask |= DISPC_IRQ_VID3_FIFO_UNDERFLOW;
437 
438 	/*
439 	 * there's SYNC_LOST_DIGIT waiting after enabling the DSS,
440 	 * so clear it
441 	 */
442 	dispc_clear_irqstatus(dispc_read_irqstatus());
443 
444 	INIT_WORK(&dispc_compat.error_work, dispc_error_worker);
445 
446 	_omap_dispc_set_irqs();
447 
448 	r = dispc_request_irq(omap_dispc_irq_handler, &dispc_compat);
449 	if (r) {
450 		DSSERR("dispc_request_irq failed\n");
451 		return r;
452 	}
453 
454 	return 0;
455 }
456 
457 void dss_dispc_uninitialize_irq(void)
458 {
459 	dispc_free_irq(&dispc_compat);
460 }
461 
462 static void dispc_mgr_disable_isr(void *data, u32 mask)
463 {
464 	struct completion *compl = data;
465 	complete(compl);
466 }
467 
468 static void dispc_mgr_enable_lcd_out(enum omap_channel channel)
469 {
470 	dispc_mgr_enable(channel, true);
471 }
472 
473 static void dispc_mgr_disable_lcd_out(enum omap_channel channel)
474 {
475 	DECLARE_COMPLETION_ONSTACK(framedone_compl);
476 	int r;
477 	u32 irq;
478 
479 	if (!dispc_mgr_is_enabled(channel))
480 		return;
481 
482 	/*
483 	 * When we disable LCD output, we need to wait for FRAMEDONE to know
484 	 * that DISPC has finished with the LCD output.
485 	 */
486 
487 	irq = dispc_mgr_get_framedone_irq(channel);
488 
489 	r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
490 			irq);
491 	if (r)
492 		DSSERR("failed to register FRAMEDONE isr\n");
493 
494 	dispc_mgr_enable(channel, false);
495 
496 	/* if we couldn't register for framedone, just sleep and exit */
497 	if (r) {
498 		msleep(100);
499 		return;
500 	}
501 
502 	if (!wait_for_completion_timeout(&framedone_compl,
503 				msecs_to_jiffies(100)))
504 		DSSERR("timeout waiting for FRAME DONE\n");
505 
506 	r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
507 			irq);
508 	if (r)
509 		DSSERR("failed to unregister FRAMEDONE isr\n");
510 }
511 
512 static void dispc_digit_out_enable_isr(void *data, u32 mask)
513 {
514 	struct completion *compl = data;
515 
516 	/* ignore any sync lost interrupts */
517 	if (mask & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD))
518 		complete(compl);
519 }
520 
521 static void dispc_mgr_enable_digit_out(void)
522 {
523 	DECLARE_COMPLETION_ONSTACK(vsync_compl);
524 	int r;
525 	u32 irq_mask;
526 
527 	if (dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT))
528 		return;
529 
530 	/*
531 	 * Digit output produces some sync lost interrupts during the first
532 	 * frame when enabling. Those need to be ignored, so we register for the
533 	 * sync lost irq to prevent the error handler from triggering.
534 	 */
535 
536 	irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT) |
537 		dispc_mgr_get_sync_lost_irq(OMAP_DSS_CHANNEL_DIGIT);
538 
539 	r = omap_dispc_register_isr(dispc_digit_out_enable_isr, &vsync_compl,
540 			irq_mask);
541 	if (r) {
542 		DSSERR("failed to register %x isr\n", irq_mask);
543 		return;
544 	}
545 
546 	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true);
547 
548 	/* wait for the first evsync */
549 	if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100)))
550 		DSSERR("timeout waiting for digit out to start\n");
551 
552 	r = omap_dispc_unregister_isr(dispc_digit_out_enable_isr, &vsync_compl,
553 			irq_mask);
554 	if (r)
555 		DSSERR("failed to unregister %x isr\n", irq_mask);
556 }
557 
558 static void dispc_mgr_disable_digit_out(void)
559 {
560 	DECLARE_COMPLETION_ONSTACK(framedone_compl);
561 	int r, i;
562 	u32 irq_mask;
563 	int num_irqs;
564 
565 	if (!dispc_mgr_is_enabled(OMAP_DSS_CHANNEL_DIGIT))
566 		return;
567 
568 	/*
569 	 * When we disable the digit output, we need to wait for FRAMEDONE to
570 	 * know that DISPC has finished with the output.
571 	 */
572 
573 	irq_mask = dispc_mgr_get_framedone_irq(OMAP_DSS_CHANNEL_DIGIT);
574 	num_irqs = 1;
575 
576 	if (!irq_mask) {
577 		/*
578 		 * omap 2/3 don't have framedone irq for TV, so we need to use
579 		 * vsyncs for this.
580 		 */
581 
582 		irq_mask = dispc_mgr_get_vsync_irq(OMAP_DSS_CHANNEL_DIGIT);
583 		/*
584 		 * We need to wait for both even and odd vsyncs. Note that this
585 		 * is not totally reliable, as we could get a vsync interrupt
586 		 * before we disable the output, which leads to timeout in the
587 		 * wait_for_completion.
588 		 */
589 		num_irqs = 2;
590 	}
591 
592 	r = omap_dispc_register_isr(dispc_mgr_disable_isr, &framedone_compl,
593 			irq_mask);
594 	if (r)
595 		DSSERR("failed to register %x isr\n", irq_mask);
596 
597 	dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false);
598 
599 	/* if we couldn't register the irq, just sleep and exit */
600 	if (r) {
601 		msleep(100);
602 		return;
603 	}
604 
605 	for (i = 0; i < num_irqs; ++i) {
606 		if (!wait_for_completion_timeout(&framedone_compl,
607 					msecs_to_jiffies(100)))
608 			DSSERR("timeout waiting for digit out to stop\n");
609 	}
610 
611 	r = omap_dispc_unregister_isr(dispc_mgr_disable_isr, &framedone_compl,
612 			irq_mask);
613 	if (r)
614 		DSSERR("failed to unregister %x isr\n", irq_mask);
615 }
616 
617 void dispc_mgr_enable_sync(enum omap_channel channel)
618 {
619 	if (dss_mgr_is_lcd(channel))
620 		dispc_mgr_enable_lcd_out(channel);
621 	else if (channel == OMAP_DSS_CHANNEL_DIGIT)
622 		dispc_mgr_enable_digit_out();
623 	else
624 		WARN_ON(1);
625 }
626 
627 void dispc_mgr_disable_sync(enum omap_channel channel)
628 {
629 	if (dss_mgr_is_lcd(channel))
630 		dispc_mgr_disable_lcd_out(channel);
631 	else if (channel == OMAP_DSS_CHANNEL_DIGIT)
632 		dispc_mgr_disable_digit_out();
633 	else
634 		WARN_ON(1);
635 }
636 
637 static inline void dispc_irq_wait_handler(void *data, u32 mask)
638 {
639 	complete((struct completion *)data);
640 }
641 
642 int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
643 		unsigned long timeout)
644 {
645 
646 	int r;
647 	long time_left;
648 	DECLARE_COMPLETION_ONSTACK(completion);
649 
650 	r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
651 			irqmask);
652 
653 	if (r)
654 		return r;
655 
656 	time_left = wait_for_completion_interruptible_timeout(&completion,
657 			timeout);
658 
659 	omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
660 
661 	if (time_left == 0)
662 		return -ETIMEDOUT;
663 
664 	if (time_left == -ERESTARTSYS)
665 		return -ERESTARTSYS;
666 
667 	return 0;
668 }
669