/**
 * @brief Decide whether a split in core affinity is required across job slots
 *
 * The following locking conditions are made on the caller:
 * - it must hold kbasep_js_device_data::runpool_irq::lock
 *
 * @param kbdev The kbase device structure of the device
 * @return MALI_FALSE if a core split is not required
 * @return != MALI_FALSE if a core split is required.
 */
STATIC INLINE mali_bool kbase_affinity_requires_split(kbase_device *kbdev)
{
	KBASE_DEBUG_ASSERT(kbdev != NULL);
	lockdep_assert_held(&kbdev->js_data.runpool_irq.lock);

	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_8987)) {
		s8 nr_compute_ctxs = kbasep_js_ctx_attr_count_on_runpool(kbdev, KBASEP_JS_CTX_ATTR_COMPUTE);
		s8 nr_noncompute_ctxs = kbasep_js_ctx_attr_count_on_runpool(kbdev, KBASEP_JS_CTX_ATTR_NON_COMPUTE);

		/* In this case, a mix of Compute+Non-Compute determines whether a
		 * core-split is required, to ensure jobs with different numbers of RMUs
		 * don't use the same cores.
		 *
		 * When it's entirely compute, or entirely non-compute, then no split is
		 * required.
		 *
		 * A context can be both Compute and Non-compute, in which case this will
		 * correctly decide that a core-split is required. */

		return (mali_bool) (nr_compute_ctxs > 0 && nr_noncompute_ctxs > 0);
	}
	return MALI_FALSE;
}
/*
 * Hold the runpool_mutex for this
 */
static inline bool timer_callback_should_run(struct kbase_device *kbdev)
{
	struct kbase_backend_data *backend = &kbdev->hwaccess.backend;
	s8 nr_running_ctxs;

	lockdep_assert_held(&kbdev->js_data.runpool_mutex);

	/* Timer must stop if we are suspending */
	if (backend->suspend_timer)
		return false;

	/* nr_contexts_pullable is updated with the runpool_mutex. However, the
	 * locking in the caller gives us a barrier that ensures
	 * nr_contexts_pullable is up-to-date for reading */
	nr_running_ctxs = atomic_read(&kbdev->js_data.nr_contexts_runnable);

#ifdef CONFIG_MALI_DEBUG
	if (kbdev->js_data.softstop_always) {
		/* Debug support for allowing soft-stop on a single context */
		return true;
	}
#endif				/* CONFIG_MALI_DEBUG */

	if (kbase_hw_has_issue(kbdev, BASE_HW_ISSUE_9435)) {
		/* Timeouts would have to be 4x longer (due to micro-
		 * architectural design) to support OpenCL conformance tests, so
		 * only run the timer when there's:
		 * - 2 or more CL contexts
		 * - 1 or more GLES contexts
		 *
		 * NOTE: We will treat a context that has both Compute and Non-
		 * Compute jobs will be treated as an OpenCL context (hence, we
		 * don't check KBASEP_JS_CTX_ATTR_NON_COMPUTE).
		 */
		{
			s8 nr_compute_ctxs =
				kbasep_js_ctx_attr_count_on_runpool(kbdev,
						KBASEP_JS_CTX_ATTR_COMPUTE);
			s8 nr_noncompute_ctxs = nr_running_ctxs -
							nr_compute_ctxs;

			return (bool) (nr_compute_ctxs >= 2 ||
							nr_noncompute_ctxs > 0);
		}
	} else {
		/* Run the timer callback whenever you have at least 1 context
		 */
		return (bool) (nr_running_ctxs > 0);
	}
}