/*
 * SD/MMC Greybus driver.
 *
 * Copyright 2014-2015 Google Inc.
 * Copyright 2014-2015 Linaro Ltd.
 *
 * Released under the GPLv2 only.
 */

#include <linux/kernel.h>
#include <linux/mmc/core.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/scatterlist.h>
#include <linux/workqueue.h>

#include "greybus.h"
#include "gbphy.h"

struct gb_sdio_host {
	struct gb_connection	*connection;
	struct gbphy_device	*gbphy_dev;
	struct mmc_host		*mmc;
	struct mmc_request	*mrq;
	struct mutex		lock;	/* lock for this host */
	size_t			data_max;
	spinlock_t		xfer;	/* lock to cancel ongoing transfer */
	bool			xfer_stop;
	struct workqueue_struct	*mrq_workqueue;
	struct work_struct	mrqwork;
	u8			queued_events;
	bool			removed;
	bool			card_present;
	bool			read_only;
};


#define GB_SDIO_RSP_R1_R5_R6_R7	(GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
				 GB_SDIO_RSP_OPCODE)
#define GB_SDIO_RSP_R3_R4	(GB_SDIO_RSP_PRESENT)
#define GB_SDIO_RSP_R2		(GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
				 GB_SDIO_RSP_136)
#define GB_SDIO_RSP_R1B		(GB_SDIO_RSP_PRESENT | GB_SDIO_RSP_CRC | \
				 GB_SDIO_RSP_OPCODE | GB_SDIO_RSP_BUSY)

/* kernel vdd starts at 0x80 and we need to translate to greybus ones 0x01 */
#define GB_SDIO_VDD_SHIFT	8

#ifndef MMC_CAP2_CORE_RUNTIME_PM
#define MMC_CAP2_CORE_RUNTIME_PM	0
#endif

static inline bool single_op(struct mmc_command *cmd)
{
	u32 opcode = cmd->opcode;

	return opcode == MMC_WRITE_BLOCK ||
	       opcode == MMC_READ_SINGLE_BLOCK;
}

static void _gb_sdio_set_host_caps(struct gb_sdio_host *host, u32 r)
{
	u32 caps = 0;
	u32 caps2 = 0;

	caps = ((r & GB_SDIO_CAP_NONREMOVABLE) ? MMC_CAP_NONREMOVABLE : 0) |
		((r & GB_SDIO_CAP_4_BIT_DATA) ? MMC_CAP_4_BIT_DATA : 0) |
		((r & GB_SDIO_CAP_8_BIT_DATA) ? MMC_CAP_8_BIT_DATA : 0) |
		((r & GB_SDIO_CAP_MMC_HS) ? MMC_CAP_MMC_HIGHSPEED : 0) |
		((r & GB_SDIO_CAP_SD_HS) ? MMC_CAP_SD_HIGHSPEED : 0) |
		((r & GB_SDIO_CAP_ERASE) ? MMC_CAP_ERASE : 0) |
		((r & GB_SDIO_CAP_1_2V_DDR) ? MMC_CAP_1_2V_DDR : 0) |
		((r & GB_SDIO_CAP_1_8V_DDR) ? MMC_CAP_1_8V_DDR : 0) |
		((r & GB_SDIO_CAP_POWER_OFF_CARD) ? MMC_CAP_POWER_OFF_CARD : 0) |
		((r & GB_SDIO_CAP_UHS_SDR12) ? MMC_CAP_UHS_SDR12 : 0) |
		((r & GB_SDIO_CAP_UHS_SDR25) ? MMC_CAP_UHS_SDR25 : 0) |
		((r & GB_SDIO_CAP_UHS_SDR50) ? MMC_CAP_UHS_SDR50 : 0) |
		((r & GB_SDIO_CAP_UHS_SDR104) ? MMC_CAP_UHS_SDR104 : 0) |
		((r & GB_SDIO_CAP_UHS_DDR50) ? MMC_CAP_UHS_DDR50 : 0) |
		((r & GB_SDIO_CAP_DRIVER_TYPE_A) ? MMC_CAP_DRIVER_TYPE_A : 0) |
		((r & GB_SDIO_CAP_DRIVER_TYPE_C) ? MMC_CAP_DRIVER_TYPE_C : 0) |
		((r & GB_SDIO_CAP_DRIVER_TYPE_D) ? MMC_CAP_DRIVER_TYPE_D : 0);

	caps2 = ((r & GB_SDIO_CAP_HS200_1_2V) ? MMC_CAP2_HS200_1_2V_SDR : 0) |
		((r & GB_SDIO_CAP_HS400_1_2V) ? MMC_CAP2_HS400_1_2V : 0) |
		((r & GB_SDIO_CAP_HS400_1_8V) ? MMC_CAP2_HS400_1_8V : 0) |
		((r & GB_SDIO_CAP_HS200_1_8V) ? MMC_CAP2_HS200_1_8V_SDR : 0);

	host->mmc->caps = caps;
	host->mmc->caps2 = caps2 | MMC_CAP2_CORE_RUNTIME_PM;

	if (caps & MMC_CAP_NONREMOVABLE)
		host->card_present = true;
}

static u32 _gb_sdio_get_host_ocr(u32 ocr)
{
	return (((ocr & GB_SDIO_VDD_165_195) ? MMC_VDD_165_195 : 0) |
		((ocr & GB_SDIO_VDD_20_21) ? MMC_VDD_20_21 : 0) |
		((ocr & GB_SDIO_VDD_21_22) ? MMC_VDD_21_22 : 0) |
		((ocr & GB_SDIO_VDD_22_23) ? MMC_VDD_22_23 : 0) |
		((ocr & GB_SDIO_VDD_23_24) ? MMC_VDD_23_24 : 0) |
		((ocr & GB_SDIO_VDD_24_25) ? MMC_VDD_24_25 : 0) |
		((ocr & GB_SDIO_VDD_25_26) ? MMC_VDD_25_26 : 0) |
		((ocr & GB_SDIO_VDD_26_27) ? MMC_VDD_26_27 : 0) |
		((ocr & GB_SDIO_VDD_27_28) ? MMC_VDD_27_28 : 0) |
		((ocr & GB_SDIO_VDD_28_29) ? MMC_VDD_28_29 : 0) |
		((ocr & GB_SDIO_VDD_29_30) ? MMC_VDD_29_30 : 0) |
		((ocr & GB_SDIO_VDD_30_31) ? MMC_VDD_30_31 : 0) |
		((ocr & GB_SDIO_VDD_31_32) ? MMC_VDD_31_32 : 0) |
		((ocr & GB_SDIO_VDD_32_33) ? MMC_VDD_32_33 : 0) |
		((ocr & GB_SDIO_VDD_33_34) ? MMC_VDD_33_34 : 0) |
		((ocr & GB_SDIO_VDD_34_35) ? MMC_VDD_34_35 : 0) |
		((ocr & GB_SDIO_VDD_35_36) ? MMC_VDD_35_36 : 0)
		);
}

static int gb_sdio_get_caps(struct gb_sdio_host *host)
{
	struct gb_sdio_get_caps_response response;
	struct mmc_host *mmc = host->mmc;
	u16 data_max;
	u32 blksz;
	u32 ocr;
	u32 r;
	int ret;

	ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_GET_CAPABILITIES,
				NULL, 0, &response, sizeof(response));
	if (ret < 0)
		return ret;
	r = le32_to_cpu(response.caps);

	_gb_sdio_set_host_caps(host, r);

	/* get the max block size that could fit our payload */
	data_max = gb_operation_get_payload_size_max(host->connection);
	data_max = min(data_max - sizeof(struct gb_sdio_transfer_request),
		       data_max - sizeof(struct gb_sdio_transfer_response));

	blksz = min_t(u16, le16_to_cpu(response.max_blk_size), data_max);
	blksz = max_t(u32, 512, blksz);

	mmc->max_blk_size = rounddown_pow_of_two(blksz);
	mmc->max_blk_count = le16_to_cpu(response.max_blk_count);
	host->data_max = data_max;

	/* get ocr supported values */
	ocr = _gb_sdio_get_host_ocr(le32_to_cpu(response.ocr));
	mmc->ocr_avail = ocr;
	mmc->ocr_avail_sdio = mmc->ocr_avail;
	mmc->ocr_avail_sd = mmc->ocr_avail;
	mmc->ocr_avail_mmc = mmc->ocr_avail;

	/* get frequency range values */
	mmc->f_min = le32_to_cpu(response.f_min);
	mmc->f_max = le32_to_cpu(response.f_max);

	return 0;
}

static void _gb_queue_event(struct gb_sdio_host *host, u8 event)
{
	if (event & GB_SDIO_CARD_INSERTED)
		host->queued_events &= ~GB_SDIO_CARD_REMOVED;
	else if (event & GB_SDIO_CARD_REMOVED)
		host->queued_events &= ~GB_SDIO_CARD_INSERTED;

	host->queued_events |= event;
}

static int _gb_sdio_process_events(struct gb_sdio_host *host, u8 event)
{
	u8 state_changed = 0;

	if (event & GB_SDIO_CARD_INSERTED) {
		if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
			return 0;
		if (host->card_present)
			return 0;
		host->card_present = true;
		state_changed = 1;
	}

	if (event & GB_SDIO_CARD_REMOVED) {
		if (host->mmc->caps & MMC_CAP_NONREMOVABLE)
			return 0;
		if (!(host->card_present))
			return 0;
		host->card_present = false;
		state_changed = 1;
	}

	if (event & GB_SDIO_WP)
		host->read_only = true;

	if (state_changed) {
		dev_info(mmc_dev(host->mmc), "card %s now event\n",
			 (host->card_present ?  "inserted" : "removed"));
		mmc_detect_change(host->mmc, 0);
	}

	return 0;
}

static int gb_sdio_request_handler(struct gb_operation *op)
{
	struct gb_sdio_host *host = gb_connection_get_data(op->connection);
	struct gb_message *request;
	struct gb_sdio_event_request *payload;
	u8 type = op->type;
	int ret =  0;
	u8 event;

	if (type != GB_SDIO_TYPE_EVENT) {
		dev_err(mmc_dev(host->mmc),
			"unsupported unsolicited event: %u\n", type);
		return -EINVAL;
	}

	request = op->request;

	if (request->payload_size < sizeof(*payload)) {
		dev_err(mmc_dev(host->mmc), "wrong event size received (%zu < %zu)\n",
			request->payload_size, sizeof(*payload));
		return -EINVAL;
	}

	payload = request->payload;
	event = payload->event;

	if (host->removed)
		_gb_queue_event(host, event);
	else
		ret = _gb_sdio_process_events(host, event);

	return ret;
}

static int gb_sdio_set_ios(struct gb_sdio_host *host,
			   struct gb_sdio_set_ios_request *request)
{
	int ret;

	ret = gbphy_runtime_get_sync(host->gbphy_dev);
	if (ret)
		return ret;

	ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_SET_IOS, request,
				sizeof(*request), NULL, 0);

	gbphy_runtime_put_autosuspend(host->gbphy_dev);

	return ret;
}

static int _gb_sdio_send(struct gb_sdio_host *host, struct mmc_data *data,
			 size_t len, u16 nblocks, off_t skip)
{
	struct gb_sdio_transfer_request *request;
	struct gb_sdio_transfer_response *response;
	struct gb_operation *operation;
	struct scatterlist *sg = data->sg;
	unsigned int sg_len = data->sg_len;
	size_t copied;
	u16 send_blksz;
	u16 send_blocks;
	int ret;

	WARN_ON(len > host->data_max);

	operation = gb_operation_create(host->connection, GB_SDIO_TYPE_TRANSFER,
					len + sizeof(*request),
					sizeof(*response), GFP_KERNEL);
	if (!operation)
		return -ENOMEM;

	request = operation->request->payload;
	request->data_flags = (data->flags >> 8);
	request->data_blocks = cpu_to_le16(nblocks);
	request->data_blksz = cpu_to_le16(data->blksz);

	copied = sg_pcopy_to_buffer(sg, sg_len, &request->data[0], len, skip);

	if (copied != len) {
		ret = -EINVAL;
		goto err_put_operation;
	}

	ret = gb_operation_request_send_sync(operation);
	if (ret < 0)
		goto err_put_operation;

	response = operation->response->payload;

	send_blocks = le16_to_cpu(response->data_blocks);
	send_blksz = le16_to_cpu(response->data_blksz);

	if (len != send_blksz * send_blocks) {
		dev_err(mmc_dev(host->mmc), "send: size received: %zu != %d\n",
			len, send_blksz * send_blocks);
		ret = -EINVAL;
	}

err_put_operation:
	gb_operation_put(operation);

	return ret;
}

static int _gb_sdio_recv(struct gb_sdio_host *host, struct mmc_data *data,
			 size_t len, u16 nblocks, off_t skip)
{
	struct gb_sdio_transfer_request *request;
	struct gb_sdio_transfer_response *response;
	struct gb_operation *operation;
	struct scatterlist *sg = data->sg;
	unsigned int sg_len = data->sg_len;
	size_t copied;
	u16 recv_blksz;
	u16 recv_blocks;
	int ret;

	WARN_ON(len > host->data_max);

	operation = gb_operation_create(host->connection, GB_SDIO_TYPE_TRANSFER,
					sizeof(*request),
					len + sizeof(*response), GFP_KERNEL);
	if (!operation)
		return -ENOMEM;

	request = operation->request->payload;
	request->data_flags = (data->flags >> 8);
	request->data_blocks = cpu_to_le16(nblocks);
	request->data_blksz = cpu_to_le16(data->blksz);

	ret = gb_operation_request_send_sync(operation);
	if (ret < 0)
		goto err_put_operation;

	response = operation->response->payload;
	recv_blocks = le16_to_cpu(response->data_blocks);
	recv_blksz = le16_to_cpu(response->data_blksz);

	if (len != recv_blksz * recv_blocks) {
		dev_err(mmc_dev(host->mmc), "recv: size received: %d != %zu\n",
			recv_blksz * recv_blocks, len);
		ret = -EINVAL;
		goto err_put_operation;
	}

	copied = sg_pcopy_from_buffer(sg, sg_len, &response->data[0], len,
				      skip);
	if (copied != len)
		ret = -EINVAL;

err_put_operation:
	gb_operation_put(operation);

	return ret;
}

static int gb_sdio_transfer(struct gb_sdio_host *host, struct mmc_data *data)
{
	size_t left, len;
	off_t skip = 0;
	int ret = 0;
	u16 nblocks;

	if (single_op(data->mrq->cmd) && data->blocks > 1) {
		ret = -ETIMEDOUT;
		goto out;
	}

	left = data->blksz * data->blocks;

	while (left) {
		/* check is a stop transmission is pending */
		spin_lock(&host->xfer);
		if (host->xfer_stop) {
			host->xfer_stop = false;
			spin_unlock(&host->xfer);
			ret = -EINTR;
			goto out;
		}
		spin_unlock(&host->xfer);
		len = min(left, host->data_max);
		nblocks = len / data->blksz;
		len = nblocks * data->blksz;

		if (data->flags & MMC_DATA_READ) {
			ret = _gb_sdio_recv(host, data, len, nblocks, skip);
			if (ret < 0)
				goto out;
		} else {
			ret = _gb_sdio_send(host, data, len, nblocks, skip);
			if (ret < 0)
				goto out;
		}
		data->bytes_xfered += len;
		left -= len;
		skip += len;
	}

out:
	data->error = ret;
	return ret;
}

static int gb_sdio_command(struct gb_sdio_host *host, struct mmc_command *cmd)
{
	struct gb_sdio_command_request request = {0};
	struct gb_sdio_command_response response;
	struct mmc_data *data = host->mrq->data;
	u8 cmd_flags;
	u8 cmd_type;
	int i;
	int ret;

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		cmd_flags = GB_SDIO_RSP_NONE;
		break;
	case MMC_RSP_R1:
		cmd_flags = GB_SDIO_RSP_R1_R5_R6_R7;
		break;
	case MMC_RSP_R1B:
		cmd_flags = GB_SDIO_RSP_R1B;
		break;
	case MMC_RSP_R2:
		cmd_flags = GB_SDIO_RSP_R2;
		break;
	case MMC_RSP_R3:
		cmd_flags = GB_SDIO_RSP_R3_R4;
		break;
	default:
		dev_err(mmc_dev(host->mmc), "cmd flag invalid 0x%04x\n",
			mmc_resp_type(cmd));
		ret = -EINVAL;
		goto out;
	}

	switch (mmc_cmd_type(cmd)) {
	case MMC_CMD_BC:
		cmd_type = GB_SDIO_CMD_BC;
		break;
	case MMC_CMD_BCR:
		cmd_type = GB_SDIO_CMD_BCR;
		break;
	case MMC_CMD_AC:
		cmd_type = GB_SDIO_CMD_AC;
		break;
	case MMC_CMD_ADTC:
		cmd_type = GB_SDIO_CMD_ADTC;
		break;
	default:
		dev_err(mmc_dev(host->mmc), "cmd type invalid 0x%04x\n",
			mmc_cmd_type(cmd));
		ret = -EINVAL;
		goto out;
	}

	request.cmd = cmd->opcode;
	request.cmd_flags = cmd_flags;
	request.cmd_type = cmd_type;
	request.cmd_arg = cpu_to_le32(cmd->arg);
	/* some controllers need to know at command time data details */
	if (data) {
		request.data_blocks = cpu_to_le16(data->blocks);
		request.data_blksz = cpu_to_le16(data->blksz);
	}

	ret = gb_operation_sync(host->connection, GB_SDIO_TYPE_COMMAND,
				&request, sizeof(request), &response,
				sizeof(response));
	if (ret < 0)
		goto out;

	/* no response expected */
	if (cmd_flags == GB_SDIO_RSP_NONE)
		goto out;

	/* long response expected */
	if (cmd_flags & GB_SDIO_RSP_R2)
		for (i = 0; i < 4; i++)
			cmd->resp[i] = le32_to_cpu(response.resp[i]);
	else
		cmd->resp[0] = le32_to_cpu(response.resp[0]);

out:
	cmd->error = ret;
	return ret;
}

static void gb_sdio_mrq_work(struct work_struct *work)
{
	struct gb_sdio_host *host;
	struct mmc_request *mrq;
	int ret;

	host = container_of(work, struct gb_sdio_host, mrqwork);

	ret = gbphy_runtime_get_sync(host->gbphy_dev);
	if (ret)
		return;

	mutex_lock(&host->lock);
	mrq = host->mrq;
	if (!mrq) {
		mutex_unlock(&host->lock);
		gbphy_runtime_put_autosuspend(host->gbphy_dev);
		dev_err(mmc_dev(host->mmc), "mmc request is NULL");
		return;
	}

	if (host->removed) {
		mrq->cmd->error = -ESHUTDOWN;
		goto done;
	}

	if (mrq->sbc) {
		ret = gb_sdio_command(host, mrq->sbc);
		if (ret < 0)
			goto done;
	}

	ret = gb_sdio_command(host, mrq->cmd);
	if (ret < 0)
		goto done;

	if (mrq->data) {
		ret = gb_sdio_transfer(host, mrq->data);
		if (ret < 0)
			goto done;
	}

	if (mrq->stop) {
		ret = gb_sdio_command(host, mrq->stop);
		if (ret < 0)
			goto done;
	}

done:
	host->mrq = NULL;
	mutex_unlock(&host->lock);
	mmc_request_done(host->mmc, mrq);
	gbphy_runtime_put_autosuspend(host->gbphy_dev);
}

static void gb_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
	struct gb_sdio_host *host = mmc_priv(mmc);
	struct mmc_command *cmd = mrq->cmd;

	/* Check if it is a cancel to ongoing transfer */
	if (cmd->opcode == MMC_STOP_TRANSMISSION) {
		spin_lock(&host->xfer);
		host->xfer_stop = true;
		spin_unlock(&host->xfer);
	}

	mutex_lock(&host->lock);

	WARN_ON(host->mrq);
	host->mrq = mrq;

	if (host->removed) {
		mrq->cmd->error = -ESHUTDOWN;
		goto out;
	}
	if (!host->card_present) {
		mrq->cmd->error = -ENOMEDIUM;
		goto out;
	}

	queue_work(host->mrq_workqueue, &host->mrqwork);

	mutex_unlock(&host->lock);
	return;

out:
	host->mrq = NULL;
	mutex_unlock(&host->lock);
	mmc_request_done(mmc, mrq);
}

static void gb_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
	struct gb_sdio_host *host = mmc_priv(mmc);
	struct gb_sdio_set_ios_request request;
	int ret;
	u8 power_mode;
	u8 bus_width;
	u8 timing;
	u8 signal_voltage;
	u8 drv_type;
	u32 vdd = 0;

	mutex_lock(&host->lock);
	request.clock = cpu_to_le32(ios->clock);

	if (ios->vdd)
		vdd = 1 << (ios->vdd - GB_SDIO_VDD_SHIFT);
	request.vdd = cpu_to_le32(vdd);

	request.bus_mode = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN ?
			    GB_SDIO_BUSMODE_OPENDRAIN :
			    GB_SDIO_BUSMODE_PUSHPULL);

	switch (ios->power_mode) {
	case MMC_POWER_OFF:
	default:
		power_mode = GB_SDIO_POWER_OFF;
		break;
	case MMC_POWER_UP:
		power_mode = GB_SDIO_POWER_UP;
		break;
	case MMC_POWER_ON:
		power_mode = GB_SDIO_POWER_ON;
		break;
	case MMC_POWER_UNDEFINED:
		power_mode = GB_SDIO_POWER_UNDEFINED;
		break;
	}
	request.power_mode = power_mode;

	switch (ios->bus_width) {
	case MMC_BUS_WIDTH_1:
		bus_width = GB_SDIO_BUS_WIDTH_1;
		break;
	case MMC_BUS_WIDTH_4:
	default:
		bus_width = GB_SDIO_BUS_WIDTH_4;
		break;
	case MMC_BUS_WIDTH_8:
		bus_width = GB_SDIO_BUS_WIDTH_8;
		break;
	}
	request.bus_width = bus_width;

	switch (ios->timing) {
	case MMC_TIMING_LEGACY:
	default:
		timing = GB_SDIO_TIMING_LEGACY;
		break;
	case MMC_TIMING_MMC_HS:
		timing = GB_SDIO_TIMING_MMC_HS;
		break;
	case MMC_TIMING_SD_HS:
		timing = GB_SDIO_TIMING_SD_HS;
		break;
	case MMC_TIMING_UHS_SDR12:
		timing = GB_SDIO_TIMING_UHS_SDR12;
		break;
	case MMC_TIMING_UHS_SDR25:
		timing = GB_SDIO_TIMING_UHS_SDR25;
		break;
	case MMC_TIMING_UHS_SDR50:
		timing = GB_SDIO_TIMING_UHS_SDR50;
		break;
	case MMC_TIMING_UHS_SDR104:
		timing = GB_SDIO_TIMING_UHS_SDR104;
		break;
	case MMC_TIMING_UHS_DDR50:
		timing = GB_SDIO_TIMING_UHS_DDR50;
		break;
	case MMC_TIMING_MMC_DDR52:
		timing = GB_SDIO_TIMING_MMC_DDR52;
		break;
	case MMC_TIMING_MMC_HS200:
		timing = GB_SDIO_TIMING_MMC_HS200;
		break;
	case MMC_TIMING_MMC_HS400:
		timing = GB_SDIO_TIMING_MMC_HS400;
		break;
	}
	request.timing = timing;

	switch (ios->signal_voltage) {
	case MMC_SIGNAL_VOLTAGE_330:
		signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_330;
		break;
	case MMC_SIGNAL_VOLTAGE_180:
	default:
		signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_180;
		break;
	case MMC_SIGNAL_VOLTAGE_120:
		signal_voltage = GB_SDIO_SIGNAL_VOLTAGE_120;
		break;
	}
	request.signal_voltage = signal_voltage;

	switch (ios->drv_type) {
	case MMC_SET_DRIVER_TYPE_A:
		drv_type = GB_SDIO_SET_DRIVER_TYPE_A;
		break;
	case MMC_SET_DRIVER_TYPE_C:
		drv_type = GB_SDIO_SET_DRIVER_TYPE_C;
		break;
	case MMC_SET_DRIVER_TYPE_D:
		drv_type = GB_SDIO_SET_DRIVER_TYPE_D;
		break;
	case MMC_SET_DRIVER_TYPE_B:
	default:
		drv_type = GB_SDIO_SET_DRIVER_TYPE_B;
		break;
	}
	request.drv_type = drv_type;

	ret = gb_sdio_set_ios(host, &request);
	if (ret < 0)
		goto out;

	memcpy(&mmc->ios, ios, sizeof(mmc->ios));

out:
	mutex_unlock(&host->lock);
}

static int gb_mmc_get_ro(struct mmc_host *mmc)
{
	struct gb_sdio_host *host = mmc_priv(mmc);

	mutex_lock(&host->lock);
	if (host->removed) {
		mutex_unlock(&host->lock);
		return -ESHUTDOWN;
	}
	mutex_unlock(&host->lock);

	return host->read_only;
}

static int gb_mmc_get_cd(struct mmc_host *mmc)
{
	struct gb_sdio_host *host = mmc_priv(mmc);

	mutex_lock(&host->lock);
	if (host->removed) {
		mutex_unlock(&host->lock);
		return -ESHUTDOWN;
	}
	mutex_unlock(&host->lock);

	return host->card_present;
}

static int gb_mmc_switch_voltage(struct mmc_host *mmc, struct mmc_ios *ios)
{
	return 0;
}

static const struct mmc_host_ops gb_sdio_ops = {
	.request	= gb_mmc_request,
	.set_ios	= gb_mmc_set_ios,
	.get_ro		= gb_mmc_get_ro,
	.get_cd		= gb_mmc_get_cd,
	.start_signal_voltage_switch	= gb_mmc_switch_voltage,
};

static int gb_sdio_probe(struct gbphy_device *gbphy_dev,
			 const struct gbphy_device_id *id)
{
	struct gb_connection *connection;
	struct mmc_host *mmc;
	struct gb_sdio_host *host;
	int ret = 0;

	mmc = mmc_alloc_host(sizeof(*host), &gbphy_dev->dev);
	if (!mmc)
		return -ENOMEM;

	connection = gb_connection_create(gbphy_dev->bundle,
					  le16_to_cpu(gbphy_dev->cport_desc->id),
					  gb_sdio_request_handler);
	if (IS_ERR(connection)) {
		ret = PTR_ERR(connection);
		goto exit_mmc_free;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;
	host->removed = true;

	host->connection = connection;
	gb_connection_set_data(connection, host);
	host->gbphy_dev = gbphy_dev;
	gb_gbphy_set_data(gbphy_dev, host);

	ret = gb_connection_enable_tx(connection);
	if (ret)
		goto exit_connection_destroy;

	ret = gb_sdio_get_caps(host);
	if (ret < 0)
		goto exit_connection_disable;

	mmc->ops = &gb_sdio_ops;

	mmc->max_segs = host->mmc->max_blk_count;

	/* for now we make a map 1:1 between max request and segment size */
	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
	mmc->max_seg_size = mmc->max_req_size;

	mutex_init(&host->lock);
	spin_lock_init(&host->xfer);
	host->mrq_workqueue = alloc_workqueue("mmc-%s", 0, 1,
					      dev_name(&gbphy_dev->dev));
	if (!host->mrq_workqueue) {
		ret = -ENOMEM;
		goto exit_connection_disable;
	}
	INIT_WORK(&host->mrqwork, gb_sdio_mrq_work);

	ret = gb_connection_enable(connection);
	if (ret)
		goto exit_wq_destroy;

	ret = mmc_add_host(mmc);
	if (ret < 0)
		goto exit_wq_destroy;
	host->removed = false;
	ret = _gb_sdio_process_events(host, host->queued_events);
	host->queued_events = 0;

	gbphy_runtime_put_autosuspend(gbphy_dev);

	return ret;

exit_wq_destroy:
	destroy_workqueue(host->mrq_workqueue);
exit_connection_disable:
	gb_connection_disable(connection);
exit_connection_destroy:
	gb_connection_destroy(connection);
exit_mmc_free:
	mmc_free_host(mmc);

	return ret;
}

static void gb_sdio_remove(struct gbphy_device *gbphy_dev)
{
	struct gb_sdio_host *host = gb_gbphy_get_data(gbphy_dev);
	struct gb_connection *connection = host->connection;
	struct mmc_host *mmc;
	int ret;

	ret = gbphy_runtime_get_sync(gbphy_dev);
	if (ret)
		gbphy_runtime_get_noresume(gbphy_dev);

	mutex_lock(&host->lock);
	host->removed = true;
	mmc = host->mmc;
	gb_connection_set_data(connection, NULL);
	mutex_unlock(&host->lock);

	flush_workqueue(host->mrq_workqueue);
	destroy_workqueue(host->mrq_workqueue);
	gb_connection_disable_rx(connection);
	mmc_remove_host(mmc);
	gb_connection_disable(connection);
	gb_connection_destroy(connection);
	mmc_free_host(mmc);
}

static const struct gbphy_device_id gb_sdio_id_table[] = {
	{ GBPHY_PROTOCOL(GREYBUS_PROTOCOL_SDIO) },
	{ },
};
MODULE_DEVICE_TABLE(gbphy, gb_sdio_id_table);

static struct gbphy_driver sdio_driver = {
	.name		= "sdio",
	.probe		= gb_sdio_probe,
	.remove		= gb_sdio_remove,
	.id_table	= gb_sdio_id_table,
};

module_gbphy_driver(sdio_driver);
MODULE_LICENSE("GPL v2");
