brintos

brintos / linux-shallow public Read only

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