diff --git a/arch/sim/src/up_internal.h b/arch/sim/src/up_internal.h
index 2a1d9372a1d46368693525359e13a9d80c8ac0c1..fdb798fc2391a7e60322f47102c6d030a47ffee9 100644
--- a/arch/sim/src/up_internal.h
+++ b/arch/sim/src/up_internal.h
@@ -114,12 +114,16 @@
  * Public Variables
  **************************************************************************/
 
+#ifndef __ASSEMBLY__
+
+#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
+extern volatile int g_evloopactive;
+#endif
+
 /**************************************************************************
  * Public Function Prototypes
  **************************************************************************/
 
-#ifndef __ASSEMBLY__
-
 /* up_setjmp.S ************************************************************/
 
 extern int  up_setjmp(int *jb);
@@ -160,20 +164,16 @@ extern int up_x11cmap(unsigned short first, unsigned short len,
 
 /* up_eventloop.c ***********************************************************/
 
-#ifdef CONFIG_SIM_X11FB
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
 extern int up_x11eventloop(void);
 #endif
-#endif
 
 /* up_eventloop.c ***********************************************************/
 
-#ifdef CONFIG_SIM_X11FB
-#ifdef CONFIG_SIM_TOUCHSCREEN
+#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
 extern int up_tcenter(int x, int y, int buttons);
 extern int up_tcleave(int x, int y, int buttons);
 #endif
-#endif
 
 /* up_tapdev.c ************************************************************/
 
diff --git a/arch/sim/src/up_touchscreen.c b/arch/sim/src/up_touchscreen.c
index 277bfb73994c1592ba14147190cc986ac05c4b75..b012ff5b24af8040c2817bdbcde05caaaef43762 100644
--- a/arch/sim/src/up_touchscreen.c
+++ b/arch/sim/src/up_touchscreen.c
@@ -103,6 +103,7 @@ struct up_dev_s
 {
   uint8_t nwaiters;                    /* Number of threads waiting for touchscreen data */
   uint8_t id;                          /* Current touch point ID */
+  uint8_t minor;                       /* Minor device number */
   bool penchange;                      /* An unreported event is buffered */
   sem_t devsem;                        /* Manages exclusive access to this structure */
   sem_t waitsem;                       /* Used to wait for the availability of data */
@@ -601,7 +602,7 @@ errout:
  ****************************************************************************/
 
 /****************************************************************************
- * Name: up_simtouchscreen
+ * Name: sim_tcinitialize
  *
  * Description:
  *   Configure the simulated touchscreen.  This will register the driver as
@@ -616,13 +617,13 @@ errout:
  *
  ****************************************************************************/
 
-int up_simtouchscreen(int minor)
+int sim_tcinitialize(int minor)
 {
   FAR struct up_dev_s *priv = ( FAR struct up_dev_s *)&g_simtouchscreen;
   char devname[DEV_NAMELEN];
   int ret;
 
-  ivdbg("dev: %p minor: %d\n", dev, minor);
+  ivdbg("minor: %d\n", minor);
 
   /* Debug-only sanity checks */
 
@@ -634,6 +635,8 @@ int up_simtouchscreen(int minor)
   sem_init(&priv->devsem,  0, 1); /* Initialize device structure semaphore */
   sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */
 
+  priv->minor = minor;
+
   /* Start the X11 event loop */
 
   ret = up_x11eventloop();
@@ -655,7 +658,7 @@ int up_simtouchscreen(int minor)
       goto errout_with_priv;
     }
 
-  /* And return success (?) */
+  /* And return success */
 
   return OK;
 
@@ -665,6 +668,64 @@ errout_with_priv:
   return ret;
 }
 
+/****************************************************************************
+ * Name: sim_tcuninitialize
+ *
+ * Description:
+ *   Uninitialized the simulated touchscreen
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void sim_tcuninitialize(void)
+{
+  FAR struct up_dev_s *priv = ( FAR struct up_dev_s *)&g_simtouchscreen;
+  char devname[DEV_NAMELEN];
+  int ret;
+
+  /* Get exclusive access */
+
+  do
+    {
+      ret = sem_wait(&priv->devsem);
+      if (ret < 0)
+        {
+          /* This should only happen if the wait was canceled by an signal */
+
+          DEBUGASSERT(errno == EINTR);
+        }
+    }
+  while (ret != OK);
+
+  /* Stop the event loop (Hmm.. the caller must be sure that there are no
+   * open references to the touchscreen driver.  This might better be
+   * done in close() using a reference count).
+   */
+
+  g_evloopactive = 0;
+
+  /* Un-register the device*/
+
+  (void)snprintf(devname, DEV_NAMELEN, DEV_FORMAT, priv->minor);
+  ivdbg("Un-registering %s\n", devname);
+
+  ret = runegister_driver(devname);
+  if (ret < 0)
+    {
+      idbg("uregister_driver() failed: %d\n", ret);
+    }
+
+  /* Clean up any resources.  Ouch!  While we are holding the semaphore? */
+
+  sem_destroy(&priv->waitsem);
+  sem_destroy(&priv->devsem);
+}
+
 /****************************************************************************
  * Name: up_tcenter
  ****************************************************************************/
@@ -672,7 +733,9 @@ errout_with_priv:
 int up_tcenter(int x, int y, int buttons)
 {
   FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen;
-  bool                         pendown;  /* true: pend is down */
+  bool                 pendown;  /* true: pen is down */
+
+  ivdbg("x=%d y=%d buttons=%02x\n", x, y, buttons);
 
   /* Any button press will count as pendown. */
 
@@ -735,6 +798,8 @@ int up_tcleave(int x, int y, int buttons)
 {
   FAR struct up_dev_s *priv = (FAR struct up_dev_s *)&g_simtouchscreen;
 
+  ivdbg("x=%d y=%d buttons=%02x\n", x, y, buttons);
+
   /* Treat leaving as penup */
 
   /* Ignore the pen up if the pen was already up (CONTACT_NONE == pen up and
diff --git a/arch/sim/src/up_x11eventloop.c b/arch/sim/src/up_x11eventloop.c
index 6020433c44fec49d7928f2716a45e7ba82c3f6b1..4973508ea82c298de327eb96559dd3ed3173cde4 100644
--- a/arch/sim/src/up_x11eventloop.c
+++ b/arch/sim/src/up_x11eventloop.c
@@ -71,6 +71,7 @@ extern Display *g_display;
 extern Window g_window;
 
 pthread_t g_eventloop;
+volatile int g_evloopactive;
 
 /****************************************************************************
  * Private Variables
@@ -147,7 +148,7 @@ static void *up_x11eventthread(void *arg)
    * within the following loop.
    */
  
-  for (;;)
+  while (g_evloopactive)
     {
       XNextEvent(g_display, &event);
       switch (event.type)
@@ -196,6 +197,7 @@ int up_x11eventloop(void)
 {
   /* Start the X11 event loop */
 
+  g_evloopactive = 1;
   return pthread_create(&g_eventloop, 0, up_x11eventthread, 0);
 }
 
diff --git a/configs/sim/README.txt b/configs/sim/README.txt
index 3a9348d1ce8d938dac5515dd2754172fa257d5e8..592fb3a471e281071f975a7183c2a2edf3d524bc 100644
--- a/configs/sim/README.txt
+++ b/configs/sim/README.txt
@@ -267,16 +267,23 @@ nx11
     CONFIG_SIM_TOUCHSCREEN=y
 
   Then you must also have some application logic that will call
-  up_simtouchscreen(0) to register the touchscreen driver.
+  sim_tcinitializ(0) to register the touchscreen driver.
 
   NOTES:
-  1. If you do not have this call, the build will mysteriously
-     fail claiming that is can't find up_tcenter(0 and up_tcleave().
-     That is a consequence of the crazy way that the simulation is
-     built and can only be eliminated by call up_simtouchscreen(0)
-     from your application.
 
-  2. You must first call 
+  1. If you do not have the call to sim_tcinitializE(0), the build
+     will mysteriously fail claiming that is can't find up_tcenter()
+     and up_tcleave().  That is a consequence of the crazy way that
+     the simulation is built and can only be eliminated by calling
+     up_simtouchscreen(0) from your application.
+
+  2. You must first up_fbinitialize() before calling up_simtouchscreen()
+     or you will get a crash.
+
+  3. Call sim_tcuninintialize() when you are finished with the
+     simulated touchscreen.
+
+  4. Enable CONFIG_DEBUG_INPUT=y for touchscreen debug output.
 
   X11 Build Issues
   ----------------
diff --git a/include/nuttx/input/touchscreen.h b/include/nuttx/input/touchscreen.h
index 35fdf346962f126b8a862f595a21d231b5d81e26..33d5c5282ffe2812e7da8f246e21fd5edc69e93f 100644
--- a/include/nuttx/input/touchscreen.h
+++ b/include/nuttx/input/touchscreen.h
@@ -128,11 +128,11 @@ extern "C" {
 #endif
 
 /****************************************************************************
- * Name: up_simtouchscreen
+ * Name: sim_tcinitialize
  *
  * Description:
  *   Configure the simulated touchscreen.  This will register the driver as
- *   /dev/inputN where N is the minor device number
+ *   /dev/inputN where N is the minor device number.
  *
  * Input Parameters:
  *   minor   - The input device minor number
@@ -144,7 +144,25 @@ extern "C" {
  ****************************************************************************/
 
 #if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
-EXTERN int up_simtouchscreen(int minor);
+EXTERN int sim_tcinitialize(int minor);
+#endif
+
+/****************************************************************************
+ * Name: sim_tcuninitialize
+ *
+ * Description:
+ *   Uninitialized the simulated touchscreen
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_SIM_X11FB) && defined(CONFIG_SIM_TOUCHSCREEN)
+EXTERN void sim_tcuninitialize(void);
 #endif
 
 #undef EXTERN