StartCoroutine fires once

The following snippet is inside a monobehavior. FadeOut() is called externally. For whatever reason, it only returns a value to the callback to the first time.

	public void FadeOut(Action<float> callback)
	{
		StartCoroutine(FadeOutC(callback));
	}
	
	private float _fadeOut = 1;
	private IEnumerator FadeOutC(Action<float> callback)
	{
		if(_fadeOut > 0)
		{
			yield return new WaitForEndOfFrame();
			
			var value = _fadeOut -= Time.deltaTime;
			callback(value);
			Debug.Log(_fadeOut);
		}
		else
		{
			callback(0);
			StopCoroutine("FadeOutC");
			_fadeOut = 1;
		}
	}

Change

if(_fadeOut > 0)

to

while(_fadeOut > 0)

and remove the StopCoroutine call. It will stop on its own or you can yield break if necessary.

Coroutines are just functions that run once and are able to be split up. Its up to you to make them continually call or to loop or w/e.

EDIT:
Agreed with erik5h5, replace your yield with a yield return null. This will return on the next frame.