diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2016-12-05 01:07:20 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-12-08 16:57:21 -0500 |
commit | 906e4a3c7e03701008d343daec8952d6cf49f82b (patch) | |
tree | 1971ad8a833d53b0f2dfbfb716be3149a63840be | |
parent | 89fa9b5cb08c9d8ad709415b88395be463eceeee (diff) |
scsi: g_NCR5380: Use probe_irq_*() for IRQ probing
Use standard probe_irq_on() and probe_irq_off() functions instead of own
implementation. This prevents warning messages like this in the kernel
log: genirq: Flags mismatch irq 1. 00000000 (NCR-probe) vs. 00000080
(i8042)
Move the IRQ trigger code from NCR5380 to g_NCR5380 where it is used.
Also clear interrupt flag before and after the probe.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/NCR5380.c | 77 | ||||
-rw-r--r-- | drivers/scsi/NCR5380.h | 11 | ||||
-rw-r--r-- | drivers/scsi/g_NCR5380.c | 52 | ||||
-rw-r--r-- | drivers/scsi/g_NCR5380.h | 2 |
4 files changed, 54 insertions, 88 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index d849ffa378b1..4f5ca794bb71 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -97,9 +97,6 @@ | |||
97 | * and macros and include this file in your driver. | 97 | * and macros and include this file in your driver. |
98 | * | 98 | * |
99 | * These macros control options : | 99 | * These macros control options : |
100 | * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be | ||
101 | * defined. | ||
102 | * | ||
103 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically | 100 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically |
104 | * for commands that return with a CHECK CONDITION status. | 101 | * for commands that return with a CHECK CONDITION status. |
105 | * | 102 | * |
@@ -127,9 +124,7 @@ | |||
127 | * NCR5380_dma_residual - residual byte count | 124 | * NCR5380_dma_residual - residual byte count |
128 | * | 125 | * |
129 | * The generic driver is initialized by calling NCR5380_init(instance), | 126 | * The generic driver is initialized by calling NCR5380_init(instance), |
130 | * after setting the appropriate host specific fields and ID. If the | 127 | * after setting the appropriate host specific fields and ID. |
131 | * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, | ||
132 | * possible) function may be used. | ||
133 | */ | 128 | */ |
134 | 129 | ||
135 | #ifndef NCR5380_io_delay | 130 | #ifndef NCR5380_io_delay |
@@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) | |||
351 | } | 346 | } |
352 | #endif | 347 | #endif |
353 | 348 | ||
354 | |||
355 | static int probe_irq; | ||
356 | |||
357 | /** | ||
358 | * probe_intr - helper for IRQ autoprobe | ||
359 | * @irq: interrupt number | ||
360 | * @dev_id: unused | ||
361 | * @regs: unused | ||
362 | * | ||
363 | * Set a flag to indicate the IRQ in question was received. This is | ||
364 | * used by the IRQ probe code. | ||
365 | */ | ||
366 | |||
367 | static irqreturn_t probe_intr(int irq, void *dev_id) | ||
368 | { | ||
369 | probe_irq = irq; | ||
370 | return IRQ_HANDLED; | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * NCR5380_probe_irq - find the IRQ of an NCR5380 | ||
375 | * @instance: NCR5380 controller | ||
376 | * @possible: bitmask of ISA IRQ lines | ||
377 | * | ||
378 | * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ | ||
379 | * and then looking to see what interrupt actually turned up. | ||
380 | */ | ||
381 | |||
382 | static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, | ||
383 | int possible) | ||
384 | { | ||
385 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
386 | unsigned long timeout; | ||
387 | int trying_irqs, i, mask; | ||
388 | |||
389 | for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) | ||
390 | if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) | ||
391 | trying_irqs |= mask; | ||
392 | |||
393 | timeout = jiffies + msecs_to_jiffies(250); | ||
394 | probe_irq = NO_IRQ; | ||
395 | |||
396 | /* | ||
397 | * A interrupt is triggered whenever BSY = false, SEL = true | ||
398 | * and a bit set in the SELECT_ENABLE_REG is asserted on the | ||
399 | * SCSI bus. | ||
400 | * | ||
401 | * Note that the bus is only driven when the phase control signals | ||
402 | * (I/O, C/D, and MSG) match those in the TCR, so we must reset that | ||
403 | * to zero. | ||
404 | */ | ||
405 | |||
406 | NCR5380_write(TARGET_COMMAND_REG, 0); | ||
407 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
408 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); | ||
409 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); | ||
410 | |||
411 | while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) | ||
412 | schedule_timeout_uninterruptible(1); | ||
413 | |||
414 | NCR5380_write(SELECT_ENABLE_REG, 0); | ||
415 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
416 | |||
417 | for (i = 1, mask = 2; i < 16; ++i, mask <<= 1) | ||
418 | if (trying_irqs & mask) | ||
419 | free_irq(i, NULL); | ||
420 | |||
421 | return probe_irq; | ||
422 | } | ||
423 | |||
424 | /** | 349 | /** |
425 | * NCR58380_info - report driver and host information | 350 | * NCR58380_info - report driver and host information |
426 | * @instance: relevant scsi host instance | 351 | * @instance: relevant scsi host instance |
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 3c6ce5434449..51a3567a6fb2 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h | |||
@@ -199,16 +199,6 @@ | |||
199 | 199 | ||
200 | #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) | 200 | #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) |
201 | 201 | ||
202 | /* | ||
203 | * These are "special" values for the irq and dma_channel fields of the | ||
204 | * Scsi_Host structure | ||
205 | */ | ||
206 | |||
207 | #define DMA_NONE 255 | ||
208 | #define IRQ_AUTO 254 | ||
209 | #define DMA_AUTO 254 | ||
210 | #define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */ | ||
211 | |||
212 | #ifndef NO_IRQ | 202 | #ifndef NO_IRQ |
213 | #define NO_IRQ 0 | 203 | #define NO_IRQ 0 |
214 | #endif | 204 | #endif |
@@ -290,7 +280,6 @@ static void NCR5380_print(struct Scsi_Host *instance); | |||
290 | #define NCR5380_dprint_phase(flg, arg) do {} while (0) | 280 | #define NCR5380_dprint_phase(flg, arg) do {} while (0) |
291 | #endif | 281 | #endif |
292 | 282 | ||
293 | static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); | ||
294 | static int NCR5380_init(struct Scsi_Host *instance, int flags); | 283 | static int NCR5380_init(struct Scsi_Host *instance, int flags); |
295 | static int NCR5380_maybe_reset_bus(struct Scsi_Host *); | 284 | static int NCR5380_maybe_reset_bus(struct Scsi_Host *); |
296 | static void NCR5380_exit(struct Scsi_Host *instance); | 285 | static void NCR5380_exit(struct Scsi_Host *instance); |
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 76e37455480e..6d245a7b9363 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c | |||
@@ -67,6 +67,56 @@ MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC31 | |||
67 | MODULE_ALIAS("g_NCR5380_mmio"); | 67 | MODULE_ALIAS("g_NCR5380_mmio"); |
68 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
69 | 69 | ||
70 | static void g_NCR5380_trigger_irq(struct Scsi_Host *instance) | ||
71 | { | ||
72 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
73 | |||
74 | /* | ||
75 | * An interrupt is triggered whenever BSY = false, SEL = true | ||
76 | * and a bit set in the SELECT_ENABLE_REG is asserted on the | ||
77 | * SCSI bus. | ||
78 | * | ||
79 | * Note that the bus is only driven when the phase control signals | ||
80 | * (I/O, C/D, and MSG) match those in the TCR. | ||
81 | */ | ||
82 | NCR5380_write(TARGET_COMMAND_REG, | ||
83 | PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); | ||
84 | NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); | ||
85 | NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); | ||
86 | NCR5380_write(INITIATOR_COMMAND_REG, | ||
87 | ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); | ||
88 | |||
89 | msleep(1); | ||
90 | |||
91 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); | ||
92 | NCR5380_write(SELECT_ENABLE_REG, 0); | ||
93 | NCR5380_write(TARGET_COMMAND_REG, 0); | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent | ||
98 | * @instance: SCSI host instance | ||
99 | * | ||
100 | * Autoprobe for the IRQ line used by the card by triggering an IRQ | ||
101 | * and then looking to see what interrupt actually turned up. | ||
102 | */ | ||
103 | |||
104 | static int g_NCR5380_probe_irq(struct Scsi_Host *instance) | ||
105 | { | ||
106 | struct NCR5380_hostdata *hostdata = shost_priv(instance); | ||
107 | int irq_mask, irq; | ||
108 | |||
109 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
110 | irq_mask = probe_irq_on(); | ||
111 | g_NCR5380_trigger_irq(instance); | ||
112 | irq = probe_irq_off(irq_mask); | ||
113 | NCR5380_read(RESET_PARITY_INTERRUPT_REG); | ||
114 | |||
115 | if (irq <= 0) | ||
116 | return NO_IRQ; | ||
117 | return irq; | ||
118 | } | ||
119 | |||
70 | /* | 120 | /* |
71 | * Configure I/O address of 53C400A or DTC436 by writing magic numbers | 121 | * Configure I/O address of 53C400A or DTC436 by writing magic numbers |
72 | * to ports 0x779 and 0x379. | 122 | * to ports 0x779 and 0x379. |
@@ -272,7 +322,7 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, | |||
272 | if (irq != IRQ_AUTO) | 322 | if (irq != IRQ_AUTO) |
273 | instance->irq = irq; | 323 | instance->irq = irq; |
274 | else | 324 | else |
275 | instance->irq = NCR5380_probe_irq(instance, 0xffff); | 325 | instance->irq = g_NCR5380_probe_irq(instance); |
276 | 326 | ||
277 | /* Compatibility with documented NCR5380 kernel parameters */ | 327 | /* Compatibility with documented NCR5380 kernel parameters */ |
278 | if (instance->irq == 255) | 328 | if (instance->irq == 255) |
diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index 3ce5b65ccb00..81b22d989648 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h | |||
@@ -51,4 +51,6 @@ | |||
51 | #define BOARD_DTC3181E 3 | 51 | #define BOARD_DTC3181E 3 |
52 | #define BOARD_HP_C2502 4 | 52 | #define BOARD_HP_C2502 4 |
53 | 53 | ||
54 | #define IRQ_AUTO 254 | ||
55 | |||
54 | #endif /* GENERIC_NCR5380_H */ | 56 | #endif /* GENERIC_NCR5380_H */ |