diff options
| author | Sudeep Dutt <sudeep.dutt@intel.com> | 2015-04-29 08:32:38 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-05-24 15:13:37 -0400 |
| commit | 74321d4c99fc1d2582085cbb614d5a3ea9da962d (patch) | |
| tree | 903b803d6a3ce4f7d49348b18b357dc69b4d4102 /drivers/misc/mic/host | |
| parent | fdd9fd5c38afe732258a0af4c6be14f3fbd1585c (diff) | |
misc: mic: MIC host driver specific changes to enable SCIF
MIC host driver specific changes to enable SCIF. This patch implements
the SCIF hardware bus operations and registers a SCIF device on the
SCIF hardware bus.
Reviewed-by: Nikhil Rao <nikhil.rao@intel.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc/mic/host')
| -rw-r--r-- | drivers/misc/mic/host/mic_boot.c | 264 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_debugfs.c | 13 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_device.h | 11 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_intr.h | 3 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_main.c | 6 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_smpt.c | 7 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_smpt.h | 1 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_virtio.c | 6 | ||||
| -rw-r--r-- | drivers/misc/mic/host/mic_x100.c | 3 |
9 files changed, 291 insertions, 23 deletions
diff --git a/drivers/misc/mic/host/mic_boot.c b/drivers/misc/mic/host/mic_boot.c index d9fa609da061..e5f6a5e7bca1 100644 --- a/drivers/misc/mic/host/mic_boot.c +++ b/drivers/misc/mic/host/mic_boot.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/firmware.h> | 22 | #include <linux/firmware.h> |
| 23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 24 | #include <linux/kmod.h> | ||
| 24 | 25 | ||
| 25 | #include <linux/mic_common.h> | 26 | #include <linux/mic_common.h> |
| 26 | #include <linux/mic_bus.h> | 27 | #include <linux/mic_bus.h> |
| @@ -29,6 +30,188 @@ | |||
| 29 | #include "mic_smpt.h" | 30 | #include "mic_smpt.h" |
| 30 | #include "mic_virtio.h" | 31 | #include "mic_virtio.h" |
| 31 | 32 | ||
| 33 | static inline struct mic_device *scdev_to_mdev(struct scif_hw_dev *scdev) | ||
| 34 | { | ||
| 35 | return dev_get_drvdata(scdev->dev.parent); | ||
| 36 | } | ||
| 37 | |||
| 38 | static void *__mic_dma_alloc(struct device *dev, size_t size, | ||
| 39 | dma_addr_t *dma_handle, gfp_t gfp, | ||
| 40 | struct dma_attrs *attrs) | ||
| 41 | { | ||
| 42 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 43 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 44 | dma_addr_t tmp; | ||
| 45 | void *va = kmalloc(size, gfp); | ||
| 46 | |||
| 47 | if (va) { | ||
| 48 | tmp = mic_map_single(mdev, va, size); | ||
| 49 | if (dma_mapping_error(dev, tmp)) { | ||
| 50 | kfree(va); | ||
| 51 | va = NULL; | ||
| 52 | } else { | ||
| 53 | *dma_handle = tmp; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | return va; | ||
| 57 | } | ||
| 58 | |||
| 59 | static void __mic_dma_free(struct device *dev, size_t size, void *vaddr, | ||
| 60 | dma_addr_t dma_handle, struct dma_attrs *attrs) | ||
| 61 | { | ||
| 62 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 63 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 64 | |||
| 65 | mic_unmap_single(mdev, dma_handle, size); | ||
| 66 | kfree(vaddr); | ||
| 67 | } | ||
| 68 | |||
| 69 | static dma_addr_t | ||
| 70 | __mic_dma_map_page(struct device *dev, struct page *page, unsigned long offset, | ||
| 71 | size_t size, enum dma_data_direction dir, | ||
| 72 | struct dma_attrs *attrs) | ||
| 73 | { | ||
| 74 | void *va = phys_to_virt(page_to_phys(page)) + offset; | ||
| 75 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 76 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 77 | |||
| 78 | return mic_map_single(mdev, va, size); | ||
| 79 | } | ||
| 80 | |||
| 81 | static void | ||
| 82 | __mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, | ||
| 83 | size_t size, enum dma_data_direction dir, | ||
| 84 | struct dma_attrs *attrs) | ||
| 85 | { | ||
| 86 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 87 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 88 | |||
| 89 | mic_unmap_single(mdev, dma_addr, size); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int __mic_dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
| 93 | int nents, enum dma_data_direction dir, | ||
| 94 | struct dma_attrs *attrs) | ||
| 95 | { | ||
| 96 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 97 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 98 | struct scatterlist *s; | ||
| 99 | int i, j, ret; | ||
| 100 | dma_addr_t da; | ||
| 101 | |||
| 102 | ret = dma_map_sg(mdev->sdev->parent, sg, nents, dir); | ||
| 103 | if (ret <= 0) | ||
| 104 | return 0; | ||
| 105 | |||
| 106 | for_each_sg(sg, s, nents, i) { | ||
| 107 | da = mic_map(mdev, sg_dma_address(s) + s->offset, s->length); | ||
| 108 | if (!da) | ||
| 109 | goto err; | ||
| 110 | sg_dma_address(s) = da; | ||
| 111 | } | ||
| 112 | return nents; | ||
| 113 | err: | ||
| 114 | for_each_sg(sg, s, i, j) { | ||
| 115 | mic_unmap(mdev, sg_dma_address(s), s->length); | ||
| 116 | sg_dma_address(s) = mic_to_dma_addr(mdev, sg_dma_address(s)); | ||
| 117 | } | ||
| 118 | dma_unmap_sg(mdev->sdev->parent, sg, nents, dir); | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | static void __mic_dma_unmap_sg(struct device *dev, | ||
| 123 | struct scatterlist *sg, int nents, | ||
| 124 | enum dma_data_direction dir, | ||
| 125 | struct dma_attrs *attrs) | ||
| 126 | { | ||
| 127 | struct scif_hw_dev *scdev = dev_get_drvdata(dev); | ||
| 128 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 129 | struct scatterlist *s; | ||
| 130 | dma_addr_t da; | ||
| 131 | int i; | ||
| 132 | |||
| 133 | for_each_sg(sg, s, nents, i) { | ||
| 134 | da = mic_to_dma_addr(mdev, sg_dma_address(s)); | ||
| 135 | mic_unmap(mdev, sg_dma_address(s), s->length); | ||
| 136 | sg_dma_address(s) = da; | ||
| 137 | } | ||
| 138 | dma_unmap_sg(mdev->sdev->parent, sg, nents, dir); | ||
| 139 | } | ||
| 140 | |||
| 141 | static struct dma_map_ops __mic_dma_ops = { | ||
| 142 | .alloc = __mic_dma_alloc, | ||
| 143 | .free = __mic_dma_free, | ||
| 144 | .map_page = __mic_dma_map_page, | ||
| 145 | .unmap_page = __mic_dma_unmap_page, | ||
| 146 | .map_sg = __mic_dma_map_sg, | ||
| 147 | .unmap_sg = __mic_dma_unmap_sg, | ||
| 148 | }; | ||
| 149 | |||
| 150 | static struct mic_irq * | ||
| 151 | ___mic_request_irq(struct scif_hw_dev *scdev, | ||
| 152 | irqreturn_t (*func)(int irq, void *data), | ||
| 153 | const char *name, | ||
| 154 | void *data, int db) | ||
| 155 | { | ||
| 156 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 157 | |||
| 158 | return mic_request_threaded_irq(mdev, func, NULL, name, data, | ||
| 159 | db, MIC_INTR_DB); | ||
| 160 | } | ||
| 161 | |||
| 162 | static void | ||
| 163 | ___mic_free_irq(struct scif_hw_dev *scdev, | ||
| 164 | struct mic_irq *cookie, void *data) | ||
| 165 | { | ||
| 166 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 167 | |||
| 168 | return mic_free_irq(mdev, cookie, data); | ||
| 169 | } | ||
| 170 | |||
| 171 | static void ___mic_ack_interrupt(struct scif_hw_dev *scdev, int num) | ||
| 172 | { | ||
| 173 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 174 | |||
| 175 | mdev->ops->intr_workarounds(mdev); | ||
| 176 | } | ||
| 177 | |||
| 178 | static int ___mic_next_db(struct scif_hw_dev *scdev) | ||
| 179 | { | ||
| 180 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 181 | |||
| 182 | return mic_next_db(mdev); | ||
| 183 | } | ||
| 184 | |||
| 185 | static void ___mic_send_intr(struct scif_hw_dev *scdev, int db) | ||
| 186 | { | ||
| 187 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 188 | |||
| 189 | mdev->ops->send_intr(mdev, db); | ||
| 190 | } | ||
| 191 | |||
| 192 | static void __iomem *___mic_ioremap(struct scif_hw_dev *scdev, | ||
| 193 | phys_addr_t pa, size_t len) | ||
| 194 | { | ||
| 195 | struct mic_device *mdev = scdev_to_mdev(scdev); | ||
| 196 | |||
| 197 | return mdev->aper.va + pa; | ||
| 198 | } | ||
| 199 | |||
| 200 | static void ___mic_iounmap(struct scif_hw_dev *scdev, void __iomem *va) | ||
| 201 | { | ||
| 202 | /* nothing to do */ | ||
| 203 | } | ||
| 204 | |||
| 205 | static struct scif_hw_ops scif_hw_ops = { | ||
| 206 | .request_irq = ___mic_request_irq, | ||
| 207 | .free_irq = ___mic_free_irq, | ||
| 208 | .ack_interrupt = ___mic_ack_interrupt, | ||
| 209 | .next_db = ___mic_next_db, | ||
| 210 | .send_intr = ___mic_send_intr, | ||
| 211 | .ioremap = ___mic_ioremap, | ||
| 212 | .iounmap = ___mic_iounmap, | ||
| 213 | }; | ||
| 214 | |||
| 32 | static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev) | 215 | static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev) |
| 33 | { | 216 | { |
| 34 | return dev_get_drvdata(mbdev->dev.parent); | 217 | return dev_get_drvdata(mbdev->dev.parent); |
| @@ -127,6 +310,58 @@ void mic_bootparam_init(struct mic_device *mdev) | |||
| 127 | bootparam->h2c_config_db = -1; | 310 | bootparam->h2c_config_db = -1; |
| 128 | bootparam->shutdown_status = 0; | 311 | bootparam->shutdown_status = 0; |
| 129 | bootparam->shutdown_card = 0; | 312 | bootparam->shutdown_card = 0; |
| 313 | /* Total nodes = number of MICs + 1 for self node */ | ||
| 314 | bootparam->tot_nodes = atomic_read(&g_num_mics) + 1; | ||
| 315 | bootparam->node_id = mdev->id + 1; | ||
| 316 | bootparam->scif_host_dma_addr = 0x0; | ||
| 317 | bootparam->scif_card_dma_addr = 0x0; | ||
| 318 | bootparam->c2h_scif_db = -1; | ||
| 319 | bootparam->h2c_scif_db = -1; | ||
| 320 | } | ||
| 321 | |||
| 322 | /** | ||
| 323 | * mic_request_dma_chans - Request DMA channels | ||
| 324 | * @mdev: pointer to mic_device instance | ||
| 325 | * | ||
| 326 | * returns number of DMA channels acquired | ||
| 327 | */ | ||
| 328 | static int mic_request_dma_chans(struct mic_device *mdev) | ||
| 329 | { | ||
| 330 | dma_cap_mask_t mask; | ||
| 331 | struct dma_chan *chan; | ||
| 332 | |||
| 333 | request_module("mic_x100_dma"); | ||
| 334 | dma_cap_zero(mask); | ||
| 335 | dma_cap_set(DMA_MEMCPY, mask); | ||
| 336 | |||
| 337 | do { | ||
| 338 | chan = dma_request_channel(mask, mdev->ops->dma_filter, | ||
| 339 | mdev->sdev->parent); | ||
| 340 | if (chan) { | ||
| 341 | mdev->dma_ch[mdev->num_dma_ch++] = chan; | ||
| 342 | if (mdev->num_dma_ch >= MIC_MAX_DMA_CHAN) | ||
| 343 | break; | ||
| 344 | } | ||
| 345 | } while (chan); | ||
| 346 | dev_info(mdev->sdev->parent, "DMA channels # %d\n", mdev->num_dma_ch); | ||
| 347 | return mdev->num_dma_ch; | ||
| 348 | } | ||
| 349 | |||
| 350 | /** | ||
| 351 | * mic_free_dma_chans - release DMA channels | ||
| 352 | * @mdev: pointer to mic_device instance | ||
| 353 | * | ||
| 354 | * returns none | ||
| 355 | */ | ||
| 356 | static void mic_free_dma_chans(struct mic_device *mdev) | ||
| 357 | { | ||
| 358 | int i = 0; | ||
| 359 | |||
| 360 | for (i = 0; i < mdev->num_dma_ch; i++) { | ||
| 361 | dma_release_channel(mdev->dma_ch[i]); | ||
| 362 | mdev->dma_ch[i] = NULL; | ||
| 363 | } | ||
| 364 | mdev->num_dma_ch = 0; | ||
| 130 | } | 365 | } |
| 131 | 366 | ||
| 132 | /** | 367 | /** |
| @@ -141,6 +376,7 @@ int mic_start(struct mic_device *mdev, const char *buf) | |||
| 141 | { | 376 | { |
| 142 | int rc; | 377 | int rc; |
| 143 | mutex_lock(&mdev->mic_mutex); | 378 | mutex_lock(&mdev->mic_mutex); |
| 379 | mic_bootparam_init(mdev); | ||
| 144 | retry: | 380 | retry: |
| 145 | if (MIC_OFFLINE != mdev->state) { | 381 | if (MIC_OFFLINE != mdev->state) { |
| 146 | rc = -EINVAL; | 382 | rc = -EINVAL; |
| @@ -161,14 +397,22 @@ retry: | |||
| 161 | rc = PTR_ERR(mdev->dma_mbdev); | 397 | rc = PTR_ERR(mdev->dma_mbdev); |
| 162 | goto unlock_ret; | 398 | goto unlock_ret; |
| 163 | } | 399 | } |
| 164 | mdev->dma_ch = mic_request_dma_chan(mdev); | 400 | if (!mic_request_dma_chans(mdev)) { |
| 165 | if (!mdev->dma_ch) { | 401 | rc = -ENODEV; |
| 166 | rc = -ENXIO; | ||
| 167 | goto dma_remove; | 402 | goto dma_remove; |
| 168 | } | 403 | } |
| 404 | mdev->scdev = scif_register_device(mdev->sdev->parent, MIC_SCIF_DEV, | ||
| 405 | &__mic_dma_ops, &scif_hw_ops, | ||
| 406 | mdev->id + 1, 0, &mdev->mmio, | ||
| 407 | &mdev->aper, mdev->dp, NULL, | ||
| 408 | mdev->dma_ch, mdev->num_dma_ch); | ||
| 409 | if (IS_ERR(mdev->scdev)) { | ||
| 410 | rc = PTR_ERR(mdev->scdev); | ||
| 411 | goto dma_free; | ||
| 412 | } | ||
| 169 | rc = mdev->ops->load_mic_fw(mdev, buf); | 413 | rc = mdev->ops->load_mic_fw(mdev, buf); |
| 170 | if (rc) | 414 | if (rc) |
| 171 | goto dma_release; | 415 | goto scif_remove; |
| 172 | mic_smpt_restore(mdev); | 416 | mic_smpt_restore(mdev); |
| 173 | mic_intr_restore(mdev); | 417 | mic_intr_restore(mdev); |
| 174 | mdev->intr_ops->enable_interrupts(mdev); | 418 | mdev->intr_ops->enable_interrupts(mdev); |
| @@ -177,8 +421,10 @@ retry: | |||
| 177 | mdev->ops->send_firmware_intr(mdev); | 421 | mdev->ops->send_firmware_intr(mdev); |
| 178 | mic_set_state(mdev, MIC_ONLINE); | 422 | mic_set_state(mdev, MIC_ONLINE); |
| 179 | goto unlock_ret; | 423 | goto unlock_ret; |
| 180 | dma_release: | 424 | scif_remove: |
| 181 | dma_release_channel(mdev->dma_ch); | 425 | scif_unregister_device(mdev->scdev); |
| 426 | dma_free: | ||
| 427 | mic_free_dma_chans(mdev); | ||
| 182 | dma_remove: | 428 | dma_remove: |
| 183 | mbus_unregister_device(mdev->dma_mbdev); | 429 | mbus_unregister_device(mdev->dma_mbdev); |
| 184 | unlock_ret: | 430 | unlock_ret: |
| @@ -197,11 +443,9 @@ void mic_stop(struct mic_device *mdev, bool force) | |||
| 197 | { | 443 | { |
| 198 | mutex_lock(&mdev->mic_mutex); | 444 | mutex_lock(&mdev->mic_mutex); |
| 199 | if (MIC_OFFLINE != mdev->state || force) { | 445 | if (MIC_OFFLINE != mdev->state || force) { |
| 446 | scif_unregister_device(mdev->scdev); | ||
| 200 | mic_virtio_reset_devices(mdev); | 447 | mic_virtio_reset_devices(mdev); |
| 201 | if (mdev->dma_ch) { | 448 | mic_free_dma_chans(mdev); |
| 202 | dma_release_channel(mdev->dma_ch); | ||
| 203 | mdev->dma_ch = NULL; | ||
| 204 | } | ||
| 205 | mbus_unregister_device(mdev->dma_mbdev); | 449 | mbus_unregister_device(mdev->dma_mbdev); |
| 206 | mic_bootparam_init(mdev); | 450 | mic_bootparam_init(mdev); |
| 207 | mic_reset(mdev); | 451 | mic_reset(mdev); |
diff --git a/drivers/misc/mic/host/mic_debugfs.c b/drivers/misc/mic/host/mic_debugfs.c index 687e9aacf3bb..3c9ea4896f3c 100644 --- a/drivers/misc/mic/host/mic_debugfs.c +++ b/drivers/misc/mic/host/mic_debugfs.c | |||
| @@ -214,6 +214,19 @@ static int mic_dp_show(struct seq_file *s, void *pos) | |||
| 214 | bootparam->shutdown_status); | 214 | bootparam->shutdown_status); |
| 215 | seq_printf(s, "Bootparam: shutdown_card %d\n", | 215 | seq_printf(s, "Bootparam: shutdown_card %d\n", |
| 216 | bootparam->shutdown_card); | 216 | bootparam->shutdown_card); |
| 217 | seq_printf(s, "Bootparam: tot_nodes %d\n", | ||
| 218 | bootparam->tot_nodes); | ||
| 219 | seq_printf(s, "Bootparam: node_id %d\n", | ||
| 220 | bootparam->node_id); | ||
| 221 | seq_printf(s, "Bootparam: c2h_scif_db %d\n", | ||
| 222 | bootparam->c2h_scif_db); | ||
| 223 | seq_printf(s, "Bootparam: h2c_scif_db %d\n", | ||
| 224 | bootparam->h2c_scif_db); | ||
| 225 | seq_printf(s, "Bootparam: scif_host_dma_addr 0x%llx\n", | ||
| 226 | bootparam->scif_host_dma_addr); | ||
| 227 | seq_printf(s, "Bootparam: scif_card_dma_addr 0x%llx\n", | ||
| 228 | bootparam->scif_card_dma_addr); | ||
| 229 | |||
| 217 | 230 | ||
| 218 | for (i = sizeof(*bootparam); i < MIC_DP_SIZE; | 231 | for (i = sizeof(*bootparam); i < MIC_DP_SIZE; |
| 219 | i += mic_total_desc_size(d)) { | 232 | i += mic_total_desc_size(d)) { |
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h index 016bd15a7bd1..01a7555aa648 100644 --- a/drivers/misc/mic/host/mic_device.h +++ b/drivers/misc/mic/host/mic_device.h | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <linux/irqreturn.h> | 27 | #include <linux/irqreturn.h> |
| 28 | #include <linux/dmaengine.h> | 28 | #include <linux/dmaengine.h> |
| 29 | #include <linux/mic_bus.h> | 29 | #include <linux/mic_bus.h> |
| 30 | 30 | #include "../bus/scif_bus.h" | |
| 31 | #include "mic_intr.h" | 31 | #include "mic_intr.h" |
| 32 | 32 | ||
| 33 | /* The maximum number of MIC devices supported in a single host system. */ | 33 | /* The maximum number of MIC devices supported in a single host system. */ |
| @@ -90,7 +90,9 @@ enum mic_stepping { | |||
| 90 | * @vdev_list: list of virtio devices. | 90 | * @vdev_list: list of virtio devices. |
| 91 | * @pm_notifier: Handles PM notifications from the OS. | 91 | * @pm_notifier: Handles PM notifications from the OS. |
| 92 | * @dma_mbdev: MIC BUS DMA device. | 92 | * @dma_mbdev: MIC BUS DMA device. |
| 93 | * @dma_ch: DMA channel reserved by this driver for use by virtio devices. | 93 | * @dma_ch - Array of DMA channels |
| 94 | * @num_dma_ch - Number of DMA channels available | ||
| 95 | * @scdev: SCIF device on the SCIF virtual bus. | ||
| 94 | */ | 96 | */ |
| 95 | struct mic_device { | 97 | struct mic_device { |
| 96 | struct mic_mw mmio; | 98 | struct mic_mw mmio; |
| @@ -129,7 +131,9 @@ struct mic_device { | |||
| 129 | struct list_head vdev_list; | 131 | struct list_head vdev_list; |
| 130 | struct notifier_block pm_notifier; | 132 | struct notifier_block pm_notifier; |
| 131 | struct mbus_device *dma_mbdev; | 133 | struct mbus_device *dma_mbdev; |
| 132 | struct dma_chan *dma_ch; | 134 | struct dma_chan *dma_ch[MIC_MAX_DMA_CHAN]; |
| 135 | int num_dma_ch; | ||
| 136 | struct scif_hw_dev *scdev; | ||
| 133 | }; | 137 | }; |
| 134 | 138 | ||
| 135 | /** | 139 | /** |
| @@ -228,4 +232,5 @@ void mic_exit_debugfs(void); | |||
| 228 | void mic_prepare_suspend(struct mic_device *mdev); | 232 | void mic_prepare_suspend(struct mic_device *mdev); |
| 229 | void mic_complete_resume(struct mic_device *mdev); | 233 | void mic_complete_resume(struct mic_device *mdev); |
| 230 | void mic_suspend(struct mic_device *mdev); | 234 | void mic_suspend(struct mic_device *mdev); |
| 235 | extern atomic_t g_num_mics; | ||
| 231 | #endif | 236 | #endif |
diff --git a/drivers/misc/mic/host/mic_intr.h b/drivers/misc/mic/host/mic_intr.h index 9f783d4ad7f1..cce28824db8a 100644 --- a/drivers/misc/mic/host/mic_intr.h +++ b/drivers/misc/mic/host/mic_intr.h | |||
| @@ -28,8 +28,9 @@ | |||
| 28 | * 3 for virtio network, console and block devices. | 28 | * 3 for virtio network, console and block devices. |
| 29 | * 1 for card shutdown notifications. | 29 | * 1 for card shutdown notifications. |
| 30 | * 4 for host owned DMA channels. | 30 | * 4 for host owned DMA channels. |
| 31 | * 1 for SCIF | ||
| 31 | */ | 32 | */ |
| 32 | #define MIC_MIN_MSIX 8 | 33 | #define MIC_MIN_MSIX 9 |
| 33 | #define MIC_NUM_OFFSETS 32 | 34 | #define MIC_NUM_OFFSETS 32 |
| 34 | 35 | ||
| 35 | /** | 36 | /** |
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c index ab37a3117d23..456462932151 100644 --- a/drivers/misc/mic/host/mic_main.c +++ b/drivers/misc/mic/host/mic_main.c | |||
| @@ -67,6 +67,8 @@ static struct ida g_mic_ida; | |||
| 67 | static struct class *g_mic_class; | 67 | static struct class *g_mic_class; |
| 68 | /* Base device node number for MIC devices */ | 68 | /* Base device node number for MIC devices */ |
| 69 | static dev_t g_mic_devno; | 69 | static dev_t g_mic_devno; |
| 70 | /* Track the total number of MIC devices */ | ||
| 71 | atomic_t g_num_mics; | ||
| 70 | 72 | ||
| 71 | static const struct file_operations mic_fops = { | 73 | static const struct file_operations mic_fops = { |
| 72 | .open = mic_open, | 74 | .open = mic_open, |
| @@ -408,6 +410,7 @@ static int mic_probe(struct pci_dev *pdev, | |||
| 408 | dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc); | 410 | dev_err(&pdev->dev, "cdev_add err id %d rc %d\n", mdev->id, rc); |
| 409 | goto cleanup_debug_dir; | 411 | goto cleanup_debug_dir; |
| 410 | } | 412 | } |
| 413 | atomic_inc(&g_num_mics); | ||
| 411 | return 0; | 414 | return 0; |
| 412 | cleanup_debug_dir: | 415 | cleanup_debug_dir: |
| 413 | mic_delete_debug_dir(mdev); | 416 | mic_delete_debug_dir(mdev); |
| @@ -459,6 +462,7 @@ static void mic_remove(struct pci_dev *pdev) | |||
| 459 | return; | 462 | return; |
| 460 | 463 | ||
| 461 | mic_stop(mdev, false); | 464 | mic_stop(mdev, false); |
| 465 | atomic_dec(&g_num_mics); | ||
| 462 | cdev_del(&mdev->cdev); | 466 | cdev_del(&mdev->cdev); |
| 463 | mic_delete_debug_dir(mdev); | 467 | mic_delete_debug_dir(mdev); |
| 464 | mutex_lock(&mdev->mic_mutex); | 468 | mutex_lock(&mdev->mic_mutex); |
| @@ -478,6 +482,7 @@ static void mic_remove(struct pci_dev *pdev) | |||
| 478 | ida_simple_remove(&g_mic_ida, mdev->id); | 482 | ida_simple_remove(&g_mic_ida, mdev->id); |
| 479 | kfree(mdev); | 483 | kfree(mdev); |
| 480 | } | 484 | } |
| 485 | |||
| 481 | static struct pci_driver mic_driver = { | 486 | static struct pci_driver mic_driver = { |
| 482 | .name = mic_driver_name, | 487 | .name = mic_driver_name, |
| 483 | .id_table = mic_pci_tbl, | 488 | .id_table = mic_pci_tbl, |
| @@ -512,6 +517,7 @@ static int __init mic_init(void) | |||
| 512 | } | 517 | } |
| 513 | return ret; | 518 | return ret; |
| 514 | cleanup_debugfs: | 519 | cleanup_debugfs: |
| 520 | ida_destroy(&g_mic_ida); | ||
| 515 | mic_exit_debugfs(); | 521 | mic_exit_debugfs(); |
| 516 | class_destroy(g_mic_class); | 522 | class_destroy(g_mic_class); |
| 517 | cleanup_chrdev: | 523 | cleanup_chrdev: |
diff --git a/drivers/misc/mic/host/mic_smpt.c b/drivers/misc/mic/host/mic_smpt.c index fae474c4899e..cec82034875f 100644 --- a/drivers/misc/mic/host/mic_smpt.c +++ b/drivers/misc/mic/host/mic_smpt.c | |||
| @@ -174,8 +174,7 @@ static int mic_get_smpt_ref_count(struct mic_device *mdev, dma_addr_t dma_addr, | |||
| 174 | * | 174 | * |
| 175 | * returns a DMA address. | 175 | * returns a DMA address. |
| 176 | */ | 176 | */ |
| 177 | static dma_addr_t | 177 | dma_addr_t mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr) |
| 178 | mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr) | ||
| 179 | { | 178 | { |
| 180 | struct mic_smpt_info *smpt_info = mdev->smpt; | 179 | struct mic_smpt_info *smpt_info = mdev->smpt; |
| 181 | int spt; | 180 | int spt; |
| @@ -214,7 +213,7 @@ dma_addr_t mic_map(struct mic_device *mdev, dma_addr_t dma_addr, size_t size) | |||
| 214 | if (!size || size > mic_max_system_memory(mdev)) | 213 | if (!size || size > mic_max_system_memory(mdev)) |
| 215 | return mic_addr; | 214 | return mic_addr; |
| 216 | 215 | ||
| 217 | ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL); | 216 | ref = kmalloc_array(mdev->smpt->info.num_reg, sizeof(s64), GFP_ATOMIC); |
| 218 | if (!ref) | 217 | if (!ref) |
| 219 | return mic_addr; | 218 | return mic_addr; |
| 220 | 219 | ||
| @@ -271,7 +270,7 @@ void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size) | |||
| 271 | } | 270 | } |
| 272 | 271 | ||
| 273 | spt = mic_sys_addr_to_smpt(mdev, mic_addr); | 272 | spt = mic_sys_addr_to_smpt(mdev, mic_addr); |
| 274 | ref = kmalloc(mdev->smpt->info.num_reg * sizeof(s64), GFP_KERNEL); | 273 | ref = kmalloc_array(mdev->smpt->info.num_reg, sizeof(s64), GFP_ATOMIC); |
| 275 | if (!ref) | 274 | if (!ref) |
| 276 | return; | 275 | return; |
| 277 | 276 | ||
diff --git a/drivers/misc/mic/host/mic_smpt.h b/drivers/misc/mic/host/mic_smpt.h index 51970abfe7df..68721c6e7455 100644 --- a/drivers/misc/mic/host/mic_smpt.h +++ b/drivers/misc/mic/host/mic_smpt.h | |||
| @@ -78,6 +78,7 @@ void mic_unmap_single(struct mic_device *mdev, | |||
| 78 | dma_addr_t mic_map(struct mic_device *mdev, | 78 | dma_addr_t mic_map(struct mic_device *mdev, |
| 79 | dma_addr_t dma_addr, size_t size); | 79 | dma_addr_t dma_addr, size_t size); |
| 80 | void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size); | 80 | void mic_unmap(struct mic_device *mdev, dma_addr_t mic_addr, size_t size); |
| 81 | dma_addr_t mic_to_dma_addr(struct mic_device *mdev, dma_addr_t mic_addr); | ||
| 81 | 82 | ||
| 82 | /** | 83 | /** |
| 83 | * mic_map_error - Check a MIC address for errors. | 84 | * mic_map_error - Check a MIC address for errors. |
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c index a020e4eb435a..cc08e9f733c9 100644 --- a/drivers/misc/mic/host/mic_virtio.c +++ b/drivers/misc/mic/host/mic_virtio.c | |||
| @@ -40,7 +40,7 @@ static int mic_sync_dma(struct mic_device *mdev, dma_addr_t dst, | |||
| 40 | { | 40 | { |
| 41 | int err = 0; | 41 | int err = 0; |
| 42 | struct dma_async_tx_descriptor *tx; | 42 | struct dma_async_tx_descriptor *tx; |
| 43 | struct dma_chan *mic_ch = mdev->dma_ch; | 43 | struct dma_chan *mic_ch = mdev->dma_ch[0]; |
| 44 | 44 | ||
| 45 | if (!mic_ch) { | 45 | if (!mic_ch) { |
| 46 | err = -EBUSY; | 46 | err = -EBUSY; |
| @@ -80,7 +80,7 @@ static int mic_virtio_copy_to_user(struct mic_vdev *mvdev, void __user *ubuf, | |||
| 80 | struct mic_device *mdev = mvdev->mdev; | 80 | struct mic_device *mdev = mvdev->mdev; |
| 81 | void __iomem *dbuf = mdev->aper.va + daddr; | 81 | void __iomem *dbuf = mdev->aper.va + daddr; |
| 82 | struct mic_vringh *mvr = &mvdev->mvr[vr_idx]; | 82 | struct mic_vringh *mvr = &mvdev->mvr[vr_idx]; |
| 83 | size_t dma_alignment = 1 << mdev->dma_ch->device->copy_align; | 83 | size_t dma_alignment = 1 << mdev->dma_ch[0]->device->copy_align; |
| 84 | size_t dma_offset; | 84 | size_t dma_offset; |
| 85 | size_t partlen; | 85 | size_t partlen; |
| 86 | int err; | 86 | int err; |
| @@ -129,7 +129,7 @@ static int mic_virtio_copy_from_user(struct mic_vdev *mvdev, void __user *ubuf, | |||
| 129 | struct mic_device *mdev = mvdev->mdev; | 129 | struct mic_device *mdev = mvdev->mdev; |
| 130 | void __iomem *dbuf = mdev->aper.va + daddr; | 130 | void __iomem *dbuf = mdev->aper.va + daddr; |
| 131 | struct mic_vringh *mvr = &mvdev->mvr[vr_idx]; | 131 | struct mic_vringh *mvr = &mvdev->mvr[vr_idx]; |
| 132 | size_t dma_alignment = 1 << mdev->dma_ch->device->copy_align; | 132 | size_t dma_alignment = 1 << mdev->dma_ch[0]->device->copy_align; |
| 133 | size_t partlen; | 133 | size_t partlen; |
| 134 | int err; | 134 | int err; |
| 135 | 135 | ||
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c index b7a21e11dcdf..3341e90dede4 100644 --- a/drivers/misc/mic/host/mic_x100.c +++ b/drivers/misc/mic/host/mic_x100.c | |||
| @@ -167,8 +167,7 @@ static void mic_x100_send_intr(struct mic_device *mdev, int doorbell) | |||
| 167 | if (doorbell < MIC_X100_NUM_SBOX_IRQ) { | 167 | if (doorbell < MIC_X100_NUM_SBOX_IRQ) { |
| 168 | mic_x100_send_sbox_intr(mdev, doorbell); | 168 | mic_x100_send_sbox_intr(mdev, doorbell); |
| 169 | } else { | 169 | } else { |
| 170 | rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ + | 170 | rdmasr_db = doorbell - MIC_X100_NUM_SBOX_IRQ; |
| 171 | MIC_X100_RDMASR_IRQ_BASE; | ||
| 172 | mic_x100_send_rdmasr_intr(mdev, rdmasr_db); | 171 | mic_x100_send_rdmasr_intr(mdev, rdmasr_db); |
| 173 | } | 172 | } |
| 174 | } | 173 | } |
