Commit 76821aad authored by Arend van Spriel's avatar Arend van Spriel Committed by Kalle Valo
Browse files

wifi: brcmfmac: add function to unbind device to bus layer api



Introduce a new bus callback .remove() which will unbind the device
from the driver. This allows the common driver layer to stop handling
a device.

Reviewed-by: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20221129135446.151065-2-arend.vanspriel@broadcom.com
parent 5107778d
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/device.h>
#include "debug.h"

/* IDs of the 6 default common rings of msgbuf protocol */
@@ -74,6 +75,7 @@ struct brcmf_bus_dcmd {
 * @get_ramsize: obtain size of device memory.
 * @get_memdump: obtain device memory dump in provided buffer.
 * @get_blob: obtain a firmware blob.
 * @remove: initiate unbind of the device.
 *
 * This structure provides an abstract interface towards the
 * bus specific driver. For control messages to common driver
@@ -94,6 +96,7 @@ struct brcmf_bus_ops {
			enum brcmf_blob_type type);
	void (*debugfs_create)(struct device *dev);
	int (*reset)(struct device *dev);
	void (*remove)(struct device *dev);
};


@@ -257,6 +260,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
 */
+11 −1
Original line number Diff line number Diff line
@@ -4171,6 +4171,15 @@ static int brcmf_sdio_bus_reset(struct device *dev)
	return 0;
}

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,
@@ -4183,7 +4192,8 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
	.get_memdump = brcmf_sdio_bus_get_memdump,
	.get_blob = brcmf_sdio_get_blob,
	.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