Skip to contentSkip to conversation

adding Pegasus IDE quirk for pata_via

PATCH In review Olaf Hering 6 participants 21 messages Apr 4, 2007 – Aug 17, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

The pegaos board needs an irq quirk in pata_via.
Where is the quirk list for libata? I dont see one in pata_via.c

drivers/ide/pci/via82cxxx.c:init_hwif_via82cxxx()

    440 #ifdef CONFIG_PPC_CHRP
    441         if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
    442                 hwif->irq = hwif->channel ? 15 : 14;
    443         }
    444 #endif

This is in the firmware node. Will a fixup of the 'interrupts' property work or does everything poke directly at the PCI registers? Should fixup_device_tree_chrp() take care of the 'interrupts' property?

/proc/device-tree/pci@80000000/ide@C,1:
name "ide"
linux,phandle 0fc5c3a0 (264618912)
interrupt-parent 0fc5b948 (264616264) assigned-addresses 01006110 00000000 fe001000 00000000 00000008

                 01006114 00000000 fe00100c 00000000 00000004
                 01006118 00000000 fe001010 00000000 00000008
                 0100611c 00000000 fe00101c 00000000 00000004
                 01006120 00000000 fe001020 00000000 00000010
device_type      "spi"
reg              00006100 00000000 00000000 00000000 00000000 01006110
                 00000000 00000000 00000000 00000008 01006114 00000000
                 00000000 00000000 00000004 01006118 00000000 00000000
                 00000000 00000008 0100611c 00000000 00000000 00000000
                 00000004 01006120 00000000 00000000 00000000 00000010
max-latency      00000000
min-grant        00000000
fast-back-to-back
devsel-speed     00000001
interrupts       00000014 00000000 00000015 00000000
.description     "PCI IDE Controller"
.part-number     "VT82C586/596/686"
.vendor-name     "VIA"
subsystem-vendor-id 00000000
subsystem-id     00000000
class-code       0001018f (65935)
revision-id      00000006
device-id        00000571 (1393)
vendor-id        00001106 (4358)

0000:00:0c.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if 8f [Master SecP SecO PriP PriO])

        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0
        Interrupt: pin A routed to IRQ 20
        Region 0: I/O ports at 1000 [size=8]
        Region 1: I/O ports at 100c [size=4]
        Region 2: I/O ports at 1010 [size=8]
        Region 3: I/O ports at 101c [size=4]
        Region 4: I/O ports at 1020 [size=16]
        Capabilities: [c0] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
#1 lore raw

PATCH 1/1 add correct interrupt property for pegasos ide

The firmware assigns irq 20/21 to the VIA IDE device on Pegasos. But the required interrupt is 14/15.
Maybe someone confused decimal vs. hexadecimal values.

---
 arch/powerpc/kernel/prom_init.c |   55 ++++++++++++++++++++++++----------------
 drivers/ide/pci/via82cxxx.c     |   11 --------
 2 files changed, 33 insertions(+), 33 deletions(-)
arch/powerpc/kernel/prom_init.c +33 -22
Index: b/arch/powerpc/kernel/prom_init.c
===================================================================
@@ -2035,39 +2035,50 @@ static void __init fixup_device_tree_map
 #endif
 
 #ifdef CONFIG_PPC_CHRP
-/* Pegasos and BriQ lacks the "ranges" property in the isa node */
+/*
+ * Pegasos and BriQ lacks the "ranges" property in the isa node
+ * Pegasos needs decimal IRQ 14/15, not hexadecimal
+ */
 static void __init fixup_device_tree_chrp(void)
 {
-	phandle isa;
-	u32 isa_ranges[6];
+	phandle ph;
+	u32 prop[6];
 	u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
 	char *name;
 	int rc;
 
 	name = "/pci@80000000/isa@c";
-	isa = call_prom("finddevice", 1, 1, ADDR(name));
-	if (!PHANDLE_VALID(isa)) {
+	ph = call_prom("finddevice", 1, 1, ADDR(name));
+	if (!PHANDLE_VALID(ph)) {
 		name = "/pci@ff500000/isa@6";
-		isa = call_prom("finddevice", 1, 1, ADDR(name));
+		ph = call_prom("finddevice", 1, 1, ADDR(name));
 		rloc = 0x01003000; /* IO space; PCI device = 6 */
 	}
-	if (!PHANDLE_VALID(isa))
-		return;
-
-	rc = prom_getproplen(isa, "ranges");
-	if (rc != 0 && rc != PROM_ERROR)
-		return;
-
-	prom_printf("Fixing up missing ISA range on Pegasos...\n");
+	if (PHANDLE_VALID(ph)) {
+		rc = prom_getproplen(ph, "ranges");
+		if (rc == 0 || rc == PROM_ERROR) {
+			prom_printf("Fixing up missing ISA range on Pegasos...\n");
+
+			prop[0] = 0x1;
+			prop[1] = 0x0;
+			prop[2] = rloc;
+			prop[3] = 0x0;
+			prop[4] = 0x0;
+			prop[5] = 0x00010000;
+			prom_setprop(ph, name, "ranges", prop, sizeof(prop));
+		}
+	}
 
-	isa_ranges[0] = 0x1;
-	isa_ranges[1] = 0x0;
-	isa_ranges[2] = rloc;
-	isa_ranges[3] = 0x0;
-	isa_ranges[4] = 0x0;
-	isa_ranges[5] = 0x00010000;
-	prom_setprop(isa, name, "ranges",
-			isa_ranges, sizeof(isa_ranges));
+	name = "/pci@80000000/ide@C,1";
+	ph = call_prom("finddevice", 1, 1, ADDR(name));
+	if (PHANDLE_VALID(ph)) {
+		prom_printf("Fixing up IDE interrupt on Pegasos...\n");
+		prop[0] = 14;
+		prop[1] = 0x0;
+		prop[2] = 15;
+		prop[3] = 0x0;
+		prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32));
+	}
 }
 #else
 #define fixup_device_tree_chrp()
drivers/ide/pci/via82cxxx.c +0 -11
Index: b/drivers/ide/pci/via82cxxx.c
===================================================================
@@ -35,10 +35,6 @@
 #include <linux/ide.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_PPC_CHRP
-#include <asm/processor.h>
-#endif
-
 #include "ide-timing.h"
 
 #define DISPLAY_VIA_TIMINGS
@@ -436,13 +432,6 @@ static void __devinit init_hwif_via82cxx
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->speedproc = &via_set_drive;
 
-
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif
-
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
#2 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

Hi,

Quoted 4 lines · Olaf Hering

The firmware assigns irq 20/21 to the VIA IDE device on Pegasos. But the required interrupt is 14/15.
Maybe someone confused decimal vs. hexadecimal values.

Good to see Pegasos platform being fixed to do the quirk in the proper way.

However I fail to see how via82cxxx will continue to work without some other modifications to via82cxxx.c or setup-pci.c, namely how will hwif->irq be assigned with correct values?

AFAICS:
* via82cxxx.c:init_chipset_via82cxxx() returns '0' instead of 'dev->irq' (won't help anyway since chipset is in legacy mode using IRQs 14 and 15)
* on CHRP platform there is no ppc_ide_md.ide_default_irq
* IRQ probing (used by ide-probe.c as a last resort) is unsupported on PPC

therefore hwif->irq won't be set et all after removing quirk from via82cxxx.c

?

Thanks,
Bart

Quoted 113 lines
---
 arch/powerpc/kernel/prom_init.c |   55 ++++++++++++++++++++++++----------------
 drivers/ide/pci/via82cxxx.c     |   11 --------
 2 files changed, 33 insertions(+), 33 deletions(-)

Index: b/arch/powerpc/kernel/prom_init.c
===================================================================

arch/powerpc/kernel/prom_init.c +33 -22
@@ -2035,39 +2035,50 @@ static void __init fixup_device_tree_map
 #endif
 
 #ifdef CONFIG_PPC_CHRP
-/* Pegasos and BriQ lacks the "ranges" property in the isa node */
+/*
+ * Pegasos and BriQ lacks the "ranges" property in the isa node
+ * Pegasos needs decimal IRQ 14/15, not hexadecimal
+ */
 static void __init fixup_device_tree_chrp(void)
 {
-	phandle isa;
-	u32 isa_ranges[6];
+	phandle ph;
+	u32 prop[6];
 	u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
 	char *name;
 	int rc;
 
 	name = "/pci@80000000/isa@c";
-	isa = call_prom("finddevice", 1, 1, ADDR(name));
-	if (!PHANDLE_VALID(isa)) {
+	ph = call_prom("finddevice", 1, 1, ADDR(name));
+	if (!PHANDLE_VALID(ph)) {
 		name = "/pci@ff500000/isa@6";
-		isa = call_prom("finddevice", 1, 1, ADDR(name));
+		ph = call_prom("finddevice", 1, 1, ADDR(name));
 		rloc = 0x01003000; /* IO space; PCI device = 6 */
 	}
-	if (!PHANDLE_VALID(isa))
-		return;
-
-	rc = prom_getproplen(isa, "ranges");
-	if (rc != 0 && rc != PROM_ERROR)
-		return;
-
-	prom_printf("Fixing up missing ISA range on Pegasos...\n");
+	if (PHANDLE_VALID(ph)) {
+		rc = prom_getproplen(ph, "ranges");
+		if (rc == 0 || rc == PROM_ERROR) {
+			prom_printf("Fixing up missing ISA range on Pegasos...\n");
+
+			prop[0] = 0x1;
+			prop[1] = 0x0;
+			prop[2] = rloc;
+			prop[3] = 0x0;
+			prop[4] = 0x0;
+			prop[5] = 0x00010000;
+			prom_setprop(ph, name, "ranges", prop, sizeof(prop));
+		}
+	}
 
-	isa_ranges[0] = 0x1;
-	isa_ranges[1] = 0x0;
-	isa_ranges[2] = rloc;
-	isa_ranges[3] = 0x0;
-	isa_ranges[4] = 0x0;
-	isa_ranges[5] = 0x00010000;
-	prom_setprop(isa, name, "ranges",
-			isa_ranges, sizeof(isa_ranges));
+	name = "/pci@80000000/ide@C,1";
+	ph = call_prom("finddevice", 1, 1, ADDR(name));
+	if (PHANDLE_VALID(ph)) {
+		prom_printf("Fixing up IDE interrupt on Pegasos...\n");
+		prop[0] = 14;
+		prop[1] = 0x0;
+		prop[2] = 15;
+		prop[3] = 0x0;
+		prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32));
+	}
 }
 #else
 #define fixup_device_tree_chrp()

Index: b/drivers/ide/pci/via82cxxx.c
===================================================================

drivers/ide/pci/via82cxxx.c +0 -11
@@ -35,10 +35,6 @@
 #include <linux/ide.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_PPC_CHRP
-#include <asm/processor.h>
-#endif
-
 #include "ide-timing.h"
 
 #define DISPLAY_VIA_TIMINGS
@@ -436,13 +432,6 @@ static void __devinit init_hwif_via82cxx
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->speedproc = &via_set_drive;
 
-
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif
-
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
#3 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

Quoted 1 line · Bartlomiej Zolnierkiewicz

?

You are right, I did not test the ide driver again. pata_via works with the change.
I will test the ide driver tomorrow.

#4 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

Quoted 7 lines · Olaf Hering
Quoted 1 line · Bartlomiej Zolnierkiewicz

?

You are right, I did not test the ide driver again. pata_via works with the change.
I will test the ide driver tomorrow.

Thanks.

There might be also the another issue here - the chipset claims fully native mode (prog-if 8f - taken from your previous mail) so driver takes IRQ value from dev->irq (which your patch fixes to be 14 instead of 20 if I'm reading it correctly) but in reality chipset seems to be still using legacy IRQs (14 for the primary port and 15 for the secondary one). What IRQ value is reported by the libata for the secondary port? Does the second port work?

Bart

#5 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

Quoted 6 lines

There might be also the another issue here - the chipset claims fully native mode (prog-if 8f - taken from your previous mail) so driver takes IRQ value from dev->irq (which your patch fixes to be 14 instead of 20 if I'm reading it correctly) but in reality chipset seems to be still using legacy IRQs (14 for the primary port and 15 for the secondary one). What IRQ value is reported by the libata for the secondary port? Does the second port work?

It's a crackpot VIA chipset... it claims to be fully native but uses legacy IRQs... go figure. So yes, we need a quirk. I don't have chipset specs so I don't know if the driver can "detect" that though.

Ben.

#6 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

In reply to Bartlomiej Zolnierkiewicz
Quoted 10 lines · Bartlomiej Zolnierkiewicz
Quoted 7 lines · Olaf Hering
Quoted 1 line · Bartlomiej Zolnierkiewicz

?

You are right, I did not test the ide driver again. pata_via works with the change.
I will test the ide driver tomorrow.

Quoted 8 lines

Thanks.

There might be also the another issue here - the chipset claims fully native mode (prog-if 8f - taken from your previous mail) so driver takes IRQ value from dev->irq (which your patch fixes to be 14 instead of 20 if I'm reading it correctly) but in reality chipset seems to be still using legacy IRQs (14 for the primary port and 15 for the secondary one). What IRQ value is reported by the libata for the secondary port? Does the second port work?

The second port does not work. My added printks did not trigger. There is not enough time to hack on this today.
I found maple_pci_get_legacy_ide_irq, maybe a similar function can be added for pegasos to remove the ifarch code from the IDE driver.

#7 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

In reply to Olaf Hering
Quoted 6 lines · Olaf Hering
Quoted 1 line · Bartlomiej Zolnierkiewicz

?

You are right, I did not test the ide driver again. pata_via works with the change.

Probably only the first channel works...

Ben.

#8 lore raw

Re: [PATCH] add correct interrupt property for pegasos ide

In reply to Olaf Hering

Hi Olaf,

arch/powerpc/kernel/prom_init.c static void __init fixup_device_tree_map · line 2045

Quoted 5 lines · On Wed, 4 Apr 2007 18:20:04 +0200 Olaf Hering <[email protected]> wrote:
arch/powerpc/kernel/prom_init.c +2 -2
-	phandle isa;
-	u32 isa_ranges[6];
+	phandle ph;
+	u32 prop[6];

Juat a small nit: If you want to rename vairables, please do it in a separate patch - doing it here just clutters the patch and makes it harder to see what the real purpose is.

--
Cheers,
Stephen Rothwell [email protected]
http://www.canb.auug.org.au/~sfr/

#9 lore raw
In reply to Olaf Hering
Quoted 12 lines · Olaf Hering

The pegaos board needs an irq quirk in pata_via.
Where is the quirk list for libata? I dont see one in pata_via.c

drivers/ide/pci/via82cxxx.c:init_hwif_via82cxxx()

    440 #ifdef CONFIG_PPC_CHRP
    441         if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
    442                 hwif->irq = hwif->channel ? 15 : 14;
    443         }
    444 #endif
Quoted 3 lines

This is in the firmware node. Will a fixup of the 'interrupts' property work or does everything poke directly at the PCI registers? Should fixup_device_tree_chrp() take care of the 'interrupts' property?

Nothing standard will work. A PCI device isn't supposed to have more than one interrupt per function and this one needs 2. It's the VIA chipset being out of specs as usual.

Ben.

#10 lore raw
In reply to Olaf Hering

Hi Olaf, IDE guys,

I believe that this quirk is not Pegasos-specific. It will also affect any Via VT8231 controller (and perhaps any Via IDE, but I can't test that assertion) which is run in PCI mode.

The basic bug is that in PCI native mode, the chip should use ONE PCI interrupt and there is logic in the driver to select which channel fired it. However, if the chip is configured to use two interrupts in the IRQ steering register, it WILL use two interrupts.

I did write a patch at one time (September last year) but abandoned it as it would only have had to be rewritten and I did not have the real resources required to make sure it did not make any other platforms explode.

(Olaf, Peter Czanik may have forwarded you an old version of this patch already)

It basically did the following where the old Pegasos check was:

+ if (vdev->via_config->flags & VIA_NATIVE_TWO_IRQ) {
+ u8 cb;
+
+ pci_read_config_byte(hwif->pci_dev, PCI_CLASS_PROG, &cb);
+
+ if (cb & 0x5) { /* if controller is configured for pci-native mode for both channels */
+ pci_read_config_byte(hwif->pci_dev, PCI_INTERRUPT_PIN, &cb);
+
+ if (cb & 0x1) { /* if controller is actually using an interrupt for native mode */
+
+ struct pci_dev *bridge = pci_find_device(PCI_VENDOR_ID_VIA, vdev->via_config->id);
+
+ if (bridge) {
+ u8 iir, irqlist[4] = { 14, 15, 10, 11 };
+
+ pci_read_config_byte(bridge, VIA_IDE_STEERING, &iir);
+
+ hwif->irq = irqlist[hwif->channel ? ((iir & 0xc) >> 2) : (iir & 0x3)];
+ }
+
+ }
+ }
}

This basically uses the IRQ that the Via chipset says to use, as it is always programmed into the chipset, and that value is always correct. Only 14, 15, 10 and 11 are valid according to the documentation, but in truth only interrupts 14 and 15 actually work. It is possible to set the interrupts to the same IRQ but this is quite rare and the old via driver did not seem to handle it correctly, so the firmware leaves the 14/15 combination in there to get a working system.

I tried to keep it as generic as possible. This patch does work on Pegasos.

Either way the steering bits will tell you which it is, rather than a switch between 14 and 15 hardcoded into the system. There is no need to use the device tree and in fact any modification to the interrupt node would be rather spurious since the device tree can only include one interrupt value for the PCI device according to the standard, and cannot define which interrupt goes with which channel (it could be reversed!).

The only safe way is to use the values programmed into the chip. This will also fix any other architecture where this chipset is used (x86) in this manner. This is 0% of x86 systems with an Award/AMI BIOS but if the chip is reconfigured in early boot, or if LinuxBIOS or OpenBIOS are used, this may well change on the author's whim.

Again some comments would be appreciated from anyone who has a better idea on how this controller works. This simple code addition came out of 2 or 3 days of discussion with the Pegasos designer based on his experiences with the chip and is so simple there cannot be much wrong with it apart from coding style and a distinct lack of testing.

Thanks for any input you can give :)

Signature · 2 lines
Matt Sealey <[email protected]>
Genesi, Manager, Developer Relations
Quoted 65 lines · Olaf Hering

The pegaos board needs an irq quirk in pata_via.
Where is the quirk list for libata? I dont see one in pata_via.c

drivers/ide/pci/via82cxxx.c:init_hwif_via82cxxx()

    440 #ifdef CONFIG_PPC_CHRP
    441         if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
    442                 hwif->irq = hwif->channel ? 15 : 14;
    443         }
    444 #endif

This is in the firmware node. Will a fixup of the 'interrupts' property work or does everything poke directly at the PCI registers? Should fixup_device_tree_chrp() take care of the 'interrupts' property?

/proc/device-tree/pci@80000000/ide@C,1:
name "ide"
linux,phandle 0fc5c3a0 (264618912)
interrupt-parent 0fc5b948 (264616264) assigned-addresses 01006110 00000000 fe001000 00000000 00000008

                 01006114 00000000 fe00100c 00000000 00000004
                 01006118 00000000 fe001010 00000000 00000008
                 0100611c 00000000 fe00101c 00000000 00000004
                 01006120 00000000 fe001020 00000000 00000010
device_type      "spi"
reg              00006100 00000000 00000000 00000000 00000000 01006110
                 00000000 00000000 00000000 00000008 01006114 00000000
                 00000000 00000000 00000004 01006118 00000000 00000000
                 00000000 00000008 0100611c 00000000 00000000 00000000
                 00000004 01006120 00000000 00000000 00000000 00000010
max-latency      00000000
min-grant        00000000
fast-back-to-back
devsel-speed     00000001
interrupts       00000014 00000000 00000015 00000000
.description     "PCI IDE Controller"
.part-number     "VT82C586/596/686"
.vendor-name     "VIA"
subsystem-vendor-id 00000000
subsystem-id     00000000
class-code       0001018f (65935)
revision-id      00000006
device-id        00000571 (1393)
vendor-id        00001106 (4358)

0000:00:0c.1 IDE interface: VIA Technologies, Inc. VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if 8f [Master SecP SecO PriP PriO])

        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
        Latency: 0
        Interrupt: pin A routed to IRQ 20
        Region 0: I/O ports at 1000 [size=8]
        Region 1: I/O ports at 100c [size=4]
        Region 2: I/O ports at 1010 [size=8]
        Region 3: I/O ports at 101c [size=4]
        Region 4: I/O ports at 1020 [size=16]
        Capabilities: [c0] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-

_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

#11 lore raw
Quoted 4 lines

Again some comments would be appreciated from anyone who has a better idea on how this controller works. This simple code addition came out of 2 or 3 days of discussion with the Pegasos designer based on his experiences with the chip and is so simple there cannot be much wrong with it apart from coding style and a distinct lack of testing.

Seems sane to me - as you said the x86 world relies on the BIOS for this and in fact pretty much never uses native mode anyway.

Patch looks fine except pci_find_device is obsolete, please use pci_get_device and refcount safe APIs.

#12 lore raw

Okay. I'll clean this up and submit a real patch to the Linux IDE mailing list (no point for PowerPC guys to get any more of these since it is very generic Via IDE stuff now)

Signature · 2 lines
Matt Sealey <[email protected]>
Genesi, Manager, Developer Relations
Quoted 10 lines · Alan Cox
Quoted 4 lines

Again some comments would be appreciated from anyone who has a better idea on how this controller works. This simple code addition came out of 2 or 3 days of discussion with the Pegasos designer based on his experiences with the chip and is so simple there cannot be much wrong with it apart from coding style and a distinct lack of testing.

Seems sane to me - as you said the x86 world relies on the BIOS for this and in fact pretty much never uses native mode anyway.

Patch looks fine except pci_find_device is obsolete, please use pci_get_device and refcount safe APIs.

#13 lore raw
In reply to Alan Cox
Quoted 7 lines · Alan Cox
Quoted 4 lines

Again some comments would be appreciated from anyone who has a better idea on how this controller works. This simple code addition came out of 2 or 3 days of discussion with the Pegasos designer based on his experiences with the chip and is so simple there cannot be much wrong with it apart from coding style and a distinct lack of testing.

Seems sane to me - as you said the x86 world relies on the BIOS for this and in fact pretty much never uses native mode anyway.

The snipped is appearently for drivers/ide.
Where is the correct place for drivers/ata?

#14 lore raw
Quoted 1 line · Olaf Hering

Where is the correct place for drivers/ata?

so, where is the place for via irq quirks in libata?

#15 lore raw
In reply to Matt Sealey
Quoted 6 lines · Matt Sealey
(quoted diff) +2 -0
+				if (bridge) {
+					u8 iir, irqlist[4] = { 14, 15, 10, 

11 };

(quoted diff) +2 -0
+
+					pci_read_config_byte(bridge, 

VIA_IDE_STEERING, &iir);

What value has VIA_IDE_STEERING?
Googles only reference is your own posting.

#16 lore raw

PATCH 1/1 advertise correct IDE mode on Pegasos2

In reply to Olaf Hering

The built-in IDE controller is configured in legacy mode, but the PCI registers advertise native mode.
Force the PCI class into legacy mode. This allows pata_via to access two drives.
The Pegasos specific irq enforcement in the via82cxxx driver can be removed.

Tested on Pegasos2 with firmware version 20040810, and two IDE disks.

---
 arch/powerpc/kernel/prom_init.c   |   11 ++++++++---
 arch/powerpc/platforms/chrp/pci.c |   28 ++++++++++++++++++++++++++++
 drivers/ide/pci/via82cxxx.c       |    7 -------
 3 files changed, 36 insertions(+), 10 deletions(-)
arch/powerpc/kernel/prom_init.c +8 -3
@@ -2041,6 +2041,7 @@ static void __init fixup_device_tree_map
 /*
  * Pegasos and BriQ lacks the "ranges" property in the isa node
  * Pegasos needs decimal IRQ 14/15, not hexadecimal
+ * Pegasos has the IDE configured in legacy mode, but advertised as native
  */
 static void __init fixup_device_tree_chrp(void)
 {
@@ -2078,9 +2079,13 @@ static void __init fixup_device_tree_chr
 		prom_printf("Fixing up IDE interrupt on Pegasos...\n");
 		prop[0] = 14;
 		prop[1] = 0x0;
-		prop[2] = 15;
-		prop[3] = 0x0;
-		prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32));
+		prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
+		prom_printf("Fixing up IDE class-code on Pegasos...\n");
+		rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
+		if (rc == sizeof(u32)) {
+			prop[0] &= ~0x5;
+			prom_setprop(ph, name, "class-code", prop, sizeof(u32));
+		}
 	}
 }
 #else
arch/powerpc/platforms/chrp/pci.c +28 -0
@@ -338,3 +338,31 @@ void chrp_pci_fixup_winbond_ata(struct p
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
 		chrp_pci_fixup_winbond_ata);
+
+/* Pegasos2 firmware version 20040810 configures the built-in IDE controller
+ * in legacy mode, but sets the PCI registers to PCI native mode.
+ * The chip can only operate in legacy mode, so force the PCI class into legacy
+ * mode as well. The same fixup must be done to the class-code property in
+ * the IDE node /pci@80000000/ide@C,1
+ */
+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+{
+	u8 progif;
+	struct pci_dev *viaisa;
+
+	if (!machine_is(chrp) || _chrp_type != _CHRP_Pegasos)
+		return;
+	if (viaide->irq != 14)
+		return;
+
+	viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
+	if (!viaisa)
+		return;
+	printk("Fixing VIA IDE, force legacy mode on '%s'\n", viaide->dev.bus_id);
+
+	pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
+
+	pci_dev_put(viaisa);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
drivers/ide/pci/via82cxxx.c +0 -7
@@ -436,13 +436,6 @@ static void __devinit init_hwif_via82cxx
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->speedproc = &via_set_drive;
 
-
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif
-
 	for (i = 0; i < 2; i++) {
 		hwif->drives[i].io_32bit = 1;
 		hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
#17 lore raw

Re: [PATCH] advertise correct IDE mode on Pegasos2

On Fri, Aug 17, Olaf Hering wrote:

Still not 100% perfect.

arch/powerpc/kernel/prom_init.c static void __init fixup_device_tree_chr · line 2088

Quoted 6 lines
arch/powerpc/kernel/prom_init.c +6 -0
+		prom_printf("Fixing up IDE class-code on Pegasos...\n");
+		rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
+		if (rc == sizeof(u32)) {
+			prop[0] &= ~0x5;
+			prom_setprop(ph, name, "class-code", prop, sizeof(u32));
+		}

This updates the class code in the device-tree, but sysfs still shows the old value.

arch/powerpc/platforms/chrp/pci.c void chrp_pci_fixup_winbond_ata(struct p · line 364

Quoted 2 lines
arch/powerpc/platforms/chrp/pci.c +2 -0
+	pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);

Is this a readonly register by any chance?
Appending a 'viaide->class &= ~0x5;' changes the code paths in do_ide_setup_pci_device(), now IDE prints 'not 100%% native mode, will probe irqs later'. Where are the irqs supposed to come from?

drivers/ide/pci/via82cxxx.c static void __devinit init_hwif_via82cxx · line 444

Quoted 5 lines
drivers/ide/pci/via82cxxx.c +0 -5
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif

Maybe we should just leave this in and dont bother about the arch specific tweak?

#18 lore raw

Re: [PATCH] advertise correct IDE mode on Pegasos2

The programming interface register is definitely writable, but the VIA IDE docs state that certain bits will always read 0 - setting '0x5' in my original patch set those two bits so it was forced into native mode if it wasn't already.

Setting them to ~0x5 will set them to 0 (legacy mode) and they will always read back as 0 (legacy mode.. sigh) even if in native mode.

Fixing the class code in the device tree doesn't mean anything as lspci, sysfs etc. read right from config space and NOTHING in linux powerpc uses the device tree for information (RTAS is about as close as it gets).

I'm still working on my little "device tree fixups" Forth script for Pegasos which is very difficult without a Pegasos to test it on. I need the correct device locations and target values to do it, and I want to add a fix so that it ONLY runs on 20040810 firmwares (and the minor updates for 2B5 boards) and complains on anything else (any developers who got a beta firmware..) as it seems the fixes you're making here do not apply.

I attached it if anyone wants to toy with it.. I can't guarantee that it even parses as I've just been poking at it, but the basic theory is in there. It should remove any kernel/prom_init device tree fixups but requires still the pci fixups in chrp/pci.

There's an Efika one too..

Any comments would be awesome.

Signature · 2 lines
Matt Sealey <[email protected]>
Genesi, Manager, Developer Relations
Quoted 22 lines · Olaf Hering

On Fri, Aug 17, Olaf Hering wrote:

Still not 100% perfect.

arch/powerpc/kernel/prom_init.c static void __init fixup_device_tree_chr · line 2088

Quoted 6 lines
arch/powerpc/kernel/prom_init.c +6 -0
+		prom_printf("Fixing up IDE class-code on Pegasos...\n");
+		rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
+		if (rc == sizeof(u32)) {
+			prop[0] &= ~0x5;
+			prom_setprop(ph, name, "class-code", prop, sizeof(u32));
+		}

This updates the class code in the device-tree, but sysfs still shows the old value.

arch/powerpc/platforms/chrp/pci.c void chrp_pci_fixup_winbond_ata(struct p · line 364

Quoted 2 lines
arch/powerpc/platforms/chrp/pci.c +2 -0
+	pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);

Is this a readonly register by any chance?
Appending a 'viaide->class &= ~0x5;' changes the code paths in do_ide_setup_pci_device(), now IDE prints 'not 100%% native mode, will probe irqs later'. Where are the irqs supposed to come from?

Quoted 12 lines

drivers/ide/pci/via82cxxx.c static void __devinit init_hwif_via82cxx · line 444

Quoted 5 lines
drivers/ide/pci/via82cxxx.c +0 -5
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif

Maybe we should just leave this in and dont bother about the arch specific tweak?
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-dev

\ FORTH

\ Pegasos fixes for device tree and peripheral configuration \
\ - Fixes up entries to "comply" with Linux specifications \ - Changes IDE class-code to help libata decide what to do \
\ Changelog:
\
\ 0.1: ISA ranges & IDE interrupts fixes from Linux
\ Requires prom_init.c patch to fix the PCI config space
\ as the
\ 0.2: keyboard controller fix

." PegasosPPC Device Tree Supplement 20070817" cr
." (c) 2007 Matt Sealey, Genesi USA, Inc." cr cr

headerless

." Linux device tree fixups" cr

\ Fix ATA
." * Fixing IDE controller class-code and interrupts .." cr ." * Fixing IDE interrupts .." cr
s" /pci@80000000/ide@C,1" find-device
d# 14 encode-int 0 encode-int
\ d# 15 encode-int 0 encode-int
encode+ encode+ encode+ s" interrupts" property

\ 0x101?? encode-int s" class-code" property
device-end

." * Fixing ISA ranges .. " cr
s" /pci@80000000/isa@C" find-device

	0x1 encode-int 0x0 encode-int 0x1006000 encode-int 
	0x0 encode-int 0x0 encode-int 0x1000 encode-int
	encode+ encode+ encode+ encode+ encode+ s" ranges" property

device-end

." * Fixing Keyboard controller type .." cr
s" /pci@8000000/isa@C/8042" find-device
s" 8042" encode-string device-type
device-end

." Done" cr cr

\ Edit for your pleasure, and uncomment to boot your Linux \ s" hd:0 vmlinuz video= root= console=" $boot

\ FORTH

\ Efika fixes for device tree and port configuration,
\ ostensibly for Linux but actually useful for a great
\ deal of other things.
\
\ Firmwares: 20061107 (1.3) - Initial Production
\ 20070122 (1.3) - Second Production
\ ???????? (2.0) - Any Day Now..
\
\ - Fixes up entries to "comply" with Linux specifications \ - Enables AC97 on PSC2 if it's not already enabled
\ - Adds GPIO, CDM, GPT, SLT, XLB and SDRAM entries
\
\ Changelog:
\
\ 0.1: Makes all device tree changes dictated by
\ arch/powerpc/kernel/prom_init.c:fixup_device_tree_efika()
\ 0.2: Adds slice timer, GPT nodes, CDM and GPIO
\ 0.3: Fixed GPT adder to use the stack properly instead of variables \ 0.4: XLB and SDRAM nodes
\ 0.9: fixed BestComm fixer to use 'i' instead of a counter variable \

." EFIKA MPC5200B Device Tree Supplement 20070810" cr

\ headerless

\ Device tree fixups for the purpose of pleasing Sylvain ." Linux device tree fixups" cr

\ Fix ATA, BestComm, PIC, serial, sound and sram just like the Linux guys want s" /builtin/ata" find-device

	s" mpc5200-ata" encode-string
	s" mpc5200b-ata" encode-string
	encode+
	s" compatible" property

device-end

\ Audio. Also enable AC97 if not done already.
s" /builtin/sound" find-device

	s" mpc5200-psc-ac97" encode-string
	s" mpc5200b-psc-ac97" encode-string
	encode+
	s" compatible" property

	0x2 encode-int
	0x2 encode-int
	0x3 encode-int
	encode+ encode+
	s" interrupts" property

	\ Audio is on PSC2, just for informational purposes
	1 encode-int s" cell-index" property

device-end

\ Quick test to see if AC97 is enabled

0xf0000b00 dup dup l@ 0x20 and
0= if

	." Enabling AC97" cr
	dup l@ 0x20 or
	swap l!

else
drop
then

\ SRAM compatibles
s" /builtin/sram" find-device

	s" mpc5200-sram" encode-string
	s" mpc5200b-sram" encode-string
	encode+
	s" compatible" property
	
	s" sram" device-type \ this is a contentious one

device-end

\ PIC compatibles
s" /builtin/pic" find-device

	s" mpc5200-pic" encode-string
	s" mpc5200b-pic" encode-string
	encode+
	s" compatible" property

device-end

\ Serial compatibles. Also fix cell-index and port-number as per bindings s" /builtin/serial" find-device
s" mpc5200-psc-uart" encode-string
s" mpc5200b-psc-uart" encode-string
encode+
s" compatible" property

\ Serial port is PSC1 for informational purposes, Linux 0-indexes it 0 encode-int s" cell-index" property
\ Since this is the main, always there, preferred serial port.. 0 encode-int s" port-number" property
device-end

\ Ethernet compatibles
s" /builtin/ethernet" find-device

	s" mpc5200-fec" encode-string
	s" mpc5200b-fec" encode-string
	encode+
	s" compatible" property

device-end

\ BestComm compatibles, interrupt mess
s" /builtin/bestcomm" find-device
s" mpc5200-bestcomm" encode-string
s" mpc5200b-bestcomm" encode-string
encode+
s" compatible" property

\ make 16 interrupt property in a batch. Note, stack usage is through \ the roof, but we have just enough to do this 16 times. 0x10 0 do
0x3 encode-int i encode-int 0x3 encode-int
loop

\ for each interrupt we need to concatenate them with encode+ for \ each value. And then two more.
0xf 0x3 do encode+ encode+ encode+ loop
encode+ encode+

\ now we can store the damn thing
s" interrupts" property
device-end

\ Go into the root node and kill off any mention of CHRP \ we're not compatible enough, it seems..

s" /" find-device
s" efika" device-type
s" EFIKA5K2 PowerPC System" encode-string s" CODEGEN,description" property
device-end

\ Find the Builtin device
\ Fix the device-type for Linux

s" /builtin" find-device
s" soc" device-type
\ device-end \ don't end here? New devices need to be made inside...

\
\
\ ADDING NEW ENTRIES TO THE DEVICE TREE
\
\

\
\ Clock Distribution Module - need this to change baud rates etc. and turn off \ clocks for power management. Useful little thing. Needs an entry to find the \ address without guessing (in case they change it in the 512X)

\ Clock Distribution Module
." Adding Clock Distribution Module" cr

new-device

	" cdm" 2dup device-name device-type
	" MPC52xx Clock Distribution Module" encode-string " .description" property
	0xf0000200 0x38 reg

	" mpc5200-cdm" encode-string 
	" mpc5200b-cdm" encode-string
	encode+
	" compatible" property

finish-device

\
\ General Purpose I/O
\
\ Does not include GPIO for GPTs (since they're not connected on Efika) or \ the dedicated GPIO group (because they're connected to the SDRAM on Efika)

\ GPIO (Simple) Module
." Adding Simple GPIO Module" cr

new-device

	s" gpio" 2dup device-name device-type
	s" MPC52xx Simple GPIO" encode-string s" .description" property
	0xf0000b00 0x10 reg

	s" mpc5200-gpio" encode-string
	s" mpc5200b-gpio" encode-string encode+ 
	s" compatible" property

	0x10000000 encode-int s" gpio-mask" property

	0x1 encode-int
	0x7 encode-int
	0x3 encode-int
	encode+ encode+
	s" interrupts" property

finish-device

\ GPIO (Wakeup) Module
." Adding Wakeup GPIO Module" cr

new-device

	s" gpio-wkup" 2dup device-name device-type
	s" MPC52xx Wakeup GPIO" encode-string s" .description" property
	0xf0000c00 0x10 reg

	s" mpc5200-gpio-wkup" encode-string
	s" mpc5200b-gpio-wkup" encode-string
	encode+
	s" compatible" property
	
	0x30000000 encode-int s" gpio-mask" property

	0x1 encode-int
	0x8 encode-int
	0x3 encode-int
	0x1 encode-int
	0x3 encode-int
	0x3 encode-int
	encode+ encode+ encode+ encode+ encode+
	s" interrupts" property

finish-device

\
\ High resolution (General Purpose and Slice) Timers
\
\ Useful since May 2007 we got high resolution timers and dynticks \ support in PowerPC semi-officially. High resolution timers are \ the new black.
\

\ Slice Timer (SLT1)
\ We ignore slice timer 0 since it has too high an interrupt priority? ." Adding Slice Timer 1" cr

new-device

	s" slt" 2dup device-name device-type
	s" MPC52xx Slice Timer" encode-string " .description" property
	0xf0000710 0x10 reg
	
	s" mpc5200-slt" encode-string 
	s" mpc5200b-slt" encode-string
	encode+
	s" compatible" property

	1 encode-int " cell-index" property

	\ THIS IS WRONG WRONG WRONG??????
	0x1 encode-int
	0x0 encode-int
	0x3 encode-int
	encode+ encode+
	s" interrupts" property

finish-device

: gpt-add ( gpt-id -- )
depth
1 > if

	dup 7 <= if    
		dup    
		0x9 +  
		swap dup
		0x10 *  
		0xf0000600 +
		swap dup    

		." Adding General Purpose Timer " .d cr 

\ s" /builtin" find-device
new-device

s" gpt" 2dup device-name device-type swap 0x10 reg

encode-int " cell-index" property

s" MPC52xx General Purpose Timer" encode-string s" .description" property

s" mpc5200-gpt" encode-string s" mpc5200b-gpt" encode-string encode+ s" compatible" property

0x1 encode-int
2 pick encode-int
0x3 encode-int
encode+ encode+
s" interrupts" property

finish-device
then
then
;

\ we'll just add 4 of them for now... plenty of timers to go around 4 gpt-add
5 gpt-add
6 gpt-add
7 gpt-add

\
\ HERE BE DRAGONS
\
\ These are parts of the system that are a little bit contentious to \ install in the device-tree, however certain tiny flags are useful \ in other components and drivers. Being able to search for these \ nodes is useful in those drivers.
\
\ This is pure device advertising: Genesi do not endorse using these to do \ screwy things like changing the way the SDRAM controller operates!!

\ SDRAM Controller (needed to enter deep sleep and turn off RAM clocks) ." Adding SDRAM Controller" cr

new-device
s" sdram" device-name
s" memory-controller" device-type
s" MPC52xx SDRAM Memory Controller" encode-string " .description" property 0xf0000100 0x10 reg

s" mpc5200b-sdram" encode-string
s" mpc5200-sdram" encode-string
encode+
s" compatible" property
finish-device

\ XLB Arbiter (pipeline/bestcomm stuff enabled here) ." Adding XLB Arbiter" cr

new-device

	s" xlb" 2dup device-name device-type
	0xf0001f00 0x100 reg
	s" MPC52xx XLB Arbiter" encode-string " .description" property	
	s" mpc5200-xlb" encode-string
	s" mpc5200b-xlb" encode-string
	encode+
	s" compatible" property

finish-device

\ Uncomment and boot your Linux
\ s" hd:0 vmlinuz console= blah=" $boot

#19 lore raw

Re: [PATCH] advertise correct IDE mode on Pegasos2

Quoted 3 lines · Matt Sealey

Setting them to ~0x5 will set them to 0 (legacy mode) and they will always read
back as 0 (legacy mode.. sigh) even if in native mode.

The pci_dev->class needs updating as well, see second version of the patch.

#20 lore raw

PATCH 1/1 advertise correct IDE mode on Pegasos2

In reply to Olaf Hering

The built-in IDE controller is configured in legacy mode,
but the PCI registers advertise native mode.
Force the PCI class into legacy mode. This allows pata_via to access two drives.
The Pegasos specific irq enforcement in the via82cxxx driver
must stay because there is aparently no generic way to setup irq per channel.

Tested on Pegasos2 with firmware version 20040810, and two IDE disks.

---
 arch/powerpc/kernel/prom_init.c   |   11 ++++++++---
 arch/powerpc/platforms/chrp/pci.c |   29 +++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 3 deletions(-)
arch/powerpc/kernel/prom_init.c +8 -3
@@ -2044,6 +2044,7 @@ static void __init fixup_device_tree_map
 /*
  * Pegasos and BriQ lacks the "ranges" property in the isa node
  * Pegasos needs decimal IRQ 14/15, not hexadecimal
+ * Pegasos has the IDE configured in legacy mode, but advertised as native
  */
 static void __init fixup_device_tree_chrp(void)
 {
@@ -2081,9 +2082,13 @@ static void __init fixup_device_tree_chr
 		prom_printf("Fixing up IDE interrupt on Pegasos...\n");
 		prop[0] = 14;
 		prop[1] = 0x0;
-		prop[2] = 15;
-		prop[3] = 0x0;
-		prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32));
+		prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
+		prom_printf("Fixing up IDE class-code on Pegasos...\n");
+		rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
+		if (rc == sizeof(u32)) {
+			prop[0] &= ~0x5;
+			prom_setprop(ph, name, "class-code", prop, sizeof(u32));
+		}
 	}
 }
 #else
arch/powerpc/platforms/chrp/pci.c +29 -0
@@ -338,3 +338,32 @@ void chrp_pci_fixup_winbond_ata(struct p
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
 		chrp_pci_fixup_winbond_ata);
+
+/* Pegasos2 firmware version 20040810 configures the built-in IDE controller
+ * in legacy mode, but sets the PCI registers to PCI native mode.
+ * The chip can only operate in legacy mode, so force the PCI class into legacy
+ * mode as well. The same fixup must be done to the class-code property in
+ * the IDE node /pci@80000000/ide@C,1
+ */
+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+{
+	u8 progif;
+	struct pci_dev *viaisa;
+
+	if (!machine_is(chrp) || _chrp_type != _CHRP_Pegasos)
+		return;
+	if (viaide->irq != 14)
+		return;
+
+	viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
+	if (!viaisa)
+		return;
+	printk("Fixing VIA IDE, force legacy mode on '%s'\n", viaide->dev.bus_id);
+
+	pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
+	viaide->class &= ~0x5;
+
+	pci_dev_put(viaisa);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);