diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2013-03-27 11:29:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-03-29 11:44:12 -0400 |
commit | a7b71bc043aded9da4cf51f85271e0779161fe22 (patch) | |
tree | 68b69d683542f91b883eb097e2c7bf332b4f3ecf | |
parent | 3e8332952dedd2c17bb497e3909e3b6fbac10ce7 (diff) |
mei: bus: Add bus related structures to mei_cl
We keep track of all MEI devices on the bus through a specific linked list.
We also have a mei_device instance in the mei_cl structure.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mei/bus.c | 49 | ||||
-rw-r--r-- | drivers/misc/mei/client.c | 1 | ||||
-rw-r--r-- | drivers/misc/mei/init.c | 1 | ||||
-rw-r--r-- | drivers/misc/mei/mei_dev.h | 8 |
4 files changed, 44 insertions, 15 deletions
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 16c7fff50549..162cd542cac9 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -140,36 +140,53 @@ static struct device_type mei_cl_device_type = { | |||
140 | .release = mei_cl_dev_release, | 140 | .release = mei_cl_dev_release, |
141 | }; | 141 | }; |
142 | 142 | ||
143 | struct mei_cl_device *mei_cl_add_device(struct mei_device *mei_device, | 143 | static struct mei_cl *mei_bus_find_mei_cl_by_uuid(struct mei_device *dev, |
144 | uuid_le uuid) | ||
145 | { | ||
146 | struct mei_cl *cl, *next; | ||
147 | |||
148 | list_for_each_entry_safe(cl, next, &dev->device_list, device_link) { | ||
149 | if (!uuid_le_cmp(uuid, cl->device_uuid)) | ||
150 | return cl; | ||
151 | } | ||
152 | |||
153 | return NULL; | ||
154 | } | ||
155 | struct mei_cl_device *mei_cl_add_device(struct mei_device *dev, | ||
144 | uuid_le uuid, char *name) | 156 | uuid_le uuid, char *name) |
145 | { | 157 | { |
146 | struct mei_cl_device *device; | 158 | struct mei_cl_device *device; |
159 | struct mei_cl *cl; | ||
147 | int status; | 160 | int status; |
148 | 161 | ||
162 | cl = mei_bus_find_mei_cl_by_uuid(dev, uuid); | ||
163 | if (cl == NULL) | ||
164 | return NULL; | ||
165 | |||
149 | device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); | 166 | device = kzalloc(sizeof(struct mei_cl_device), GFP_KERNEL); |
150 | if (!device) | 167 | if (!device) |
151 | return NULL; | 168 | return NULL; |
152 | 169 | ||
153 | device->dev.parent = &mei_device->pdev->dev; | 170 | device->cl = cl; |
171 | |||
172 | device->dev.parent = &dev->pdev->dev; | ||
154 | device->dev.bus = &mei_cl_bus_type; | 173 | device->dev.bus = &mei_cl_bus_type; |
155 | device->dev.type = &mei_cl_device_type; | 174 | device->dev.type = &mei_cl_device_type; |
156 | 175 | ||
157 | dev_set_name(&device->dev, "%s", name); | 176 | dev_set_name(&device->dev, "%s", name); |
158 | 177 | ||
159 | status = device_register(&device->dev); | 178 | status = device_register(&device->dev); |
160 | if (status) | 179 | if (status) { |
161 | goto out_err; | 180 | dev_err(&dev->pdev->dev, "Failed to register MEI device\n"); |
181 | kfree(device); | ||
182 | return NULL; | ||
183 | } | ||
184 | |||
185 | cl->device = device; | ||
162 | 186 | ||
163 | dev_dbg(&device->dev, "client %s registered\n", name); | 187 | dev_dbg(&device->dev, "client %s registered\n", name); |
164 | 188 | ||
165 | return device; | 189 | return device; |
166 | |||
167 | out_err: | ||
168 | dev_err(device->dev.parent, "Failed to register MEI client\n"); | ||
169 | |||
170 | kfree(device); | ||
171 | |||
172 | return NULL; | ||
173 | } | 190 | } |
174 | EXPORT_SYMBOL_GPL(mei_cl_add_device); | 191 | EXPORT_SYMBOL_GPL(mei_cl_add_device); |
175 | 192 | ||
@@ -367,9 +384,10 @@ out: | |||
367 | 384 | ||
368 | int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) | 385 | int mei_cl_send(struct mei_cl_device *device, u8 *buf, size_t length) |
369 | { | 386 | { |
370 | struct mei_cl *cl = NULL; | 387 | struct mei_cl *cl = device->cl; |
371 | 388 | ||
372 | /* TODO: hook between mei_bus_client and mei_cl */ | 389 | if (cl == NULL) |
390 | return -ENODEV; | ||
373 | 391 | ||
374 | if (device->ops && device->ops->send) | 392 | if (device->ops && device->ops->send) |
375 | return device->ops->send(device, buf, length); | 393 | return device->ops->send(device, buf, length); |
@@ -380,9 +398,10 @@ EXPORT_SYMBOL_GPL(mei_cl_send); | |||
380 | 398 | ||
381 | int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) | 399 | int mei_cl_recv(struct mei_cl_device *device, u8 *buf, size_t length) |
382 | { | 400 | { |
383 | struct mei_cl *cl = NULL; | 401 | struct mei_cl *cl = device->cl; |
384 | 402 | ||
385 | /* TODO: hook between mei_bus_client and mei_cl */ | 403 | if (cl == NULL) |
404 | return -ENODEV; | ||
386 | 405 | ||
387 | if (device->ops && device->ops->recv) | 406 | if (device->ops && device->ops->recv) |
388 | return device->ops->recv(device, buf, length); | 407 | return device->ops->recv(device, buf, length); |
diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 1569afe935de..e14397b09187 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c | |||
@@ -216,6 +216,7 @@ void mei_cl_init(struct mei_cl *cl, struct mei_device *dev) | |||
216 | init_waitqueue_head(&cl->rx_wait); | 216 | init_waitqueue_head(&cl->rx_wait); |
217 | init_waitqueue_head(&cl->tx_wait); | 217 | init_waitqueue_head(&cl->tx_wait); |
218 | INIT_LIST_HEAD(&cl->link); | 218 | INIT_LIST_HEAD(&cl->link); |
219 | INIT_LIST_HEAD(&cl->device_link); | ||
219 | cl->reading_state = MEI_IDLE; | 220 | cl->reading_state = MEI_IDLE; |
220 | cl->writing_state = MEI_IDLE; | 221 | cl->writing_state = MEI_IDLE; |
221 | cl->dev = dev; | 222 | cl->dev = dev; |
diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index c1c8d760bc34..54b51c05fa41 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c | |||
@@ -47,6 +47,7 @@ void mei_device_init(struct mei_device *dev) | |||
47 | { | 47 | { |
48 | /* setup our list array */ | 48 | /* setup our list array */ |
49 | INIT_LIST_HEAD(&dev->file_list); | 49 | INIT_LIST_HEAD(&dev->file_list); |
50 | INIT_LIST_HEAD(&dev->device_list); | ||
50 | mutex_init(&dev->device_lock); | 51 | mutex_init(&dev->device_lock); |
51 | init_waitqueue_head(&dev->wait_hw_ready); | 52 | init_waitqueue_head(&dev->wait_hw_ready); |
52 | init_waitqueue_head(&dev->wait_recvd_msg); | 53 | init_waitqueue_head(&dev->wait_recvd_msg); |
diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index cde5687039f3..0313c24a1a49 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h | |||
@@ -209,6 +209,11 @@ struct mei_cl { | |||
209 | enum mei_file_transaction_states writing_state; | 209 | enum mei_file_transaction_states writing_state; |
210 | int sm_state; | 210 | int sm_state; |
211 | struct mei_cl_cb *read_cb; | 211 | struct mei_cl_cb *read_cb; |
212 | |||
213 | /* MEI CL bus data */ | ||
214 | struct mei_cl_device *device; | ||
215 | struct list_head device_link; | ||
216 | uuid_le device_uuid; | ||
212 | }; | 217 | }; |
213 | 218 | ||
214 | /** struct mei_hw_ops | 219 | /** struct mei_hw_ops |
@@ -423,6 +428,9 @@ struct mei_device { | |||
423 | 428 | ||
424 | struct work_struct init_work; | 429 | struct work_struct init_work; |
425 | 430 | ||
431 | /* List of bus devices */ | ||
432 | struct list_head device_list; | ||
433 | |||
426 | const struct mei_hw_ops *ops; | 434 | const struct mei_hw_ops *ops; |
427 | char hw[0] __aligned(sizeof(void *)); | 435 | char hw[0] __aligned(sizeof(void *)); |
428 | }; | 436 | }; |