What kind of speed are you looking for? In general, smart interval-based solvers work well for this sort of thing: the core idea is that by using interval arithmetic you can bound the values of the 'potential function' (the quartic polynomial whose roots you're trying to find) within any given interval, and then fast-reject if those bounds don't contain zero - that is, if you can confirm that the function is always-positive or always-negative on the interval. Find starting values of tmin and tmax by intersecting your ray with the bounding box of the torus, use the interval arithmetic mentioned above to determine whether it's possible for an intersection to appear within that range, and then use binary subdivision (always exploring the 'earlier' - closer to the camera - branch of the subdivision first) to narrow in on the first zero to whatever accuracy is desired. In practice this isn't much slower than explicitly solving the quartic, and it tends to be more robust, particularly around tangent points/double zeroes.
One question I think it's worth asking, though: why are you trying to explicitly handle ray-torus intersection? Tori don't, in general, make very good primitives for composing a scene; they're too geometric and not particularly organic enough. IMHO you're much better off going the pile-of-triangles route and giving yourself more flexibility, rather than tying yourself too closely to complicated geometric primitives.