Device driver code runs in the process which invoked the system calls. The kernel does not have an implicit "module lock" it locks before invoking module code. It is definitely possible for concurrent driver calls to happen when separate processes invoke system calls that end up in your driver code.
As you might expect, the kernel favors simplicity and performance over ease of implementation. It is up to you to grab the necessary spinlocks and semaphores when accessing shared state.
See Chapter 5 of Linux Device Drivers, which talks about concurrency and race conditions in great detail.
Concurrency and Its Management
In a modern Linux system, there are numerous sources of concurrency and, therefore, possible race conditions. Multiple user-space processes are running, and they can access your code in surprising combinations of ways. SMP systems can be executing your code simultaneously on different processors. Kernel code is preemptible; your driver’s code can lose the processor at any time, and the process that replaces it could also be running in your driver. Device interrupts are asynchronous events that can cause concurrent execution of your code. The kernel also provides various mechanisms for delayed code execution, such as workqueues, tasklets, and timers, which can cause your code to run at any time in ways unrelated to what the current process is doing. In the modern, hot-pluggable world, your device could simply disappear while you are in the middle of working with it.