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/export.h>
9 #include <linux/slab.h>
10 #include <linux/sched.h>
11 #include "ishtp-dev.h"
12 #include "hbm.h"
13 #include "client.h"
14 
15 /**
16  * ishtp_dev_state_str() -Convert to string format
17  * @state: state to convert
18  *
19  * Convert state to string for prints
20  *
21  * Return: character pointer to converted string
22  */
ishtp_dev_state_str(int state)23 const char *ishtp_dev_state_str(int state)
24 {
25 	switch (state) {
26 	case ISHTP_DEV_INITIALIZING:
27 		return	"INITIALIZING";
28 	case ISHTP_DEV_INIT_CLIENTS:
29 		return	"INIT_CLIENTS";
30 	case ISHTP_DEV_ENABLED:
31 		return	"ENABLED";
32 	case ISHTP_DEV_RESETTING:
33 		return	"RESETTING";
34 	case ISHTP_DEV_DISABLED:
35 		return	"DISABLED";
36 	case ISHTP_DEV_POWER_DOWN:
37 		return	"POWER_DOWN";
38 	case ISHTP_DEV_POWER_UP:
39 		return	"POWER_UP";
40 	default:
41 		return "unknown";
42 	}
43 }
44 
45 /**
46  * ishtp_device_init() - ishtp device init
47  * @dev: ISHTP device instance
48  *
49  * After ISHTP device is alloacted, this function is used to initialize
50  * each field which includes spin lock, work struct and lists
51  */
ishtp_device_init(struct ishtp_device * dev)52 void ishtp_device_init(struct ishtp_device *dev)
53 {
54 	dev->dev_state = ISHTP_DEV_INITIALIZING;
55 	INIT_LIST_HEAD(&dev->cl_list);
56 	INIT_LIST_HEAD(&dev->device_list);
57 	dev->rd_msg_fifo_head = 0;
58 	dev->rd_msg_fifo_tail = 0;
59 	spin_lock_init(&dev->rd_msg_spinlock);
60 
61 	init_waitqueue_head(&dev->wait_hbm_recvd_msg);
62 	spin_lock_init(&dev->read_list_spinlock);
63 	spin_lock_init(&dev->device_lock);
64 	spin_lock_init(&dev->device_list_lock);
65 	spin_lock_init(&dev->cl_list_lock);
66 	spin_lock_init(&dev->fw_clients_lock);
67 	INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn);
68 
69 	bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX);
70 	dev->open_handle_count = 0;
71 
72 	/*
73 	 * Reserving client ID 0 for ISHTP Bus Message communications
74 	 */
75 	bitmap_set(dev->host_clients_map, 0, 1);
76 
77 	INIT_LIST_HEAD(&dev->read_list.list);
78 
79 }
80 EXPORT_SYMBOL(ishtp_device_init);
81 
82 /**
83  * ishtp_start() - Start ISH processing
84  * @dev: ISHTP device instance
85  *
86  * Start ISHTP processing by sending query subscriber message
87  *
88  * Return: 0 on success else -ENODEV
89  */
ishtp_start(struct ishtp_device * dev)90 int ishtp_start(struct ishtp_device *dev)
91 {
92 	if (ishtp_hbm_start_wait(dev)) {
93 		dev_err(dev->devc, "HBM haven't started");
94 		goto err;
95 	}
96 
97 	/* suspend & resume notification - send QUERY_SUBSCRIBERS msg */
98 	ishtp_query_subscribers(dev);
99 
100 	return 0;
101 err:
102 	dev_err(dev->devc, "link layer initialization failed.\n");
103 	dev->dev_state = ISHTP_DEV_DISABLED;
104 	return -ENODEV;
105 }
106 EXPORT_SYMBOL(ishtp_start);
107