As Stefan points out, some decisions were made in ChromiumOS to avoid modifying generic code and (in theory) make upstreaming easier. The writeprotect stuff is the main example. We can re-visit some of those decisions and put some code in generic locations if it makes sense to do so.
I don't like the idea of using a FEATURE_SR2 bit - It doesn't describe the functionality it represents in a useful manner IMO. As you point out, reading SR2 needlessly can slow things down, especially for the common use case where we only really care about reading the busy bit. For the write protection use case, the exact layout of the status registers needs to be taken into account, not just whether SR2 is present or not since SR2 is not as well standardized. To make matters more complicated, Gigadevice GD25Q128 even has a 3rd status register which has a bit that defines the entire write-protection scheme. Also, some chips such as Spansion S25FS and S25FL series don't use status registers in the same manner as other chips and instead define a set of control registers with special opcodes to read/write them.
Also, as Stefan points out, the status register bits are relevant to 4B addressing and quad I/O in addition to write protection. The implementation details are non-uniform.
Consequently, I think we need a combination of #2 and #3. For #2, we'll have functions which read the status registers (but must be careful since reading SR2 and SR3 aren't standardized AFAIK). For #3 we can describe the functionality we desire in a reasonably generic way and add chip-specific helper functions to carry out the task regardless of where the bits we are interested in reside. I started going in this direction for ChromiumOS's writeprotect.c, but it's still a work in progress: