Linux-libre 4.19.20-gnu
[librecmc/linux-libre.git] / drivers / hid / intel-ish-hid / ishtp / init.c
1 /*
2  * Initialization protocol for ISHTP driver
3  *
4  * Copyright (c) 2003-2016, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  */
15
16 #include <linux/export.h>
17 #include <linux/slab.h>
18 #include <linux/sched.h>
19 #include "ishtp-dev.h"
20 #include "hbm.h"
21 #include "client.h"
22
23 /**
24  * ishtp_dev_state_str() -Convert to string format
25  * @state: state to convert
26  *
27  * Convert state to string for prints
28  *
29  * Return: character pointer to converted string
30  */
31 const char *ishtp_dev_state_str(int state)
32 {
33         switch (state) {
34         case ISHTP_DEV_INITIALIZING:
35                 return  "INITIALIZING";
36         case ISHTP_DEV_INIT_CLIENTS:
37                 return  "INIT_CLIENTS";
38         case ISHTP_DEV_ENABLED:
39                 return  "ENABLED";
40         case ISHTP_DEV_RESETTING:
41                 return  "RESETTING";
42         case ISHTP_DEV_DISABLED:
43                 return  "DISABLED";
44         case ISHTP_DEV_POWER_DOWN:
45                 return  "POWER_DOWN";
46         case ISHTP_DEV_POWER_UP:
47                 return  "POWER_UP";
48         default:
49                 return "unknown";
50         }
51 }
52
53 /**
54  * ishtp_device_init() - ishtp device init
55  * @dev: ISHTP device instance
56  *
57  * After ISHTP device is alloacted, this function is used to initialize
58  * each field which includes spin lock, work struct and lists
59  */
60 void ishtp_device_init(struct ishtp_device *dev)
61 {
62         dev->dev_state = ISHTP_DEV_INITIALIZING;
63         INIT_LIST_HEAD(&dev->cl_list);
64         INIT_LIST_HEAD(&dev->device_list);
65         dev->rd_msg_fifo_head = 0;
66         dev->rd_msg_fifo_tail = 0;
67         spin_lock_init(&dev->rd_msg_spinlock);
68
69         init_waitqueue_head(&dev->wait_hbm_recvd_msg);
70         spin_lock_init(&dev->read_list_spinlock);
71         spin_lock_init(&dev->device_lock);
72         spin_lock_init(&dev->device_list_lock);
73         spin_lock_init(&dev->cl_list_lock);
74         spin_lock_init(&dev->fw_clients_lock);
75         INIT_WORK(&dev->bh_hbm_work, bh_hbm_work_fn);
76
77         bitmap_zero(dev->host_clients_map, ISHTP_CLIENTS_MAX);
78         dev->open_handle_count = 0;
79
80         /*
81          * Reserving client ID 0 for ISHTP Bus Message communications
82          */
83         bitmap_set(dev->host_clients_map, 0, 1);
84
85         INIT_LIST_HEAD(&dev->read_list.list);
86
87 }
88 EXPORT_SYMBOL(ishtp_device_init);
89
90 /**
91  * ishtp_start() - Start ISH processing
92  * @dev: ISHTP device instance
93  *
94  * Start ISHTP processing by sending query subscriber message
95  *
96  * Return: 0 on success else -ENODEV
97  */
98 int ishtp_start(struct ishtp_device *dev)
99 {
100         if (ishtp_hbm_start_wait(dev)) {
101                 dev_err(dev->devc, "HBM haven't started");
102                 goto err;
103         }
104
105         /* suspend & resume notification - send QUERY_SUBSCRIBERS msg */
106         ishtp_query_subscribers(dev);
107
108         return 0;
109 err:
110         dev_err(dev->devc, "link layer initialization failed.\n");
111         dev->dev_state = ISHTP_DEV_DISABLED;
112         return -ENODEV;
113 }
114 EXPORT_SYMBOL(ishtp_start);