diff options
Diffstat (limited to 'drivers/ide/pmac.c')
| -rw-r--r-- | drivers/ide/pmac.c | 92 |
1 files changed, 57 insertions, 35 deletions
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c index 97642a7a79c4..7a4e788cab2f 100644 --- a/drivers/ide/pmac.c +++ b/drivers/ide/pmac.c | |||
| @@ -43,10 +43,7 @@ | |||
| 43 | #include <asm/pmac_feature.h> | 43 | #include <asm/pmac_feature.h> |
| 44 | #include <asm/sections.h> | 44 | #include <asm/sections.h> |
| 45 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
| 46 | |||
| 47 | #ifndef CONFIG_PPC64 | ||
| 48 | #include <asm/mediabay.h> | 46 | #include <asm/mediabay.h> |
| 49 | #endif | ||
| 50 | 47 | ||
| 51 | #define DRV_NAME "ide-pmac" | 48 | #define DRV_NAME "ide-pmac" |
| 52 | 49 | ||
| @@ -59,13 +56,14 @@ typedef struct pmac_ide_hwif { | |||
| 59 | int irq; | 56 | int irq; |
| 60 | int kind; | 57 | int kind; |
| 61 | int aapl_bus_id; | 58 | int aapl_bus_id; |
| 62 | unsigned mediabay : 1; | ||
| 63 | unsigned broken_dma : 1; | 59 | unsigned broken_dma : 1; |
| 64 | unsigned broken_dma_warn : 1; | 60 | unsigned broken_dma_warn : 1; |
| 65 | struct device_node* node; | 61 | struct device_node* node; |
| 66 | struct macio_dev *mdev; | 62 | struct macio_dev *mdev; |
| 67 | u32 timings[4]; | 63 | u32 timings[4]; |
| 68 | volatile u32 __iomem * *kauai_fcr; | 64 | volatile u32 __iomem * *kauai_fcr; |
| 65 | ide_hwif_t *hwif; | ||
| 66 | |||
| 69 | /* Those fields are duplicating what is in hwif. We currently | 67 | /* Those fields are duplicating what is in hwif. We currently |
| 70 | * can't use the hwif ones because of some assumptions that are | 68 | * can't use the hwif ones because of some assumptions that are |
| 71 | * beeing done by the generic code about the kind of dma controller | 69 | * beeing done by the generic code about the kind of dma controller |
| @@ -854,6 +852,11 @@ sanitize_timings(pmac_ide_hwif_t *pmif) | |||
| 854 | pmif->timings[2] = pmif->timings[3] = value2; | 852 | pmif->timings[2] = pmif->timings[3] = value2; |
| 855 | } | 853 | } |
| 856 | 854 | ||
| 855 | static int on_media_bay(pmac_ide_hwif_t *pmif) | ||
| 856 | { | ||
| 857 | return pmif->mdev && pmif->mdev->media_bay != NULL; | ||
| 858 | } | ||
| 859 | |||
| 857 | /* Suspend call back, should be called after the child devices | 860 | /* Suspend call back, should be called after the child devices |
| 858 | * have actually been suspended | 861 | * have actually been suspended |
| 859 | */ | 862 | */ |
| @@ -866,7 +869,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif) | |||
| 866 | disable_irq(pmif->irq); | 869 | disable_irq(pmif->irq); |
| 867 | 870 | ||
| 868 | /* The media bay will handle itself just fine */ | 871 | /* The media bay will handle itself just fine */ |
| 869 | if (pmif->mediabay) | 872 | if (on_media_bay(pmif)) |
| 870 | return 0; | 873 | return 0; |
| 871 | 874 | ||
| 872 | /* Kauai has bus control FCRs directly here */ | 875 | /* Kauai has bus control FCRs directly here */ |
| @@ -889,7 +892,7 @@ static int pmac_ide_do_suspend(pmac_ide_hwif_t *pmif) | |||
| 889 | static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif) | 892 | static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif) |
| 890 | { | 893 | { |
| 891 | /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */ | 894 | /* Hard reset & re-enable controller (do we really need to reset ? -BenH) */ |
| 892 | if (!pmif->mediabay) { | 895 | if (!on_media_bay(pmif)) { |
| 893 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1); | 896 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1); |
| 894 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); | 897 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1); |
| 895 | msleep(10); | 898 | msleep(10); |
| @@ -950,13 +953,11 @@ static void pmac_ide_init_dev(ide_drive_t *drive) | |||
| 950 | pmac_ide_hwif_t *pmif = | 953 | pmac_ide_hwif_t *pmif = |
| 951 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); | 954 | (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); |
| 952 | 955 | ||
| 953 | if (pmif->mediabay) { | 956 | if (on_media_bay(pmif)) { |
| 954 | #ifdef CONFIG_PMAC_MEDIABAY | 957 | if (check_media_bay(pmif->mdev->media_bay) == MB_CD) { |
| 955 | if (check_media_bay_by_base(pmif->regbase, MB_CD) == 0) { | ||
| 956 | drive->dev_flags &= ~IDE_DFLAG_NOPROBE; | 958 | drive->dev_flags &= ~IDE_DFLAG_NOPROBE; |
| 957 | return; | 959 | return; |
| 958 | } | 960 | } |
| 959 | #endif | ||
| 960 | drive->dev_flags |= IDE_DFLAG_NOPROBE; | 961 | drive->dev_flags |= IDE_DFLAG_NOPROBE; |
| 961 | } | 962 | } |
| 962 | } | 963 | } |
| @@ -1072,26 +1073,23 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, | |||
| 1072 | writel(KAUAI_FCR_UATA_MAGIC | | 1073 | writel(KAUAI_FCR_UATA_MAGIC | |
| 1073 | KAUAI_FCR_UATA_RESET_N | | 1074 | KAUAI_FCR_UATA_RESET_N | |
| 1074 | KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr); | 1075 | KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr); |
| 1075 | |||
| 1076 | pmif->mediabay = 0; | ||
| 1077 | 1076 | ||
| 1078 | /* Make sure we have sane timings */ | 1077 | /* Make sure we have sane timings */ |
| 1079 | sanitize_timings(pmif); | 1078 | sanitize_timings(pmif); |
| 1080 | 1079 | ||
| 1080 | /* If we are on a media bay, wait for it to settle and lock it */ | ||
| 1081 | if (pmif->mdev) | ||
| 1082 | lock_media_bay(pmif->mdev->media_bay); | ||
| 1083 | |||
| 1081 | host = ide_host_alloc(&d, hws, 1); | 1084 | host = ide_host_alloc(&d, hws, 1); |
| 1082 | if (host == NULL) | 1085 | if (host == NULL) { |
| 1083 | return -ENOMEM; | 1086 | rc = -ENOMEM; |
| 1084 | hwif = host->ports[0]; | 1087 | goto bail; |
| 1088 | } | ||
| 1089 | hwif = pmif->hwif = host->ports[0]; | ||
| 1085 | 1090 | ||
| 1086 | #ifndef CONFIG_PPC64 | 1091 | if (on_media_bay(pmif)) { |
| 1087 | /* XXX FIXME: Media bay stuff need re-organizing */ | 1092 | /* Fixup bus ID for media bay */ |
| 1088 | if (np->parent && np->parent->name | ||
| 1089 | && strcasecmp(np->parent->name, "media-bay") == 0) { | ||
| 1090 | #ifdef CONFIG_PMAC_MEDIABAY | ||
| 1091 | media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, | ||
| 1092 | hwif); | ||
| 1093 | #endif /* CONFIG_PMAC_MEDIABAY */ | ||
| 1094 | pmif->mediabay = 1; | ||
| 1095 | if (!bidp) | 1093 | if (!bidp) |
| 1096 | pmif->aapl_bus_id = 1; | 1094 | pmif->aapl_bus_id = 1; |
| 1097 | } else if (pmif->kind == controller_ohare) { | 1095 | } else if (pmif->kind == controller_ohare) { |
| @@ -1100,9 +1098,7 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, | |||
| 1100 | * units, I keep the old way | 1098 | * units, I keep the old way |
| 1101 | */ | 1099 | */ |
| 1102 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); | 1100 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1); |
| 1103 | } else | 1101 | } else { |
| 1104 | #endif | ||
| 1105 | { | ||
| 1106 | /* This is necessary to enable IDE when net-booting */ | 1102 | /* This is necessary to enable IDE when net-booting */ |
| 1107 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); | 1103 | ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1); |
| 1108 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); | 1104 | ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1); |
| @@ -1112,17 +1108,21 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, | |||
| 1112 | } | 1108 | } |
| 1113 | 1109 | ||
| 1114 | printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), " | 1110 | printk(KERN_INFO DRV_NAME ": Found Apple %s controller (%s), " |
| 1115 | "bus ID %d%s, irq %d\n", model_name[pmif->kind], | 1111 | "bus ID %d%s, irq %d\n", model_name[pmif->kind], |
| 1116 | pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id, | 1112 | pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id, |
| 1117 | pmif->mediabay ? " (mediabay)" : "", hw->irq); | 1113 | on_media_bay(pmif) ? " (mediabay)" : "", hw->irq); |
| 1118 | 1114 | ||
| 1119 | rc = ide_host_register(host, &d, hws); | 1115 | rc = ide_host_register(host, &d, hws); |
| 1120 | if (rc) { | 1116 | if (rc) |
| 1121 | ide_host_free(host); | 1117 | pmif->hwif = NULL; |
| 1122 | return rc; | ||
| 1123 | } | ||
| 1124 | 1118 | ||
| 1125 | return 0; | 1119 | if (pmif->mdev) |
| 1120 | unlock_media_bay(pmif->mdev->media_bay); | ||
| 1121 | |||
| 1122 | bail: | ||
| 1123 | if (rc && host) | ||
| 1124 | ide_host_free(host); | ||
| 1125 | return rc; | ||
| 1126 | } | 1126 | } |
| 1127 | 1127 | ||
| 1128 | static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base) | 1128 | static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base) |
| @@ -1362,6 +1362,25 @@ pmac_ide_pci_resume(struct pci_dev *pdev) | |||
| 1362 | return rc; | 1362 | return rc; |
| 1363 | } | 1363 | } |
| 1364 | 1364 | ||
| 1365 | #ifdef CONFIG_PMAC_MEDIABAY | ||
| 1366 | static void pmac_ide_macio_mb_event(struct macio_dev* mdev, int mb_state) | ||
| 1367 | { | ||
| 1368 | pmac_ide_hwif_t *pmif = | ||
| 1369 | (pmac_ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev); | ||
| 1370 | |||
| 1371 | switch(mb_state) { | ||
| 1372 | case MB_CD: | ||
| 1373 | if (!pmif->hwif->present) | ||
| 1374 | ide_port_scan(pmif->hwif); | ||
| 1375 | break; | ||
| 1376 | default: | ||
| 1377 | if (pmif->hwif->present) | ||
| 1378 | ide_port_unregister_devices(pmif->hwif); | ||
| 1379 | } | ||
| 1380 | } | ||
| 1381 | #endif /* CONFIG_PMAC_MEDIABAY */ | ||
| 1382 | |||
| 1383 | |||
| 1365 | static struct of_device_id pmac_ide_macio_match[] = | 1384 | static struct of_device_id pmac_ide_macio_match[] = |
| 1366 | { | 1385 | { |
| 1367 | { | 1386 | { |
| @@ -1386,6 +1405,9 @@ static struct macio_driver pmac_ide_macio_driver = | |||
| 1386 | .probe = pmac_ide_macio_attach, | 1405 | .probe = pmac_ide_macio_attach, |
| 1387 | .suspend = pmac_ide_macio_suspend, | 1406 | .suspend = pmac_ide_macio_suspend, |
| 1388 | .resume = pmac_ide_macio_resume, | 1407 | .resume = pmac_ide_macio_resume, |
| 1408 | #ifdef CONFIG_PMAC_MEDIABAY | ||
| 1409 | .mediabay_event = pmac_ide_macio_mb_event, | ||
| 1410 | #endif | ||
| 1389 | }; | 1411 | }; |
| 1390 | 1412 | ||
| 1391 | static const struct pci_device_id pmac_ide_pci_match[] = { | 1413 | static const struct pci_device_id pmac_ide_pci_match[] = { |
