aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/mic
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mic')
-rw-r--r--drivers/misc/mic/host/mic_device.h5
-rw-r--r--drivers/misc/mic/host/mic_main.c2
-rw-r--r--drivers/misc/mic/host/mic_virtio.c5
-rw-r--r--drivers/misc/mic/host/mic_x100.c36
4 files changed, 28 insertions, 20 deletions
diff --git a/drivers/misc/mic/host/mic_device.h b/drivers/misc/mic/host/mic_device.h
index 3574cc375bb9..1a6edce2ecde 100644
--- a/drivers/misc/mic/host/mic_device.h
+++ b/drivers/misc/mic/host/mic_device.h
@@ -112,7 +112,7 @@ struct mic_device {
112 struct work_struct shutdown_work; 112 struct work_struct shutdown_work;
113 u8 state; 113 u8 state;
114 u8 shutdown_status; 114 u8 shutdown_status;
115 struct sysfs_dirent *state_sysfs; 115 struct kernfs_node *state_sysfs;
116 struct completion reset_wait; 116 struct completion reset_wait;
117 void *log_buf_addr; 117 void *log_buf_addr;
118 int *log_buf_len; 118 int *log_buf_len;
@@ -134,6 +134,8 @@ struct mic_device {
134 * @send_intr: Send an interrupt for a particular doorbell on the card. 134 * @send_intr: Send an interrupt for a particular doorbell on the card.
135 * @ack_interrupt: Hardware specific operations to ack the h/w on 135 * @ack_interrupt: Hardware specific operations to ack the h/w on
136 * receipt of an interrupt. 136 * receipt of an interrupt.
137 * @intr_workarounds: Hardware specific workarounds needed after
138 * handling an interrupt.
137 * @reset: Reset the remote processor. 139 * @reset: Reset the remote processor.
138 * @reset_fw_ready: Reset firmware ready field. 140 * @reset_fw_ready: Reset firmware ready field.
139 * @is_fw_ready: Check if firmware is ready for OS download. 141 * @is_fw_ready: Check if firmware is ready for OS download.
@@ -149,6 +151,7 @@ struct mic_hw_ops {
149 void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val); 151 void (*write_spad)(struct mic_device *mdev, unsigned int idx, u32 val);
150 void (*send_intr)(struct mic_device *mdev, int doorbell); 152 void (*send_intr)(struct mic_device *mdev, int doorbell);
151 u32 (*ack_interrupt)(struct mic_device *mdev); 153 u32 (*ack_interrupt)(struct mic_device *mdev);
154 void (*intr_workarounds)(struct mic_device *mdev);
152 void (*reset)(struct mic_device *mdev); 155 void (*reset)(struct mic_device *mdev);
153 void (*reset_fw_ready)(struct mic_device *mdev); 156 void (*reset_fw_ready)(struct mic_device *mdev);
154 bool (*is_fw_ready)(struct mic_device *mdev); 157 bool (*is_fw_ready)(struct mic_device *mdev);
diff --git a/drivers/misc/mic/host/mic_main.c b/drivers/misc/mic/host/mic_main.c
index ad838c7651c4..c04a021e20c7 100644
--- a/drivers/misc/mic/host/mic_main.c
+++ b/drivers/misc/mic/host/mic_main.c
@@ -115,7 +115,7 @@ static irqreturn_t mic_shutdown_db(int irq, void *data)
115 struct mic_device *mdev = data; 115 struct mic_device *mdev = data;
116 struct mic_bootparam *bootparam = mdev->dp; 116 struct mic_bootparam *bootparam = mdev->dp;
117 117
118 mdev->ops->ack_interrupt(mdev); 118 mdev->ops->intr_workarounds(mdev);
119 119
120 switch (bootparam->shutdown_status) { 120 switch (bootparam->shutdown_status) {
121 case MIC_HALTED: 121 case MIC_HALTED:
diff --git a/drivers/misc/mic/host/mic_virtio.c b/drivers/misc/mic/host/mic_virtio.c
index e04bb4fe6823..7e1ef0ebbb80 100644
--- a/drivers/misc/mic/host/mic_virtio.c
+++ b/drivers/misc/mic/host/mic_virtio.c
@@ -156,7 +156,8 @@ static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
156static int _mic_virtio_copy(struct mic_vdev *mvdev, 156static int _mic_virtio_copy(struct mic_vdev *mvdev,
157 struct mic_copy_desc *copy) 157 struct mic_copy_desc *copy)
158{ 158{
159 int ret = 0, iovcnt = copy->iovcnt; 159 int ret = 0;
160 u32 iovcnt = copy->iovcnt;
160 struct iovec iov; 161 struct iovec iov;
161 struct iovec __user *u_iov = copy->iov; 162 struct iovec __user *u_iov = copy->iov;
162 void __user *ubuf = NULL; 163 void __user *ubuf = NULL;
@@ -369,7 +370,7 @@ static irqreturn_t mic_virtio_intr_handler(int irq, void *data)
369 struct mic_vdev *mvdev = data; 370 struct mic_vdev *mvdev = data;
370 struct mic_device *mdev = mvdev->mdev; 371 struct mic_device *mdev = mvdev->mdev;
371 372
372 mdev->ops->ack_interrupt(mdev); 373 mdev->ops->intr_workarounds(mdev);
373 schedule_work(&mvdev->virtio_bh_work); 374 schedule_work(&mvdev->virtio_bh_work);
374 return IRQ_HANDLED; 375 return IRQ_HANDLED;
375} 376}
diff --git a/drivers/misc/mic/host/mic_x100.c b/drivers/misc/mic/host/mic_x100.c
index 0dfa8a81436e..5562fdd3ef4e 100644
--- a/drivers/misc/mic/host/mic_x100.c
+++ b/drivers/misc/mic/host/mic_x100.c
@@ -174,35 +174,38 @@ static void mic_x100_send_intr(struct mic_device *mdev, int doorbell)
174} 174}
175 175
176/** 176/**
177 * mic_ack_interrupt - Device specific interrupt handling. 177 * mic_x100_ack_interrupt - Read the interrupt sources register and
178 * @mdev: pointer to mic_device instance 178 * clear it. This function will be called in the MSI/INTx case.
179 * @mdev: Pointer to mic_device instance.
179 * 180 *
180 * Returns: bitmask of doorbell events triggered. 181 * Returns: bitmask of interrupt sources triggered.
181 */ 182 */
182static u32 mic_x100_ack_interrupt(struct mic_device *mdev) 183static u32 mic_x100_ack_interrupt(struct mic_device *mdev)
183{ 184{
184 u32 reg = 0;
185 struct mic_mw *mw = &mdev->mmio;
186 u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0; 185 u32 sicr0 = MIC_X100_SBOX_BASE_ADDRESS + MIC_X100_SBOX_SICR0;
186 u32 reg = mic_mmio_read(&mdev->mmio, sicr0);
187 mic_mmio_write(&mdev->mmio, reg, sicr0);
188 return reg;
189}
190
191/**
192 * mic_x100_intr_workarounds - These hardware specific workarounds are
193 * to be invoked everytime an interrupt is handled.
194 * @mdev: Pointer to mic_device instance.
195 *
196 * Returns: none
197 */
198static void mic_x100_intr_workarounds(struct mic_device *mdev)
199{
200 struct mic_mw *mw = &mdev->mmio;
187 201
188 /* Clear pending bit array. */ 202 /* Clear pending bit array. */
189 if (MIC_A0_STEP == mdev->stepping) 203 if (MIC_A0_STEP == mdev->stepping)
190 mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS + 204 mic_mmio_write(mw, 1, MIC_X100_SBOX_BASE_ADDRESS +
191 MIC_X100_SBOX_MSIXPBACR); 205 MIC_X100_SBOX_MSIXPBACR);
192 206
193 if (mdev->irq_info.num_vectors <= 1) {
194 reg = mic_mmio_read(mw, sicr0);
195
196 if (unlikely(!reg))
197 goto done;
198
199 mic_mmio_write(mw, reg, sicr0);
200 }
201
202 if (mdev->stepping >= MIC_B0_STEP) 207 if (mdev->stepping >= MIC_B0_STEP)
203 mdev->intr_ops->enable_interrupts(mdev); 208 mdev->intr_ops->enable_interrupts(mdev);
204done:
205 return reg;
206} 209}
207 210
208/** 211/**
@@ -553,6 +556,7 @@ struct mic_hw_ops mic_x100_ops = {
553 .write_spad = mic_x100_write_spad, 556 .write_spad = mic_x100_write_spad,
554 .send_intr = mic_x100_send_intr, 557 .send_intr = mic_x100_send_intr,
555 .ack_interrupt = mic_x100_ack_interrupt, 558 .ack_interrupt = mic_x100_ack_interrupt,
559 .intr_workarounds = mic_x100_intr_workarounds,
556 .reset = mic_x100_hw_reset, 560 .reset = mic_x100_hw_reset,
557 .reset_fw_ready = mic_x100_reset_fw_ready, 561 .reset_fw_ready = mic_x100_reset_fw_ready,
558 .is_fw_ready = mic_x100_is_fw_ready, 562 .is_fw_ready = mic_x100_is_fw_ready,