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 /drivers/misc/mic/card | |
| 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>
Diffstat (limited to 'drivers/misc/mic/card')
| -rw-r--r-- | drivers/misc/mic/card/mic_device.h | 8 | ||||
| -rw-r--r-- | drivers/misc/mic/card/mic_x100.c | 55 |
2 files changed, 60 insertions, 3 deletions
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 | } |
