Cook the bacon until crispy in a skillet over medium heat. Remove, chop and set aside. Drain grease from skillet, but don’t clean it out. Add the onion, garlic, salt and pepper to the skillet. Cook, stirring occasionally, until onions are soft and fragrant, approximately 3 minutes.
Transfer the onion mixture to a Dutch oven or heavy saucepan. Add the chicken stock and potatoes. Bring to a boil over medium-high heat. Reduce to a simmer and let cook for 10 minutes, or until the potatoes are tender. Use an immersion blender or potato masher to reduce chunkiness (this is optional).
Make the roux: Melt the butter over medium heat in the skillet the bacon was cooked in. Add the flour and whisk until combined. Add the milk and continue to whisk until the mixture is thick, approximately 3 minutes.
Transfer this mixture to the Dutch oven, along with the chopped bacon, ham and cheese. Stir until the cheese has melted and the soup is warmed through. Serve immediately and top with sour cream, extra cheese, bacon bits, ham and/or sliced green onions.