diff options
authorAwais Belal <awais_belal@mentor.com>2015-10-06 14:47:57 +0500
committerAwais Belal <awais_belal@mentor.com>2015-10-08 19:02:45 +0500
commit94086229476952a01a18b1645fe1bac25a410cb6 (patch)
parent5e29969ef2b848257482200a3295299bc140f948 (diff)
amd-spi: unregister spirom device on exit
The driver registers spirom device on init by using the spi_new_device call which acquires the chip select pin through board_info. If the driver does not unregister this device while exiting the chip select pin never frees and consequently a second modprobe for the device will fail with chip select already in use error. We now keep the device pointer for the device added through spi_new_device and make an unregister call on the same on driver's exit. Signed-off-by: Awais Belal <awais_belal@mentor.com>
1 files changed, 20 insertions, 3 deletions
diff --git a/meta-amdfalconx86/recipes-kernel/amd-spi/files/spirom.c b/meta-amdfalconx86/recipes-kernel/amd-spi/files/spirom.c
index dd3538be..14a76478 100644
--- a/meta-amdfalconx86/recipes-kernel/amd-spi/files/spirom.c
+++ b/meta-amdfalconx86/recipes-kernel/amd-spi/files/spirom.c
@@ -71,6 +71,17 @@ static DEFINE_MUTEX(device_list_lock);
+/* We need to keep the device pointer because we explicity add the device
+ * by using spi_new_device at the end of spirom_init. In order to confirm
+ * a clean exit we need to unregister the device while exiting.
+ * This cannot be done in the driver's remove call as that would generate
+ * a recursive loop.
+ */
+static struct spi_device *spirom_device;
* We can't use the standard synchronous wrappers for file I/O; we
* need to protect against async removal of the underlying spi_device.
@@ -345,7 +356,6 @@ static const struct file_operations spirom_fops = {
static int __init add_spi_device_to_bus(void)
struct spi_master *spi_master;
- struct spi_device *spi_device;
struct spi_board_info spi_info;
spi_master = spi_busnum_to_master(SPI_BUS);
@@ -360,13 +370,19 @@ static int __init add_spi_device_to_bus(void)
spi_info.bus_num = SPI_BUS; //Bus number of SPI master
spi_info.chip_select = SPI_BUS_CS1; //CS on which SPI device is connected
- spi_device = spi_new_device(spi_master, &spi_info);
- if (!spi_device)
+ spirom_device = spi_new_device(spi_master, &spi_info);
+ if (!spirom_device)
return -ENODEV;
return 0;
+static void remove_spi_device_from_bus(void)
+ if (spirom_device)
+ spi_unregister_device(spirom_device);
/* The main reason to have this class is to make mdev/udev create the
@@ -507,6 +523,7 @@ module_init(spirom_init);
static void __exit spirom_exit(void)
+ remove_spi_device_from_bus();
unregister_chrdev(SPIROM_MAJOR, spirom_spi.driver.name);