mei: fix comments
[pandora-kernel.git] / drivers / misc / mei / pci-txe.c
1 /*
2  *
3  * Intel Management Engine Interface (Intel MEI) Linux driver
4  * Copyright (c) 2013-2014, 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
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/device.h>
20 #include <linux/fs.h>
21 #include <linux/errno.h>
22 #include <linux/types.h>
23 #include <linux/pci.h>
24 #include <linux/init.h>
25 #include <linux/sched.h>
26 #include <linux/uuid.h>
27 #include <linux/jiffies.h>
28 #include <linux/interrupt.h>
29 #include <linux/workqueue.h>
30 #include <linux/pm_runtime.h>
31
32 #include <linux/mei.h>
33
34
35 #include "mei_dev.h"
36 #include "hw-txe.h"
37
38 static const struct pci_device_id mei_txe_pci_tbl[] = {
39         {MEI_PCI_DEVICE(0x0F18, mei_txe_cfg)}, /* Baytrail */
40         {0, }
41 };
42 MODULE_DEVICE_TABLE(pci, mei_txe_pci_tbl);
43
44 #ifdef CONFIG_PM_RUNTIME
45 static inline void mei_txe_set_pm_domain(struct mei_device *dev);
46 static inline void mei_txe_unset_pm_domain(struct mei_device *dev);
47 #else
48 static inline void mei_txe_set_pm_domain(struct mei_device *dev) {}
49 static inline void mei_txe_unset_pm_domain(struct mei_device *dev) {}
50 #endif /* CONFIG_PM_RUNTIME */
51
52 static void mei_txe_pci_iounmap(struct pci_dev *pdev, struct mei_txe_hw *hw)
53 {
54         int i;
55         for (i = SEC_BAR; i < NUM_OF_MEM_BARS; i++) {
56                 if (hw->mem_addr[i]) {
57                         pci_iounmap(pdev, hw->mem_addr[i]);
58                         hw->mem_addr[i] = NULL;
59                 }
60         }
61 }
62 /**
63  * mei_probe - Device Initialization Routine
64  *
65  * @pdev: PCI device structure
66  * @ent: entry in mei_txe_pci_tbl
67  *
68  * returns 0 on success, <0 on failure.
69  */
70 static int mei_txe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
71 {
72         const struct mei_cfg *cfg = (struct mei_cfg *)(ent->driver_data);
73         struct mei_device *dev;
74         struct mei_txe_hw *hw;
75         int err;
76         int i;
77
78         /* enable pci dev */
79         err = pci_enable_device(pdev);
80         if (err) {
81                 dev_err(&pdev->dev, "failed to enable pci device.\n");
82                 goto end;
83         }
84         /* set PCI host mastering  */
85         pci_set_master(pdev);
86         /* pci request regions for mei driver */
87         err = pci_request_regions(pdev, KBUILD_MODNAME);
88         if (err) {
89                 dev_err(&pdev->dev, "failed to get pci regions.\n");
90                 goto disable_device;
91         }
92
93         err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
94         if (err) {
95                 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
96                 if (err) {
97                         dev_err(&pdev->dev, "No suitable DMA available.\n");
98                         goto release_regions;
99                 }
100         }
101
102         /* allocates and initializes the mei dev structure */
103         dev = mei_txe_dev_init(pdev, cfg);
104         if (!dev) {
105                 err = -ENOMEM;
106                 goto release_regions;
107         }
108         hw = to_txe_hw(dev);
109
110         /* mapping  IO device memory */
111         for (i = SEC_BAR; i < NUM_OF_MEM_BARS; i++) {
112                 hw->mem_addr[i] = pci_iomap(pdev, i, 0);
113                 if (!hw->mem_addr[i]) {
114                         dev_err(&pdev->dev, "mapping I/O device memory failure.\n");
115                         err = -ENOMEM;
116                         goto free_device;
117                 }
118         }
119
120
121         pci_enable_msi(pdev);
122
123         /* clear spurious interrupts */
124         mei_clear_interrupts(dev);
125
126         /* request and enable interrupt  */
127         if (pci_dev_msi_enabled(pdev))
128                 err = request_threaded_irq(pdev->irq,
129                         NULL,
130                         mei_txe_irq_thread_handler,
131                         IRQF_ONESHOT, KBUILD_MODNAME, dev);
132         else
133                 err = request_threaded_irq(pdev->irq,
134                         mei_txe_irq_quick_handler,
135                         mei_txe_irq_thread_handler,
136                         IRQF_SHARED, KBUILD_MODNAME, dev);
137         if (err) {
138                 dev_err(&pdev->dev, "mei: request_threaded_irq failure. irq = %d\n",
139                         pdev->irq);
140                 goto free_device;
141         }
142
143         if (mei_start(dev)) {
144                 dev_err(&pdev->dev, "init hw failure.\n");
145                 err = -ENODEV;
146                 goto release_irq;
147         }
148
149         pm_runtime_set_autosuspend_delay(&pdev->dev, MEI_TXI_RPM_TIMEOUT);
150         pm_runtime_use_autosuspend(&pdev->dev);
151
152         err = mei_register(dev, &pdev->dev);
153         if (err)
154                 goto release_irq;
155
156         pci_set_drvdata(pdev, dev);
157
158         /*
159         * For not wake-able HW runtime pm framework
160         * can't be used on pci device level.
161         * Use domain runtime pm callbacks instead.
162         */
163         if (!pci_dev_run_wake(pdev))
164                 mei_txe_set_pm_domain(dev);
165
166         pm_runtime_put_noidle(&pdev->dev);
167
168         return 0;
169
170 release_irq:
171
172         mei_cancel_work(dev);
173
174         /* disable interrupts */
175         mei_disable_interrupts(dev);
176
177         free_irq(pdev->irq, dev);
178         pci_disable_msi(pdev);
179
180 free_device:
181         mei_txe_pci_iounmap(pdev, hw);
182
183         kfree(dev);
184 release_regions:
185         pci_release_regions(pdev);
186 disable_device:
187         pci_disable_device(pdev);
188 end:
189         dev_err(&pdev->dev, "initialization failed.\n");
190         return err;
191 }
192
193 /**
194  * mei_remove - Device Removal Routine
195  *
196  * @pdev: PCI device structure
197  *
198  * mei_remove is called by the PCI subsystem to alert the driver
199  * that it should release a PCI device.
200  */
201 static void mei_txe_remove(struct pci_dev *pdev)
202 {
203         struct mei_device *dev;
204         struct mei_txe_hw *hw;
205
206         dev = pci_get_drvdata(pdev);
207         if (!dev) {
208                 dev_err(&pdev->dev, "mei: dev =NULL\n");
209                 return;
210         }
211
212         pm_runtime_get_noresume(&pdev->dev);
213
214         hw = to_txe_hw(dev);
215
216         mei_stop(dev);
217
218         if (!pci_dev_run_wake(pdev))
219                 mei_txe_unset_pm_domain(dev);
220
221         /* disable interrupts */
222         mei_disable_interrupts(dev);
223         free_irq(pdev->irq, dev);
224         pci_disable_msi(pdev);
225
226         pci_set_drvdata(pdev, NULL);
227
228         mei_txe_pci_iounmap(pdev, hw);
229
230         mei_deregister(dev);
231
232         kfree(dev);
233
234         pci_release_regions(pdev);
235         pci_disable_device(pdev);
236 }
237
238
239 #ifdef CONFIG_PM_SLEEP
240 static int mei_txe_pci_suspend(struct device *device)
241 {
242         struct pci_dev *pdev = to_pci_dev(device);
243         struct mei_device *dev = pci_get_drvdata(pdev);
244
245         if (!dev)
246                 return -ENODEV;
247
248         dev_dbg(&pdev->dev, "suspend\n");
249
250         mei_stop(dev);
251
252         mei_disable_interrupts(dev);
253
254         free_irq(pdev->irq, dev);
255         pci_disable_msi(pdev);
256
257         return 0;
258 }
259
260 static int mei_txe_pci_resume(struct device *device)
261 {
262         struct pci_dev *pdev = to_pci_dev(device);
263         struct mei_device *dev;
264         int err;
265
266         dev = pci_get_drvdata(pdev);
267         if (!dev)
268                 return -ENODEV;
269
270         pci_enable_msi(pdev);
271
272         mei_clear_interrupts(dev);
273
274         /* request and enable interrupt */
275         if (pci_dev_msi_enabled(pdev))
276                 err = request_threaded_irq(pdev->irq,
277                         NULL,
278                         mei_txe_irq_thread_handler,
279                         IRQF_ONESHOT, KBUILD_MODNAME, dev);
280         else
281                 err = request_threaded_irq(pdev->irq,
282                         mei_txe_irq_quick_handler,
283                         mei_txe_irq_thread_handler,
284                         IRQF_SHARED, KBUILD_MODNAME, dev);
285         if (err) {
286                 dev_err(&pdev->dev, "request_threaded_irq failed: irq = %d.\n",
287                                 pdev->irq);
288                 return err;
289         }
290
291         err = mei_restart(dev);
292
293         return err;
294 }
295 #endif /* CONFIG_PM_SLEEP */
296
297 #ifdef CONFIG_PM_RUNTIME
298 static int mei_txe_pm_runtime_idle(struct device *device)
299 {
300         struct pci_dev *pdev = to_pci_dev(device);
301         struct mei_device *dev;
302
303         dev_dbg(&pdev->dev, "rpm: txe: runtime_idle\n");
304
305         dev = pci_get_drvdata(pdev);
306         if (!dev)
307                 return -ENODEV;
308         if (mei_write_is_idle(dev))
309                 pm_runtime_autosuspend(device);
310
311         return -EBUSY;
312 }
313 static int mei_txe_pm_runtime_suspend(struct device *device)
314 {
315         struct pci_dev *pdev = to_pci_dev(device);
316         struct mei_device *dev;
317         int ret;
318
319         dev_dbg(&pdev->dev, "rpm: txe: runtime suspend\n");
320
321         dev = pci_get_drvdata(pdev);
322         if (!dev)
323                 return -ENODEV;
324
325         mutex_lock(&dev->device_lock);
326
327         if (mei_write_is_idle(dev))
328                 ret = mei_txe_aliveness_set_sync(dev, 0);
329         else
330                 ret = -EAGAIN;
331
332         /*
333          * If everything is okay we're about to enter PCI low
334          * power state (D3) therefor we need to disable the
335          * interrupts towards host.
336          * However if device is not wakeable we do not enter
337          * D-low state and we need to keep the interrupt kicking
338          */
339          if (!ret && pci_dev_run_wake(pdev))
340                 mei_disable_interrupts(dev);
341
342         dev_dbg(&pdev->dev, "rpm: txe: runtime suspend ret=%d\n", ret);
343
344         mutex_unlock(&dev->device_lock);
345         return ret;
346 }
347
348 static int mei_txe_pm_runtime_resume(struct device *device)
349 {
350         struct pci_dev *pdev = to_pci_dev(device);
351         struct mei_device *dev;
352         int ret;
353
354         dev_dbg(&pdev->dev, "rpm: txe: runtime resume\n");
355
356         dev = pci_get_drvdata(pdev);
357         if (!dev)
358                 return -ENODEV;
359
360         mutex_lock(&dev->device_lock);
361
362         mei_enable_interrupts(dev);
363
364         ret = mei_txe_aliveness_set_sync(dev, 1);
365
366         mutex_unlock(&dev->device_lock);
367
368         dev_dbg(&pdev->dev, "rpm: txe: runtime resume ret = %d\n", ret);
369
370         return ret;
371 }
372
373 /**
374  * mei_txe_set_pm_domain - fill and set pm domain structure for device
375  *
376  * @dev: mei_device
377  */
378 static inline void mei_txe_set_pm_domain(struct mei_device *dev)
379 {
380         struct pci_dev *pdev  = dev->pdev;
381
382         if (pdev->dev.bus && pdev->dev.bus->pm) {
383                 dev->pg_domain.ops = *pdev->dev.bus->pm;
384
385                 dev->pg_domain.ops.runtime_suspend = mei_txe_pm_runtime_suspend;
386                 dev->pg_domain.ops.runtime_resume = mei_txe_pm_runtime_resume;
387                 dev->pg_domain.ops.runtime_idle = mei_txe_pm_runtime_idle;
388
389                 pdev->dev.pm_domain = &dev->pg_domain;
390         }
391 }
392
393 /**
394  * mei_txe_unset_pm_domain - clean pm domain structure for device
395  *
396  * @dev: mei_device
397  */
398 static inline void mei_txe_unset_pm_domain(struct mei_device *dev)
399 {
400         /* stop using pm callbacks if any */
401         dev->pdev->dev.pm_domain = NULL;
402 }
403 #endif /* CONFIG_PM_RUNTIME */
404
405 #ifdef CONFIG_PM
406 static const struct dev_pm_ops mei_txe_pm_ops = {
407         SET_SYSTEM_SLEEP_PM_OPS(mei_txe_pci_suspend,
408                                 mei_txe_pci_resume)
409         SET_RUNTIME_PM_OPS(
410                 mei_txe_pm_runtime_suspend,
411                 mei_txe_pm_runtime_resume,
412                 mei_txe_pm_runtime_idle)
413 };
414
415 #define MEI_TXE_PM_OPS  (&mei_txe_pm_ops)
416 #else
417 #define MEI_TXE_PM_OPS  NULL
418 #endif /* CONFIG_PM */
419
420 /*
421  *  PCI driver structure
422  */
423 static struct pci_driver mei_txe_driver = {
424         .name = KBUILD_MODNAME,
425         .id_table = mei_txe_pci_tbl,
426         .probe = mei_txe_probe,
427         .remove = mei_txe_remove,
428         .shutdown = mei_txe_remove,
429         .driver.pm = MEI_TXE_PM_OPS,
430 };
431
432 module_pci_driver(mei_txe_driver);
433
434 MODULE_AUTHOR("Intel Corporation");
435 MODULE_DESCRIPTION("Intel(R) Trusted Execution Environment Interface");
436 MODULE_LICENSE("GPL v2");