diff --git a/drivers/input/touchscreen/da9034-ts.c b/drivers/input/touchscreen/da9034-ts.c
index 666a6e74be4014c3e33832c1698f7d144805cb92..3ffd4c4b170c6ae21354e191d2483637e4048224 100644
--- a/drivers/input/touchscreen/da9034-ts.c
+++ b/drivers/input/touchscreen/da9034-ts.c
@@ -176,6 +176,16 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 			goto err_reset;
 
 		touch->state = STATE_STOP;
+
+		/* FIXME: PEN_{UP/DOWN} events are expected to be
+		 * available by stopping TSI, but this is found not
+		 * always true, delay and simulate such an event
+		 * here is more reliable
+		 */
+		mdelay(1);
+		da9034_event_handler(touch,
+				     is_pen_down(touch) ? EVENT_PEN_DOWN :
+							  EVENT_PEN_UP);
 		break;
 
 	case STATE_STOP:
@@ -190,8 +200,6 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 			report_pen_up(touch);
 			touch->state = STATE_IDLE;
 		}
-
-		input_sync(touch->input_dev);
 		break;
 
 	case STATE_WAIT:
@@ -201,8 +209,10 @@ static void da9034_event_handler(struct da9034_touch *touch, int event)
 		if (is_pen_down(touch)) {
 			start_tsi(touch);
 			touch->state = STATE_BUSY;
-		} else
+		} else {
+			report_pen_up(touch);
 			touch->state = STATE_IDLE;
+		}
 		break;
 	}
 	return;
@@ -227,16 +237,12 @@ static int da9034_touch_notifier(struct notifier_block *nb,
 	struct da9034_touch *touch =
 		container_of(nb, struct da9034_touch, notifier);
 
-	if (event & DA9034_EVENT_PEN_DOWN) {
-		if (is_pen_down(touch))
-			da9034_event_handler(touch, EVENT_PEN_DOWN);
-		else
-			da9034_event_handler(touch, EVENT_PEN_UP);
-	}
-
 	if (event & DA9034_EVENT_TSI_READY)
 		da9034_event_handler(touch, EVENT_TSI_READY);
 
+	if ((event & DA9034_EVENT_PEN_DOWN) && touch->state == STATE_IDLE)
+		da9034_event_handler(touch, EVENT_PEN_DOWN);
+
 	return 0;
 }