/*
 * Copyright (c) 2014 Redpine Signals Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <linux/module.h>
#include "rsi_sdio.h"
#include "rsi_common.h"
#include "rsi_coex.h"
#include "rsi_hal.h"

/* Default operating mode is wlan STA + BT */
static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL;
module_param(dev_oper_mode, ushort, 0444);
MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);

/**
 * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg.
 * @rw: Read/write
 * @func: function number
 * @raw: indicates whether to perform read after write
 * @address: address to which to read/write
 * @writedata: data to write
 *
 * Return: argument
 */
static u32 rsi_sdio_set_cmd52_arg(bool rw,
				  u8 func,
				  u8 raw,
				  u32 address,
				  u8 writedata)
{
	return ((rw & 1) << 31) | ((func & 0x7) << 28) |
		((raw & 1) << 27) | (1 << 26) |
		((address & 0x1FFFF) << 9) | (1 << 8) |
		(writedata & 0xFF);
}

/**
 * rsi_cmd52writebyte() - This function issues cmd52 byte write onto the card.
 * @card: Pointer to the mmc_card.
 * @address: Address to write.
 * @byte: Data to write.
 *
 * Return: Write status.
 */
static int rsi_cmd52writebyte(struct mmc_card *card,
			      u32 address,
			      u8 byte)
{
	struct mmc_command io_cmd;
	u32 arg;

	memset(&io_cmd, 0, sizeof(io_cmd));
	arg = rsi_sdio_set_cmd52_arg(1, 0, 0, address, byte);
	io_cmd.opcode = SD_IO_RW_DIRECT;
	io_cmd.arg = arg;
	io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;

	return mmc_wait_for_cmd(card->host, &io_cmd, 0);
}

/**
 * rsi_cmd52readbyte() - This function issues cmd52 byte read onto the card.
 * @card: Pointer to the mmc_card.
 * @address: Address to read from.
 * @byte: Variable to store read value.
 *
 * Return: Read status.
 */
static int rsi_cmd52readbyte(struct mmc_card *card,
			     u32 address,
			     u8 *byte)
{
	struct mmc_command io_cmd;
	u32 arg;
	int err;

	memset(&io_cmd, 0, sizeof(io_cmd));
	arg = rsi_sdio_set_cmd52_arg(0, 0, 0, address, 0);
	io_cmd.opcode = SD_IO_RW_DIRECT;
	io_cmd.arg = arg;
	io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;

	err = mmc_wait_for_cmd(card->host, &io_cmd, 0);
	if ((!err) && (byte))
		*byte =  io_cmd.resp[0] & 0xFF;
	return err;
}

/**
 * rsi_issue_sdiocommand() - This function issues sdio commands.
 * @func: Pointer to the sdio_func structure.
 * @opcode: Opcode value.
 * @arg: Arguments to pass.
 * @flags: Flags which are set.
 * @resp: Pointer to store response.
 *
 * Return: err: command status as 0 or -1.
 */
static int rsi_issue_sdiocommand(struct sdio_func *func,
				 u32 opcode,
				 u32 arg,
				 u32 flags,
				 u32 *resp)
{
	struct mmc_command cmd;
	struct mmc_host *host;
	int err;

	host = func->card->host;

	memset(&cmd, 0, sizeof(struct mmc_command));
	cmd.opcode = opcode;
	cmd.arg = arg;
	cmd.flags = flags;
	err = mmc_wait_for_cmd(host, &cmd, 3);

	if ((!err) && (resp))
		*resp = cmd.resp[0];

	return err;
}

/**
 * rsi_handle_interrupt() - This function is called upon the occurrence
 *			    of an interrupt.
 * @function: Pointer to the sdio_func structure.
 *
 * Return: None.
 */
static void rsi_handle_interrupt(struct sdio_func *function)
{
	struct rsi_hw *adapter = sdio_get_drvdata(function);
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;

	if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED)
		return;

	rsi_set_event(&dev->rx_thread.event);
}

/**
 * rsi_reset_card() - This function resets and re-initializes the card.
 * @pfunction: Pointer to the sdio_func structure.
 *
 * Return: None.
 */
static void rsi_reset_card(struct sdio_func *pfunction)
{
	int ret = 0;
	int err;
	struct mmc_card *card = pfunction->card;
	struct mmc_host *host = card->host;
	u8 cmd52_resp;
	u32 clock, resp, i;
	u16 rca;

	/* Reset 9110 chip */
	ret = rsi_cmd52writebyte(pfunction->card,
				 SDIO_CCCR_ABORT,
				 (1 << 3));

	/* Card will not send any response as it is getting reset immediately
	 * Hence expect a timeout status from host controller
	 */
	if (ret != -ETIMEDOUT)
		rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, ret);

	/* Wait for few milli seconds to get rid of residue charges if any */
	msleep(20);

	/* Initialize the SDIO card */
	host->ios.chip_select = MMC_CS_DONTCARE;
	host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
	host->ios.power_mode = MMC_POWER_UP;
	host->ios.bus_width = MMC_BUS_WIDTH_1;
	host->ios.timing = MMC_TIMING_LEGACY;
	host->ops->set_ios(host, &host->ios);

	/*
	 * This delay should be sufficient to allow the power supply
	 * to reach the minimum voltage.
	 */
	msleep(20);

	host->ios.clock = host->f_min;
	host->ios.power_mode = MMC_POWER_ON;
	host->ops->set_ios(host, &host->ios);

	/*
	 * This delay must be at least 74 clock sizes, or 1 ms, or the
	 * time required to reach a stable voltage.
	 */
	msleep(20);

	/* Issue CMD0. Goto idle state */
	host->ios.chip_select = MMC_CS_HIGH;
	host->ops->set_ios(host, &host->ios);
	msleep(20);
	err = rsi_issue_sdiocommand(pfunction,
				    MMC_GO_IDLE_STATE,
				    0,
				    (MMC_RSP_NONE | MMC_CMD_BC),
				    NULL);
	host->ios.chip_select = MMC_CS_DONTCARE;
	host->ops->set_ios(host, &host->ios);
	msleep(20);
	host->use_spi_crc = 0;

	if (err)
		rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);

	/* Issue CMD5, arg = 0 */
	err = rsi_issue_sdiocommand(pfunction,	SD_IO_SEND_OP_COND, 0,
				    (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
	if (err)
		rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
			__func__, err);
	card->ocr = resp;
	/* Issue CMD5, arg = ocr. Wait till card is ready  */
	for (i = 0; i < 100; i++) {
		err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND,
					    card->ocr,
					    (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
		if (err) {
			rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
				__func__, err);
			break;
		}

		if (resp & MMC_CARD_BUSY)
			break;
		msleep(20);
	}

	if ((i == 100) || (err)) {
		rsi_dbg(ERR_ZONE, "%s: card in not ready : %d %d\n",
			__func__, i, err);
		return;
	}

	/* Issue CMD3, get RCA */
	err = rsi_issue_sdiocommand(pfunction,
				    SD_SEND_RELATIVE_ADDR,
				    0,
				    (MMC_RSP_R6 | MMC_CMD_BCR),
				    &resp);
	if (err) {
		rsi_dbg(ERR_ZONE, "%s: CMD3 failed : %d\n", __func__, err);
		return;
	}
	rca = resp >> 16;
	host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
	host->ops->set_ios(host, &host->ios);

	/* Issue CMD7, select card  */
	err = rsi_issue_sdiocommand(pfunction,
				    MMC_SELECT_CARD,
				    (rca << 16),
				    (MMC_RSP_R1 | MMC_CMD_AC),
				    NULL);
	if (err) {
		rsi_dbg(ERR_ZONE, "%s: CMD7 failed : %d\n", __func__, err);
		return;
	}

	/* Enable high speed */
	if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
		rsi_dbg(ERR_ZONE, "%s: Set high speed mode\n", __func__);
		err = rsi_cmd52readbyte(card, SDIO_CCCR_SPEED, &cmd52_resp);
		if (err) {
			rsi_dbg(ERR_ZONE, "%s: CCCR speed reg read failed: %d\n",
				__func__, err);
		} else {
			err = rsi_cmd52writebyte(card,
						 SDIO_CCCR_SPEED,
						 (cmd52_resp | SDIO_SPEED_EHS));
			if (err) {
				rsi_dbg(ERR_ZONE,
					"%s: CCR speed regwrite failed %d\n",
					__func__, err);
				return;
			}
			host->ios.timing = MMC_TIMING_SD_HS;
			host->ops->set_ios(host, &host->ios);
		}
	}

	/* Set clock */
	if (mmc_card_hs(card))
		clock = 50000000;
	else
		clock = card->cis.max_dtr;

	if (clock > host->f_max)
		clock = host->f_max;

	host->ios.clock = clock;
	host->ops->set_ios(host, &host->ios);

	if (card->host->caps & MMC_CAP_4_BIT_DATA) {
		/* CMD52: Set bus width & disable card detect resistor */
		err = rsi_cmd52writebyte(card,
					 SDIO_CCCR_IF,
					 (SDIO_BUS_CD_DISABLE |
					  SDIO_BUS_WIDTH_4BIT));
		if (err) {
			rsi_dbg(ERR_ZONE, "%s: Set bus mode failed : %d\n",
				__func__, err);
			return;
		}
		host->ios.bus_width = MMC_BUS_WIDTH_4;
		host->ops->set_ios(host, &host->ios);
	}
}

/**
 * rsi_setclock() - This function sets the clock frequency.
 * @adapter: Pointer to the adapter structure.
 * @freq: Clock frequency.
 *
 * Return: None.
 */
static void rsi_setclock(struct rsi_hw *adapter, u32 freq)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	struct mmc_host *host = dev->pfunction->card->host;
	u32 clock;

	clock = freq * 1000;
	if (clock > host->f_max)
		clock = host->f_max;
	host->ios.clock = clock;
	host->ops->set_ios(host, &host->ios);
}

/**
 * rsi_setblocklength() - This function sets the host block length.
 * @adapter: Pointer to the adapter structure.
 * @length: Block length to be set.
 *
 * Return: status: 0 on success, -1 on failure.
 */
static int rsi_setblocklength(struct rsi_hw *adapter, u32 length)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	int status;
	rsi_dbg(INIT_ZONE, "%s: Setting the block length\n", __func__);

	status = sdio_set_block_size(dev->pfunction, length);
	dev->pfunction->max_blksize = 256;
	adapter->block_size = dev->pfunction->max_blksize;

	rsi_dbg(INFO_ZONE,
		"%s: Operational blk length is %d\n", __func__, length);
	return status;
}

/**
 * rsi_setupcard() - This function queries and sets the card's features.
 * @adapter: Pointer to the adapter structure.
 *
 * Return: status: 0 on success, -1 on failure.
 */
static int rsi_setupcard(struct rsi_hw *adapter)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	int status = 0;

	rsi_setclock(adapter, 50000);

	dev->tx_blk_size = 256;
	status = rsi_setblocklength(adapter, dev->tx_blk_size);
	if (status)
		rsi_dbg(ERR_ZONE,
			"%s: Unable to set block length\n", __func__);
	return status;
}

/**
 * rsi_sdio_read_register() - This function reads one byte of information
 *			      from a register.
 * @adapter: Pointer to the adapter structure.
 * @addr: Address of the register.
 * @data: Pointer to the data that stores the data read.
 *
 * Return: 0 on success, -1 on failure.
 */
int rsi_sdio_read_register(struct rsi_hw *adapter,
			   u32 addr,
			   u8 *data)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u8 fun_num = 0;
	int status;

	if (likely(dev->sdio_irq_task != current))
		sdio_claim_host(dev->pfunction);

	if (fun_num == 0)
		*data = sdio_f0_readb(dev->pfunction, addr, &status);
	else
		*data = sdio_readb(dev->pfunction, addr, &status);

	if (likely(dev->sdio_irq_task != current))
		sdio_release_host(dev->pfunction);

	return status;
}

/**
 * rsi_sdio_write_register() - This function writes one byte of information
 *			       into a register.
 * @adapter: Pointer to the adapter structure.
 * @function: Function Number.
 * @addr: Address of the register.
 * @data: Pointer to the data tha has to be written.
 *
 * Return: 0 on success, -1 on failure.
 */
int rsi_sdio_write_register(struct rsi_hw *adapter,
			    u8 function,
			    u32 addr,
			    u8 *data)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	int status = 0;

	if (likely(dev->sdio_irq_task != current))
		sdio_claim_host(dev->pfunction);

	if (function == 0)
		sdio_f0_writeb(dev->pfunction, *data, addr, &status);
	else
		sdio_writeb(dev->pfunction, *data, addr, &status);

	if (likely(dev->sdio_irq_task != current))
		sdio_release_host(dev->pfunction);

	return status;
}

/**
 * rsi_sdio_ack_intr() - This function acks the interrupt received.
 * @adapter: Pointer to the adapter structure.
 * @int_bit: Interrupt bit to write into register.
 *
 * Return: None.
 */
void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit)
{
	int status;
	status = rsi_sdio_write_register(adapter,
					 1,
					 (SDIO_FUN1_INTR_CLR_REG |
					  RSI_SD_REQUEST_MASTER),
					 &int_bit);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__);
}



/**
 * rsi_sdio_read_register_multiple() - This function read multiple bytes of
 *				       information from the SD card.
 * @adapter: Pointer to the adapter structure.
 * @addr: Address of the register.
 * @count: Number of multiple bytes to be read.
 * @data: Pointer to the read data.
 *
 * Return: 0 on success, -1 on failure.
 */
static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
					   u32 addr,
					   u8 *data,
					   u16 count)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u32 status;

	if (likely(dev->sdio_irq_task != current))
		sdio_claim_host(dev->pfunction);

	status =  sdio_readsb(dev->pfunction, data, addr, count);

	if (likely(dev->sdio_irq_task != current))
		sdio_release_host(dev->pfunction);

	if (status != 0)
		rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 read failed\n", __func__);
	return status;
}

/**
 * rsi_sdio_write_register_multiple() - This function writes multiple bytes of
 *					information to the SD card.
 * @adapter: Pointer to the adapter structure.
 * @addr: Address of the register.
 * @data: Pointer to the data that has to be written.
 * @count: Number of multiple bytes to be written.
 *
 * Return: 0 on success, -1 on failure.
 */
int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
				     u32 addr,
				     u8 *data,
				     u16 count)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	int status;

	if (dev->write_fail > 1) {
		rsi_dbg(ERR_ZONE, "%s: Stopping card writes\n", __func__);
		return 0;
	} else if (dev->write_fail == 1) {
		/**
		 * Assuming it is a CRC failure, we want to allow another
		 *  card write
		 */
		rsi_dbg(ERR_ZONE, "%s: Continue card writes\n", __func__);
		dev->write_fail++;
	}

	if (likely(dev->sdio_irq_task != current))
		sdio_claim_host(dev->pfunction);

	status = sdio_writesb(dev->pfunction, addr, data, count);

	if (likely(dev->sdio_irq_task != current))
		sdio_release_host(dev->pfunction);

	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 write failed %d\n",
			__func__, status);
		dev->write_fail = 2;
	} else {
		memcpy(dev->prev_desc, data, FRAME_DESC_SZ);
	}
	return status;
}

static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
					   u32 base_address,
					   u32 instructions_sz,
					   u16 block_size,
					   u8 *ta_firmware)
{
	u32 num_blocks, offset, i;
	u16 msb_address, lsb_address;
	u8 *temp_buf;
	int status;

	num_blocks = instructions_sz / block_size;
	msb_address = base_address >> 16;

	rsi_dbg(INFO_ZONE, "ins_size: %d, num_blocks: %d\n",
		instructions_sz, num_blocks);

	temp_buf = kmalloc(block_size, GFP_KERNEL);
	if (!temp_buf)
		return -ENOMEM;

	/* Loading DM ms word in the sdio slave */
	status = rsi_sdio_master_access_msword(adapter, msb_address);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
		goto out_free;
	}

	for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) {
		memcpy(temp_buf, ta_firmware + offset, block_size);
		lsb_address = (u16)base_address;
		status = rsi_sdio_write_register_multiple
					(adapter,
					 lsb_address | RSI_SD_REQUEST_MASTER,
					 temp_buf, block_size);
		if (status < 0) {
			rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__);
			goto out_free;
		}
		rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i);
		base_address += block_size;

		if ((base_address >> 16) != msb_address) {
			msb_address += 1;

			/* Loading DM ms word in the sdio slave */
			status = rsi_sdio_master_access_msword(adapter,
							       msb_address);
			if (status < 0) {
				rsi_dbg(ERR_ZONE,
					"%s: Unable to set ms word reg\n",
					__func__);
				goto out_free;
			}
		}
	}

	if (instructions_sz % block_size) {
		memset(temp_buf, 0, block_size);
		memcpy(temp_buf, ta_firmware + offset,
		       instructions_sz % block_size);
		lsb_address = (u16)base_address;
		status = rsi_sdio_write_register_multiple
					(adapter,
					 lsb_address | RSI_SD_REQUEST_MASTER,
					 temp_buf,
					 instructions_sz % block_size);
		if (status < 0)
			goto out_free;
		rsi_dbg(INFO_ZONE,
			"Written Last Block in Address 0x%x Successfully\n",
			offset | RSI_SD_REQUEST_MASTER);
	}

	status = 0;
out_free:
	kfree(temp_buf);
	return status;
}

#define FLASH_SIZE_ADDR                 0x04000016
static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
				    u32 *read_buf, u16 size)
{
	u32 addr_on_bus, *data;
	u16 ms_addr;
	int status;

	data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	ms_addr = (addr >> 16);
	status = rsi_sdio_master_access_msword(adapter, ms_addr);
	if (status < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to set ms word to common reg\n",
			__func__);
		goto err;
	}
	addr &= 0xFFFF;

	addr_on_bus = (addr & 0xFF000000);
	if ((addr_on_bus == (FLASH_SIZE_ADDR & 0xFF000000)) ||
	    (addr_on_bus == 0x0))
		addr_on_bus = (addr & ~(0x3));
	else
		addr_on_bus = addr;

	/* Bring TA out of reset */
	status = rsi_sdio_read_register_multiple
					(adapter,
					 (addr_on_bus | RSI_SD_REQUEST_MASTER),
					 (u8 *)data, 4);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
		goto err;
	}
	if (size == 2) {
		if ((addr & 0x3) == 0)
			*read_buf = *data;
		else
			*read_buf  = (*data >> 16);
		*read_buf = (*read_buf & 0xFFFF);
	} else if (size == 1) {
		if ((addr & 0x3) == 0)
			*read_buf = *data;
		else if ((addr & 0x3) == 1)
			*read_buf = (*data >> 8);
		else if ((addr & 0x3) == 2)
			*read_buf = (*data >> 16);
		else
			*read_buf = (*data >> 24);
		*read_buf = (*read_buf & 0xFF);
	} else {
		*read_buf = *data;
	}

err:
	kfree(data);
	return status;
}

static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
				     unsigned long addr,
				     unsigned long data, u16 size)
{
	unsigned long *data_aligned;
	int status;

	data_aligned = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
	if (!data_aligned)
		return -ENOMEM;

	if (size == 2) {
		*data_aligned = ((data << 16) | (data & 0xFFFF));
	} else if (size == 1) {
		u32 temp_data = data & 0xFF;

		*data_aligned = ((temp_data << 24) | (temp_data << 16) |
				 (temp_data << 8) | temp_data);
	} else {
		*data_aligned = data;
	}
	size = 4;

	status = rsi_sdio_master_access_msword(adapter, (addr >> 16));
	if (status < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to set ms word to common reg\n",
			__func__);
		kfree(data_aligned);
		return -EIO;
	}
	addr = addr & 0xFFFF;

	/* Bring TA out of reset */
	status = rsi_sdio_write_register_multiple
					(adapter,
					 (addr | RSI_SD_REQUEST_MASTER),
					 (u8 *)data_aligned, size);
	if (status < 0)
		rsi_dbg(ERR_ZONE,
			"%s: Unable to do AHB reg write\n", __func__);

	kfree(data_aligned);
	return status;
}

/**
 * rsi_sdio_host_intf_write_pkt() - This function writes the packet to device.
 * @adapter: Pointer to the adapter structure.
 * @pkt: Pointer to the data to be written on to the device.
 * @len: length of the data to be written on to the device.
 *
 * Return: 0 on success, -1 on failure.
 */
static int rsi_sdio_host_intf_write_pkt(struct rsi_hw *adapter,
					u8 *pkt,
					u32 len)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	u32 block_size = dev->tx_blk_size;
	u32 num_blocks, address, length;
	u32 queueno;
	int status;

	queueno = ((pkt[1] >> 4) & 0xf);
	if (queueno == RSI_BT_MGMT_Q || queueno == RSI_BT_DATA_Q)
		queueno = RSI_BT_Q;

	num_blocks = len / block_size;

	if (len % block_size)
		num_blocks++;

	address = (num_blocks * block_size | (queueno << 12));
	length  = num_blocks * block_size;

	status = rsi_sdio_write_register_multiple(adapter,
						  address,
						  (u8 *)pkt,
						  length);
	if (status)
		rsi_dbg(ERR_ZONE, "%s: Unable to write onto the card: %d\n",
			__func__, status);
	rsi_dbg(DATA_TX_ZONE, "%s: Successfully written onto card\n", __func__);
	return status;
}

/**
 * rsi_sdio_host_intf_read_pkt() - This function reads the packet
 *				   from the device.
 * @adapter: Pointer to the adapter data structure.
 * @pkt: Pointer to the packet data to be read from the the device.
 * @length: Length of the data to be read from the device.
 *
 * Return: 0 on success, -1 on failure.
 */
int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter,
				u8 *pkt,
				u32 length)
{
	int status = -EINVAL;

	if (!length) {
		rsi_dbg(ERR_ZONE, "%s: Pkt size is zero\n", __func__);
		return status;
	}

	status = rsi_sdio_read_register_multiple(adapter,
						 length,
						 (u8 *)pkt,
						 length); /*num of bytes*/

	if (status)
		rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__,
			status);
	return status;
}

/**
 * rsi_init_sdio_interface() - This function does init specific to SDIO.
 *
 * @adapter: Pointer to the adapter data structure.
 * @pfunction: Pointer to the sdio_func structure.
 *
 * Return: 0 on success, -1 on failure.
 */
static int rsi_init_sdio_interface(struct rsi_hw *adapter,
				   struct sdio_func *pfunction)
{
	struct rsi_91x_sdiodev *rsi_91x_dev;
	int status;

	rsi_91x_dev = kzalloc(sizeof(*rsi_91x_dev), GFP_KERNEL);
	if (!rsi_91x_dev)
		return -ENOMEM;

	adapter->rsi_dev = rsi_91x_dev;

	sdio_claim_host(pfunction);

	pfunction->enable_timeout = 100;
	status = sdio_enable_func(pfunction);
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Failed to enable interface\n", __func__);
		sdio_release_host(pfunction);
		return status;
	}

	rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);

	rsi_91x_dev->pfunction = pfunction;
	adapter->device = &pfunction->dev;

	sdio_set_drvdata(pfunction, adapter);

	status = rsi_setupcard(adapter);
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Failed to setup card\n", __func__);
		goto fail;
	}

	rsi_dbg(INIT_ZONE, "%s: Setup card successfully\n", __func__);

	status = rsi_init_sdio_slave_regs(adapter);
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Failed to init slave regs\n", __func__);
		goto fail;
	}
	sdio_release_host(pfunction);

	adapter->determine_event_timeout = rsi_sdio_determine_event_timeout;
	adapter->check_hw_queue_status = rsi_sdio_check_buffer_status;

#ifdef CONFIG_RSI_DEBUGFS
	adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES;
#endif
	return 0;
fail:
	sdio_disable_func(pfunction);
	sdio_release_host(pfunction);
	return status;
}

static int rsi_sdio_reinit_device(struct rsi_hw *adapter)
{
	struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
	struct sdio_func *pfunction = sdev->pfunction;
	int ii;

	for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
		skb_queue_purge(&adapter->priv->tx_queue[ii]);

	/* Initialize device again */
	sdio_claim_host(pfunction);

	sdio_release_irq(pfunction);
	rsi_reset_card(pfunction);

	sdio_enable_func(pfunction);
	rsi_setupcard(adapter);
	rsi_init_sdio_slave_regs(adapter);
	sdio_claim_irq(pfunction, rsi_handle_interrupt);
	rsi_hal_device_init(adapter);

	sdio_release_host(pfunction);

	return 0;
}

static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
{
	int status;
	u32 addr;
	u8 *data;

	data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR);
	if (status < 0) {
		rsi_dbg(ERR_ZONE,
			"Unable to set ms word to common reg\n");
		goto err;
	}

	rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
	put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
	addr = TA_HOLD_THREAD_REG | RSI_SD_REQUEST_MASTER;
	status = rsi_sdio_write_register_multiple(adapter, addr,
						  (u8 *)data,
						  RSI_9116_REG_SIZE);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n");
		goto err;
	}

	put_unaligned_le32(TA_SOFT_RST_CLR, data);
	addr = TA_SOFT_RESET_REG | RSI_SD_REQUEST_MASTER;
	status = rsi_sdio_write_register_multiple(adapter, addr,
						  (u8 *)data,
						  RSI_9116_REG_SIZE);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n");
		goto err;
	}

	put_unaligned_le32(TA_PC_ZERO, data);
	addr = TA_TH0_PC_REG | RSI_SD_REQUEST_MASTER;
	status = rsi_sdio_write_register_multiple(adapter, addr,
						  (u8 *)data,
						  RSI_9116_REG_SIZE);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
		status = -EINVAL;
		goto err;
	}

	put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
	addr = TA_RELEASE_THREAD_REG | RSI_SD_REQUEST_MASTER;
	status = rsi_sdio_write_register_multiple(adapter, addr,
						  (u8 *)data,
						  RSI_9116_REG_SIZE);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "Unable to release TA threads\n");
		goto err;
	}

	status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR);
	if (status < 0) {
		rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n");
		goto err;
	}
	rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");

err:
	kfree(data);
	return status;
}

static struct rsi_host_intf_ops sdio_host_intf_ops = {
	.write_pkt		= rsi_sdio_host_intf_write_pkt,
	.read_pkt		= rsi_sdio_host_intf_read_pkt,
	.master_access_msword	= rsi_sdio_master_access_msword,
	.read_reg_multiple	= rsi_sdio_read_register_multiple,
	.write_reg_multiple	= rsi_sdio_write_register_multiple,
	.master_reg_read	= rsi_sdio_master_reg_read,
	.master_reg_write	= rsi_sdio_master_reg_write,
	.load_data_master_write	= rsi_sdio_load_data_master_write,
	.reinit_device          = rsi_sdio_reinit_device,
	.ta_reset		= rsi_sdio_ta_reset,
};

/**
 * rsi_probe() - This function is called by kernel when the driver provided
 *		 Vendor and device IDs are matched. All the initialization
 *		 work is done here.
 * @pfunction: Pointer to the sdio_func structure.
 * @id: Pointer to sdio_device_id structure.
 *
 * Return: 0 on success, 1 on failure.
 */
static int rsi_probe(struct sdio_func *pfunction,
		     const struct sdio_device_id *id)
{
	struct rsi_hw *adapter;
	struct rsi_91x_sdiodev *sdev;
	int status = -EINVAL;

	rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);

	adapter = rsi_91x_init(dev_oper_mode);
	if (!adapter) {
		rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
			__func__);
		return -EINVAL;
	}
	adapter->rsi_host_intf = RSI_HOST_INTF_SDIO;
	adapter->host_intf_ops = &sdio_host_intf_ops;

	if (rsi_init_sdio_interface(adapter, pfunction)) {
		rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n",
			__func__);
		status = -EIO;
		goto fail_free_adapter;
	}

	if (pfunction->device == SDIO_DEVICE_ID_RSI_9113) {
		rsi_dbg(ERR_ZONE, "%s: 9113 module detected\n", __func__);
		adapter->device_model = RSI_DEV_9113;
	} else  if (pfunction->device == SDIO_DEVICE_ID_RSI_9116) {
		rsi_dbg(ERR_ZONE, "%s: 9116 module detected\n", __func__);
		adapter->device_model = RSI_DEV_9116;
	} else {
		rsi_dbg(ERR_ZONE,
			"%s: Unsupported RSI device id 0x%x\n", __func__,
			pfunction->device);
		goto fail_free_adapter;
	}

	sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
	rsi_init_event(&sdev->rx_thread.event);
	status = rsi_create_kthread(adapter->priv, &sdev->rx_thread,
				    rsi_sdio_rx_thread, "SDIO-RX-Thread");
	if (status) {
		rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
		goto fail_kill_thread;
	}

	sdio_claim_host(pfunction);
	if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
		rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
		sdio_release_host(pfunction);
		status = -EIO;
		goto fail_claim_irq;
	}
	sdio_release_host(pfunction);
	rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);

	if (rsi_hal_device_init(adapter)) {
		rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
		status = -EINVAL;
		goto fail_dev_init;
	}
	rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");

	if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) {
		rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
		status = -EIO;
		goto fail_dev_init;
	}

	adapter->priv->hibernate_resume = false;
	adapter->priv->reinit_hw = false;
	return 0;

fail_dev_init:
	sdio_claim_host(pfunction);
	sdio_release_irq(pfunction);
	sdio_release_host(pfunction);
fail_claim_irq:
	rsi_kill_thread(&sdev->rx_thread);
fail_kill_thread:
	sdio_claim_host(pfunction);
	sdio_disable_func(pfunction);
	sdio_release_host(pfunction);
fail_free_adapter:
	rsi_91x_deinit(adapter);
	rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
	return status;
}

static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
			   u16 len_in_bits)
{
	rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG1,
				  ((addr << 6) | ((data >> 16) & 0xffff)), 2);
	rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG0,
				  (data & 0xffff), 2);
	rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG0,
				  RSI_GSPI_CTRL_REG0_VALUE, 2);
	rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG1,
				  ((len_in_bits - 1) | RSI_GSPI_TRIG), 2);
	msleep(20);
}

/*This function resets and re-initializes the chip.*/
static void rsi_reset_chip(struct rsi_hw *adapter)
{
	u8 *data;
	u8 sdio_interrupt_status = 0;
	u8 request = 1;
	int ret;

	data = kzalloc(sizeof(u32), GFP_KERNEL);
	if (!data)
		return;

	rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
	ret =  rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write SDIO wakeup register\n", __func__);
		goto err;
	}
	msleep(20);
	ret =  rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
				      &sdio_interrupt_status);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
			__func__);
		goto err;
	}
	rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d\n",
		__func__, sdio_interrupt_status);

	/* Put Thread-Arch processor on hold */
	if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to set ms word to common reg\n",
			__func__);
		goto err;
	}

	put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
	if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
					     RSI_SD_REQUEST_MASTER,
					     data, 4)) {
		rsi_dbg(ERR_ZONE,
			"%s: Unable to hold Thread-Arch processor threads\n",
			__func__);
		goto err;
	}

	/* This msleep will ensure Thread-Arch processor to go to hold
	 * and any pending dma transfers to rf spi in device to finish.
	 */
	msleep(100);
	if (adapter->device_model != RSI_DEV_9116) {
		ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32);
		ulp_read_write(adapter,
			       RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32);
		ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0,
			       32);
		ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1,
			       RSI_ULP_WRITE_50, 32);
		ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2,
			       RSI_ULP_WRITE_0, 32);
		ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE,
			       RSI_ULP_TIMER_ENABLE, 32);
	} else {
		if ((rsi_sdio_master_reg_write(adapter,
					       NWP_WWD_INTERRUPT_TIMER,
					       NWP_WWD_INT_TIMER_CLKS,
					       RSI_9116_REG_SIZE)) < 0) {
			rsi_dbg(ERR_ZONE, "Failed to write to intr timer\n");
		}
		if ((rsi_sdio_master_reg_write(adapter,
					       NWP_WWD_SYSTEM_RESET_TIMER,
					       NWP_WWD_SYS_RESET_TIMER_CLKS,
					       RSI_9116_REG_SIZE)) < 0) {
			rsi_dbg(ERR_ZONE,
				"Failed to write to system reset timer\n");
		}
		if ((rsi_sdio_master_reg_write(adapter,
					       NWP_WWD_MODE_AND_RSTART,
					       NWP_WWD_TIMER_DISABLE,
					       RSI_9116_REG_SIZE)) < 0) {
			rsi_dbg(ERR_ZONE,
				"Failed to write to mode and restart\n");
		}
		rsi_dbg(ERR_ZONE, "***** Watch Dog Reset Successful *****\n");
	}
	/* This msleep will be sufficient for the ulp
	 * read write operations to complete for chip reset.
	 */
	msleep(500);
err:
	kfree(data);
	return;
}

/**
 * rsi_disconnect() - This function performs the reverse of the probe function.
 * @pfunction: Pointer to the sdio_func structure.
 *
 * Return: void.
 */
static void rsi_disconnect(struct sdio_func *pfunction)
{
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_91x_sdiodev *dev;

	if (!adapter)
		return;

	dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;

	rsi_kill_thread(&dev->rx_thread);
	sdio_claim_host(pfunction);
	sdio_release_irq(pfunction);
	sdio_release_host(pfunction);
	mdelay(10);

	rsi_mac80211_detach(adapter);
	mdelay(10);

	if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
	    adapter->priv->bt_adapter) {
		rsi_bt_ops.detach(adapter->priv->bt_adapter);
		adapter->priv->bt_adapter = NULL;
	}

	/* Reset Chip */
	rsi_reset_chip(adapter);

	/* Resetting to take care of the case, where-in driver is re-loaded */
	sdio_claim_host(pfunction);
	rsi_reset_card(pfunction);
	sdio_disable_func(pfunction);
	sdio_release_host(pfunction);
	dev->write_fail = 2;
	rsi_91x_deinit(adapter);
	rsi_dbg(ERR_ZONE, "##### RSI SDIO device disconnected #####\n");

}

#ifdef CONFIG_PM
static int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
{
	struct rsi_91x_sdiodev *dev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	struct sdio_func *func = dev->pfunction;
	int ret;

	ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
	if (ret)
		rsi_dbg(ERR_ZONE, "Set sdio keep pwr flag failed: %d\n", ret);

	return ret;
}

static int rsi_sdio_disable_interrupts(struct sdio_func *pfunc)
{
	struct rsi_hw *adapter = sdio_get_drvdata(pfunc);
	u8 isr_status = 0, data = 0;
	int ret;
	unsigned long t1;

	rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
	t1 = jiffies;
	do {
		rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
				       &isr_status);
		rsi_dbg(INFO_ZONE, ".");
	} while ((isr_status) && (jiffies_to_msecs(jiffies - t1) < 20));
	rsi_dbg(INFO_ZONE, "Interrupts cleared\n");

	sdio_claim_host(pfunc);
	ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to read int enable register\n",
			__func__);
		goto done;
	}

	data &= RSI_INT_ENABLE_MASK;
	ret = rsi_cmd52writebyte(pfunc->card, RSI_INT_ENABLE_REGISTER, data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write to int enable register\n",
			__func__);
		goto done;
	}
	ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to read int enable register\n",
			__func__);
		goto done;
	}
	rsi_dbg(INFO_ZONE, "int enable reg content = %x\n", data);

done:
	sdio_release_host(pfunc);
	return ret;
}

static int rsi_sdio_enable_interrupts(struct sdio_func *pfunc)
{
	u8 data;
	int ret;
	struct rsi_hw *adapter = sdio_get_drvdata(pfunc);
	struct rsi_common *common = adapter->priv;

	sdio_claim_host(pfunc);
	ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to read int enable register\n", __func__);
		goto done;
	}

	data |= ~RSI_INT_ENABLE_MASK & 0xff;

	ret = rsi_cmd52writebyte(pfunc->card, RSI_INT_ENABLE_REGISTER, data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to write to int enable register\n",
			__func__);
		goto done;
	}

	if ((common->wow_flags & RSI_WOW_ENABLED) &&
	    (common->wow_flags & RSI_WOW_NO_CONNECTION))
		rsi_dbg(ERR_ZONE,
			"##### Device can not wake up through WLAN\n");

	ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
	if (ret < 0) {
		rsi_dbg(ERR_ZONE,
			"%s: Failed to read int enable register\n", __func__);
		goto done;
	}
	rsi_dbg(INFO_ZONE, "int enable reg content = %x\n", data);

done:
	sdio_release_host(pfunc);
	return ret;
}

static int rsi_suspend(struct device *dev)
{
	int ret;
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_common *common;

	if (!adapter) {
		rsi_dbg(ERR_ZONE, "Device is not ready\n");
		return -ENODEV;
	}
	common = adapter->priv;
	rsi_sdio_disable_interrupts(pfunction);

	ret = rsi_set_sdio_pm_caps(adapter);
	if (ret)
		rsi_dbg(INFO_ZONE,
			"Setting power management caps failed\n");
	common->fsm_state = FSM_CARD_NOT_READY;

	return 0;
}

static int rsi_resume(struct device *dev)
{
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_common *common = adapter->priv;

	common->fsm_state = FSM_MAC_INIT_DONE;
	rsi_sdio_enable_interrupts(pfunction);

	return 0;
}

static int rsi_freeze(struct device *dev)
{
	int ret;
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_common *common;
	struct rsi_91x_sdiodev *sdev;

	rsi_dbg(INFO_ZONE, "SDIO Bus freeze ===>\n");

	if (!adapter) {
		rsi_dbg(ERR_ZONE, "Device is not ready\n");
		return -ENODEV;
	}
	common = adapter->priv;
	sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;

	if ((common->wow_flags & RSI_WOW_ENABLED) &&
	    (common->wow_flags & RSI_WOW_NO_CONNECTION))
		rsi_dbg(ERR_ZONE,
			"##### Device can not wake up through WLAN\n");

	if (IS_ENABLED(CONFIG_RSI_COEX) && common->coex_mode > 1 &&
	    common->bt_adapter) {
		rsi_bt_ops.detach(common->bt_adapter);
		common->bt_adapter = NULL;
	}

	ret = rsi_sdio_disable_interrupts(pfunction);

	if (sdev->write_fail)
		rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");

	ret = rsi_set_sdio_pm_caps(adapter);
	if (ret)
		rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");

	rsi_dbg(INFO_ZONE, "***** RSI module freezed *****\n");

	return 0;
}

static int rsi_thaw(struct device *dev)
{
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_common *common = adapter->priv;

	rsi_dbg(ERR_ZONE, "SDIO Bus thaw =====>\n");

	common->hibernate_resume = true;
	common->fsm_state = FSM_CARD_NOT_READY;
	common->iface_down = true;

	rsi_sdio_enable_interrupts(pfunction);

	rsi_dbg(INFO_ZONE, "***** RSI module thaw done *****\n");

	return 0;
}

static void rsi_shutdown(struct device *dev)
{
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_91x_sdiodev *sdev =
		(struct rsi_91x_sdiodev *)adapter->rsi_dev;
	struct ieee80211_hw *hw = adapter->hw;

	rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");

	if (hw) {
		struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;

		if (rsi_config_wowlan(adapter, wowlan))
			rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n");
	}

	if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
	    adapter->priv->bt_adapter) {
		rsi_bt_ops.detach(adapter->priv->bt_adapter);
		adapter->priv->bt_adapter = NULL;
	}

	rsi_sdio_disable_interrupts(sdev->pfunction);

	if (sdev->write_fail)
		rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");

	if (rsi_set_sdio_pm_caps(adapter))
		rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");

	rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n");
}

static int rsi_restore(struct device *dev)
{
	struct sdio_func *pfunction = dev_to_sdio_func(dev);
	struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
	struct rsi_common *common = adapter->priv;

	rsi_dbg(INFO_ZONE, "SDIO Bus restore ======>\n");
	common->hibernate_resume = true;
	common->fsm_state = FSM_FW_NOT_LOADED;
	common->iface_down = true;

	adapter->sc_nvifs = 0;
	adapter->ps_state = PS_NONE;

	common->wow_flags = 0;
	common->iface_down = false;

	rsi_dbg(INFO_ZONE, "RSI module restored\n");

	return 0;
}
static const struct dev_pm_ops rsi_pm_ops = {
	.suspend = rsi_suspend,
	.resume_noirq = rsi_resume,
	.freeze = rsi_freeze,
	.thaw = rsi_thaw,
	.restore = rsi_restore,
};
#endif

static const struct sdio_device_id rsi_dev_table[] =  {
	{ SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9113) },
	{ SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9116) },
	{ /* Blank */},
};

static struct sdio_driver rsi_driver = {
	.name       = "RSI-SDIO WLAN",
	.probe      = rsi_probe,
	.remove     = rsi_disconnect,
	.id_table   = rsi_dev_table,
#ifdef CONFIG_PM
	.drv = {
		.pm = &rsi_pm_ops,
		.shutdown   = rsi_shutdown,
	}
#endif
};

/**
 * rsi_module_init() - This function registers the sdio module.
 * @void: Void.
 *
 * Return: 0 on success.
 */
static int rsi_module_init(void)
{
	int ret;

	ret = sdio_register_driver(&rsi_driver);
	rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
	return ret;
}

/**
 * rsi_module_exit() - This function unregisters the sdio module.
 * @void: Void.
 *
 * Return: None.
 */
static void rsi_module_exit(void)
{
	sdio_unregister_driver(&rsi_driver);
	rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
}

module_init(rsi_module_init);
module_exit(rsi_module_exit);

MODULE_AUTHOR("Redpine Signals Inc");
MODULE_DESCRIPTION("Common SDIO layer for RSI drivers");
MODULE_DEVICE_TABLE(sdio, rsi_dev_table);
MODULE_FIRMWARE(FIRMWARE_RSI9113);
MODULE_VERSION("0.1");
MODULE_LICENSE("Dual BSD/GPL");
