xref: /linux/drivers/hid/intel-ish-hid/ishtp/init.c (revision e814f3fd16acfb7f9966773953de8f740a1e3202)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Initialization protocol for ISHTP driver
4  *
5  * Copyright (c) 2003-2016, Intel Corporation.
6  */
7 
8 #include <linux/devm-helpers.h>
9 #include <linux/export.h>
10 #include <linux/slab.h>
11 #include <linux/sched.h>
12 #include "ishtp-dev.h"
13 #include "hbm.h"
14 #include "client.h"
15 #include "loader.h"
16 
17 /**
18  * ishtp_device_init() - ishtp device init
19  * @dev: ISHTP device instance
20  *
21  * After ISHTP device is alloacted, this function is used to initialize
22  * each field which includes spin lock, work struct and lists
23  */
24 void ishtp_device_init(struct ishtp_device *dev)
25 {
26 	int ret;
27 
28 	dev->dev_state = ISHTP_DEV_INITIALIZING;
29 	INIT_LIST_HEAD(&dev->cl_list);
30 	INIT_LIST_HEAD(&dev->device_list);
31 	dev->rd_msg_fifo_head = 0;
32 	dev->rd_msg_fifo_tail = 0;
33 	spin_lock_init(&dev->rd_msg_spinlock);
34 
35 	init_waitqueue_head(&dev->wait_hbm_recvd_msg);
36 	init_waitqueue_head(&dev->wait_loader_recvd_msg);
37 	spin_lock_init(&dev->read_list_spinlock);
38 	spin_lock_init(&dev->device_lock);
39 	spin_lock_init(&dev->device_list_lock);
40 	spin_lock_init(&dev->cl_list_lock);
41 	spin_lock_init(&dev->fw_clients_lock);
42 	INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn);
43 
44 	bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX);
45 	dev->open_handle_count = 0;
46 
47 	/*
48 	 * Reserving client ID 0 for ISHTP Bus Message communications
49 	 */
50 	bitmap_set(dev->host_clients_map, 0, 1);
51 
52 	INIT_LIST_HEAD(&dev->read_list.list);
53 
54 	ret = devm_work_autocancel(dev->devc, &dev->work_fw_loader, ishtp_loader_work);
55 	if (ret)
56 		dev_err_probe(dev->devc, ret, "Failed to initialise FW loader work\n");
57 }
58 EXPORT_SYMBOL(ishtp_device_init);
59 
60 /**
61  * ishtp_start() - Start ISH processing
62  * @dev: ISHTP device instance
63  *
64  * Start ISHTP processing by sending query subscriber message
65  *
66  * Return: 0 on success else -ENODEV
67  */
68 int ishtp_start(struct ishtp_device *dev)
69 {
70 	if (ishtp_hbm_start_wait(dev)) {
71 		dev_err(dev->devc, "HBM haven't started");
72 		goto err;
73 	}
74 
75 	/* suspend & resume notification - send QUERY_SUBSCRIBERS msg */
76 	ishtp_query_subscribers(dev);
77 
78 	return 0;
79 err:
80 	dev_err(dev->devc, "link layer initialization failed.\n");
81 	dev->dev_state = ISHTP_DEV_DISABLED;
82 	return -ENODEV;
83 }
84 EXPORT_SYMBOL(ishtp_start);
85