diff options
Diffstat (limited to 'drivers/ide/icside.c')
| -rw-r--r-- | drivers/ide/icside.c | 87 |
1 files changed, 17 insertions, 70 deletions
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 36da913cc553..0f67f1abbbd3 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
| @@ -65,8 +65,6 @@ static struct cardinfo icside_cardinfo_v6_2 = { | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | struct icside_state { | 67 | struct icside_state { |
| 68 | unsigned int channel; | ||
| 69 | unsigned int enabled; | ||
| 70 | void __iomem *irq_port; | 68 | void __iomem *irq_port; |
| 71 | void __iomem *ioc_base; | 69 | void __iomem *ioc_base; |
| 72 | unsigned int sel; | 70 | unsigned int sel; |
| @@ -116,18 +114,11 @@ static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr) | |||
| 116 | struct icside_state *state = ec->irq_data; | 114 | struct icside_state *state = ec->irq_data; |
| 117 | void __iomem *base = state->irq_port; | 115 | void __iomem *base = state->irq_port; |
| 118 | 116 | ||
| 119 | state->enabled = 1; | 117 | writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); |
| 118 | readb(base + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 120 | 119 | ||
| 121 | switch (state->channel) { | 120 | writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); |
| 122 | case 0: | 121 | readb(base + ICS_ARCIN_V6_INTROFFSET_1); |
| 123 | writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1); | ||
| 124 | readb(base + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 125 | break; | ||
| 126 | case 1: | ||
| 127 | writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 128 | readb(base + ICS_ARCIN_V6_INTROFFSET_1); | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | } | 122 | } |
| 132 | 123 | ||
| 133 | /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) | 124 | /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) |
| @@ -137,8 +128,6 @@ static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr) | |||
| 137 | { | 128 | { |
| 138 | struct icside_state *state = ec->irq_data; | 129 | struct icside_state *state = ec->irq_data; |
| 139 | 130 | ||
| 140 | state->enabled = 0; | ||
| 141 | |||
| 142 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); | 131 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); |
| 143 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); | 132 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); |
| 144 | } | 133 | } |
| @@ -160,44 +149,6 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { | |||
| 160 | .irqpending = icside_irqpending_arcin_v6, | 149 | .irqpending = icside_irqpending_arcin_v6, |
| 161 | }; | 150 | }; |
| 162 | 151 | ||
| 163 | /* | ||
| 164 | * Handle routing of interrupts. This is called before | ||
| 165 | * we write the command to the drive. | ||
| 166 | */ | ||
| 167 | static void icside_maskproc(ide_drive_t *drive, int mask) | ||
| 168 | { | ||
| 169 | ide_hwif_t *hwif = drive->hwif; | ||
| 170 | struct expansion_card *ec = ECARD_DEV(hwif->dev); | ||
| 171 | struct icside_state *state = ecard_get_drvdata(ec); | ||
| 172 | unsigned long flags; | ||
| 173 | |||
| 174 | local_irq_save(flags); | ||
| 175 | |||
| 176 | state->channel = hwif->channel; | ||
| 177 | |||
| 178 | if (state->enabled && !mask) { | ||
| 179 | switch (hwif->channel) { | ||
| 180 | case 0: | ||
| 181 | writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); | ||
| 182 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 183 | break; | ||
| 184 | case 1: | ||
| 185 | writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 186 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); | ||
| 187 | break; | ||
| 188 | } | ||
| 189 | } else { | ||
| 190 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2); | ||
| 191 | readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1); | ||
| 192 | } | ||
| 193 | |||
| 194 | local_irq_restore(flags); | ||
| 195 | } | ||
| 196 | |||
| 197 | static const struct ide_port_ops icside_v6_no_dma_port_ops = { | ||
| 198 | .maskproc = icside_maskproc, | ||
| 199 | }; | ||
| 200 | |||
| 201 | #ifdef CONFIG_BLK_DEV_IDEDMA_ICS | 152 | #ifdef CONFIG_BLK_DEV_IDEDMA_ICS |
| 202 | /* | 153 | /* |
| 203 | * SG-DMA support. | 154 | * SG-DMA support. |
| @@ -236,7 +187,8 @@ static const struct ide_port_ops icside_v6_no_dma_port_ops = { | |||
| 236 | */ | 187 | */ |
| 237 | static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | 188 | static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) |
| 238 | { | 189 | { |
| 239 | int cycle_time, use_dma_info = 0; | 190 | unsigned long cycle_time; |
| 191 | int use_dma_info = 0; | ||
| 240 | 192 | ||
| 241 | switch (xfer_mode) { | 193 | switch (xfer_mode) { |
| 242 | case XFER_MW_DMA_2: | 194 | case XFER_MW_DMA_2: |
| @@ -267,15 +219,15 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | |||
| 267 | if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME] > cycle_time) | 219 | if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME] > cycle_time) |
| 268 | cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME]; | 220 | cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME]; |
| 269 | 221 | ||
| 270 | drive->drive_data = cycle_time; | 222 | ide_set_drivedata(drive, (void *)cycle_time); |
| 271 | 223 | ||
| 272 | printk("%s: %s selected (peak %dMB/s)\n", drive->name, | 224 | printk("%s: %s selected (peak %dMB/s)\n", drive->name, |
| 273 | ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); | 225 | ide_xfer_verbose(xfer_mode), |
| 226 | 2000 / (unsigned long)ide_get_drivedata(drive)); | ||
| 274 | } | 227 | } |
| 275 | 228 | ||
| 276 | static const struct ide_port_ops icside_v6_port_ops = { | 229 | static const struct ide_port_ops icside_v6_port_ops = { |
| 277 | .set_dma_mode = icside_set_dma_mode, | 230 | .set_dma_mode = icside_set_dma_mode, |
| 278 | .maskproc = icside_maskproc, | ||
| 279 | }; | 231 | }; |
| 280 | 232 | ||
| 281 | static void icside_dma_host_set(ide_drive_t *drive, int on) | 233 | static void icside_dma_host_set(ide_drive_t *drive, int on) |
| @@ -320,11 +272,6 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 320 | BUG_ON(dma_channel_active(ec->dma)); | 272 | BUG_ON(dma_channel_active(ec->dma)); |
| 321 | 273 | ||
| 322 | /* | 274 | /* |
| 323 | * Ensure that we have the right interrupt routed. | ||
| 324 | */ | ||
| 325 | icside_maskproc(drive, 0); | ||
| 326 | |||
| 327 | /* | ||
| 328 | * Route the DMA signals to the correct interface. | 275 | * Route the DMA signals to the correct interface. |
| 329 | */ | 276 | */ |
| 330 | writeb(state->sel | hwif->channel, state->ioc_base); | 277 | writeb(state->sel | hwif->channel, state->ioc_base); |
| @@ -332,7 +279,7 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 332 | /* | 279 | /* |
| 333 | * Select the correct timing for this drive. | 280 | * Select the correct timing for this drive. |
| 334 | */ | 281 | */ |
| 335 | set_dma_speed(ec->dma, drive->drive_data); | 282 | set_dma_speed(ec->dma, (unsigned long)ide_get_drivedata(drive)); |
| 336 | 283 | ||
| 337 | /* | 284 | /* |
| 338 | * Tell the DMA engine about the SG table and | 285 | * Tell the DMA engine about the SG table and |
| @@ -381,7 +328,7 @@ static int icside_dma_off_init(ide_hwif_t *hwif, const struct ide_port_info *d) | |||
| 381 | return -EOPNOTSUPP; | 328 | return -EOPNOTSUPP; |
| 382 | } | 329 | } |
| 383 | 330 | ||
| 384 | static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, | 331 | static void icside_setup_ports(struct ide_hw *hw, void __iomem *base, |
| 385 | struct cardinfo *info, struct expansion_card *ec) | 332 | struct cardinfo *info, struct expansion_card *ec) |
| 386 | { | 333 | { |
| 387 | unsigned long port = (unsigned long)base + info->dataoffset; | 334 | unsigned long port = (unsigned long)base + info->dataoffset; |
| @@ -398,11 +345,11 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, | |||
| 398 | 345 | ||
| 399 | hw->irq = ec->irq; | 346 | hw->irq = ec->irq; |
| 400 | hw->dev = &ec->dev; | 347 | hw->dev = &ec->dev; |
| 401 | hw->chipset = ide_acorn; | ||
| 402 | } | 348 | } |
| 403 | 349 | ||
| 404 | static const struct ide_port_info icside_v5_port_info = { | 350 | static const struct ide_port_info icside_v5_port_info = { |
| 405 | .host_flags = IDE_HFLAG_NO_DMA, | 351 | .host_flags = IDE_HFLAG_NO_DMA, |
| 352 | .chipset = ide_acorn, | ||
| 406 | }; | 353 | }; |
| 407 | 354 | ||
| 408 | static int __devinit | 355 | static int __devinit |
| @@ -410,7 +357,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
| 410 | { | 357 | { |
| 411 | void __iomem *base; | 358 | void __iomem *base; |
| 412 | struct ide_host *host; | 359 | struct ide_host *host; |
| 413 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 360 | struct ide_hw hw, *hws[] = { &hw }; |
| 414 | int ret; | 361 | int ret; |
| 415 | 362 | ||
| 416 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); | 363 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); |
| @@ -431,7 +378,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
| 431 | 378 | ||
| 432 | icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); | 379 | icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); |
| 433 | 380 | ||
| 434 | host = ide_host_alloc(&icside_v5_port_info, hws); | 381 | host = ide_host_alloc(&icside_v5_port_info, hws, 1); |
| 435 | if (host == NULL) | 382 | if (host == NULL) |
| 436 | return -ENODEV; | 383 | return -ENODEV; |
| 437 | 384 | ||
| @@ -452,11 +399,11 @@ err_free: | |||
| 452 | 399 | ||
| 453 | static const struct ide_port_info icside_v6_port_info __initdata = { | 400 | static const struct ide_port_info icside_v6_port_info __initdata = { |
| 454 | .init_dma = icside_dma_off_init, | 401 | .init_dma = icside_dma_off_init, |
| 455 | .port_ops = &icside_v6_no_dma_port_ops, | ||
| 456 | .dma_ops = &icside_v6_dma_ops, | 402 | .dma_ops = &icside_v6_dma_ops, |
| 457 | .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, | 403 | .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO, |
| 458 | .mwdma_mask = ATA_MWDMA2, | 404 | .mwdma_mask = ATA_MWDMA2, |
| 459 | .swdma_mask = ATA_SWDMA2, | 405 | .swdma_mask = ATA_SWDMA2, |
| 406 | .chipset = ide_acorn, | ||
| 460 | }; | 407 | }; |
| 461 | 408 | ||
| 462 | static int __devinit | 409 | static int __devinit |
| @@ -466,7 +413,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
| 466 | struct ide_host *host; | 413 | struct ide_host *host; |
| 467 | unsigned int sel = 0; | 414 | unsigned int sel = 0; |
| 468 | int ret; | 415 | int ret; |
| 469 | hw_regs_t hw[2], *hws[] = { &hw[0], &hw[1], NULL, NULL }; | 416 | struct ide_hw hw[2], *hws[] = { &hw[0], &hw[1] }; |
| 470 | struct ide_port_info d = icside_v6_port_info; | 417 | struct ide_port_info d = icside_v6_port_info; |
| 471 | 418 | ||
| 472 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); | 419 | ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); |
| @@ -506,7 +453,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
| 506 | icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec); | 453 | icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec); |
| 507 | icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec); | 454 | icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec); |
| 508 | 455 | ||
| 509 | host = ide_host_alloc(&d, hws); | 456 | host = ide_host_alloc(&d, hws, 2); |
| 510 | if (host == NULL) | 457 | if (host == NULL) |
| 511 | return -ENODEV; | 458 | return -ENODEV; |
| 512 | 459 | ||
