cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sdio.c (22198B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
      4 * All rights reserved.
      5 */
      6
      7#include <linux/clk.h>
      8#include <linux/mmc/sdio_func.h>
      9#include <linux/mmc/sdio_ids.h>
     10#include <linux/mmc/host.h>
     11#include <linux/mmc/sdio.h>
     12#include <linux/of_irq.h>
     13
     14#include "netdev.h"
     15#include "cfg80211.h"
     16
     17#define SDIO_MODALIAS "wilc1000_sdio"
     18
     19static const struct sdio_device_id wilc_sdio_ids[] = {
     20	{ SDIO_DEVICE(SDIO_VENDOR_ID_MICROCHIP_WILC, SDIO_DEVICE_ID_MICROCHIP_WILC1000) },
     21	{ },
     22};
     23
     24#define WILC_SDIO_BLOCK_SIZE 512
     25
     26struct wilc_sdio {
     27	bool irq_gpio;
     28	u32 block_size;
     29	int has_thrpt_enh3;
     30};
     31
     32struct sdio_cmd52 {
     33	u32 read_write:		1;
     34	u32 function:		3;
     35	u32 raw:		1;
     36	u32 address:		17;
     37	u32 data:		8;
     38};
     39
     40struct sdio_cmd53 {
     41	u32 read_write:		1;
     42	u32 function:		3;
     43	u32 block_mode:		1;
     44	u32 increment:		1;
     45	u32 address:		17;
     46	u32 count:		9;
     47	u8 *buffer;
     48	u32 block_size;
     49};
     50
     51static const struct wilc_hif_func wilc_hif_sdio;
     52
     53static void wilc_sdio_interrupt(struct sdio_func *func)
     54{
     55	sdio_release_host(func);
     56	wilc_handle_isr(sdio_get_drvdata(func));
     57	sdio_claim_host(func);
     58}
     59
     60static int wilc_sdio_cmd52(struct wilc *wilc, struct sdio_cmd52 *cmd)
     61{
     62	struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
     63	int ret;
     64	u8 data;
     65
     66	sdio_claim_host(func);
     67
     68	func->num = cmd->function;
     69	if (cmd->read_write) {  /* write */
     70		if (cmd->raw) {
     71			sdio_writeb(func, cmd->data, cmd->address, &ret);
     72			data = sdio_readb(func, cmd->address, &ret);
     73			cmd->data = data;
     74		} else {
     75			sdio_writeb(func, cmd->data, cmd->address, &ret);
     76		}
     77	} else {        /* read */
     78		data = sdio_readb(func, cmd->address, &ret);
     79		cmd->data = data;
     80	}
     81
     82	sdio_release_host(func);
     83
     84	if (ret)
     85		dev_err(&func->dev, "%s..failed, err(%d)\n", __func__, ret);
     86	return ret;
     87}
     88
     89static int wilc_sdio_cmd53(struct wilc *wilc, struct sdio_cmd53 *cmd)
     90{
     91	struct sdio_func *func = container_of(wilc->dev, struct sdio_func, dev);
     92	int size, ret;
     93
     94	sdio_claim_host(func);
     95
     96	func->num = cmd->function;
     97	func->cur_blksize = cmd->block_size;
     98	if (cmd->block_mode)
     99		size = cmd->count * cmd->block_size;
    100	else
    101		size = cmd->count;
    102
    103	if (cmd->read_write) {  /* write */
    104		ret = sdio_memcpy_toio(func, cmd->address,
    105				       (void *)cmd->buffer, size);
    106	} else {        /* read */
    107		ret = sdio_memcpy_fromio(func, (void *)cmd->buffer,
    108					 cmd->address,  size);
    109	}
    110
    111	sdio_release_host(func);
    112
    113	if (ret)
    114		dev_err(&func->dev, "%s..failed, err(%d)\n", __func__,  ret);
    115
    116	return ret;
    117}
    118
    119static int wilc_sdio_probe(struct sdio_func *func,
    120			   const struct sdio_device_id *id)
    121{
    122	struct wilc *wilc;
    123	int ret;
    124	struct wilc_sdio *sdio_priv;
    125
    126	sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL);
    127	if (!sdio_priv)
    128		return -ENOMEM;
    129
    130	ret = wilc_cfg80211_init(&wilc, &func->dev, WILC_HIF_SDIO,
    131				 &wilc_hif_sdio);
    132	if (ret)
    133		goto free;
    134
    135	if (IS_ENABLED(CONFIG_WILC1000_HW_OOB_INTR)) {
    136		struct device_node *np = func->card->dev.of_node;
    137		int irq_num = of_irq_get(np, 0);
    138
    139		if (irq_num > 0) {
    140			wilc->dev_irq_num = irq_num;
    141			sdio_priv->irq_gpio = true;
    142		}
    143	}
    144
    145	sdio_set_drvdata(func, wilc);
    146	wilc->bus_data = sdio_priv;
    147	wilc->dev = &func->dev;
    148
    149	wilc->rtc_clk = devm_clk_get_optional(&func->card->dev, "rtc");
    150	if (IS_ERR(wilc->rtc_clk)) {
    151		ret = PTR_ERR(wilc->rtc_clk);
    152		goto dispose_irq;
    153	}
    154	clk_prepare_enable(wilc->rtc_clk);
    155
    156	dev_info(&func->dev, "Driver Initializing success\n");
    157	return 0;
    158
    159dispose_irq:
    160	irq_dispose_mapping(wilc->dev_irq_num);
    161	wilc_netdev_cleanup(wilc);
    162free:
    163	kfree(sdio_priv);
    164	return ret;
    165}
    166
    167static void wilc_sdio_remove(struct sdio_func *func)
    168{
    169	struct wilc *wilc = sdio_get_drvdata(func);
    170	struct wilc_sdio *sdio_priv = wilc->bus_data;
    171
    172	clk_disable_unprepare(wilc->rtc_clk);
    173	wilc_netdev_cleanup(wilc);
    174	kfree(sdio_priv);
    175}
    176
    177static int wilc_sdio_reset(struct wilc *wilc)
    178{
    179	struct sdio_cmd52 cmd;
    180	int ret;
    181	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    182
    183	cmd.read_write = 1;
    184	cmd.function = 0;
    185	cmd.raw = 0;
    186	cmd.address = SDIO_CCCR_ABORT;
    187	cmd.data = WILC_SDIO_CCCR_ABORT_RESET;
    188	ret = wilc_sdio_cmd52(wilc, &cmd);
    189	if (ret) {
    190		dev_err(&func->dev, "Fail cmd 52, reset cmd ...\n");
    191		return ret;
    192	}
    193	return 0;
    194}
    195
    196static int wilc_sdio_suspend(struct device *dev)
    197{
    198	struct sdio_func *func = dev_to_sdio_func(dev);
    199	struct wilc *wilc = sdio_get_drvdata(func);
    200	int ret;
    201
    202	dev_info(dev, "sdio suspend\n");
    203	chip_wakeup(wilc);
    204
    205	if (!IS_ERR(wilc->rtc_clk))
    206		clk_disable_unprepare(wilc->rtc_clk);
    207
    208	if (wilc->suspend_event) {
    209		host_sleep_notify(wilc);
    210		chip_allow_sleep(wilc);
    211	}
    212
    213	ret = wilc_sdio_reset(wilc);
    214	if (ret) {
    215		dev_err(&func->dev, "Fail reset sdio\n");
    216		return ret;
    217	}
    218	sdio_claim_host(func);
    219
    220	return 0;
    221}
    222
    223static int wilc_sdio_enable_interrupt(struct wilc *dev)
    224{
    225	struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
    226	int ret = 0;
    227
    228	sdio_claim_host(func);
    229	ret = sdio_claim_irq(func, wilc_sdio_interrupt);
    230	sdio_release_host(func);
    231
    232	if (ret < 0) {
    233		dev_err(&func->dev, "can't claim sdio_irq, err(%d)\n", ret);
    234		ret = -EIO;
    235	}
    236	return ret;
    237}
    238
    239static void wilc_sdio_disable_interrupt(struct wilc *dev)
    240{
    241	struct sdio_func *func = container_of(dev->dev, struct sdio_func, dev);
    242	int ret;
    243
    244	sdio_claim_host(func);
    245	ret = sdio_release_irq(func);
    246	if (ret < 0)
    247		dev_err(&func->dev, "can't release sdio_irq, err(%d)\n", ret);
    248	sdio_release_host(func);
    249}
    250
    251/********************************************
    252 *
    253 *      Function 0
    254 *
    255 ********************************************/
    256
    257static int wilc_sdio_set_func0_csa_address(struct wilc *wilc, u32 adr)
    258{
    259	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    260	struct sdio_cmd52 cmd;
    261	int ret;
    262
    263	/**
    264	 *      Review: BIG ENDIAN
    265	 **/
    266	cmd.read_write = 1;
    267	cmd.function = 0;
    268	cmd.raw = 0;
    269	cmd.address = WILC_SDIO_FBR_CSA_REG;
    270	cmd.data = (u8)adr;
    271	ret = wilc_sdio_cmd52(wilc, &cmd);
    272	if (ret) {
    273		dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
    274			cmd.address);
    275		return ret;
    276	}
    277
    278	cmd.address = WILC_SDIO_FBR_CSA_REG + 1;
    279	cmd.data = (u8)(adr >> 8);
    280	ret = wilc_sdio_cmd52(wilc, &cmd);
    281	if (ret) {
    282		dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
    283			cmd.address);
    284		return ret;
    285	}
    286
    287	cmd.address = WILC_SDIO_FBR_CSA_REG + 2;
    288	cmd.data = (u8)(adr >> 16);
    289	ret = wilc_sdio_cmd52(wilc, &cmd);
    290	if (ret) {
    291		dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
    292			cmd.address);
    293		return ret;
    294	}
    295
    296	return 0;
    297}
    298
    299static int wilc_sdio_set_block_size(struct wilc *wilc, u8 func_num,
    300				    u32 block_size)
    301{
    302	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    303	struct sdio_cmd52 cmd;
    304	int ret;
    305
    306	cmd.read_write = 1;
    307	cmd.function = 0;
    308	cmd.raw = 0;
    309	cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE;
    310	cmd.data = (u8)block_size;
    311	ret = wilc_sdio_cmd52(wilc, &cmd);
    312	if (ret) {
    313		dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
    314			cmd.address);
    315		return ret;
    316	}
    317
    318	cmd.address = SDIO_FBR_BASE(func_num) + SDIO_CCCR_BLKSIZE +  1;
    319	cmd.data = (u8)(block_size >> 8);
    320	ret = wilc_sdio_cmd52(wilc, &cmd);
    321	if (ret) {
    322		dev_err(&func->dev, "Failed cmd52, set %04x data...\n",
    323			cmd.address);
    324		return ret;
    325	}
    326
    327	return 0;
    328}
    329
    330/********************************************
    331 *
    332 *      Sdio interfaces
    333 *
    334 ********************************************/
    335static int wilc_sdio_write_reg(struct wilc *wilc, u32 addr, u32 data)
    336{
    337	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    338	struct wilc_sdio *sdio_priv = wilc->bus_data;
    339	int ret;
    340
    341	cpu_to_le32s(&data);
    342
    343	if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
    344		struct sdio_cmd52 cmd;
    345
    346		cmd.read_write = 1;
    347		cmd.function = 0;
    348		cmd.raw = 0;
    349		cmd.address = addr;
    350		cmd.data = data;
    351		ret = wilc_sdio_cmd52(wilc, &cmd);
    352		if (ret)
    353			dev_err(&func->dev,
    354				"Failed cmd 52, read reg (%08x) ...\n", addr);
    355	} else {
    356		struct sdio_cmd53 cmd;
    357
    358		/**
    359		 *      set the AHB address
    360		 **/
    361		ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    362		if (ret)
    363			return ret;
    364
    365		cmd.read_write = 1;
    366		cmd.function = 0;
    367		cmd.address = WILC_SDIO_FBR_DATA_REG;
    368		cmd.block_mode = 0;
    369		cmd.increment = 1;
    370		cmd.count = 4;
    371		cmd.buffer = (u8 *)&data;
    372		cmd.block_size = sdio_priv->block_size;
    373		ret = wilc_sdio_cmd53(wilc, &cmd);
    374		if (ret)
    375			dev_err(&func->dev,
    376				"Failed cmd53, write reg (%08x)...\n", addr);
    377	}
    378
    379	return ret;
    380}
    381
    382static int wilc_sdio_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
    383{
    384	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    385	struct wilc_sdio *sdio_priv = wilc->bus_data;
    386	u32 block_size = sdio_priv->block_size;
    387	struct sdio_cmd53 cmd;
    388	int nblk, nleft, ret;
    389
    390	cmd.read_write = 1;
    391	if (addr > 0) {
    392		/**
    393		 *      func 0 access
    394		 **/
    395		cmd.function = 0;
    396		cmd.address = WILC_SDIO_FBR_DATA_REG;
    397	} else {
    398		/**
    399		 *      func 1 access
    400		 **/
    401		cmd.function = 1;
    402		cmd.address = WILC_SDIO_F1_DATA_REG;
    403	}
    404
    405	size = ALIGN(size, 4);
    406	nblk = size / block_size;
    407	nleft = size % block_size;
    408
    409	if (nblk > 0) {
    410		cmd.block_mode = 1;
    411		cmd.increment = 1;
    412		cmd.count = nblk;
    413		cmd.buffer = buf;
    414		cmd.block_size = block_size;
    415		if (addr > 0) {
    416			ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    417			if (ret)
    418				return ret;
    419		}
    420		ret = wilc_sdio_cmd53(wilc, &cmd);
    421		if (ret) {
    422			dev_err(&func->dev,
    423				"Failed cmd53 [%x], block send...\n", addr);
    424			return ret;
    425		}
    426		if (addr > 0)
    427			addr += nblk * block_size;
    428		buf += nblk * block_size;
    429	}
    430
    431	if (nleft > 0) {
    432		cmd.block_mode = 0;
    433		cmd.increment = 1;
    434		cmd.count = nleft;
    435		cmd.buffer = buf;
    436
    437		cmd.block_size = block_size;
    438
    439		if (addr > 0) {
    440			ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    441			if (ret)
    442				return ret;
    443		}
    444		ret = wilc_sdio_cmd53(wilc, &cmd);
    445		if (ret) {
    446			dev_err(&func->dev,
    447				"Failed cmd53 [%x], bytes send...\n", addr);
    448			return ret;
    449		}
    450	}
    451
    452	return 0;
    453}
    454
    455static int wilc_sdio_read_reg(struct wilc *wilc, u32 addr, u32 *data)
    456{
    457	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    458	struct wilc_sdio *sdio_priv = wilc->bus_data;
    459	int ret;
    460
    461	if (addr >= 0xf0 && addr <= 0xff) { /* only vendor specific registers */
    462		struct sdio_cmd52 cmd;
    463
    464		cmd.read_write = 0;
    465		cmd.function = 0;
    466		cmd.raw = 0;
    467		cmd.address = addr;
    468		ret = wilc_sdio_cmd52(wilc, &cmd);
    469		if (ret) {
    470			dev_err(&func->dev,
    471				"Failed cmd 52, read reg (%08x) ...\n", addr);
    472			return ret;
    473		}
    474		*data = cmd.data;
    475	} else {
    476		struct sdio_cmd53 cmd;
    477
    478		ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    479		if (ret)
    480			return ret;
    481
    482		cmd.read_write = 0;
    483		cmd.function = 0;
    484		cmd.address = WILC_SDIO_FBR_DATA_REG;
    485		cmd.block_mode = 0;
    486		cmd.increment = 1;
    487		cmd.count = 4;
    488		cmd.buffer = (u8 *)data;
    489
    490		cmd.block_size = sdio_priv->block_size;
    491		ret = wilc_sdio_cmd53(wilc, &cmd);
    492		if (ret) {
    493			dev_err(&func->dev,
    494				"Failed cmd53, read reg (%08x)...\n", addr);
    495			return ret;
    496		}
    497	}
    498
    499	le32_to_cpus(data);
    500	return 0;
    501}
    502
    503static int wilc_sdio_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size)
    504{
    505	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    506	struct wilc_sdio *sdio_priv = wilc->bus_data;
    507	u32 block_size = sdio_priv->block_size;
    508	struct sdio_cmd53 cmd;
    509	int nblk, nleft, ret;
    510
    511	cmd.read_write = 0;
    512	if (addr > 0) {
    513		/**
    514		 *      func 0 access
    515		 **/
    516		cmd.function = 0;
    517		cmd.address = WILC_SDIO_FBR_DATA_REG;
    518	} else {
    519		/**
    520		 *      func 1 access
    521		 **/
    522		cmd.function = 1;
    523		cmd.address = WILC_SDIO_F1_DATA_REG;
    524	}
    525
    526	size = ALIGN(size, 4);
    527	nblk = size / block_size;
    528	nleft = size % block_size;
    529
    530	if (nblk > 0) {
    531		cmd.block_mode = 1;
    532		cmd.increment = 1;
    533		cmd.count = nblk;
    534		cmd.buffer = buf;
    535		cmd.block_size = block_size;
    536		if (addr > 0) {
    537			ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    538			if (ret)
    539				return ret;
    540		}
    541		ret = wilc_sdio_cmd53(wilc, &cmd);
    542		if (ret) {
    543			dev_err(&func->dev,
    544				"Failed cmd53 [%x], block read...\n", addr);
    545			return ret;
    546		}
    547		if (addr > 0)
    548			addr += nblk * block_size;
    549		buf += nblk * block_size;
    550	}       /* if (nblk > 0) */
    551
    552	if (nleft > 0) {
    553		cmd.block_mode = 0;
    554		cmd.increment = 1;
    555		cmd.count = nleft;
    556		cmd.buffer = buf;
    557
    558		cmd.block_size = block_size;
    559
    560		if (addr > 0) {
    561			ret = wilc_sdio_set_func0_csa_address(wilc, addr);
    562			if (ret)
    563				return ret;
    564		}
    565		ret = wilc_sdio_cmd53(wilc, &cmd);
    566		if (ret) {
    567			dev_err(&func->dev,
    568				"Failed cmd53 [%x], bytes read...\n", addr);
    569			return ret;
    570		}
    571	}
    572
    573	return 0;
    574}
    575
    576/********************************************
    577 *
    578 *      Bus interfaces
    579 *
    580 ********************************************/
    581
    582static int wilc_sdio_deinit(struct wilc *wilc)
    583{
    584	return 0;
    585}
    586
    587static int wilc_sdio_init(struct wilc *wilc, bool resume)
    588{
    589	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    590	struct wilc_sdio *sdio_priv = wilc->bus_data;
    591	struct sdio_cmd52 cmd;
    592	int loop, ret;
    593	u32 chipid;
    594
    595	/**
    596	 *      function 0 csa enable
    597	 **/
    598	cmd.read_write = 1;
    599	cmd.function = 0;
    600	cmd.raw = 1;
    601	cmd.address = SDIO_FBR_BASE(1);
    602	cmd.data = SDIO_FBR_ENABLE_CSA;
    603	ret = wilc_sdio_cmd52(wilc, &cmd);
    604	if (ret) {
    605		dev_err(&func->dev, "Fail cmd 52, enable csa...\n");
    606		return ret;
    607	}
    608
    609	/**
    610	 *      function 0 block size
    611	 **/
    612	ret = wilc_sdio_set_block_size(wilc, 0, WILC_SDIO_BLOCK_SIZE);
    613	if (ret) {
    614		dev_err(&func->dev, "Fail cmd 52, set func 0 block size...\n");
    615		return ret;
    616	}
    617	sdio_priv->block_size = WILC_SDIO_BLOCK_SIZE;
    618
    619	/**
    620	 *      enable func1 IO
    621	 **/
    622	cmd.read_write = 1;
    623	cmd.function = 0;
    624	cmd.raw = 1;
    625	cmd.address = SDIO_CCCR_IOEx;
    626	cmd.data = WILC_SDIO_CCCR_IO_EN_FUNC1;
    627	ret = wilc_sdio_cmd52(wilc, &cmd);
    628	if (ret) {
    629		dev_err(&func->dev,
    630			"Fail cmd 52, set IOE register...\n");
    631		return ret;
    632	}
    633
    634	/**
    635	 *      make sure func 1 is up
    636	 **/
    637	cmd.read_write = 0;
    638	cmd.function = 0;
    639	cmd.raw = 0;
    640	cmd.address = SDIO_CCCR_IORx;
    641	loop = 3;
    642	do {
    643		cmd.data = 0;
    644		ret = wilc_sdio_cmd52(wilc, &cmd);
    645		if (ret) {
    646			dev_err(&func->dev,
    647				"Fail cmd 52, get IOR register...\n");
    648			return ret;
    649		}
    650		if (cmd.data == WILC_SDIO_CCCR_IO_EN_FUNC1)
    651			break;
    652	} while (loop--);
    653
    654	if (loop <= 0) {
    655		dev_err(&func->dev, "Fail func 1 is not ready...\n");
    656		return -EINVAL;
    657	}
    658
    659	/**
    660	 *      func 1 is ready, set func 1 block size
    661	 **/
    662	ret = wilc_sdio_set_block_size(wilc, 1, WILC_SDIO_BLOCK_SIZE);
    663	if (ret) {
    664		dev_err(&func->dev, "Fail set func 1 block size...\n");
    665		return ret;
    666	}
    667
    668	/**
    669	 *      func 1 interrupt enable
    670	 **/
    671	cmd.read_write = 1;
    672	cmd.function = 0;
    673	cmd.raw = 1;
    674	cmd.address = SDIO_CCCR_IENx;
    675	cmd.data = WILC_SDIO_CCCR_IEN_MASTER | WILC_SDIO_CCCR_IEN_FUNC1;
    676	ret = wilc_sdio_cmd52(wilc, &cmd);
    677	if (ret) {
    678		dev_err(&func->dev, "Fail cmd 52, set IEN register...\n");
    679		return ret;
    680	}
    681
    682	/**
    683	 *      make sure can read back chip id correctly
    684	 **/
    685	if (!resume) {
    686		int rev;
    687
    688		ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid);
    689		if (ret) {
    690			dev_err(&func->dev, "Fail cmd read chip id...\n");
    691			return ret;
    692		}
    693		dev_err(&func->dev, "chipid (%08x)\n", chipid);
    694		rev = FIELD_GET(WILC_CHIP_REV_FIELD, chipid);
    695		if (rev > FIELD_GET(WILC_CHIP_REV_FIELD, WILC_1000_BASE_ID_2A))
    696			sdio_priv->has_thrpt_enh3 = 1;
    697		else
    698			sdio_priv->has_thrpt_enh3 = 0;
    699		dev_info(&func->dev, "has_thrpt_enh3 = %d...\n",
    700			 sdio_priv->has_thrpt_enh3);
    701	}
    702
    703	return 0;
    704}
    705
    706static int wilc_sdio_read_size(struct wilc *wilc, u32 *size)
    707{
    708	u32 tmp;
    709	struct sdio_cmd52 cmd;
    710
    711	/**
    712	 *      Read DMA count in words
    713	 **/
    714	cmd.read_write = 0;
    715	cmd.function = 0;
    716	cmd.raw = 0;
    717	cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG;
    718	cmd.data = 0;
    719	wilc_sdio_cmd52(wilc, &cmd);
    720	tmp = cmd.data;
    721
    722	cmd.address = WILC_SDIO_INTERRUPT_DATA_SZ_REG + 1;
    723	cmd.data = 0;
    724	wilc_sdio_cmd52(wilc, &cmd);
    725	tmp |= (cmd.data << 8);
    726
    727	*size = tmp;
    728	return 0;
    729}
    730
    731static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
    732{
    733	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    734	struct wilc_sdio *sdio_priv = wilc->bus_data;
    735	u32 tmp;
    736	u8 irq_flags;
    737	struct sdio_cmd52 cmd;
    738
    739	wilc_sdio_read_size(wilc, &tmp);
    740
    741	/**
    742	 *      Read IRQ flags
    743	 **/
    744	if (!sdio_priv->irq_gpio) {
    745		cmd.function = 1;
    746		cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
    747	} else {
    748		cmd.function = 0;
    749		cmd.address = WILC_SDIO_IRQ_FLAG_REG;
    750	}
    751	cmd.raw = 0;
    752	cmd.read_write = 0;
    753	cmd.data = 0;
    754	wilc_sdio_cmd52(wilc, &cmd);
    755	irq_flags = cmd.data;
    756	tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
    757
    758	if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
    759		dev_err(&func->dev, "Unexpected interrupt (1) int=%lx\n",
    760			FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags));
    761
    762	*int_status = tmp;
    763
    764	return 0;
    765}
    766
    767static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
    768{
    769	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    770	struct wilc_sdio *sdio_priv = wilc->bus_data;
    771	int ret;
    772	int vmm_ctl;
    773
    774	if (sdio_priv->has_thrpt_enh3) {
    775		u32 reg = 0;
    776
    777		if (sdio_priv->irq_gpio)
    778			reg = val & (BIT(MAX_NUM_INT) - 1);
    779
    780		/* select VMM table 0 */
    781		if (val & SEL_VMM_TBL0)
    782			reg |= BIT(5);
    783		/* select VMM table 1 */
    784		if (val & SEL_VMM_TBL1)
    785			reg |= BIT(6);
    786		/* enable VMM */
    787		if (val & EN_VMM)
    788			reg |= BIT(7);
    789		if (reg) {
    790			struct sdio_cmd52 cmd;
    791
    792			cmd.read_write = 1;
    793			cmd.function = 0;
    794			cmd.raw = 0;
    795			cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
    796			cmd.data = reg;
    797
    798			ret = wilc_sdio_cmd52(wilc, &cmd);
    799			if (ret) {
    800				dev_err(&func->dev,
    801					"Failed cmd52, set (%02x) data (%d) ...\n",
    802					cmd.address, __LINE__);
    803				return ret;
    804			}
    805		}
    806		return 0;
    807	}
    808	if (sdio_priv->irq_gpio) {
    809		/* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */
    810		/*
    811		 * Cannot clear multiple interrupts.
    812		 * Must clear each interrupt individually.
    813		 */
    814		u32 flags;
    815		int i;
    816
    817		flags = val & (BIT(MAX_NUM_INT) - 1);
    818		for (i = 0; i < NUM_INT_EXT && flags; i++) {
    819			if (flags & BIT(i)) {
    820				struct sdio_cmd52 cmd;
    821
    822				cmd.read_write = 1;
    823				cmd.function = 0;
    824				cmd.raw = 0;
    825				cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG;
    826				cmd.data = BIT(i);
    827
    828				ret = wilc_sdio_cmd52(wilc, &cmd);
    829				if (ret) {
    830					dev_err(&func->dev,
    831						"Failed cmd52, set (%02x) data (%d) ...\n",
    832						cmd.address, __LINE__);
    833					return ret;
    834				}
    835				flags &= ~BIT(i);
    836			}
    837		}
    838
    839		for (i = NUM_INT_EXT; i < MAX_NUM_INT && flags; i++) {
    840			if (flags & BIT(i)) {
    841				dev_err(&func->dev,
    842					"Unexpected interrupt cleared %d...\n",
    843					i);
    844				flags &= ~BIT(i);
    845			}
    846		}
    847	}
    848
    849	vmm_ctl = 0;
    850	/* select VMM table 0 */
    851	if (val & SEL_VMM_TBL0)
    852		vmm_ctl |= BIT(0);
    853	/* select VMM table 1 */
    854	if (val & SEL_VMM_TBL1)
    855		vmm_ctl |= BIT(1);
    856	/* enable VMM */
    857	if (val & EN_VMM)
    858		vmm_ctl |= BIT(2);
    859
    860	if (vmm_ctl) {
    861		struct sdio_cmd52 cmd;
    862
    863		cmd.read_write = 1;
    864		cmd.function = 0;
    865		cmd.raw = 0;
    866		cmd.address = WILC_SDIO_VMM_TBL_CTRL_REG;
    867		cmd.data = vmm_ctl;
    868		ret = wilc_sdio_cmd52(wilc, &cmd);
    869		if (ret) {
    870			dev_err(&func->dev,
    871				"Failed cmd52, set (%02x) data (%d) ...\n",
    872				cmd.address, __LINE__);
    873			return ret;
    874		}
    875	}
    876	return 0;
    877}
    878
    879static int wilc_sdio_sync_ext(struct wilc *wilc, int nint)
    880{
    881	struct sdio_func *func = dev_to_sdio_func(wilc->dev);
    882	struct wilc_sdio *sdio_priv = wilc->bus_data;
    883	u32 reg;
    884
    885	if (nint > MAX_NUM_INT) {
    886		dev_err(&func->dev, "Too many interrupts (%d)...\n", nint);
    887		return -EINVAL;
    888	}
    889
    890	/**
    891	 *      Disable power sequencer
    892	 **/
    893	if (wilc_sdio_read_reg(wilc, WILC_MISC, &reg)) {
    894		dev_err(&func->dev, "Failed read misc reg...\n");
    895		return -EINVAL;
    896	}
    897
    898	reg &= ~BIT(8);
    899	if (wilc_sdio_write_reg(wilc, WILC_MISC, reg)) {
    900		dev_err(&func->dev, "Failed write misc reg...\n");
    901		return -EINVAL;
    902	}
    903
    904	if (sdio_priv->irq_gpio) {
    905		u32 reg;
    906		int ret, i;
    907
    908		/**
    909		 *      interrupt pin mux select
    910		 **/
    911		ret = wilc_sdio_read_reg(wilc, WILC_PIN_MUX_0, &reg);
    912		if (ret) {
    913			dev_err(&func->dev, "Failed read reg (%08x)...\n",
    914				WILC_PIN_MUX_0);
    915			return ret;
    916		}
    917		reg |= BIT(8);
    918		ret = wilc_sdio_write_reg(wilc, WILC_PIN_MUX_0, reg);
    919		if (ret) {
    920			dev_err(&func->dev, "Failed write reg (%08x)...\n",
    921				WILC_PIN_MUX_0);
    922			return ret;
    923		}
    924
    925		/**
    926		 *      interrupt enable
    927		 **/
    928		ret = wilc_sdio_read_reg(wilc, WILC_INTR_ENABLE, &reg);
    929		if (ret) {
    930			dev_err(&func->dev, "Failed read reg (%08x)...\n",
    931				WILC_INTR_ENABLE);
    932			return ret;
    933		}
    934
    935		for (i = 0; (i < 5) && (nint > 0); i++, nint--)
    936			reg |= BIT((27 + i));
    937		ret = wilc_sdio_write_reg(wilc, WILC_INTR_ENABLE, reg);
    938		if (ret) {
    939			dev_err(&func->dev, "Failed write reg (%08x)...\n",
    940				WILC_INTR_ENABLE);
    941			return ret;
    942		}
    943		if (nint) {
    944			ret = wilc_sdio_read_reg(wilc, WILC_INTR2_ENABLE, &reg);
    945			if (ret) {
    946				dev_err(&func->dev,
    947					"Failed read reg (%08x)...\n",
    948					WILC_INTR2_ENABLE);
    949				return ret;
    950			}
    951
    952			for (i = 0; (i < 3) && (nint > 0); i++, nint--)
    953				reg |= BIT(i);
    954
    955			ret = wilc_sdio_write_reg(wilc, WILC_INTR2_ENABLE, reg);
    956			if (ret) {
    957				dev_err(&func->dev,
    958					"Failed write reg (%08x)...\n",
    959					WILC_INTR2_ENABLE);
    960				return ret;
    961			}
    962		}
    963	}
    964	return 0;
    965}
    966
    967/* Global sdio HIF function table */
    968static const struct wilc_hif_func wilc_hif_sdio = {
    969	.hif_init = wilc_sdio_init,
    970	.hif_deinit = wilc_sdio_deinit,
    971	.hif_read_reg = wilc_sdio_read_reg,
    972	.hif_write_reg = wilc_sdio_write_reg,
    973	.hif_block_rx = wilc_sdio_read,
    974	.hif_block_tx = wilc_sdio_write,
    975	.hif_read_int = wilc_sdio_read_int,
    976	.hif_clear_int_ext = wilc_sdio_clear_int_ext,
    977	.hif_read_size = wilc_sdio_read_size,
    978	.hif_block_tx_ext = wilc_sdio_write,
    979	.hif_block_rx_ext = wilc_sdio_read,
    980	.hif_sync_ext = wilc_sdio_sync_ext,
    981	.enable_interrupt = wilc_sdio_enable_interrupt,
    982	.disable_interrupt = wilc_sdio_disable_interrupt,
    983	.hif_reset = wilc_sdio_reset,
    984};
    985
    986static int wilc_sdio_resume(struct device *dev)
    987{
    988	struct sdio_func *func = dev_to_sdio_func(dev);
    989	struct wilc *wilc = sdio_get_drvdata(func);
    990
    991	dev_info(dev, "sdio resume\n");
    992	sdio_release_host(func);
    993	chip_wakeup(wilc);
    994	wilc_sdio_init(wilc, true);
    995
    996	if (wilc->suspend_event)
    997		host_wakeup_notify(wilc);
    998
    999	chip_allow_sleep(wilc);
   1000
   1001	return 0;
   1002}
   1003
   1004static const struct of_device_id wilc_of_match[] = {
   1005	{ .compatible = "microchip,wilc1000", },
   1006	{ /* sentinel */ }
   1007};
   1008MODULE_DEVICE_TABLE(of, wilc_of_match);
   1009
   1010static const struct dev_pm_ops wilc_sdio_pm_ops = {
   1011	.suspend = wilc_sdio_suspend,
   1012	.resume = wilc_sdio_resume,
   1013};
   1014
   1015static struct sdio_driver wilc_sdio_driver = {
   1016	.name		= SDIO_MODALIAS,
   1017	.id_table	= wilc_sdio_ids,
   1018	.probe		= wilc_sdio_probe,
   1019	.remove		= wilc_sdio_remove,
   1020	.drv = {
   1021		.pm = &wilc_sdio_pm_ops,
   1022		.of_match_table = wilc_of_match,
   1023	}
   1024};
   1025module_driver(wilc_sdio_driver,
   1026	      sdio_register_driver,
   1027	      sdio_unregister_driver);
   1028MODULE_LICENSE("GPL");