The state of each card (I / O address, IRQ, ...) is stored in a driver-specific structure, which is transmitted (directly or indirectly) to each driver entry point, which can thus distinguish cards, Thus, the same code can manage different cards (which means that yes, the kernel stores only one instance of the driver module, regardless of the number of devices it controls).
For example, look at drivers/video/backlight/platform_lcd.c , which is a very simple LCD power driver. It contains a structure called platform_lcd that is private to this file and retains the state of the LCD (regardless of whether the power is on and paused). One instance of this structure is allocated in the probe function via kzalloc , that is, one per LCD device, and stored in the platform device representing the LCD using platform_set_drvdata . The instance allocated for this device is then returned at the beginning of all other driver functions so that it knows which instance it is working on:
struct platform_lcd *plcd = to_our_lcd(lcd);
to_our_lcd expands to lcd_get_data , which itself extends to dev_get_drvdata (an analog of the dev_get_drvdata platform) if you look at include/linux/lcd.h Then the function can know what the state of the device was called for.
This is a very simple example, and the platform_lcd driver does not directly control any device (this is deferred to the function pointer in the platform data), but adds hardware parameters (IRQ, I / O base, etc.), and you will learn how 99% of drivers work on Linux.
source share