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) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * ISHTP bus driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2012-2016, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "bus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "ishtp-dev.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "client.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "hbm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static int ishtp_use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) module_param_named(ishtp_use_dma, ishtp_use_dma, int, 0600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) MODULE_PARM_DESC(ishtp_use_dma, "Use DMA to send messages");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define to_ishtp_cl_driver(d) container_of(d, struct ishtp_cl_driver, driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define to_ishtp_cl_device(d) container_of(d, struct ishtp_cl_device, dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static bool ishtp_device_ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * ishtp_recv() - process ishtp message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * @dev: ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * If a message with valid header and size is received, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * this function calls appropriate handler. The host or firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * address is zero, then they are host bus management message,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * otherwise they are message fo clients.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) void ishtp_recv(struct ishtp_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	uint32_t	msg_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	struct ishtp_msg_hdr	*ishtp_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	/* Read ISHTP header dword */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	msg_hdr = dev->ops->ishtp_read_hdr(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	if (!msg_hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	dev->ops->sync_fw_clock(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	ishtp_hdr = (struct ishtp_msg_hdr *)&msg_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	dev->ishtp_msg_hdr = msg_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	/* Sanity check: ISHTP frag. length in header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (ishtp_hdr->length > dev->mtu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		dev_err(dev->devc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			"ISHTP hdr - bad length: %u; dropped [%08X]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			(unsigned int)ishtp_hdr->length, msg_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/* ISHTP bus message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (!ishtp_hdr->host_addr && !ishtp_hdr->fw_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		recv_hbm(dev, ishtp_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	/* ISHTP fixed-client message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	else if (!ishtp_hdr->host_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		recv_fixed_cl_msg(dev, ishtp_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		/* ISHTP client message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		recv_ishtp_cl_msg(dev, ishtp_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) EXPORT_SYMBOL(ishtp_recv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * ishtp_send_msg() - Send ishtp message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * @dev: ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * @hdr: Message header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * @msg: Message contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * @ipc_send_compl: completion callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * @ipc_send_compl_prm: completion callback parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * Send a multi fragment message via IPC. After sending the first fragment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * the completion callback is called to schedule transmit of next fragment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * Return: This returns IPC send message status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) int ishtp_send_msg(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		       void *msg, void(*ipc_send_compl)(void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		       void *ipc_send_compl_prm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	unsigned char	ipc_msg[IPC_FULL_MSG_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	uint32_t	drbl_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	drbl_val = dev->ops->ipc_get_header(dev, hdr->length +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 					    sizeof(struct ishtp_msg_hdr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 					    1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	memcpy(ipc_msg, &drbl_val, sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	memcpy(ipc_msg + sizeof(uint32_t), hdr, sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	memcpy(ipc_msg + 2 * sizeof(uint32_t), msg, hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return	dev->ops->write(dev, ipc_send_compl, ipc_send_compl_prm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 				ipc_msg, 2 * sizeof(uint32_t) + hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * ishtp_write_message() - Send ishtp single fragment message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * @dev: ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * @hdr: Message header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * @buf: message data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * Send a single fragment message via IPC.  This returns IPC send message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * Return: This returns IPC send message status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int ishtp_write_message(struct ishtp_device *dev, struct ishtp_msg_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 			void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	return ishtp_send_msg(dev, hdr, buf, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^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)  * ishtp_fw_cl_by_uuid() - locate index of fw client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * @dev: ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @uuid: uuid of the client to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Search firmware client using UUID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * Return: fw client index or -ENOENT if not found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) int ishtp_fw_cl_by_uuid(struct ishtp_device *dev, const guid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	for (i = 0; i < dev->fw_clients_num; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		if (guid_equal(uuid, &dev->fw_clients[i].props.protocol_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) EXPORT_SYMBOL(ishtp_fw_cl_by_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * ishtp_fw_cl_get_client() - return client information to client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * @dev: the ishtp device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @uuid: uuid of the client to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * Search firmware client using UUID and reture related client information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * Return: pointer of client information on success, NULL on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 					       const guid_t *uuid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	spin_lock_irqsave(&dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	i = ishtp_fw_cl_by_uuid(dev, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (i < 0 || dev->fw_clients[i].props.fixed_address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	return &dev->fw_clients[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) EXPORT_SYMBOL(ishtp_fw_cl_get_client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * ishtp_get_fw_client_id() - Get fw client id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  * This interface is used to reset HW get FW client id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)  * Return: firmware client id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int ishtp_get_fw_client_id(struct ishtp_fw_client *fw_client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	return fw_client->client_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) EXPORT_SYMBOL(ishtp_get_fw_client_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)  * ishtp_fw_cl_by_id() - return index to fw_clients for client_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)  * @dev: the ishtp device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)  * @client_id: fw client id to search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)  * Search firmware client using client id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)  * Return: index on success, -ENOENT on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int ishtp_fw_cl_by_id(struct ishtp_device *dev, uint8_t client_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	int i, res = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	spin_lock_irqsave(&dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	for (i = 0; i < dev->fw_clients_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		if (dev->fw_clients[i].client_id == client_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			res = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	spin_unlock_irqrestore(&dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * ishtp_cl_device_probe() - Bus probe() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  * This is a bus probe callback and calls the drive probe function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)  * Return: Return value from driver probe() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int ishtp_cl_device_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	struct ishtp_cl_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	driver = to_ishtp_cl_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (!driver || !driver->probe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return driver->probe(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)  * ishtp_cl_bus_match() - Bus match() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  * @drv: the driver structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  * This is a bus match callback, called when a new ishtp_cl_device is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * registered during ishtp bus client enumeration. Use the guid_t in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * drv and dev to decide whether they match or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * Return: 1 if dev & drv matches, 0 otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static int ishtp_cl_bus_match(struct device *dev, struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	struct ishtp_cl_driver *driver = to_ishtp_cl_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return guid_equal(driver->guid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 			  &device->fw_client->props.protocol_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  * ishtp_cl_device_remove() - Bus remove() callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * @dev: the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)  * This is a bus remove callback and calls the drive remove function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)  * Since the ISH driver model supports only built in, this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * primarily can be called during pci driver init failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  * Return: Return value from driver remove() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int ishtp_cl_device_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	struct ishtp_cl_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	if (!device || !dev->driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (device->event_cb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		device->event_cb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		cancel_work_sync(&device->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	driver = to_ishtp_cl_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	if (!driver->remove) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		dev->driver = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return 0;
^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) 	return driver->remove(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  * ishtp_cl_device_suspend() - Bus suspend callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * @dev:	device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  * Called during device suspend process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * Return: Return value from driver suspend() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int ishtp_cl_device_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	struct ishtp_cl_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	driver = to_ishtp_cl_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (driver && driver->driver.pm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		if (driver->driver.pm->suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			ret = driver->driver.pm->suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * ishtp_cl_device_resume() - Bus resume callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * @dev:	device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  * Called during device resume process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  * Return: Return value from driver resume() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static int ishtp_cl_device_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct ishtp_cl_device *device = to_ishtp_cl_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct ishtp_cl_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	 * When ISH needs hard reset, it is done asynchrnously, hence bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	 * resume will  be called before full ISH resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (device->ishtp_dev->resume_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	driver = to_ishtp_cl_driver(dev->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	if (driver && driver->driver.pm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		if (driver->driver.pm->resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			ret = driver->driver.pm->resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  * ishtp_cl_device_reset() - Reset callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * @device:	ishtp client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)  * This is a callback when HW reset is done and the device need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)  * reinit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)  * Return: Return value from driver reset() call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static int ishtp_cl_device_reset(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	struct ishtp_cl_driver *driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	device->event_cb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	cancel_work_sync(&device->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	driver = to_ishtp_cl_driver(device->dev.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	if (driver && driver->reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		ret = driver->reset(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	len = snprintf(buf, PAGE_SIZE, "ishtp:%s\n", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static DEVICE_ATTR_RO(modalias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static struct attribute *ishtp_cl_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	&dev_attr_modalias.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ATTRIBUTE_GROUPS(ishtp_cl_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int ishtp_cl_uevent(struct device *dev, struct kobj_uevent_env *env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (add_uevent_var(env, "MODALIAS=ishtp:%s", dev_name(dev)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static const struct dev_pm_ops ishtp_cl_bus_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	/* Suspend callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	.suspend = ishtp_cl_device_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	.resume = ishtp_cl_device_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	/* Hibernate callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	.freeze = ishtp_cl_device_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	.thaw = ishtp_cl_device_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	.restore = ishtp_cl_device_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static struct bus_type ishtp_cl_bus_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	.name		= "ishtp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	.dev_groups	= ishtp_cl_dev_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	.probe		= ishtp_cl_device_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	.match		= ishtp_cl_bus_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	.remove		= ishtp_cl_device_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	.pm		= &ishtp_cl_bus_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	.uevent		= ishtp_cl_uevent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) static void ishtp_cl_dev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	kfree(to_ishtp_cl_device(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) static const struct device_type ishtp_cl_device_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.release	= ishtp_cl_dev_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  * ishtp_bus_add_device() - Function to create device on bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * @dev:	ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * @uuid:	uuid of the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  * @name:	Name of the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * Allocate ISHTP bus client device, attach it to uuid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  * and register with ISHTP bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)  * Return: ishtp_cl_device pointer or NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 						    guid_t uuid, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	struct ishtp_cl_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	spin_lock_irqsave(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	list_for_each_entry(device, &dev->device_list, device_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		if (!strcmp(name, dev_name(&device->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			device->fw_client = &dev->fw_clients[
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 				dev->fw_client_presentation_num - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			spin_unlock_irqrestore(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			ishtp_cl_device_reset(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			return device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	spin_unlock_irqrestore(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	device = kzalloc(sizeof(struct ishtp_cl_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	if (!device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	device->dev.parent = dev->devc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	device->dev.bus = &ishtp_cl_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	device->dev.type = &ishtp_cl_device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	device->ishtp_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	device->fw_client =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		&dev->fw_clients[dev->fw_client_presentation_num - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	dev_set_name(&device->dev, "%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	spin_lock_irqsave(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	list_add_tail(&device->device_link, &dev->device_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	spin_unlock_irqrestore(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	status = device_register(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		spin_lock_irqsave(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		list_del(&device->device_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		spin_unlock_irqrestore(&dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		dev_err(dev->devc, "Failed to register ISHTP client device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		put_device(&device->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		return NULL;
^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) 	ishtp_device_ready = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	return device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  * ishtp_bus_remove_device() - Function to relase device on bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  * @device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)  * This is a counterpart of ishtp_bus_add_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)  * Device is unregistered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)  * the device structure is freed in 'ishtp_cl_dev_release' function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)  * Called only during error in pci driver init path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void ishtp_bus_remove_device(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	device_unregister(&device->dev);
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)  * ishtp_cl_driver_register() - Client driver register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)  * @driver:	the client driver instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)  * @owner:	Owner of this driver module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)  * Once a client driver is probed, it created a client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)  * instance and registers with the bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)  * Return: Return value of driver_register or -ENODEV if not ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int ishtp_cl_driver_register(struct ishtp_cl_driver *driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 			     struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	if (!ishtp_device_ready)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	driver->driver.name = driver->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	driver->driver.owner = owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	driver->driver.bus = &ishtp_cl_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	return driver_register(&driver->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) EXPORT_SYMBOL(ishtp_cl_driver_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  * ishtp_cl_driver_unregister() - Client driver unregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)  * @driver:	the client driver instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)  * Unregister client during device removal process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) void ishtp_cl_driver_unregister(struct ishtp_cl_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	driver_unregister(&driver->driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) EXPORT_SYMBOL(ishtp_cl_driver_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)  * ishtp_bus_event_work() - event work function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)  * @work:	work struct pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  * Once an event is received for a client this work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * function is called. If the device has registered a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  * callback then the callback is called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static void ishtp_bus_event_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	struct ishtp_cl_device *device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	device = container_of(work, struct ishtp_cl_device, event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (device->event_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		device->event_cb(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)  * ishtp_cl_bus_rx_event() - schedule event work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)  * @device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)  * Once an event is received for a client this schedules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)  * a work function to process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) void ishtp_cl_bus_rx_event(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (!device || !device->event_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	if (device->event_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		schedule_work(&device->event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^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)  * ishtp_register_event_cb() - Register callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  * @device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  * @event_cb:	Event processor for an client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)  * Register a callback for events, called from client driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)  * Return: Return 0 or -EALREADY if already registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int ishtp_register_event_cb(struct ishtp_cl_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	void (*event_cb)(struct ishtp_cl_device *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	if (device->event_cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 		return -EALREADY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	device->event_cb = event_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	INIT_WORK(&device->event_work, ishtp_bus_event_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) EXPORT_SYMBOL(ishtp_register_event_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)  * ishtp_get_device() - update usage count for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)  * @cl_device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)  * Increment the usage count. The device can't be deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) void ishtp_get_device(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	cl_device->reference_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) EXPORT_SYMBOL(ishtp_get_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)  * ishtp_put_device() - decrement usage count for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)  * @cl_device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)  * Decrement the usage count. The device can be deleted is count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) void ishtp_put_device(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	cl_device->reference_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) EXPORT_SYMBOL(ishtp_put_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)  * ishtp_set_drvdata() - set client driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)  * @cl_device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)  * @data:	driver data need to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  * Set client driver data to cl_device->driver_data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	cl_device->driver_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) EXPORT_SYMBOL(ishtp_set_drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)  * ishtp_get_drvdata() - get client driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)  * @cl_device:	client device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)  * Get client driver data from cl_device->driver_data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)  * Return: pointer of driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	return cl_device->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) EXPORT_SYMBOL(ishtp_get_drvdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  * ishtp_dev_to_cl_device() - get ishtp_cl_device instance from device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)  * @device: device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)  * Get ish_cl_device instance which embeds device instance in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)  * Return: pointer to ishtp_cl_device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	return to_ishtp_cl_device(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) EXPORT_SYMBOL(ishtp_dev_to_cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)  * ishtp_bus_new_client() - Create a new client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)  * @dev:	ISHTP device instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)  * Once bus protocol enumerates a client, this is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)  * to add a device for the client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)  * Return: 0 on success or error code on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) int ishtp_bus_new_client(struct ishtp_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	char	*dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	struct ishtp_cl_device	*cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	guid_t	device_uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	 * For all reported clients, create an unconnected client and add its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	 * device to ISHTP bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	 * If appropriate driver has loaded, this will trigger its probe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	 * Otherwise, probe() will be called when driver is loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	i = dev->fw_client_presentation_num - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	device_uuid = dev->fw_clients[i].props.protocol_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	dev_name = kasprintf(GFP_KERNEL, "{%pUL}", &device_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	if (!dev_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		return	-ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	cl_device = ishtp_bus_add_device(dev, device_uuid, dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (!cl_device) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		kfree(dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		return	-ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	kfree(dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	return	0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^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)  * ishtp_cl_device_bind() - bind a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)  * @cl:		ishtp client device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)  * Binds connected ishtp_cl to ISHTP bus device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)  * Return: 0 on success or fault code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int ishtp_cl_device_bind(struct ishtp_cl *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	struct ishtp_cl_device	*cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	int	rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	if (!cl->fw_client_id || cl->state != ISHTP_CL_CONNECTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		return	-EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	rv = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	spin_lock_irqsave(&cl->dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	list_for_each_entry(cl_device, &cl->dev->device_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 			device_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		if (cl_device->fw_client &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 		    cl_device->fw_client->client_id == cl->fw_client_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 			cl->device = cl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 			rv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	spin_unlock_irqrestore(&cl->dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	return	rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)  * ishtp_bus_remove_all_clients() - Remove all clients
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)  * @ishtp_dev:		ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)  * @warm_reset:		Reset due to FW reset dure to errors or S3 suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)  * This is part of reset/remove flow. This function the main processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)  * only targets error processing, if the FW has forced reset or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)  * error to remove connected clients. When warm reset the client devices are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)  * not removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) void ishtp_bus_remove_all_clients(struct ishtp_device *ishtp_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 				  bool warm_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	struct ishtp_cl_device	*cl_device, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	struct ishtp_cl	*cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	spin_lock_irqsave(&ishtp_dev->cl_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	list_for_each_entry(cl, &ishtp_dev->cl_list, link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		cl->state = ISHTP_CL_DISCONNECTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		 * Wake any pending process. The waiter would check dev->state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		 * and determine that it's not enabled already,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		 * and will return error to its caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		wake_up_interruptible(&cl->wait_ctrl_res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		/* Disband any pending read/write requests and free rb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		ishtp_cl_flush_queues(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		/* Remove all free and in_process rings, both Rx and Tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		ishtp_cl_free_rx_ring(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		ishtp_cl_free_tx_ring(cl);
^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) 		 * Free client and ISHTP bus client device structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		 * don't free host client because it is part of the OS fd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		 * structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	spin_unlock_irqrestore(&ishtp_dev->cl_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	/* Release DMA buffers for client messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	ishtp_cl_free_dma_buf(ishtp_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	/* remove bus clients */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	list_for_each_entry_safe(cl_device, n, &ishtp_dev->device_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 				 device_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 		cl_device->fw_client = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 		if (warm_reset && cl_device->reference_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 		list_del(&cl_device->device_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 		spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 		ishtp_bus_remove_device(cl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 		spin_lock_irqsave(&ishtp_dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	spin_unlock_irqrestore(&ishtp_dev->device_list_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	/* Free all client structures */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	spin_lock_irqsave(&ishtp_dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	kfree(ishtp_dev->fw_clients);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	ishtp_dev->fw_clients = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	ishtp_dev->fw_clients_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	ishtp_dev->fw_client_presentation_num = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	ishtp_dev->fw_client_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	bitmap_zero(ishtp_dev->fw_clients_map, ISHTP_CLIENTS_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	spin_unlock_irqrestore(&ishtp_dev->fw_clients_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) EXPORT_SYMBOL(ishtp_bus_remove_all_clients);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)  * ishtp_reset_handler() - IPC reset handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)  * @dev:	ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)  * ISHTP Handler for IPC_RESET notification
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) void ishtp_reset_handler(struct ishtp_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	unsigned long	flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	/* Handle FW-initiated reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	dev->dev_state = ISHTP_DEV_RESETTING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	/* Clear BH processing queue - no further HBMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	spin_lock_irqsave(&dev->rd_msg_spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	dev->rd_msg_fifo_head = dev->rd_msg_fifo_tail = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	spin_unlock_irqrestore(&dev->rd_msg_spinlock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	/* Handle ISH FW reset against upper layers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	ishtp_bus_remove_all_clients(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) EXPORT_SYMBOL(ishtp_reset_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)  * ishtp_reset_compl_handler() - Reset completion handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)  * @dev:	ishtp device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)  * ISHTP handler for IPC_RESET sequence completion to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)  * host message bus start protocol sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) void ishtp_reset_compl_handler(struct ishtp_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	dev->dev_state = ISHTP_DEV_INIT_CLIENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	dev->hbm_state = ISHTP_HBM_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	ishtp_hbm_start_req(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) EXPORT_SYMBOL(ishtp_reset_compl_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)  * ishtp_use_dma_transfer() - Function to use DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)  * This interface is used to enable usage of DMA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)  * Return non zero if DMA can be enabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) int ishtp_use_dma_transfer(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	return ishtp_use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)  * ishtp_device() - Return device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)  * This interface is used to return device pointer from ishtp_cl_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)  * instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)  * Return: device *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct device *ishtp_device(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	return &device->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) EXPORT_SYMBOL(ishtp_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)  * ishtp_get_pci_device() - Return PCI device dev pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)  * This interface is used to return PCI device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)  * from ishtp_cl_device instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)  * Return: device *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct device *ishtp_get_pci_device(struct ishtp_cl_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	return device->ishtp_dev->devc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) EXPORT_SYMBOL(ishtp_get_pci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)  * ishtp_trace_callback() - Return trace callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)  * This interface is used to return trace callback function pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)  * Return: void *.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) void *ishtp_trace_callback(struct ishtp_cl_device *cl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	return cl_device->ishtp_dev->print_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) EXPORT_SYMBOL(ishtp_trace_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)  * ish_hw_reset() - Call HW reset IPC callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)  * This interface is used to reset HW in case of error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)  * Return: value from IPC hw_reset callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) int ish_hw_reset(struct ishtp_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	return dev->ops->hw_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) EXPORT_SYMBOL(ish_hw_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)  * ishtp_bus_register() - Function to register bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)  * This register ishtp bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)  * Return: Return output of bus_register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int  __init ishtp_bus_register(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	return bus_register(&ishtp_cl_bus_type);
^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)  * ishtp_bus_unregister() - Function to unregister bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)  * This unregister ishtp bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) static void __exit ishtp_bus_unregister(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	bus_unregister(&ishtp_cl_bus_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) module_init(ishtp_bus_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) module_exit(ishtp_bus_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) MODULE_LICENSE("GPL");