aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pmac.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/ide/pmac.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/ide/pmac.c')
-rw-r--r--drivers/ide/pmac.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 97642a7a79c4..159955d16c47 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -33,6 +33,7 @@
33#include <linux/adb.h> 33#include <linux/adb.h>
34#include <linux/pmu.h> 34#include <linux/pmu.h>
35#include <linux/scatterlist.h> 35#include <linux/scatterlist.h>
36#include <linux/slab.h>
36 37
37#include <asm/prom.h> 38#include <asm/prom.h>
38#include <asm/io.h> 39#include <asm/io.h>
@@ -43,10 +44,7 @@
43#include <asm/pmac_feature.h> 44#include <asm/pmac_feature.h>
44#include <asm/sections.h> 45#include <asm/sections.h>
45#include <asm/irq.h> 46#include <asm/irq.h>
46
47#ifndef CONFIG_PPC64
48#include <asm/mediabay.h> 47#include <asm/mediabay.h>
49#endif
50 48
51#define DRV_NAME "ide-pmac" 49#define DRV_NAME "ide-pmac"
52 50
@@ -59,13 +57,14 @@ typedef struct pmac_ide_hwif {
59 int irq; 57 int irq;
60 int kind; 58 int kind;
61 int aapl_bus_id; 59 int aapl_bus_id;
62 unsigned mediabay : 1;
63 unsigned broken_dma : 1; 60 unsigned broken_dma : 1;
64 unsigned broken_dma_warn : 1; 61 unsigned broken_dma_warn : 1;
65 struct device_node* node; 62 struct device_node* node;
66 struct macio_dev *mdev; 63 struct macio_dev *mdev;
67 u32 timings[4]; 64 u32 timings[4];
68 volatile u32 __iomem * *kauai_fcr; 65 volatile u32 __iomem * *kauai_fcr;
66 ide_hwif_t *hwif;
67
69 /* Those fields are duplicating what is in hwif. We currently 68 /* Those fields are duplicating what is in hwif. We currently
70 * can't use the hwif ones because of some assumptions that are 69 * 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 70 * beeing done by the generic code about the kind of dma controller
@@ -498,12 +497,11 @@ static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
498/* 497/*
499 * Old tuning functions (called on hdparm -p), sets up drive PIO timings 498 * Old tuning functions (called on hdparm -p), sets up drive PIO timings
500 */ 499 */
501static void 500static void pmac_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
502pmac_ide_set_pio_mode(ide_drive_t *drive, const u8 pio)
503{ 501{
504 ide_hwif_t *hwif = drive->hwif;
505 pmac_ide_hwif_t *pmif = 502 pmac_ide_hwif_t *pmif =
506 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); 503 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
504 const u8 pio = drive->pio_mode - XFER_PIO_0;
507 struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio); 505 struct ide_timing *tim = ide_timing_find_mode(XFER_PIO_0 + pio);
508 u32 *timings, t; 506 u32 *timings, t;
509 unsigned accessTicks, recTicks; 507 unsigned accessTicks, recTicks;
@@ -780,14 +778,14 @@ set_timings_mdma(ide_drive_t *drive, int intf_type, u32 *timings, u32 *timings2,
780#endif 778#endif
781} 779}
782 780
783static void pmac_ide_set_dma_mode(ide_drive_t *drive, const u8 speed) 781static void pmac_ide_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
784{ 782{
785 ide_hwif_t *hwif = drive->hwif;
786 pmac_ide_hwif_t *pmif = 783 pmac_ide_hwif_t *pmif =
787 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); 784 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
788 int ret = 0; 785 int ret = 0;
789 u32 *timings, *timings2, tl[2]; 786 u32 *timings, *timings2, tl[2];
790 u8 unit = drive->dn & 1; 787 u8 unit = drive->dn & 1;
788 const u8 speed = drive->dma_mode;
791 789
792 timings = &pmif->timings[unit]; 790 timings = &pmif->timings[unit];
793 timings2 = &pmif->timings[unit+2]; 791 timings2 = &pmif->timings[unit+2];
@@ -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
855static 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)
889static int pmac_ide_do_resume(pmac_ide_hwif_t *pmif) 892static 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
1128static void __devinit pmac_ide_init_ports(struct ide_hw *hw, unsigned long base) 1128static 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
1366static 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
1365static struct of_device_id pmac_ide_macio_match[] = 1384static 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
1391static const struct pci_device_id pmac_ide_pci_match[] = { 1413static const struct pci_device_id pmac_ide_pci_match[] = {
@@ -1629,8 +1651,8 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
1629 if ((status & FLUSH) == 0) 1651 if ((status & FLUSH) == 0)
1630 break; 1652 break;
1631 if (++timeout > 100) { 1653 if (++timeout > 100) {
1632 printk(KERN_WARNING "ide%d, ide_dma_test_irq \ 1654 printk(KERN_WARNING "ide%d, ide_dma_test_irq timeout flushing channel\n",
1633 timeout flushing channel\n", hwif->index); 1655 hwif->index);
1634 break; 1656 break;
1635 } 1657 }
1636 } 1658 }