Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) ISA Drivers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) ===========
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) The following text is adapted from the commit message of the initial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) commit of the ISA bus driver authored by Rene Herman.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) During the recent "isa drivers using platform devices" discussion it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) pointed out that (ALSA) ISA drivers ran into the problem of not having
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) the option to fail driver load (device registration rather) upon not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) finding their hardware due to a probe() error not being passed up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) through the driver model. In the course of that, I suggested a separate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) ISA bus might be best; Russell King agreed and suggested this bus could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) use the .match() method for the actual device discovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) The attached does this. For this old non (generically) discoverable ISA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) hardware only the driver itself can do discovery so as a difference with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) the platform_bus, this isa_bus also distributes match() up to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) As another difference: these devices only exist in the driver model due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) to the driver creating them because it might want to drive them, meaning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) that all device creation has been made internal as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) The usage model this provides is nice, and has been acked from the ALSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) side by Takashi Iwai and Jaroslav Kysela. The ALSA driver module_init's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) now (for oldisa-only drivers) become::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	static int __init alsa_card_foo_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		return isa_register_driver(&snd_foo_isa_driver, SNDRV_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	static void __exit alsa_card_foo_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		isa_unregister_driver(&snd_foo_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) Quite like the other bus models therefore. This removes a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) duplicated init code from the ALSA ISA drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) The passed in isa_driver struct is the regular driver struct embedding a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) struct device_driver, the normal probe/remove/shutdown/suspend/resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) callbacks, and as indicated that .match callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) The "SNDRV_CARDS" you see being passed in is a "unsigned int ndev"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) parameter, indicating how many devices to create and call our methods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) with.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) The platform_driver callbacks are called with a platform_device param;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) the isa_driver callbacks are being called with a ``struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) unsigned int id`` pair directly -- with the device creation completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) internal to the bus it's much cleaner to not leak isa_dev's by passing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) them in at all. The id is the only thing we ever want other then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) struct device anyways, and it makes for nicer code in the callbacks as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) With this additional .match() callback ISA drivers have all options. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) ALSA would want to keep the old non-load behaviour, it could stick all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) of the old .probe in .match, which would only keep them registered after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) everything was found to be present and accounted for. If it wanted the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) behaviour of always loading as it inadvertently did for a bit after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) changeover to platform devices, it could just not provide a .match() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) do everything in .probe() as before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) If it, as Takashi Iwai already suggested earlier as a way of following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) the model from saner buses more closely, wants to load when a later bind
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) could conceivably succeed, it could use .match() for the prerequisites
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) (such as checking the user wants the card enabled and that port/irq/dma
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) values have been passed in) and .probe() for everything else. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) the nicest model.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) To the code...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) This exports only two functions; isa_{,un}register_driver().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) isa_register_driver() register's the struct device_driver, and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) loops over the passed in ndev creating devices and registering them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) This causes the bus match method to be called for them, which is::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int isa_bus_match(struct device *dev, struct device_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		struct isa_driver *isa_driver = to_isa_driver(driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		if (dev->platform_data == isa_driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			if (!isa_driver->match ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				isa_driver->match(dev, to_isa_dev(dev)->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			dev->platform_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) The first thing this does is check if this device is in fact one of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) driver's devices by seeing if the device's platform_data pointer is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) to this driver. Platform devices compare strings, but we don't need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) do that with everything being internal, so isa_register_driver() abuses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) dev->platform_data as a isa_driver pointer which we can then check here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) I believe platform_data is available for this, but if rather not, moving
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) the isa_driver pointer to the private struct isa_dev is ofcourse fine as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) Then, if the the driver did not provide a .match, it matches. If it did,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) the driver match() method is called to determine a match.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) If it did **not** match, dev->platform_data is reset to indicate this to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) isa_register_driver which can then unregister the device again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) If during all this, there's any error, or no devices matched at all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) everything is backed out again and the error, or -ENODEV, is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) isa_unregister_driver() just unregisters the matched devices and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) driver itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) module_isa_driver is a helper macro for ISA drivers which do not do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) anything special in module init/exit. This eliminates a lot of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) boilerplate code. Each module may only use this macro once, and calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) it replaces module_init and module_exit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) max_num_isa_dev is a macro to determine the maximum possible number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ISA devices which may be registered in the I/O port address space given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) the address extent of the ISA devices.