Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * Marvell BT-over-SDIO driver: SDIO interface related functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 2009, Marvell International Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * This software file (the "File") is distributed by Marvell International
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * (the "License").  You may use, redistribute and/or modify this File in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * accordance with the terms and conditions of the License, a copy of which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * is available by writing to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15)  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16)  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17)  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18)  * this warranty disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19)  **/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/mmc/sdio_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/mmc/sdio_func.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/devcoredump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <net/bluetooth/bluetooth.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <net/bluetooth/hci_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include "btmrvl_drv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include "btmrvl_sdio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define VERSION "1.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) static struct memory_type_mapping mem_type_mapping_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	{"ITCM", NULL, 0, 0xF0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	{"DTCM", NULL, 0, 0xF1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	{"SQRAM", NULL, 0, 0xF2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	{"APU", NULL, 0, 0xF3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	{"CIU", NULL, 0, 0xF4},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	{"ICU", NULL, 0, 0xF5},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 	{"MAC", NULL, 0, 0xF6},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	{"EXT7", NULL, 0, 0xF7},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 	{"EXT8", NULL, 0, 0xF8},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	{"EXT9", NULL, 0, 0xF9},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	{"EXT10", NULL, 0, 0xFA},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	{"EXT11", NULL, 0, 0xFB},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 	{"EXT12", NULL, 0, 0xFC},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	{"EXT13", NULL, 0, 0xFD},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	{"EXTLAST", NULL, 0, 0xFE},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) static const struct of_device_id btmrvl_sdio_of_match_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	{ .compatible = "marvell,sd8897-bt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	{ .compatible = "marvell,sd8997-bt" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct btmrvl_sdio_card *card = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct device *dev = &card->func->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	dev_info(dev, "wake by bt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	cfg->wake_by_bt = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	disable_irq_nosync(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	pm_wakeup_event(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	pm_system_wakeup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) /* This function parses device tree node using mmc subnode devicetree API.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * The device node is saved in card->plt_of_node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * If the device tree node exists and includes interrupts attributes, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * function will request platform specific wakeup interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) static int btmrvl_sdio_probe_of(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 				struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	struct btmrvl_plt_wake_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	if (!dev->of_node ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	    !of_match_node(btmrvl_sdio_of_match_table, dev->of_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		dev_info(dev, "sdio device tree data not available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	card->plt_of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	card->plt_wake_cfg = devm_kzalloc(dev, sizeof(*card->plt_wake_cfg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 					  GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	cfg = card->plt_wake_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	if (cfg && card->plt_of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 		cfg->irq_bt = irq_of_parse_and_map(card->plt_of_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		if (!cfg->irq_bt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 			dev_err(dev, "fail to parse irq_bt from device tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 			cfg->irq_bt = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 			ret = devm_request_irq(dev, cfg->irq_bt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 					       btmrvl_wake_irq_bt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 					       0, "bt_wake", card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 				dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 					"Failed to request irq_bt %d (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 					cfg->irq_bt, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 			/* Configure wakeup (enabled by default) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 			device_init_wakeup(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 			disable_irq(cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) /* The btmrvl_sdio_remove() callback function is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * when user removes this module from kernel space or ejects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  * the card from the slot. The driver handles these 2 cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127)  * differently.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128)  * If the user is removing the module, a MODULE_SHUTDOWN_REQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  * command is sent to firmware and interrupt will be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * If the card is removed, there is no need to send command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131)  * or disable interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133)  * The variable 'user_rmmod' is used to distinguish these two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134)  * scenarios. This flag is initialized as FALSE in case the card
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135)  * is removed, and will be set to TRUE for module removal when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136)  * module_exit function is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) static u8 user_rmmod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) static u8 sdio_ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	.cfg = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	.host_int_mask = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	.host_intstatus = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	.card_status = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	.sq_read_base_addr_a0 = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	.sq_read_base_addr_a1 = 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	.card_fw_status0 = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	.card_fw_status1 = 0x41,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	.card_rx_len = 0x42,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	.card_rx_unit = 0x43,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	.io_port_0 = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	.io_port_1 = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	.io_port_2 = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	.int_read_to_clear = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) static const struct btmrvl_sdio_card_reg btmrvl_reg_87xx = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	.cfg = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	.host_int_mask = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	.host_intstatus = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	.card_status = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	.sq_read_base_addr_a0 = 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	.sq_read_base_addr_a1 = 0x41,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	.card_revision = 0x5c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	.card_fw_status0 = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	.card_fw_status1 = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	.card_rx_len = 0x62,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	.card_rx_unit = 0x63,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	.io_port_0 = 0x78,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	.io_port_1 = 0x79,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	.io_port_2 = 0x7a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	.int_read_to_clear = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) static const struct btmrvl_sdio_card_reg btmrvl_reg_8887 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	.cfg = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	.host_int_mask = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	.host_intstatus = 0x0C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	.card_status = 0x5C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	.sq_read_base_addr_a0 = 0x6C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	.sq_read_base_addr_a1 = 0x6D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	.card_revision = 0xC8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	.card_fw_status0 = 0x88,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	.card_fw_status1 = 0x89,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	.card_rx_len = 0x8A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	.card_rx_unit = 0x8B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	.io_port_0 = 0xE4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	.io_port_1 = 0xE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	.io_port_2 = 0xE6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	.int_read_to_clear = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	.host_int_rsr = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	.card_misc_cfg = 0xD8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	.cfg = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	.host_int_mask = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	.host_intstatus = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	.card_status = 0x50,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	.sq_read_base_addr_a0 = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	.sq_read_base_addr_a1 = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	.card_revision = 0xbc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	.card_fw_status0 = 0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	.card_fw_status1 = 0xc1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	.card_rx_len = 0xc2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	.card_rx_unit = 0xc3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	.io_port_0 = 0xd8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	.io_port_1 = 0xd9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	.io_port_2 = 0xda,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	.int_read_to_clear = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	.host_int_rsr = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	.card_misc_cfg = 0xcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	.fw_dump_ctrl = 0xe2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	.fw_dump_start = 0xe3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	.fw_dump_end = 0xea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static const struct btmrvl_sdio_card_reg btmrvl_reg_89xx = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	.cfg = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	.host_int_mask = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	.host_intstatus = 0x0c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	.card_status = 0x5c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	.sq_read_base_addr_a0 = 0xf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	.sq_read_base_addr_a1 = 0xf9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	.card_revision = 0xc8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	.card_fw_status0 = 0xe8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	.card_fw_status1 = 0xe9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	.card_rx_len = 0xea,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	.card_rx_unit = 0xeb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	.io_port_0 = 0xe4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	.io_port_1 = 0xe5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	.io_port_2 = 0xe6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	.int_read_to_clear = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	.host_int_rsr = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	.card_misc_cfg = 0xd8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	.fw_dump_ctrl = 0xf0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	.fw_dump_start = 0xf1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	.fw_dump_end = 0xf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	.helper		= "mrvl/sd8688_helper.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	.firmware	= "mrvl/sd8688.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	.reg		= &btmrvl_reg_8688,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	.support_pscan_win_report = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	.sd_blksz_fw_dl	= 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	.supports_fw_dump = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	.helper		= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	.firmware	= "mrvl/sd8787_uapsta.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	.reg		= &btmrvl_reg_87xx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	.support_pscan_win_report = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	.sd_blksz_fw_dl	= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	.supports_fw_dump = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	.helper		= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	.firmware	= "mrvl/sd8797_uapsta.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	.reg		= &btmrvl_reg_87xx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	.support_pscan_win_report = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	.sd_blksz_fw_dl	= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	.supports_fw_dump = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) static const struct btmrvl_sdio_device btmrvl_sdio_sd8887 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	.helper		= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	.firmware	= "mrvl/sd8887_uapsta.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	.reg		= &btmrvl_reg_8887,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	.support_pscan_win_report = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	.sd_blksz_fw_dl	= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	.supports_fw_dump = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	.helper		= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	.firmware	= "mrvl/sd8897_uapsta.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	.reg		= &btmrvl_reg_8897,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	.support_pscan_win_report = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	.sd_blksz_fw_dl	= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	.supports_fw_dump = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	.helper         = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	.firmware       = "mrvl/sdsd8977_combo_v2.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	.reg            = &btmrvl_reg_89xx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	.support_pscan_win_report = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	.sd_blksz_fw_dl = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	.supports_fw_dump = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) static const struct btmrvl_sdio_device btmrvl_sdio_sd8987 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	.helper		= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	.firmware	= "mrvl/sd8987_uapsta.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	.reg		= &btmrvl_reg_89xx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	.support_pscan_win_report = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	.sd_blksz_fw_dl	= 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	.supports_fw_dump = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	.helper         = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	.firmware       = "mrvl/sdsd8997_combo_v4.bin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	.reg            = &btmrvl_reg_89xx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	.support_pscan_win_report = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	.sd_blksz_fw_dl = 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	.supports_fw_dump = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static const struct sdio_device_id btmrvl_sdio_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	/* Marvell SD8688 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8688_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8688 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	/* Marvell SD8787 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8787 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	/* Marvell SD8787 Bluetooth AMP device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787_BT_AMP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8787 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	/* Marvell SD8797 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8797 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	/* Marvell SD8887 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8887 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	/* Marvell SD8897 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8897 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	/* Marvell SD8977 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8977_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8977 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	/* Marvell SD8987 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8987_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8987 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	/* Marvell SD8997 Bluetooth device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8997_BT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			.driver_data = (unsigned long)&btmrvl_sdio_sd8997 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	{ }	/* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) MODULE_DEVICE_TABLE(sdio, btmrvl_sdio_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static int btmrvl_sdio_get_rx_unit(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		card->rx_unit = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	u8 fws0, fws1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	*dat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	*dat = (((u16) fws1) << 8) | fws0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) static int btmrvl_sdio_read_rx_len(struct btmrvl_sdio_card *card, u16 *dat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	reg = sdio_readb(card->func, card->reg->card_rx_len, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		*dat = (u16) reg << card->rx_unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) static int btmrvl_sdio_enable_host_int_mask(struct btmrvl_sdio_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 								u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		BT_ERR("Unable to enable the host interrupt!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) static int btmrvl_sdio_disable_host_int_mask(struct btmrvl_sdio_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 								u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	u8 host_int_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	host_int_mask &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		BT_ERR("Unable to disable the host interrupt!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) static int btmrvl_sdio_poll_card_status(struct btmrvl_sdio_card *card, u8 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	unsigned int tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		status = sdio_readb(card->func, card->reg->card_status,	&ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		if ((status & bits) == bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	BT_ERR("FAILED! ret=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 								int pollnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	u16 firmwarestat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	int tries, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	 /* Wait for firmware to become ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	for (tries = 0; tries < pollnum; tries++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		ret = btmrvl_sdio_read_fw_status(card, &firmwarestat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		if (firmwarestat == FIRMWARE_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	const struct firmware *fw_helper = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	const u8 *helper = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	void *tmphlprbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	int tmphlprbufsz, hlprblknow, helperlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	u8 *helperbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	u32 tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	ret = request_firmware(&fw_helper, card->helper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 						&card->func->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	if ((ret < 0) || !fw_helper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		BT_ERR("request_firmware(helper) failed, error code = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 									ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	helper = fw_helper->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	helperlen = fw_helper->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	BT_DBG("Downloading helper image (%d bytes), block size %d bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 						helperlen, SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 	if (!tmphlprbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 		BT_ERR("Unable to allocate buffer for helper."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			" Terminating download");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	/* Perform helper data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	tx_len = (FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			- SDIO_HEADER_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	hlprblknow = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		ret = btmrvl_sdio_poll_card_status(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 					    CARD_IO_READY | DN_LD_CARD_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 			BT_ERR("Helper download poll status timeout @ %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 				hlprblknow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		/* Check if there is more data? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		if (hlprblknow >= helperlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		if (helperlen - hlprblknow < tx_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 			tx_len = helperlen - hlprblknow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		/* Little-endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		helperbuf[0] = ((tx_len & 0x000000ff) >> 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		helperbuf[1] = ((tx_len & 0x0000ff00) >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		helperbuf[2] = ((tx_len & 0x00ff0000) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		helperbuf[3] = ((tx_len & 0xff000000) >> 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		memcpy(&helperbuf[SDIO_HEADER_LEN], &helper[hlprblknow],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				tx_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		/* Now send the data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		ret = sdio_writesb(card->func, card->ioport, helperbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 				FIRMWARE_TRANSFER_NBLOCK * SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			BT_ERR("IO error during helper download @ %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 				hlprblknow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		hlprblknow += tx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	} while (true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	BT_DBG("Transferring helper image EOF block");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	memset(helperbuf, 0x0, SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	ret = sdio_writesb(card->func, card->ioport, helperbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 							SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		BT_ERR("IO error in writing helper image EOF block");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	kfree(tmphlprbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	release_firmware(fw_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	const struct firmware *fw_firmware = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	const u8 *firmware = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	int firmwarelen, tmpfwbufsz, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	unsigned int tries, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	u8 base0, base1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	void *tmpfwbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	u8 *fwbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	u16 len, blksz_dl = card->sd_blksz_fw_dl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	int txlen = 0, tx_blocks = 0, count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	ret = request_firmware(&fw_firmware, card->firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 							&card->func->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	if ((ret < 0) || !fw_firmware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		BT_ERR("request_firmware(firmware) failed, error code = %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 									ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	firmware = fw_firmware->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	firmwarelen = fw_firmware->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	if (!tmpfwbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		BT_ERR("Unable to allocate buffer for firmware."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		       " Terminating download");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	/* Ensure aligned firmware buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	/* Perform firmware data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		ret = btmrvl_sdio_poll_card_status(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 					CARD_IO_READY | DN_LD_CARD_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 			BT_ERR("FW download with helper poll status"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 						" timeout @ %d", offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		/* Check if there is more data ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		if (offset >= firmwarelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			base0 = sdio_readb(card->func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 					card->reg->sq_read_base_addr_a0, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 				BT_ERR("BASE0 register read failed:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 					" base0 = 0x%04X(%d)."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 					" Terminating download",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 					base0, base0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			base1 = sdio_readb(card->func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 					card->reg->sq_read_base_addr_a1, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				BT_ERR("BASE1 register read failed:"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 					" base1 = 0x%04X(%d)."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 					" Terminating download",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 					base1, base1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			len = (((u16) base1) << 8) | base0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		else if (len > BTM_UPLD_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			BT_ERR("FW download failure @%d, invalid length %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 								offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		txlen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		if (len & BIT(0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			if (count > MAX_WRITE_IOMEM_RETRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 				BT_ERR("FW download failure @%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 					"over max retry count", offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			BT_ERR("FW CRC error indicated by the helper: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 				"len = 0x%04X, txlen = %d", len, txlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			len &= ~BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			/* Set txlen to 0 so as to resend from same offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			txlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			/* Last block ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			if (firmwarelen - offset < txlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 				txlen = firmwarelen - offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 			tx_blocks = DIV_ROUND_UP(txlen, blksz_dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 			memcpy(fwbuf, &firmware[offset], txlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		ret = sdio_writesb(card->func, card->ioport, fwbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 						tx_blocks * blksz_dl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			BT_ERR("FW download, writesb(%d) failed @%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 							count, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			sdio_writeb(card->func, HOST_CMD53_FIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 						card->reg->cfg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 				BT_ERR("writeb failed (CFG)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		offset += txlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	} while (true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	BT_INFO("FW download over, size %d bytes", offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	kfree(tmpfwbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	release_firmware(fw_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	u16 buf_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	int ret, num_blocks, blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	struct sk_buff *skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	u8 *payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	struct hci_dev *hdev = priv->btmrvl_dev.hcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	if (!card || !card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 		BT_ERR("card or function is NULL!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	/* Read the length of data to be transferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	ret = btmrvl_sdio_read_rx_len(card, &buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		BT_ERR("read rx_len failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	blksz = SDIO_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	num_blocks = DIV_ROUND_UP(buf_len, blksz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (buf_len <= SDIO_HEADER_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	    || (num_blocks * blksz) > ALLOC_BUF_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 		BT_ERR("invalid packet length: %d", buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	/* Allocate buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		BT_ERR("No free skb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	if ((unsigned long) skb->data & (BTSDIO_DMA_ALIGN - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		skb_put(skb, (unsigned long) skb->data &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 					(BTSDIO_DMA_ALIGN - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		skb_pull(skb, (unsigned long) skb->data &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 					(BTSDIO_DMA_ALIGN - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	payload = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	ret = sdio_readsb(card->func, payload, card->ioport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 			  num_blocks * blksz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		BT_ERR("readsb failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	/* This is SDIO specific header length: byte[2][1][0], type: byte[3]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	 * (HCI_COMMAND = 1, ACL_DATA = 2, SCO_DATA = 3, 0xFE = Vendor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	buf_len = payload[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	buf_len |= payload[1] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	buf_len |= payload[2] << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	if (buf_len > blksz * num_blocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		BT_ERR("Skip incorrect packet: hdrlen %d buffer %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		       buf_len, blksz * num_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	type = payload[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	case HCI_ACLDATA_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	case HCI_SCODATA_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	case HCI_EVENT_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		hci_skb_pkt_type(skb) = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		skb_put(skb, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		skb_pull(skb, SDIO_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		if (type == HCI_EVENT_PKT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			if (btmrvl_check_evtpkt(priv, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				hci_recv_frame(hdev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			hci_recv_frame(hdev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		hdev->stat.byte_rx += buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	case MRVL_VENDOR_PKT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 		hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		skb_put(skb, buf_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		skb_pull(skb, SDIO_HEADER_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		if (btmrvl_process_event(priv, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 			hci_recv_frame(hdev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		hdev->stat.byte_rx += buf_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		BT_ERR("Unknown packet type:%d", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 		BT_ERR("hex: %*ph", blksz * num_blocks, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 		skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		hdev->stat.err_rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	u8 ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	spin_lock_irqsave(&priv->driver_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	ireg = sdio_ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	sdio_ireg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	spin_unlock_irqrestore(&priv->driver_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	if (ireg & DN_LD_HOST_INT_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 		if (priv->btmrvl_dev.tx_dnld_rdy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			BT_DBG("tx_done already received: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 				" int_status=0x%x", ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			priv->btmrvl_dev.tx_dnld_rdy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (ireg & UP_LD_HOST_INT_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		btmrvl_sdio_card_to_host(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) static int btmrvl_sdio_read_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	struct btmrvl_adapter *adapter = card->priv->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	ret = sdio_readsb(card->func, adapter->hw_regs, 0, SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		BT_ERR("sdio_readsb: read int hw_regs failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	*ireg = adapter->hw_regs[card->reg->host_intstatus];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	BT_DBG("hw_regs[%#x]=%#x", card->reg->host_intstatus, *ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) static int btmrvl_sdio_write_to_clear(struct btmrvl_sdio_card *card, u8 *ireg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	*ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		BT_ERR("sdio_readb: read int status failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (*ireg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		 * Clear the interrupt status register and re-enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		 * interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		BT_DBG("int_status = 0x%x", *ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		sdio_writeb(card->func, ~(*ireg) & (DN_LD_HOST_INT_STATUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 						    UP_LD_HOST_INT_STATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			    card->reg->host_intstatus, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			BT_ERR("sdio_writeb: clear int status failed: %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) static void btmrvl_sdio_interrupt(struct sdio_func *func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	struct btmrvl_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	struct btmrvl_sdio_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	u8 ireg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	card = sdio_get_drvdata(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (!card || !card->priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		BT_ERR("sbi_interrupt(%p) card or priv is NULL, card=%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		       func, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	priv = card->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	if (priv->surprise_removed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (card->reg->int_read_to_clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		ret = btmrvl_sdio_read_to_clear(card, &ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		ret = btmrvl_sdio_write_to_clear(card, &ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	spin_lock_irqsave(&priv->driver_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	sdio_ireg |= ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	spin_unlock_irqrestore(&priv->driver_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	btmrvl_interrupt(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	struct sdio_func *func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	if (!card || !card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		BT_ERR("Error: card or function is NULL!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	func = card->func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	sdio_claim_host(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	ret = sdio_enable_func(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		BT_ERR("sdio_enable_func() failed: ret=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		goto release_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	ret = sdio_claim_irq(func, btmrvl_sdio_interrupt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		BT_ERR("sdio_claim_irq failed: ret=%d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		goto disable_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	ret = sdio_set_block_size(card->func, SDIO_BLOCK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 		BT_ERR("cannot set SDIO block size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	reg = sdio_readb(func, card->reg->io_port_0, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	card->ioport = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	reg = sdio_readb(func, card->reg->io_port_1, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	card->ioport |= (reg << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	reg = sdio_readb(func, card->reg->io_port_2, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	card->ioport |= (reg << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	BT_DBG("SDIO FUNC%d IO port: 0x%x", func->num, card->ioport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	if (card->reg->int_read_to_clear) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		reg = sdio_readb(func, card->reg->host_int_rsr, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 			goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		sdio_writeb(func, reg | 0x3f, card->reg->host_int_rsr, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 			goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		reg = sdio_readb(func, card->reg->card_misc_cfg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 			goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		sdio_writeb(func, reg | 0x10, card->reg->card_misc_cfg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 			goto release_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	sdio_set_drvdata(func, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	sdio_release_host(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) release_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	sdio_release_irq(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) disable_func:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	sdio_disable_func(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) release_host:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	sdio_release_host(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static int btmrvl_sdio_unregister_dev(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	if (card && card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		sdio_release_irq(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 		sdio_disable_func(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		sdio_set_drvdata(card->func, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) static int btmrvl_sdio_enable_host_int(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (!card || !card->func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	ret = btmrvl_sdio_enable_host_int_mask(card, HIM_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	btmrvl_sdio_get_rx_unit(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static int btmrvl_sdio_disable_host_int(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	if (!card || !card->func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	ret = btmrvl_sdio_disable_host_int_mask(card, HIM_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 				u8 *payload, u16 nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	int blksz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	u8 *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	void *tmpbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	int tmpbufsz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	if (!card || !card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		BT_ERR("card or function is NULL!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	blksz = DIV_ROUND_UP(nb, SDIO_BLOCK_SIZE) * SDIO_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	buf = payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	if ((unsigned long) payload & (BTSDIO_DMA_ALIGN - 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	    nb < blksz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		tmpbufsz = ALIGN_SZ(blksz, BTSDIO_DMA_ALIGN) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 			   BTSDIO_DMA_ALIGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		tmpbuf = kzalloc(tmpbufsz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		if (!tmpbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		buf = (u8 *) ALIGN_ADDR(tmpbuf, BTSDIO_DMA_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		memcpy(buf, payload, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		/* Transfer data to card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		ret = sdio_writesb(card->func, card->ioport, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 				   blksz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 			BT_ERR("i=%d writesb failed: %d", i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			BT_ERR("hex: %*ph", nb, payload);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 			if (i > MAX_WRITE_IOMEM_RETRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 				goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	} while (ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	priv->btmrvl_dev.tx_dnld_rdy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	kfree(tmpbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	u8 fws0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	int pollnum = MAX_POLL_TRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	if (!card || !card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		BT_ERR("card or function is NULL!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	if (!btmrvl_sdio_verify_fw_download(card, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		BT_DBG("Firmware already downloaded!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	/* Check if other function driver is downloading the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 		BT_ERR("Failed to read FW downloading status!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	if (fws0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 		BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		/* Give other function more time to download the firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		pollnum *= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		if (card->helper) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			ret = btmrvl_sdio_download_helper(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 				BT_ERR("Failed to download helper!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 				ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		if (btmrvl_sdio_download_fw_w_helper(card)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 			BT_ERR("Failed to download firmware!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	 * winner or not, with this test the FW synchronizes when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	 * module can continue its initialization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		BT_ERR("FW failed to be active in time!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int btmrvl_sdio_wakeup_fw(struct btmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!card || !card->func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		BT_ERR("card or function is NULL!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	BT_DBG("wake up firmware");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) static void btmrvl_sdio_dump_regs(struct btmrvl_private *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	unsigned int reg, reg_start, reg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	char buf[256], *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	u8 loop, func, data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	int MAX_LOOP = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	btmrvl_sdio_wakeup_fw(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	for (loop = 0; loop < MAX_LOOP; loop++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		memset(buf, 0, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		ptr = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 		if (loop == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 			/* Read the registers of SDIO function0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 			func = loop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 			reg_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 			reg_end = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 			func = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 			reg_start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 			reg_end = 0x09;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 		ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 			       func, reg_start, reg_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 		for (reg = reg_start; reg <= reg_end; reg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 			if (func == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 				data = sdio_f0_readb(card->func, reg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 				data = sdio_readb(card->func, reg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 			if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 				ptr += sprintf(ptr, "%02x ", data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 				ptr += sprintf(ptr, "ERR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 		BT_INFO("%s", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* This function read/write firmware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) rdwr_status btmrvl_sdio_rdwr_firmware(struct btmrvl_private *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 				      u8 doneflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	int ret, tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	u8 ctrl_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	sdio_writeb(card->func, FW_DUMP_HOST_READY, card->reg->fw_dump_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		    &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		BT_ERR("SDIO write err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		return RDWR_STATUS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 		ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 				       &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 			BT_ERR("SDIO read err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 			return RDWR_STATUS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 		if (ctrl_data == FW_DUMP_DONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 		if (doneflag && ctrl_data == doneflag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 			return RDWR_STATUS_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		if (ctrl_data != FW_DUMP_HOST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 			BT_INFO("The ctrl reg was changed, re-try again!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 			sdio_writeb(card->func, FW_DUMP_HOST_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 				    card->reg->fw_dump_ctrl, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 				BT_ERR("SDIO write err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 				return RDWR_STATUS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	if (ctrl_data == FW_DUMP_HOST_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		BT_ERR("Fail to pull ctrl_data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		return RDWR_STATUS_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	return RDWR_STATUS_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /* This function dump sdio register and memory data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) static void btmrvl_sdio_coredump(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	struct sdio_func *func = dev_to_sdio_func(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	struct btmrvl_sdio_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	struct btmrvl_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	unsigned int reg, reg_start, reg_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	enum rdwr_status stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	u8 *dbg_ptr, *end_ptr, *fw_dump_data, *fw_dump_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	u8 dump_num = 0, idx, i, read_reg, doneflag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	u32 memory_size, fw_dump_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	card = sdio_get_drvdata(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	priv = card->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	/* dump sdio register first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	btmrvl_sdio_dump_regs(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	if (!card->supports_fw_dump) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 		BT_ERR("Firmware dump not supported for this card!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		if (entry->mem_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 			vfree(entry->mem_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 			entry->mem_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		entry->mem_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	btmrvl_sdio_wakeup_fw(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	sdio_claim_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	BT_INFO("== btmrvl firmware dump start ==");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	if (stat == RDWR_STATUS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	reg = card->reg->fw_dump_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	/* Read the number of the memories which will dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	dump_num = sdio_readb(card->func, reg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		BT_ERR("SDIO read memory length err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	/* Read the length of every memory which will dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	for (idx = 0; idx < dump_num; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		if (stat == RDWR_STATUS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 		memory_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		reg = card->reg->fw_dump_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 			read_reg = sdio_readb(card->func, reg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 				BT_ERR("SDIO read err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 			memory_size |= (read_reg << i*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 			reg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		if (memory_size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			BT_INFO("Firmware dump finished!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 			sdio_writeb(card->func, FW_DUMP_READ_DONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 				    card->reg->fw_dump_ctrl, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 			if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 				BT_ERR("SDIO Write MEMDUMP_FINISH ERR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		BT_INFO("%s_SIZE=0x%x", entry->mem_name, memory_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		entry->mem_ptr = vzalloc(memory_size + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		entry->mem_size = memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 		if (!entry->mem_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			BT_ERR("Vzalloc %s failed", entry->mem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		fw_dump_len += (strlen("========Start dump ") +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 				strlen(entry->mem_name) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 				strlen("========\n") +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 				(memory_size + 1) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 				strlen("\n========End dump========\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 		dbg_ptr = entry->mem_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		end_ptr = dbg_ptr + memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		doneflag = entry->done_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		BT_INFO("Start %s output, please wait...",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 			entry->mem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 			stat = btmrvl_sdio_rdwr_firmware(priv, doneflag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 			if (stat == RDWR_STATUS_FAILURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 			reg_start = card->reg->fw_dump_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			reg_end = card->reg->fw_dump_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			for (reg = reg_start; reg <= reg_end; reg++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 				*dbg_ptr = sdio_readb(card->func, reg, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 				if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 					BT_ERR("SDIO read err");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 					goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 				if (dbg_ptr < end_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 					dbg_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 					BT_ERR("Allocated buffer not enough");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 			if (stat != RDWR_STATUS_DONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 				BT_INFO("%s done: size=0x%tx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 					entry->mem_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 					dbg_ptr - entry->mem_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		} while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	BT_INFO("== btmrvl firmware dump end ==");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 	sdio_release_host(card->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	if (fw_dump_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	fw_dump_data = vzalloc(fw_dump_len+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	if (!fw_dump_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		BT_ERR("Vzalloc fw_dump_data fail!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	fw_dump_ptr = fw_dump_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	/* Dump all the memory data into single file, a userspace script will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 	 * be used to split all the memory data to multiple files
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump start");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	for (idx = 0; idx < dump_num; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 		if (entry->mem_ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 			strcpy(fw_dump_ptr, "========Start dump ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			fw_dump_ptr += strlen("========Start dump ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 			strcpy(fw_dump_ptr, entry->mem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 			fw_dump_ptr += strlen(entry->mem_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			strcpy(fw_dump_ptr, "========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			fw_dump_ptr += strlen("========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			memcpy(fw_dump_ptr, entry->mem_ptr, entry->mem_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			fw_dump_ptr += entry->mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			strcpy(fw_dump_ptr, "\n========End dump========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 			fw_dump_ptr += strlen("\n========End dump========\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			vfree(mem_type_mapping_tbl[idx].mem_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 			mem_type_mapping_tbl[idx].mem_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	/* fw_dump_data will be free in device coredump release function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	 * after 5 min
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) static int btmrvl_sdio_probe(struct sdio_func *func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 					const struct sdio_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	struct btmrvl_private *priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	struct btmrvl_sdio_card *card = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	BT_INFO("vendor=0x%x, device=0x%x, class=%d, fn=%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 			id->vendor, id->device, id->class, func->num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	card = devm_kzalloc(&func->dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	card->func = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	if (id->driver_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 		struct btmrvl_sdio_device *data = (void *) id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		card->helper = data->helper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 		card->firmware = data->firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 		card->reg = data->reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 		card->support_pscan_win_report = data->support_pscan_win_report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 		card->supports_fw_dump = data->supports_fw_dump;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	if (btmrvl_sdio_register_dev(card) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 		BT_ERR("Failed to register BT device!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	/* Disable the interrupts on the card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	btmrvl_sdio_disable_host_int(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 	if (btmrvl_sdio_download_fw(card)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 		BT_ERR("Downloading firmware failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		goto unreg_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	btmrvl_sdio_enable_host_int(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	/* Device tree node parsing and platform specific configuration*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	btmrvl_sdio_probe_of(&func->dev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	priv = btmrvl_add_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	if (!priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		BT_ERR("Initializing card failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 		goto disable_host_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	card->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	/* Initialize the interface specific function pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	priv->hw_host_to_card = btmrvl_sdio_host_to_card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	priv->hw_process_int_status = btmrvl_sdio_process_int_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	if (btmrvl_register_hdev(priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		BT_ERR("Register hdev failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		goto disable_host_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) disable_host_int:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	btmrvl_sdio_disable_host_int(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) unreg_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	btmrvl_sdio_unregister_dev(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) static void btmrvl_sdio_remove(struct sdio_func *func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	struct btmrvl_sdio_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 		card = sdio_get_drvdata(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		if (card) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 			/* Send SHUTDOWN command & disable interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 			 * if user removes the module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 			if (user_rmmod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 				btmrvl_send_module_cfg_cmd(card->priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 							MODULE_SHUTDOWN_REQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 				btmrvl_sdio_disable_host_int(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 			BT_DBG("unregister dev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 			card->priv->surprise_removed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 			btmrvl_sdio_unregister_dev(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 			btmrvl_remove_card(card->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static int btmrvl_sdio_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	struct sdio_func *func = dev_to_sdio_func(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	struct btmrvl_sdio_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	struct btmrvl_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	mmc_pm_flag_t pm_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 	struct hci_dev *hcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		pm_flags = sdio_get_host_pm_caps(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		BT_DBG("%s: suspend: PM flags = 0x%x", sdio_func_id(func),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 		       pm_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		if (!(pm_flags & MMC_PM_KEEP_POWER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 			BT_ERR("%s: cannot remain alive while suspended",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 			       sdio_func_id(func));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 		card = sdio_get_drvdata(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		if (!card || !card->priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 			BT_ERR("card or priv structure is not valid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 		BT_ERR("sdio_func is not specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	/* Enable platform specific wakeup interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 	    device_may_wakeup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 		card->plt_wake_cfg->wake_by_bt = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		enable_irq(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		enable_irq_wake(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	priv = card->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	priv->adapter->is_suspending = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 	hcidev = priv->btmrvl_dev.hcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	BT_DBG("%s: SDIO suspend", hcidev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	hci_suspend_dev(hcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	if (priv->adapter->hs_state != HS_ACTIVATED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		if (btmrvl_enable_hs(priv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 			BT_ERR("HS not activated, suspend failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 			/* Disable platform specific wakeup interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 			if (card->plt_wake_cfg &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 			    card->plt_wake_cfg->irq_bt >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 			    device_may_wakeup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 				disable_irq_wake(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 				disable_irq(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 			priv->adapter->is_suspending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	priv->adapter->is_suspending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	priv->adapter->is_suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	/* We will keep the power when hs enabled successfully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	if (priv->adapter->hs_state == HS_ACTIVATED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		BT_DBG("suspend with MMC_PM_KEEP_POWER");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 		return sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	BT_DBG("suspend without MMC_PM_KEEP_POWER");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) static int btmrvl_sdio_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	struct sdio_func *func = dev_to_sdio_func(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	struct btmrvl_sdio_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	struct btmrvl_private *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	mmc_pm_flag_t pm_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	struct hci_dev *hcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	if (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 		pm_flags = sdio_get_host_pm_caps(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		BT_DBG("%s: resume: PM flags = 0x%x", sdio_func_id(func),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		       pm_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		card = sdio_get_drvdata(func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		if (!card || !card->priv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 			BT_ERR("card or priv structure is not valid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		BT_ERR("sdio_func is not specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	priv = card->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	if (!priv->adapter->is_suspended) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		BT_DBG("device already resumed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 	priv->hw_wakeup_firmware(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	priv->adapter->hs_state = HS_DEACTIVATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	hcidev = priv->btmrvl_dev.hcidev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	priv->adapter->is_suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	BT_DBG("%s: SDIO resume", hcidev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	hci_resume_dev(hcidev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	/* Disable platform specific wakeup interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	if (card->plt_wake_cfg && card->plt_wake_cfg->irq_bt >= 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	    device_may_wakeup(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 		disable_irq_wake(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		disable_irq(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		if (card->plt_wake_cfg->wake_by_bt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			/* Undo our disable, since interrupt handler already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 			 * did this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 			enable_irq(card->plt_wake_cfg->irq_bt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) static const struct dev_pm_ops btmrvl_sdio_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	.suspend	= btmrvl_sdio_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	.resume		= btmrvl_sdio_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) static struct sdio_driver bt_mrvl_sdio = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	.name		= "btmrvl_sdio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	.id_table	= btmrvl_sdio_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	.probe		= btmrvl_sdio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	.remove		= btmrvl_sdio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	.drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 		.coredump = btmrvl_sdio_coredump,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 		.pm = &btmrvl_sdio_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) static int __init btmrvl_sdio_init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	if (sdio_register_driver(&bt_mrvl_sdio) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 		BT_ERR("SDIO Driver Registration Failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	/* Clear the flag in case user removes the card. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	user_rmmod = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static void __exit btmrvl_sdio_exit_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 	/* Set the flag as user is removing this module. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	user_rmmod = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	sdio_unregister_driver(&bt_mrvl_sdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) module_init(btmrvl_sdio_init_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) module_exit(btmrvl_sdio_exit_module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) MODULE_AUTHOR("Marvell International Ltd.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) MODULE_DESCRIPTION("Marvell BT-over-SDIO driver ver " VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) MODULE_VERSION(VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) MODULE_FIRMWARE("mrvl/sd8688.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) MODULE_FIRMWARE("mrvl/sdsd8977_combo_v2.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) MODULE_FIRMWARE("mrvl/sd8987_uapsta.bin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) MODULE_FIRMWARE("mrvl/sdsd8997_combo_v4.bin");