diff --git a/platform/linux-generic/include/odp_internal.h b/platform/linux-generic/include/odp_internal.h
index 113b700..b22f956 100644
--- a/platform/linux-generic/include/odp_internal.h
+++ b/platform/linux-generic/include/odp_internal.h
@@ -38,9 +38,29 @@ struct odp_global_data_s {
 	odp_system_info_t system_info;
 };
 
+enum init_stage {
+	NO_INIT = 0,    /* No init stages completed */
+	TIME_INIT = 1,
+	SYSINFO_INIT = 2,
+	SHM_INIT = 3,
+	THREAD_INIT = 4,
+	POOL_INIT = 5,
+	QUEUE_INIT = 6,
+	SCHED_INIT = 7,
+	PKTIO_INIT = 8,
+	TIMER_INIT = 9,
+	CRYPTO_INIT = 10,
+	CLASSIFICATION_INIT = 11,
+	ALL_INIT = 12   /* All init stages completed */
+};
+
 extern struct odp_global_data_s odp_global_data;
 
+int _odp_term_global(enum init_stage stage);
+int _odp_term_local(enum init_stage stage);
+
 int odp_system_info_init(void);
+int odp_system_info_term(void);
 
 int odp_thread_init_global(void);
 int odp_thread_init_local(odp_thread_type_t type);
@@ -75,9 +95,11 @@ int odp_schedule_init_local(void);
 int odp_schedule_term_local(void);
 
 int odp_timer_init_global(void);
+int odp_timer_term_global(void);
 int odp_timer_disarm_all(void);
 
-int odp_time_global_init(void);
+int odp_time_init_global(void);
+int odp_time_term_global(void);
 
 void _odp_flush_caches(void);
 
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index ea99742..3a990d2 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -14,6 +14,7 @@ struct odp_global_data_s odp_global_data;
 int odp_init_global(const odp_init_t *params,
 		    const odp_platform_init_t *platform_params ODP_UNUSED)
 {
+	enum init_stage stage = NO_INIT;
 	odp_global_data.log_fn = odp_override_log;
 	odp_global_data.abort_fn = odp_override_abort;
 
@@ -24,105 +25,170 @@ int odp_init_global(const odp_init_t *params,
 			odp_global_data.abort_fn = params->abort_fn;
 	}
 
-	if (odp_time_global_init()) {
+	if (odp_time_init_global()) {
 		ODP_ERR("ODP time init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = TIME_INIT;
 
 	if (odp_system_info_init()) {
 		ODP_ERR("ODP system_info init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = SYSINFO_INIT;
 
 	if (odp_shm_init_global()) {
 		ODP_ERR("ODP shm init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = SHM_INIT;
 
 	if (odp_thread_init_global()) {
 		ODP_ERR("ODP thread init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = THREAD_INIT;
 
 	if (odp_pool_init_global()) {
 		ODP_ERR("ODP pool init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = POOL_INIT;
 
 	if (odp_queue_init_global()) {
 		ODP_ERR("ODP queue init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = QUEUE_INIT;
 
 	if (odp_schedule_init_global()) {
 		ODP_ERR("ODP schedule init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = SCHED_INIT;
 
 	if (odp_pktio_init_global()) {
 		ODP_ERR("ODP packet io init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = PKTIO_INIT;
 
 	if (odp_timer_init_global()) {
 		ODP_ERR("ODP timer init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = TIMER_INIT;
 
 	if (odp_crypto_init_global()) {
 		ODP_ERR("ODP crypto init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = CRYPTO_INIT;
+
 	if (odp_classification_init_global()) {
 		ODP_ERR("ODP classification init failed.\n");
-		return -1;
+		goto init_failed;
 	}
+	stage = CLASSIFICATION_INIT;
 
 	return 0;
+
+init_failed:
+	_odp_term_global(stage);
+	return -1;
 }
 
 int odp_term_global(void)
 {
-	int rc = 0;
-
-	if (odp_classification_term_global()) {
-		ODP_ERR("ODP classificatio term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_crypto_term_global()) {
-		ODP_ERR("ODP crypto term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_pktio_term_global()) {
-		ODP_ERR("ODP pktio term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_schedule_term_global()) {
-		ODP_ERR("ODP schedule term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_queue_term_global()) {
-		ODP_ERR("ODP queue term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_pool_term_global()) {
-		ODP_ERR("ODP buffer pool term failed.\n");
-		rc = -1;
-	}
+	return _odp_term_global(ALL_INIT);
+}
 
-	if (odp_thread_term_global()) {
-		ODP_ERR("ODP thread term failed.\n");
-		rc = -1;
-	}
+int _odp_term_global(enum init_stage stage)
+{
+	int rc = 0;
 
-	if (odp_shm_term_global()) {
-		ODP_ERR("ODP shm term failed.\n");
-		rc = -1;
+	switch (stage) {
+	case ALL_INIT:
+
+	case CLASSIFICATION_INIT:
+		if (odp_classification_term_global()) {
+			ODP_ERR("ODP classificatio term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case CRYPTO_INIT:
+		if (odp_crypto_term_global()) {
+			ODP_ERR("ODP crypto term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case TIMER_INIT:
+		if (odp_timer_term_global()) {
+			ODP_ERR("ODP timer term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case PKTIO_INIT:
+		if (odp_pktio_term_global()) {
+			ODP_ERR("ODP pktio term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case SCHED_INIT:
+		if (odp_schedule_term_global()) {
+			ODP_ERR("ODP schedule term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case QUEUE_INIT:
+		if (odp_queue_term_global()) {
+			ODP_ERR("ODP queue term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case POOL_INIT:
+		if (odp_pool_term_global()) {
+			ODP_ERR("ODP buffer pool term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case THREAD_INIT:
+		if (odp_thread_term_global()) {
+			ODP_ERR("ODP thread term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case SHM_INIT:
+		if (odp_shm_term_global()) {
+			ODP_ERR("ODP shm term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case SYSINFO_INIT:
+		if (odp_system_info_term()) {
+			ODP_ERR("ODP system info term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case TIME_INIT:
+		if (odp_time_term_global()) {
+			ODP_ERR("ODP time term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case NO_INIT:
+		;
 	}
 
 	return rc;
@@ -130,56 +196,85 @@ int odp_term_global(void)
 
 int odp_init_local(odp_thread_type_t thr_type)
 {
+	enum init_stage stage = NO_INIT;
+
 	if (odp_shm_init_local()) {
 		ODP_ERR("ODP shm local init failed.\n");
-		return -1;
+		goto init_fail;
 	}
+	stage = SHM_INIT;
 
 	if (odp_thread_init_local(thr_type)) {
 		ODP_ERR("ODP thread local init failed.\n");
-		return -1;
+		goto init_fail;
 	}
+	stage = THREAD_INIT;
 
 	if (odp_pktio_init_local()) {
 		ODP_ERR("ODP packet io local init failed.\n");
-		return -1;
+		goto init_fail;
 	}
+	stage = PKTIO_INIT;
 
 	if (odp_pool_init_local()) {
 		ODP_ERR("ODP pool local init failed.\n");
-		return -1;
+		goto init_fail;
 	}
+	stage = POOL_INIT;
 
 	if (odp_schedule_init_local()) {
 		ODP_ERR("ODP schedule local init failed.\n");
-		return -1;
+		goto init_fail;
 	}
+	stage = SCHED_INIT;
 
 	return 0;
+
+init_fail:
+	_odp_term_local(stage);
+	return -1;
 }
 
 int odp_term_local(void)
 {
+	return _odp_term_local(ALL_INIT);
+}
+
+int _odp_term_local(enum init_stage stage)
+{
 	int rc = 0;
 	int rc_thd = 0;
 
-	if (odp_schedule_term_local()) {
-		ODP_ERR("ODP schedule local term failed.\n");
-		rc = -1;
-	}
-
-	if (odp_pool_term_local()) {
-		ODP_ERR("ODP buffer pool local term failed.\n");
-		rc = -1;
-	}
-
-	rc_thd = odp_thread_term_local();
-	if (rc_thd < 0) {
-		ODP_ERR("ODP thread local term failed.\n");
-		rc = -1;
-	} else {
-		if (!rc)
-			rc = rc_thd;
+	switch (stage) {
+	case ALL_INIT:
+
+	case SCHED_INIT:
+		if (odp_schedule_term_local()) {
+			ODP_ERR("ODP schedule local term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case POOL_INIT:
+		if (odp_pool_term_local()) {
+			ODP_ERR("ODP buffer pool local term failed.\n");
+			rc = -1;
+		}
+		/* Fall through */
+
+	case THREAD_INIT:
+		rc_thd = odp_thread_term_local();
+		if (rc_thd < 0) {
+			ODP_ERR("ODP thread local term failed.\n");
+			rc = -1;
+		} else {
+			if (!rc)
+				rc = rc_thd;
+		}
+		/* Fall through */
+
+	default:
+		break;
 	}
 
 	return rc;
diff --git a/platform/linux-generic/odp_system_info.c b/platform/linux-generic/odp_system_info.c
index 31df29e..f556ea2 100644
--- a/platform/linux-generic/odp_system_info.c
+++ b/platform/linux-generic/odp_system_info.c
@@ -370,6 +370,14 @@ int odp_system_info_init(void)
 }
 
 /*
+ * System info termination
+ */
+int odp_system_info_term(void)
+{
+	return 0;
+}
+
+/*
  *************************
  * Public access functions
  *************************
diff --git a/platform/linux-generic/odp_time.c b/platform/linux-generic/odp_time.c
index 2cb84f2..c5215e2 100644
--- a/platform/linux-generic/odp_time.c
+++ b/platform/linux-generic/odp_time.c
@@ -192,7 +192,7 @@ uint64_t odp_time_to_u64(odp_time_t time)
 	return time_to_ns(time) / resolution;
 }
 
-int odp_time_global_init(void)
+int odp_time_init_global(void)
 {
 	int ret;
 	_odp_time_t time;
@@ -202,3 +202,8 @@ int odp_time_global_init(void)
 
 	return ret;
 }
+
+int odp_time_term_global(void)
+{
+	return 0;
+}
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 5c1f8ca..0bb348f 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -894,3 +894,8 @@ int odp_timer_init_global(void)
 	odp_atomic_init_u32(&num_timer_pools, 0);
 	return 0;
 }
+
+int odp_timer_term_global(void)
+{
+	return 0;
+}
