Here, we'll focus on employing the RMW bitwise operators; we'll leave it to you to explore the others (refer to the kernel docs mentioned). So, let's think again about how to more efficiently code our pseudocode example. We can set (to 1) any given bit in any register or memory item using the set_bit() API:
void set_bit(unsigned int nr, volatile unsigned long *p);
This atomically – safely and indivisibly – sets the nrth bit of p to 1. (The reality is that the device registers (and possibly device memory) are mapped into kernel virtual address space and thus appear to be visible as though they are RAM locations – such as the address p here. This is called MMIO and is the common way by which driver authors map in and work with device memory. Again, we cover this in Linux Kernel Programming (Part 2))
Thus, with the RMW atomic operators, we can safely achieve what we've (incorrectly) attempted...