diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2015-02-10 03:39:31 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-03-01 22:36:59 -0500 |
commit | b7d885145538ddedb1ae23b782ab7c7c0a856e9f (patch) | |
tree | 9470b5807362a068e85487a429fb3b3f543af53e /drivers/misc | |
parent | e9395e3f8952110bda60b54ad03ec52c6e9c7dbd (diff) |
mei: revamp me clients list handling
1. Use rw lock to access the me_clients list
2. Reuse already defined find functions also when
removing particular me client
3. Add wrappers for addition and deletion
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/mei/client.c | 194 | ||||
-rw-r--r-- | drivers/misc/mei/client.h | 5 | ||||
-rw-r--r-- | drivers/misc/mei/debugfs.c | 19 | ||||
-rw-r--r-- | drivers/misc/mei/hbm.c | 3 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 1 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 2 |
6 files changed, 162 insertions, 62 deletions
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index dfbddfe1c7a0..48813c27a47c 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -48,14 +48,14 @@ void mei_me_cl_init(struct mei_me_client *me_cl) | |||
48 | */ | 48 | */ |
49 | struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl) | 49 | struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl) |
50 | { | 50 | { |
51 | if (me_cl) | 51 | if (me_cl && kref_get_unless_zero(&me_cl->refcnt)) |
52 | kref_get(&me_cl->refcnt); | 52 | return me_cl; |
53 | 53 | ||
54 | return me_cl; | 54 | return NULL; |
55 | } | 55 | } |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * mei_me_cl_release - unlink and free me client | 58 | * mei_me_cl_release - free me client |
59 | * | 59 | * |
60 | * Locking: called under "dev->device_lock" lock | 60 | * Locking: called under "dev->device_lock" lock |
61 | * | 61 | * |
@@ -65,9 +65,10 @@ static void mei_me_cl_release(struct kref *ref) | |||
65 | { | 65 | { |
66 | struct mei_me_client *me_cl = | 66 | struct mei_me_client *me_cl = |
67 | container_of(ref, struct mei_me_client, refcnt); | 67 | container_of(ref, struct mei_me_client, refcnt); |
68 | list_del(&me_cl->list); | 68 | |
69 | kfree(me_cl); | 69 | kfree(me_cl); |
70 | } | 70 | } |
71 | |||
71 | /** | 72 | /** |
72 | * mei_me_cl_put - decrease me client refcount and free client if necessary | 73 | * mei_me_cl_put - decrease me client refcount and free client if necessary |
73 | * | 74 | * |
@@ -82,51 +83,146 @@ void mei_me_cl_put(struct mei_me_client *me_cl) | |||
82 | } | 83 | } |
83 | 84 | ||
84 | /** | 85 | /** |
85 | * mei_me_cl_by_uuid - locate me client by uuid | 86 | * __mei_me_cl_del - delete me client form the list and decrease |
87 | * reference counter | ||
88 | * | ||
89 | * @dev: mei device | ||
90 | * @me_cl: me client | ||
91 | * | ||
92 | * Locking: dev->me_clients_rwsem | ||
93 | */ | ||
94 | static void __mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl) | ||
95 | { | ||
96 | if (!me_cl) | ||
97 | return; | ||
98 | |||
99 | list_del(&me_cl->list); | ||
100 | mei_me_cl_put(me_cl); | ||
101 | } | ||
102 | |||
103 | /** | ||
104 | * mei_me_cl_add - add me client to the list | ||
105 | * | ||
106 | * @dev: mei device | ||
107 | * @me_cl: me client | ||
108 | */ | ||
109 | void mei_me_cl_add(struct mei_device *dev, struct mei_me_client *me_cl) | ||
110 | { | ||
111 | down_write(&dev->me_clients_rwsem); | ||
112 | list_add(&me_cl->list, &dev->me_clients); | ||
113 | up_write(&dev->me_clients_rwsem); | ||
114 | } | ||
115 | |||
116 | /** | ||
117 | * __mei_me_cl_by_uuid - locate me client by uuid | ||
86 | * increases ref count | 118 | * increases ref count |
87 | * | 119 | * |
88 | * @dev: mei device | 120 | * @dev: mei device |
89 | * @uuid: me client uuid | 121 | * @uuid: me client uuid |
90 | * | 122 | * |
91 | * Locking: called under "dev->device_lock" lock | ||
92 | * | ||
93 | * Return: me client or NULL if not found | 123 | * Return: me client or NULL if not found |
124 | * | ||
125 | * Locking: dev->me_clients_rwsem | ||
94 | */ | 126 | */ |
95 | struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, | 127 | static struct mei_me_client *__mei_me_cl_by_uuid(struct mei_device *dev, |
96 | const uuid_le *uuid) | 128 | const uuid_le *uuid) |
97 | { | 129 | { |
98 | struct mei_me_client *me_cl; | 130 | struct mei_me_client *me_cl; |
131 | const uuid_le *pn; | ||
132 | |||
133 | WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem)); | ||
99 | 134 | ||
100 | list_for_each_entry(me_cl, &dev->me_clients, list) | 135 | list_for_each_entry(me_cl, &dev->me_clients, list) { |
101 | if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0) | 136 | pn = &me_cl->props.protocol_name; |
137 | if (uuid_le_cmp(*uuid, *pn) == 0) | ||
102 | return mei_me_cl_get(me_cl); | 138 | return mei_me_cl_get(me_cl); |
139 | } | ||
103 | 140 | ||
104 | return NULL; | 141 | return NULL; |
105 | } | 142 | } |
106 | 143 | ||
107 | /** | 144 | /** |
145 | * mei_me_cl_by_uuid - locate me client by uuid | ||
146 | * increases ref count | ||
147 | * | ||
148 | * @dev: mei device | ||
149 | * @uuid: me client uuid | ||
150 | * | ||
151 | * Return: me client or NULL if not found | ||
152 | * | ||
153 | * Locking: dev->me_clients_rwsem | ||
154 | */ | ||
155 | struct mei_me_client *mei_me_cl_by_uuid(struct mei_device *dev, | ||
156 | const uuid_le *uuid) | ||
157 | { | ||
158 | struct mei_me_client *me_cl; | ||
159 | |||
160 | down_read(&dev->me_clients_rwsem); | ||
161 | me_cl = __mei_me_cl_by_uuid(dev, uuid); | ||
162 | up_read(&dev->me_clients_rwsem); | ||
163 | |||
164 | return me_cl; | ||
165 | } | ||
166 | |||
167 | /** | ||
108 | * mei_me_cl_by_id - locate me client by client id | 168 | * mei_me_cl_by_id - locate me client by client id |
109 | * increases ref count | 169 | * increases ref count |
110 | * | 170 | * |
111 | * @dev: the device structure | 171 | * @dev: the device structure |
112 | * @client_id: me client id | 172 | * @client_id: me client id |
113 | * | 173 | * |
114 | * Locking: called under "dev->device_lock" lock | ||
115 | * | ||
116 | * Return: me client or NULL if not found | 174 | * Return: me client or NULL if not found |
175 | * | ||
176 | * Locking: dev->me_clients_rwsem | ||
117 | */ | 177 | */ |
118 | struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) | 178 | struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) |
119 | { | 179 | { |
120 | 180 | ||
181 | struct mei_me_client *__me_cl, *me_cl = NULL; | ||
182 | |||
183 | down_read(&dev->me_clients_rwsem); | ||
184 | list_for_each_entry(__me_cl, &dev->me_clients, list) { | ||
185 | if (__me_cl->client_id == client_id) { | ||
186 | me_cl = mei_me_cl_get(__me_cl); | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | up_read(&dev->me_clients_rwsem); | ||
191 | |||
192 | return me_cl; | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * __mei_me_cl_by_uuid_id - locate me client by client id and uuid | ||
197 | * increases ref count | ||
198 | * | ||
199 | * @dev: the device structure | ||
200 | * @uuid: me client uuid | ||
201 | * @client_id: me client id | ||
202 | * | ||
203 | * Return: me client or null if not found | ||
204 | * | ||
205 | * Locking: dev->me_clients_rwsem | ||
206 | */ | ||
207 | static struct mei_me_client *__mei_me_cl_by_uuid_id(struct mei_device *dev, | ||
208 | const uuid_le *uuid, u8 client_id) | ||
209 | { | ||
121 | struct mei_me_client *me_cl; | 210 | struct mei_me_client *me_cl; |
211 | const uuid_le *pn; | ||
212 | |||
213 | WARN_ON(!rwsem_is_locked(&dev->me_clients_rwsem)); | ||
122 | 214 | ||
123 | list_for_each_entry(me_cl, &dev->me_clients, list) | 215 | list_for_each_entry(me_cl, &dev->me_clients, list) { |
124 | if (me_cl->client_id == client_id) | 216 | pn = &me_cl->props.protocol_name; |
217 | if (uuid_le_cmp(*uuid, *pn) == 0 && | ||
218 | me_cl->client_id == client_id) | ||
125 | return mei_me_cl_get(me_cl); | 219 | return mei_me_cl_get(me_cl); |
220 | } | ||
126 | 221 | ||
127 | return NULL; | 222 | return NULL; |
128 | } | 223 | } |
129 | 224 | ||
225 | |||
130 | /** | 226 | /** |
131 | * mei_me_cl_by_uuid_id - locate me client by client id and uuid | 227 | * mei_me_cl_by_uuid_id - locate me client by client id and uuid |
132 | * increases ref count | 228 | * increases ref count |
@@ -135,21 +231,18 @@ struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id) | |||
135 | * @uuid: me client uuid | 231 | * @uuid: me client uuid |
136 | * @client_id: me client id | 232 | * @client_id: me client id |
137 | * | 233 | * |
138 | * Locking: called under "dev->device_lock" lock | 234 | * Return: me client or null if not found |
139 | * | ||
140 | * Return: me client or NULL if not found | ||
141 | */ | 235 | */ |
142 | struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, | 236 | struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, |
143 | const uuid_le *uuid, u8 client_id) | 237 | const uuid_le *uuid, u8 client_id) |
144 | { | 238 | { |
145 | struct mei_me_client *me_cl; | 239 | struct mei_me_client *me_cl; |
146 | 240 | ||
147 | list_for_each_entry(me_cl, &dev->me_clients, list) | 241 | down_read(&dev->me_clients_rwsem); |
148 | if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0 && | 242 | me_cl = __mei_me_cl_by_uuid_id(dev, uuid, client_id); |
149 | me_cl->client_id == client_id) | 243 | up_read(&dev->me_clients_rwsem); |
150 | return mei_me_cl_get(me_cl); | ||
151 | 244 | ||
152 | return NULL; | 245 | return me_cl; |
153 | } | 246 | } |
154 | 247 | ||
155 | /** | 248 | /** |
@@ -162,12 +255,14 @@ struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, | |||
162 | */ | 255 | */ |
163 | void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid) | 256 | void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid) |
164 | { | 257 | { |
165 | struct mei_me_client *me_cl, *next; | 258 | struct mei_me_client *me_cl; |
166 | 259 | ||
167 | dev_dbg(dev->dev, "remove %pUl\n", uuid); | 260 | dev_dbg(dev->dev, "remove %pUl\n", uuid); |
168 | list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) | 261 | |
169 | if (uuid_le_cmp(*uuid, me_cl->props.protocol_name) == 0) | 262 | down_write(&dev->me_clients_rwsem); |
170 | mei_me_cl_put(me_cl); | 263 | me_cl = __mei_me_cl_by_uuid(dev, uuid); |
264 | __mei_me_cl_del(dev, me_cl); | ||
265 | up_write(&dev->me_clients_rwsem); | ||
171 | } | 266 | } |
172 | 267 | ||
173 | /** | 268 | /** |
@@ -181,15 +276,14 @@ void mei_me_cl_rm_by_uuid(struct mei_device *dev, const uuid_le *uuid) | |||
181 | */ | 276 | */ |
182 | void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id) | 277 | void mei_me_cl_rm_by_uuid_id(struct mei_device *dev, const uuid_le *uuid, u8 id) |
183 | { | 278 | { |
184 | struct mei_me_client *me_cl, *next; | 279 | struct mei_me_client *me_cl; |
185 | const uuid_le *pn; | ||
186 | 280 | ||
187 | dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id); | 281 | dev_dbg(dev->dev, "remove %pUl %d\n", uuid, id); |
188 | list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) { | 282 | |
189 | pn = &me_cl->props.protocol_name; | 283 | down_write(&dev->me_clients_rwsem); |
190 | if (me_cl->client_id == id && uuid_le_cmp(*uuid, *pn) == 0) | 284 | me_cl = __mei_me_cl_by_uuid_id(dev, uuid, id); |
191 | mei_me_cl_put(me_cl); | 285 | __mei_me_cl_del(dev, me_cl); |
192 | } | 286 | up_write(&dev->me_clients_rwsem); |
193 | } | 287 | } |
194 | 288 | ||
195 | /** | 289 | /** |
@@ -203,12 +297,12 @@ void mei_me_cl_rm_all(struct mei_device *dev) | |||
203 | { | 297 | { |
204 | struct mei_me_client *me_cl, *next; | 298 | struct mei_me_client *me_cl, *next; |
205 | 299 | ||
300 | down_write(&dev->me_clients_rwsem); | ||
206 | list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) | 301 | list_for_each_entry_safe(me_cl, next, &dev->me_clients, list) |
207 | mei_me_cl_put(me_cl); | 302 | __mei_me_cl_del(dev, me_cl); |
303 | up_write(&dev->me_clients_rwsem); | ||
208 | } | 304 | } |
209 | 305 | ||
210 | |||
211 | |||
212 | /** | 306 | /** |
213 | * mei_cl_cmp_id - tells if the clients are the same | 307 | * mei_cl_cmp_id - tells if the clients are the same |
214 | * | 308 | * |
@@ -535,28 +629,28 @@ int mei_cl_unlink(struct mei_cl *cl) | |||
535 | 629 | ||
536 | void mei_host_client_init(struct work_struct *work) | 630 | void mei_host_client_init(struct work_struct *work) |
537 | { | 631 | { |
538 | struct mei_device *dev = container_of(work, | 632 | struct mei_device *dev = |
539 | struct mei_device, init_work); | 633 | container_of(work, struct mei_device, init_work); |
540 | struct mei_me_client *me_cl; | 634 | struct mei_me_client *me_cl; |
541 | struct mei_client_properties *props; | ||
542 | 635 | ||
543 | mutex_lock(&dev->device_lock); | 636 | mutex_lock(&dev->device_lock); |
544 | 637 | ||
545 | list_for_each_entry(me_cl, &dev->me_clients, list) { | ||
546 | props = &me_cl->props; | ||
547 | 638 | ||
548 | if (!uuid_le_cmp(props->protocol_name, mei_amthif_guid)) | 639 | me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid); |
549 | mei_amthif_host_init(dev); | 640 | if (me_cl) |
550 | else if (!uuid_le_cmp(props->protocol_name, mei_wd_guid)) | 641 | mei_amthif_host_init(dev); |
551 | mei_wd_host_init(dev); | 642 | |
552 | else if (!uuid_le_cmp(props->protocol_name, mei_nfc_guid)) | 643 | me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid); |
553 | mei_nfc_host_init(dev); | 644 | if (me_cl) |
645 | mei_wd_host_init(dev); | ||
646 | |||
647 | me_cl = mei_me_cl_by_uuid(dev, &mei_nfc_guid); | ||
648 | if (me_cl) | ||
649 | mei_nfc_host_init(dev); | ||
554 | 650 | ||
555 | } | ||
556 | 651 | ||
557 | dev->dev_state = MEI_DEV_ENABLED; | 652 | dev->dev_state = MEI_DEV_ENABLED; |
558 | dev->reset_count = 0; | 653 | dev->reset_count = 0; |
559 | |||
560 | mutex_unlock(&dev->device_lock); | 654 | mutex_unlock(&dev->device_lock); |
561 | 655 | ||
562 | pm_runtime_mark_last_busy(dev->dev); | 656 | pm_runtime_mark_last_busy(dev->dev); |
diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h index cfcde8e97fc4..80386f9c27e9 100644 --- a/drivers/misc/mei/client.h +++ b/drivers/misc/mei/client.h | |||
@@ -31,7 +31,10 @@ void mei_me_cl_init(struct mei_me_client *me_cl); | |||
31 | void mei_me_cl_put(struct mei_me_client *me_cl); | 31 | void mei_me_cl_put(struct mei_me_client *me_cl); |
32 | struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl); | 32 | struct mei_me_client *mei_me_cl_get(struct mei_me_client *me_cl); |
33 | 33 | ||
34 | struct mei_me_client *mei_me_cl_by_uuid(const struct mei_device *dev, | 34 | void mei_me_cl_add(struct mei_device *dev, struct mei_me_client *me_cl); |
35 | void mei_me_cl_del(struct mei_device *dev, struct mei_me_client *me_cl); | ||
36 | |||
37 | struct mei_me_client *mei_me_cl_by_uuid(struct mei_device *dev, | ||
35 | const uuid_le *uuid); | 38 | const uuid_le *uuid); |
36 | struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id); | 39 | struct mei_me_client *mei_me_cl_by_id(struct mei_device *dev, u8 client_id); |
37 | struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, | 40 | struct mei_me_client *mei_me_cl_by_uuid_id(struct mei_device *dev, |
diff --git a/drivers/misc/mei/debugfs.c b/drivers/misc/mei/debugfs.c index b125380ee871..50fc6635fab1 100644 --- a/drivers/misc/mei/debugfs.c +++ b/drivers/misc/mei/debugfs.c | |||
@@ -28,7 +28,7 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, | |||
28 | size_t cnt, loff_t *ppos) | 28 | size_t cnt, loff_t *ppos) |
29 | { | 29 | { |
30 | struct mei_device *dev = fp->private_data; | 30 | struct mei_device *dev = fp->private_data; |
31 | struct mei_me_client *me_cl, *n; | 31 | struct mei_me_client *me_cl; |
32 | size_t bufsz = 1; | 32 | size_t bufsz = 1; |
33 | char *buf; | 33 | char *buf; |
34 | int i = 0; | 34 | int i = 0; |
@@ -38,15 +38,14 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, | |||
38 | #define HDR \ | 38 | #define HDR \ |
39 | " |id|fix| UUID |con|msg len|sb|refc|\n" | 39 | " |id|fix| UUID |con|msg len|sb|refc|\n" |
40 | 40 | ||
41 | mutex_lock(&dev->device_lock); | 41 | down_read(&dev->me_clients_rwsem); |
42 | |||
43 | list_for_each_entry(me_cl, &dev->me_clients, list) | 42 | list_for_each_entry(me_cl, &dev->me_clients, list) |
44 | bufsz++; | 43 | bufsz++; |
45 | 44 | ||
46 | bufsz *= sizeof(HDR) + 1; | 45 | bufsz *= sizeof(HDR) + 1; |
47 | buf = kzalloc(bufsz, GFP_KERNEL); | 46 | buf = kzalloc(bufsz, GFP_KERNEL); |
48 | if (!buf) { | 47 | if (!buf) { |
49 | mutex_unlock(&dev->device_lock); | 48 | up_read(&dev->me_clients_rwsem); |
50 | return -ENOMEM; | 49 | return -ENOMEM; |
51 | } | 50 | } |
52 | 51 | ||
@@ -56,10 +55,9 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, | |||
56 | if (dev->dev_state != MEI_DEV_ENABLED) | 55 | if (dev->dev_state != MEI_DEV_ENABLED) |
57 | goto out; | 56 | goto out; |
58 | 57 | ||
59 | list_for_each_entry_safe(me_cl, n, &dev->me_clients, list) { | 58 | list_for_each_entry(me_cl, &dev->me_clients, list) { |
60 | 59 | ||
61 | me_cl = mei_me_cl_get(me_cl); | 60 | if (mei_me_cl_get(me_cl)) { |
62 | if (me_cl) { | ||
63 | pos += scnprintf(buf + pos, bufsz - pos, | 61 | pos += scnprintf(buf + pos, bufsz - pos, |
64 | "%2d|%2d|%3d|%pUl|%3d|%7d|%2d|%4d|\n", | 62 | "%2d|%2d|%3d|%pUl|%3d|%7d|%2d|%4d|\n", |
65 | i++, me_cl->client_id, | 63 | i++, me_cl->client_id, |
@@ -69,12 +67,13 @@ static ssize_t mei_dbgfs_read_meclients(struct file *fp, char __user *ubuf, | |||
69 | me_cl->props.max_msg_length, | 67 | me_cl->props.max_msg_length, |
70 | me_cl->props.single_recv_buf, | 68 | me_cl->props.single_recv_buf, |
71 | atomic_read(&me_cl->refcnt.refcount)); | 69 | atomic_read(&me_cl->refcnt.refcount)); |
72 | } | ||
73 | 70 | ||
74 | mei_me_cl_put(me_cl); | 71 | mei_me_cl_put(me_cl); |
72 | } | ||
75 | } | 73 | } |
74 | |||
76 | out: | 75 | out: |
77 | mutex_unlock(&dev->device_lock); | 76 | up_read(&dev->me_clients_rwsem); |
78 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); | 77 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, pos); |
79 | kfree(buf); | 78 | kfree(buf); |
80 | return ret; | 79 | return ret; |
diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index c8412d41e4f1..4f83e9aaa6f9 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c | |||
@@ -338,7 +338,8 @@ static int mei_hbm_me_cl_add(struct mei_device *dev, | |||
338 | me_cl->client_id = res->me_addr; | 338 | me_cl->client_id = res->me_addr; |
339 | me_cl->mei_flow_ctrl_creds = 0; | 339 | me_cl->mei_flow_ctrl_creds = 0; |
340 | 340 | ||
341 | list_add(&me_cl->list, &dev->me_clients); | 341 | mei_me_cl_add(dev, me_cl); |
342 | |||
342 | return 0; | 343 | return 0; |
343 | } | 344 | } |
344 | 345 | ||
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 9306219d5675..106c054f573f 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c | |||
@@ -387,6 +387,7 @@ void mei_device_init(struct mei_device *dev, | |||
387 | INIT_LIST_HEAD(&dev->device_list); | 387 | INIT_LIST_HEAD(&dev->device_list); |
388 | INIT_LIST_HEAD(&dev->me_clients); | 388 | INIT_LIST_HEAD(&dev->me_clients); |
389 | mutex_init(&dev->device_lock); | 389 | mutex_init(&dev->device_lock); |
390 | init_rwsem(&dev->me_clients_rwsem); | ||
390 | init_waitqueue_head(&dev->wait_hw_ready); | 391 | init_waitqueue_head(&dev->wait_hw_ready); |
391 | init_waitqueue_head(&dev->wait_pg); | 392 | init_waitqueue_head(&dev->wait_pg); |
392 | init_waitqueue_head(&dev->wait_hbm_start); | 393 | init_waitqueue_head(&dev->wait_hbm_start); |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index 6c6ce9381535..102cc6603eba 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -460,6 +460,7 @@ const char *mei_pg_state_str(enum mei_pg_state state); | |||
460 | * @version : HBM protocol version in use | 460 | * @version : HBM protocol version in use |
461 | * @hbm_f_pg_supported : hbm feature pgi protocol | 461 | * @hbm_f_pg_supported : hbm feature pgi protocol |
462 | * | 462 | * |
463 | * @me_clients_rwsem: rw lock over me_clients list | ||
463 | * @me_clients : list of FW clients | 464 | * @me_clients : list of FW clients |
464 | * @me_clients_map : FW clients bit map | 465 | * @me_clients_map : FW clients bit map |
465 | * @host_clients_map : host clients id pool | 466 | * @host_clients_map : host clients id pool |
@@ -556,6 +557,7 @@ struct mei_device { | |||
556 | struct hbm_version version; | 557 | struct hbm_version version; |
557 | unsigned int hbm_f_pg_supported:1; | 558 | unsigned int hbm_f_pg_supported:1; |
558 | 559 | ||
560 | struct rw_semaphore me_clients_rwsem; | ||
559 | struct list_head me_clients; | 561 | struct list_head me_clients; |
560 | DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); | 562 | DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX); |
561 | DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); | 563 | DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX); |