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[] = { |