diff options
author | Siva Yerramreddy <yshivakrishna@gmail.com> | 2014-07-11 17:04:25 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-07-11 21:31:12 -0400 |
commit | a93a5244ed7bd3c5f7b51ccb08a14655820e38c3 (patch) | |
tree | 406592c575c8d4e767df755cd8820d2485a494dc | |
parent | 9c3d37c7a1efcb1815ec5cb22f70ca98da24f6b1 (diff) |
misc: mic: add dma support in card driver
This patch adds a dma device on the mic virtual bus
Reviewed-by: Nikhil Rao <nikhil.rao@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Siva Yerramreddy <yshivakrishna@gmail.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/misc/mic/Kconfig | 2 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_device.h | 8 | ||||
-rw-r--r-- | drivers/misc/mic/card/mic_x100.c | 55 |
3 files changed, 61 insertions, 4 deletions
diff --git a/drivers/misc/mic/Kconfig b/drivers/misc/mic/Kconfig index bf76313dab16..cc4eef040c14 100644 --- a/drivers/misc/mic/Kconfig +++ b/drivers/misc/mic/Kconfig | |||
@@ -39,7 +39,7 @@ comment "Intel MIC Card Driver" | |||
39 | 39 | ||
40 | config INTEL_MIC_CARD | 40 | config INTEL_MIC_CARD |
41 | tristate "Intel MIC Card Driver" | 41 | tristate "Intel MIC Card Driver" |
42 | depends on 64BIT && X86 | 42 | depends on 64BIT && X86 && INTEL_MIC_BUS |
43 | select VIRTIO | 43 | select VIRTIO |
44 | help | 44 | help |
45 | This enables card driver support for the Intel Many Integrated | 45 | This enables card driver support for the Intel Many Integrated |
diff --git a/drivers/misc/mic/card/mic_device.h b/drivers/misc/mic/card/mic_device.h index e12a0c2ddb3d..844be8fc9b22 100644 --- a/drivers/misc/mic/card/mic_device.h +++ b/drivers/misc/mic/card/mic_device.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/io.h> | 31 | #include <linux/io.h> |
32 | #include <linux/irqreturn.h> | 32 | #include <linux/irqreturn.h> |
33 | #include <linux/interrupt.h> | 33 | #include <linux/interrupt.h> |
34 | #include <linux/mic_bus.h> | ||
34 | 35 | ||
35 | /** | 36 | /** |
36 | * struct mic_intr_info - Contains h/w specific interrupt sources info | 37 | * struct mic_intr_info - Contains h/w specific interrupt sources info |
@@ -71,6 +72,7 @@ struct mic_device { | |||
71 | * @hotplug_work: Hot plug work for adding/removing virtio devices. | 72 | * @hotplug_work: Hot plug work for adding/removing virtio devices. |
72 | * @irq_info: The OS specific irq information | 73 | * @irq_info: The OS specific irq information |
73 | * @intr_info: H/W specific interrupt information. | 74 | * @intr_info: H/W specific interrupt information. |
75 | * @dma_mbdev: dma device on the MIC virtual bus. | ||
74 | */ | 76 | */ |
75 | struct mic_driver { | 77 | struct mic_driver { |
76 | char name[20]; | 78 | char name[20]; |
@@ -81,6 +83,7 @@ struct mic_driver { | |||
81 | struct work_struct hotplug_work; | 83 | struct work_struct hotplug_work; |
82 | struct mic_irq_info irq_info; | 84 | struct mic_irq_info irq_info; |
83 | struct mic_intr_info intr_info; | 85 | struct mic_intr_info intr_info; |
86 | struct mbus_device *dma_mbdev; | ||
84 | }; | 87 | }; |
85 | 88 | ||
86 | /** | 89 | /** |
@@ -117,8 +120,9 @@ mic_mmio_write(struct mic_mw *mw, u32 val, u32 offset) | |||
117 | int mic_driver_init(struct mic_driver *mdrv); | 120 | int mic_driver_init(struct mic_driver *mdrv); |
118 | void mic_driver_uninit(struct mic_driver *mdrv); | 121 | void mic_driver_uninit(struct mic_driver *mdrv); |
119 | int mic_next_card_db(void); | 122 | int mic_next_card_db(void); |
120 | struct mic_irq *mic_request_card_irq(irq_handler_t handler, | 123 | struct mic_irq * |
121 | irq_handler_t thread_fn, const char *name, void *data, int intr_src); | 124 | mic_request_card_irq(irq_handler_t handler, irq_handler_t thread_fn, |
125 | const char *name, void *data, int intr_src); | ||
122 | void mic_free_card_irq(struct mic_irq *cookie, void *data); | 126 | void mic_free_card_irq(struct mic_irq *cookie, void *data); |
123 | u32 mic_read_spad(struct mic_device *mdev, unsigned int idx); | 127 | u32 mic_read_spad(struct mic_device *mdev, unsigned int idx); |
124 | void mic_send_intr(struct mic_device *mdev, int doorbell); | 128 | void mic_send_intr(struct mic_device *mdev, int doorbell); |
diff --git a/drivers/misc/mic/card/mic_x100.c b/drivers/misc/mic/card/mic_x100.c index 2868945c9a4d..55c9465bd260 100644 --- a/drivers/misc/mic/card/mic_x100.c +++ b/drivers/misc/mic/card/mic_x100.c | |||
@@ -148,6 +148,47 @@ void mic_card_unmap(struct mic_device *mdev, void __iomem *addr) | |||
148 | iounmap(addr); | 148 | iounmap(addr); |
149 | } | 149 | } |
150 | 150 | ||
151 | static inline struct mic_driver *mbdev_to_mdrv(struct mbus_device *mbdev) | ||
152 | { | ||
153 | return dev_get_drvdata(mbdev->dev.parent); | ||
154 | } | ||
155 | |||
156 | static struct mic_irq * | ||
157 | _mic_request_threaded_irq(struct mbus_device *mbdev, | ||
158 | irq_handler_t handler, irq_handler_t thread_fn, | ||
159 | const char *name, void *data, int intr_src) | ||
160 | { | ||
161 | int rc = 0; | ||
162 | unsigned int irq = intr_src; | ||
163 | unsigned long cookie = irq; | ||
164 | |||
165 | rc = request_threaded_irq(irq, handler, thread_fn, 0, name, data); | ||
166 | if (rc) { | ||
167 | dev_err(mbdev_to_mdrv(mbdev)->dev, | ||
168 | "request_threaded_irq failed rc = %d\n", rc); | ||
169 | return ERR_PTR(rc); | ||
170 | } | ||
171 | return (struct mic_irq *)cookie; | ||
172 | } | ||
173 | |||
174 | static void _mic_free_irq(struct mbus_device *mbdev, | ||
175 | struct mic_irq *cookie, void *data) | ||
176 | { | ||
177 | unsigned long irq = (unsigned long)cookie; | ||
178 | free_irq(irq, data); | ||
179 | } | ||
180 | |||
181 | static void _mic_ack_interrupt(struct mbus_device *mbdev, int num) | ||
182 | { | ||
183 | mic_ack_interrupt(&mbdev_to_mdrv(mbdev)->mdev); | ||
184 | } | ||
185 | |||
186 | static struct mbus_hw_ops mbus_hw_ops = { | ||
187 | .request_threaded_irq = _mic_request_threaded_irq, | ||
188 | .free_irq = _mic_free_irq, | ||
189 | .ack_interrupt = _mic_ack_interrupt, | ||
190 | }; | ||
191 | |||
151 | static int __init mic_probe(struct platform_device *pdev) | 192 | static int __init mic_probe(struct platform_device *pdev) |
152 | { | 193 | { |
153 | struct mic_driver *mdrv = &g_drv; | 194 | struct mic_driver *mdrv = &g_drv; |
@@ -166,13 +207,24 @@ static int __init mic_probe(struct platform_device *pdev) | |||
166 | goto done; | 207 | goto done; |
167 | } | 208 | } |
168 | mic_hw_intr_init(mdrv); | 209 | mic_hw_intr_init(mdrv); |
210 | platform_set_drvdata(pdev, mdrv); | ||
211 | mdrv->dma_mbdev = mbus_register_device(mdrv->dev, MBUS_DEV_DMA_MIC, | ||
212 | NULL, &mbus_hw_ops, | ||
213 | mdrv->mdev.mmio.va); | ||
214 | if (IS_ERR(mdrv->dma_mbdev)) { | ||
215 | rc = PTR_ERR(mdrv->dma_mbdev); | ||
216 | dev_err(&pdev->dev, "mbus_add_device failed rc %d\n", rc); | ||
217 | goto iounmap; | ||
218 | } | ||
169 | rc = mic_driver_init(mdrv); | 219 | rc = mic_driver_init(mdrv); |
170 | if (rc) { | 220 | if (rc) { |
171 | dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc); | 221 | dev_err(&pdev->dev, "mic_driver_init failed rc %d\n", rc); |
172 | goto iounmap; | 222 | goto remove_dma; |
173 | } | 223 | } |
174 | done: | 224 | done: |
175 | return rc; | 225 | return rc; |
226 | remove_dma: | ||
227 | mbus_unregister_device(mdrv->dma_mbdev); | ||
176 | iounmap: | 228 | iounmap: |
177 | iounmap(mdev->mmio.va); | 229 | iounmap(mdev->mmio.va); |
178 | return rc; | 230 | return rc; |
@@ -184,6 +236,7 @@ static int mic_remove(struct platform_device *pdev) | |||
184 | struct mic_device *mdev = &mdrv->mdev; | 236 | struct mic_device *mdev = &mdrv->mdev; |
185 | 237 | ||
186 | mic_driver_uninit(mdrv); | 238 | mic_driver_uninit(mdrv); |
239 | mbus_unregister_device(mdrv->dma_mbdev); | ||
187 | iounmap(mdev->mmio.va); | 240 | iounmap(mdev->mmio.va); |
188 | return 0; | 241 | return 0; |
189 | } | 242 | } |