b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
@@ -6,6 +6,7 @@
#ifndef BRCMFMAC_BUS_H
#define BRCMFMAC_BUS_H
+#include <linux/device.h>
#include "debug.h"
/* IDs of the 6 default common rings of msgbuf protocol */
@@ -61,6 +62,7 @@ struct brcmf_bus_dcmd {
* @get_ramsize: obtain size of device memory.
* @get_memdump: obtain device memory dump in provided buffer.
* @get_fwname: obtain firmware name.
+ * @remove: initiate unbind of the device.
*
* This structure provides an abstract interface towards the
* bus specific driver. For control messages to common driver
@@ -81,6 +83,7 @@ struct brcmf_bus_ops {
unsigned char *fw_name);
void (*debugfs_create)(struct device *dev);
int (*reset)(struct device *dev);
+ void (*remove)(struct device *dev);
};
@@ -244,6 +247,16 @@ int brcmf_bus_reset(struct brcmf_bus *bus)
return bus->ops->reset(bus->dev);
}
+static inline void brcmf_bus_remove(struct brcmf_bus *bus)
+{
+ if (!bus->ops->remove) {
+ device_release_driver(bus->dev);
+ return;
+ }
+
+ bus->ops->remove(bus->dev);
+}
+
/*
* interface functions from common layer
*/
b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4179,6 +4179,15 @@ static int brcmf_sdio_bus_reset(struct device *dev)
return ret;
}
+static void brcmf_sdio_bus_remove(struct device *dev)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio;
+
+ device_release_driver(&sdiod->func2->dev);
+ device_release_driver(&sdiod->func1->dev);
+}
+
static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.stop = brcmf_sdio_bus_stop,
.preinit = brcmf_sdio_bus_preinit,
@@ -4191,7 +4200,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
.get_memdump = brcmf_sdio_bus_get_memdump,
.get_fwname = brcmf_sdio_get_fwname,
.debugfs_create = brcmf_sdio_debugfs_create,
- .reset = brcmf_sdio_bus_reset
+ .reset = brcmf_sdio_bus_reset,
+ .remove = brcmf_sdio_bus_remove,
};
#define BRCMF_SDIO_FW_CODE 0