diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/Kconfig linux-2.6.10-rc2/arch/ppc64/Kconfig --- /usr/src/linux-2.6.10-rc2/arch/ppc64/Kconfig 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/Kconfig 2004-11-22 08:30:05.000000000 +0100 @@ -77,7 +77,6 @@ config PPC_PMAC depends on PPC_MULTIPLATFORM bool " Apple G5 based machines" default y - select ADB_PMU select U3_DART config PPC_MAPLE diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/misc.S linux-2.6.10-rc2/arch/ppc64/kernel/misc.S --- /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/misc.S 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/kernel/misc.S 2004-11-22 08:30:05.000000000 +0100 @@ -316,6 +316,37 @@ _GLOBAL(flush_dcache_phys_range) isync blr +_GLOBAL(flush_inval_dcache_phys_range) + LOADADDR(r10,naca) /* Get Naca address */ + ld r10,0(r10) + LOADADDR(r11,systemcfg) /* Get systemcfg address */ + ld r11,0(r11) + lwz r7,DCACHEL1LINESIZE(r11) /* Get dcache line size */ + addi r5,r7,-1 + andc r6,r3,r5 /* round low to line bdy */ + subf r8,r6,r4 /* compute length */ + add r8,r8,r5 /* ensure we get enough */ + lwz r9,DCACHEL1LOGLINESIZE(r10) /* Get log-2 of dcache line size */ + srw. r8,r8,r9 /* compute line count */ + beqlr /* nothing to do? */ + mfmsr r5 /* Disable MMU Data Relocation */ + ori r0,r5,MSR_DR + xori r0,r0,MSR_DR + sync + mtmsr r0 + sync + isync + mtctr r8 +0: dcbf 0,r6 + add r6,r6,r7 + bdnz 0b + sync + isync + mtmsr r5 /* Re-enable MMU Data Relocation */ + sync + isync + blr + /* * Flush a particular page from the data cache to RAM. diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_feature.c linux-2.6.10-rc2/arch/ppc64/kernel/pmac_feature.c --- /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_feature.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/kernel/pmac_feature.c 2004-11-22 08:30:05.000000000 +0100 @@ -347,6 +347,10 @@ static struct pmac_mb_def pmac_mb_defs[] PMAC_TYPE_POWERMAC_G5, g5_features, 0, }, + { "PowerMac8,1", "IMac G5", + PMAC_TYPE_POWERMAC_G5, g5_features, + 0, + }, { "RackMac3,1", "XServe G5", PMAC_TYPE_POWERMAC_G5, g5_features, 0, diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_pci.c linux-2.6.10-rc2/arch/ppc64/kernel/pmac_pci.c --- /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_pci.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/kernel/pmac_pci.c 2004-11-22 08:30:05.000000000 +0100 @@ -40,7 +40,7 @@ #endif extern int pci_probe_only; -extern int pci_read_irq_line(struct pci_dev *pci_dev); +extern int pmac_pci_read_irq_line(struct pci_dev *pci_dev); /* XXX Could be per-controller, but I don't think we risk anything by * assuming we won't have both UniNorth and Bandit */ @@ -664,7 +664,7 @@ void __init pmac_pcibios_fixup(void) struct pci_dev *dev = NULL; for_each_pci_dev(dev) - pci_read_irq_line(dev); + pmac_pci_read_irq_line(dev); pci_fix_bus_sysdata(); @@ -777,3 +777,19 @@ static void fixup_k2_sata(struct pci_dev } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata); + +int pmac_pci_read_irq_line(struct pci_dev *pci_dev) +{ + struct device_node *node; + + node = pci_device_to_OF_node(pci_dev); + if (node == NULL) + return -1; + if (node->n_intrs == 0) + return -1; + pci_dev->irq = node->intrs[0].line; + pci_write_config_byte(pci_dev, PCI_INTERRUPT_LINE, pci_dev->irq); + + return 0; +} +EXPORT_SYMBOL(pmac_pci_read_irq_line); diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_setup.c linux-2.6.10-rc2/arch/ppc64/kernel/pmac_setup.c --- /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_setup.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/kernel/pmac_setup.c 2004-11-22 08:30:05.000000000 +0100 @@ -88,6 +88,11 @@ extern int powersave_nap; int sccdbg; extern void udbg_init_scc(struct device_node *np); +#ifdef CONFIG_G5_SMU +int __openfirmware smu_init (void); +void smu_shutdown (void); +void smu_restart (void); +#endif void __pmac pmac_show_cpuinfo(struct seq_file *m) { @@ -155,8 +160,14 @@ void __init pmac_setup_arch(void) /* We can NAP */ powersave_nap = 1; +#ifdef CONFIG_ADB_PMU /* Initialize the PMU */ find_via_pmu(); +#endif +#ifdef CONFIG_G5_SMU + /* Initialize the SMU */ + smu_init(); +#endif /* Init NVRAM access */ pmac_nvram_init(); @@ -221,12 +232,22 @@ void __pmac note_bootable_part(dev_t dev void __pmac pmac_restart(char *cmd) { +#ifdef CONFIG_ADB_PMU pmu_restart(); +#endif +#ifdef CONFIG_G5_SMU + smu_restart(); +#endif } void __pmac pmac_power_off(void) { +#ifdef CONFIG_ADB_PMU pmu_shutdown(); +#endif +#ifdef CONFIG_G5_SMU + smu_shutdown(); +#endif } void __pmac pmac_halt(void) diff -urNbBp /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_time.c linux-2.6.10-rc2/arch/ppc64/kernel/pmac_time.c --- /usr/src/linux-2.6.10-rc2/arch/ppc64/kernel/pmac_time.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/arch/ppc64/kernel/pmac_time.c 2004-11-22 08:30:05.000000000 +0100 @@ -42,6 +42,7 @@ extern void setup_default_decr(void); extern unsigned long ppc_tb_freq; extern unsigned long ppc_proc_freq; +#ifdef CONFIG_ADB_PMU /* Apparently the RTC stores seconds since 1 Jan 1904 */ #define RTC_OFFSET 2082844800 @@ -123,6 +124,7 @@ void __init pmac_get_boot_time(struct rt dst ? "on" : "off"); #endif } +#endif /* * Query the OF and get the decr frequency. diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/ide/ppc/pmac.c linux-2.6.10-rc2/drivers/ide/ppc/pmac.c --- /usr/src/linux-2.6.10-rc2/drivers/ide/ppc/pmac.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/ide/ppc/pmac.c 2004-11-22 08:30:05.000000000 +0100 @@ -89,7 +89,8 @@ enum { controller_kl_ata3, /* KeyLargo ATA-3 */ controller_kl_ata4, /* KeyLargo ATA-4 */ controller_un_ata6, /* UniNorth2 ATA-6 */ - controller_k2_ata6 /* K2 ATA-6 */ + controller_k2_ata6, /* K2 ATA-6 */ + controller_sh_ata6, /* Shasta ATA-6 */ }; static const char* model_name[] = { @@ -99,6 +100,7 @@ static const char* model_name[] = { "KeyLargo ATA-4", /* KeyLargo ATA-4 (UDMA/66) */ "UniNorth ATA-6", /* UniNorth2 ATA-6 (UDMA/100) */ "K2 ATA-6", /* K2 ATA-6 (UDMA/100) */ + "Shasta ATA-6", /* Shasta ATA-6 (UDMA/133) */ }; /* @@ -122,6 +124,15 @@ static const char* model_name[] = { #define IDE_SYSCLK_NS 30 /* 33Mhz cell */ #define IDE_SYSCLK_66_NS 15 /* 66Mhz cell */ +/* 133Mhz cell, found in shasta. + * See comments about 100 Mhz Uninorth 2... + * Note that PIO_MASK and MDMA_MASK seem to overlap + */ +#define TR_133_PIOREG_PIO_MASK 0xff000fff +#define TR_133_PIOREG_MDMA_MASK 0x00fff800 +#define TR_133_UDMAREG_UDMA_MASK 0x0003ffff +#define TR_133_UDMAREG_UDMA_EN 0x00000001 + /* 100Mhz cell, found in Uninorth 2. I don't have much infos about * this one yet, it appears as a pci device (106b/0033) on uninorth * internal PCI bus and it's clock is controlled like gem or fw. It @@ -322,6 +333,48 @@ static struct kauai_timing kauai_udma_ti { 0 , 0 }, }; +static struct kauai_timing shasta_pio_timings[] __pmacdata = +{ + { 930 , 0x08000fff }, + { 600 , 0x0A000c97 }, + { 383 , 0x07000712 }, + { 360 , 0x040003cd }, + { 330 , 0x040003cd }, + { 300 , 0x040003cd }, + { 270 , 0x040003cd }, + { 240 , 0x040003cd }, + { 239 , 0x040003cd }, + { 180 , 0x0400028b }, + { 120 , 0x0400010a } +}; + +static struct kauai_timing shasta_mdma_timings[] __pmacdata = +{ + { 1260 , 0x00fff000 }, + { 480 , 0x00820800 }, + { 360 , 0x00820800 }, + { 270 , 0x00820800 }, + { 240 , 0x00820800 }, + { 210 , 0x00820800 }, + { 180 , 0x00820800 }, + { 150 , 0x0028b000 }, + { 120 , 0x001ca000 }, + { 0 , 0 }, +}; + +static struct kauai_timing shasta_udma133_timings[] __pmacdata = +{ + { 120 , 0x00035901, }, + { 90 , 0x000348b1, }, + { 60 , 0x00033881, }, + { 45 , 0x00033861, }, + { 30 , 0x00033841, }, + { 20 , 0x00033031, }, + { 15 , 0x00033021, }, + { 0 , 0 }, +}; + + static inline u32 kauai_lookup_timing(struct kauai_timing* table, int cycle_time) { @@ -547,7 +600,9 @@ pmac_ide_do_update_timings(ide_drive_t * if (pmif == NULL) return; - if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) + if (pmif->kind == controller_sh_ata6 || + pmif->kind == controller_un_ata6 || + pmif->kind == controller_k2_ata6) pmac_ide_kauai_selectproc(drive); else pmac_ide_selectproc(drive); @@ -665,6 +720,14 @@ pmac_ide_tuneproc(ide_drive_t *drive, u8 pio = ide_get_best_pio_mode(drive, pio, 4, &d); switch (pmif->kind) { + case controller_sh_ata6: { + /* 133Mhz cell */ + u32 tr = kauai_lookup_timing(shasta_pio_timings, d.cycle_time); + if (tr == 0) + return; + *timings = ((*timings) & ~TR_133_PIOREG_PIO_MASK) | tr; + break; + } case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ @@ -776,6 +839,26 @@ set_timings_udma_ata6(u32 *pio_timings, } /* + * Calculate Shasta ATA/133 UDMA timings + */ +static int __pmac +set_timings_udma_shasta(u32 *pio_timings, u32 *ultra_timings, u8 speed) +{ + struct ide_timing *t = ide_timing_find_mode(speed); + u32 tr; + + if (speed > XFER_UDMA_6 || t == NULL) + return 1; + tr = kauai_lookup_timing(shasta_udma133_timings, (int)t->udma); + if (tr == 0) + return 1; + *ultra_timings = ((*ultra_timings) & ~TR_133_UDMAREG_UDMA_MASK) | tr; + *ultra_timings = (*ultra_timings) | TR_133_UDMAREG_UDMA_EN; + + return 0; +} + +/* * Calculate MDMA timings for all cells */ static int __pmac @@ -803,6 +886,7 @@ set_timings_mdma(ide_drive_t *drive, int cycleTime = 150; /* Get the proper timing array for this controller */ switch(intf_type) { + case controller_sh_ata6: case controller_un_ata6: case controller_k2_ata6: break; @@ -836,6 +920,14 @@ set_timings_mdma(ide_drive_t *drive, int #endif } switch(intf_type) { + case controller_sh_ata6: { + /* 133Mhz cell */ + u32 tr = kauai_lookup_timing(shasta_mdma_timings, cycleTime); + if (tr == 0) + return 1; + *timings = ((*timings) & ~TR_133_PIOREG_MDMA_MASK) | tr; + *timings2 = (*timings2) & ~TR_133_UDMAREG_UDMA_EN; + } case controller_un_ata6: case controller_k2_ata6: { /* 100Mhz cell */ @@ -930,9 +1022,13 @@ pmac_ide_tune_chipset (ide_drive_t *driv switch(speed) { #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC + case XFER_UDMA_6: + if (pmif->kind != controller_sh_ata6) + return 1; case XFER_UDMA_5: if (pmif->kind != controller_un_ata6 && - pmif->kind != controller_k2_ata6) + pmif->kind != controller_k2_ata6 && + pmif->kind != controller_sh_ata6) return 1; case XFER_UDMA_4: case XFER_UDMA_3: @@ -946,6 +1042,8 @@ pmac_ide_tune_chipset (ide_drive_t *driv else if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) ret = set_timings_udma_ata6(timings, timings2, speed); + else if (pmif->kind == controller_sh_ata6) + ret = set_timings_udma_shasta(timings, timings2, speed); else ret = 1; break; @@ -992,6 +1090,10 @@ sanitize_timings(pmac_ide_hwif_t *pmif) unsigned int value, value2 = 0; switch(pmif->kind) { + case controller_sh_ata6: + value = 0x0a820c97; + value2 = 0x00033031; + break; case controller_un_ata6: case controller_k2_ata6: value = 0x08618a92; @@ -1142,7 +1244,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p pmif->cable_80 = 0; pmif->broken_dma = pmif->broken_dma_warn = 0; - if (device_is_compatible(np, "kauai-ata")) + if (device_is_compatible(np, "shasta-ata")) + pmif->kind = controller_sh_ata6; + else if (device_is_compatible(np, "kauai-ata")) pmif->kind = controller_un_ata6; else if (device_is_compatible(np, "K2-UATA")) pmif->kind = controller_k2_ata6; @@ -1163,7 +1267,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p /* Get cable type from device-tree */ if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6) { + || pmif->kind == controller_k2_ata6 + || pmif->kind == controller_sh_ata6) { char* cable = get_property(np, "cable-type", NULL); if (cable && !strncmp(cable, "80-", 3)) pmif->cable_80 = 1; @@ -1217,7 +1322,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *p hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; hwif->tuneproc = pmac_ide_tuneproc; - if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) + if (pmif->kind == controller_un_ata6 + || pmif->kind == controller_k2_ata6 + || pmif->kind == controller_sh_ata6) hwif->selectproc = pmac_ide_kauai_selectproc; else hwif->selectproc = pmac_ide_selectproc; @@ -1442,11 +1549,7 @@ pmac_ide_pci_attach(struct pci_dev *pdev pmif->dma_regs = base + 0x1000; #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ - /* We use the OF node irq mapping */ - if (np->n_intrs == 0) pmif->irq = pdev->irq; - else - pmif->irq = np->intrs[0].line; pci_set_drvdata(pdev, hwif); @@ -1530,6 +1633,8 @@ static struct pci_device_id pmac_ide_pci { PCI_VENDOR_ID_APPLE, PCI_DEVIEC_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, }; static struct pci_driver pmac_ide_pci_driver = { @@ -1737,10 +1842,15 @@ pmac_ide_udma_enable(ide_drive_t *drive, timing_local[1] = *timings2; /* Calculate timings for interface */ - if (pmif->kind == controller_un_ata6 || pmif->kind == controller_k2_ata6) + if (pmif->kind == controller_un_ata6 + || pmif->kind == controller_k2_ata6) ret = set_timings_udma_ata6( &timing_local[0], &timing_local[1], mode); + else if (pmif->kind == controller_sh_ata6) + ret = set_timings_udma_shasta( &timing_local[0], + &timing_local[1], + mode); else ret = set_timings_udma_ata4(&timing_local[0], mode); if (ret) @@ -1791,14 +1901,19 @@ pmac_ide_dma_check(ide_drive_t *drive) short mode; map = XFER_MWDMA; - if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6 - || pmif->kind == controller_k2_ata6) { + if (pmif->kind == controller_kl_ata4 + || pmif->kind == controller_un_ata6 + || pmif->kind == controller_k2_ata6 + || pmif->kind == controller_sh_ata6) { map |= XFER_UDMA; if (pmif->cable_80) { map |= XFER_UDMA_66; if (pmif->kind == controller_un_ata6 || - pmif->kind == controller_k2_ata6) + pmif->kind == controller_k2_ata6 || + pmif->kind == controller_sh_ata6) map |= XFER_UDMA_100; + if (pmif->kind == controller_sh_ata6) + map |= XFER_UDMA_133; } } mode = ide_find_best_mode(drive, map); @@ -2028,6 +2143,11 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif hwif->atapi_dma = 1; switch(pmif->kind) { + case controller_sh_ata6: + hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x00; + break; case controller_un_ata6: case controller_k2_ata6: hwif->ultra_mask = pmif->cable_80 ? 0x3f : 0x07; diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/macintosh/Kconfig linux-2.6.10-rc2/drivers/macintosh/Kconfig --- /usr/src/linux-2.6.10-rc2/drivers/macintosh/Kconfig 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/macintosh/Kconfig 2004-11-22 08:30:05.000000000 +0100 @@ -78,6 +78,12 @@ config ADB_PMU this device; you should do so if your machine is one of those mentioned above. +config G5_SMU + bool "Support for SMU based PowerMacs" + depends on PPC_PMAC64 + help + * TODO * + config PMAC_PBOOK bool "Power management support for PowerBooks" depends on ADB_PMU diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/macintosh/Makefile linux-2.6.10-rc2/drivers/macintosh/Makefile --- /usr/src/linux-2.6.10-rc2/drivers/macintosh/Makefile 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/macintosh/Makefile 2004-11-22 08:30:05.000000000 +0100 @@ -15,6 +15,7 @@ obj-$(CONFIG_ANSLCD) += ans-lcd.o obj-$(CONFIG_ADB_PMU) += via-pmu.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o +obj-$(CONFIG_G5_SMU) += smu.o obj-$(CONFIG_ADB) += adb.o obj-$(CONFIG_ADB_MACII) += via-macii.o diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/macintosh/smu.c linux-2.6.10-rc2/drivers/macintosh/smu.c --- /usr/src/linux-2.6.10-rc2/drivers/macintosh/smu.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.10-rc2/drivers/macintosh/smu.c 2004-11-24 12:43:04.000000000 +0100 @@ -0,0 +1,462 @@ +/* + * PowerMac G5 SMU driver + * + * Copyright 2004 J. Mayer + * + * Released under the term of the GNU GPL v2. + */ + +/* + * For now, this driver includes: + * - RTC get & set + * - reboot & shutdown commands + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_SMU 1 + +#if defined(DEBUG_SMU) +#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) +#else +#define DPRINTK(fmt, args...) do { } while (0) +#endif + +typedef struct cmd_buf_t cmd_buf_t; +struct cmd_buf_t { + uint8_t cmd; + uint8_t length; + uint8_t data[0x0FFE]; +}; + +struct SMU_dev_t { + spinlock_t lock; + struct device_node *np; + unsigned char name[16]; + int db_ack; /* SMU doorbell ack GPIO */ + int db_req; /* SMU doorbell req GPIO */ + u32 db_buff0; + u32 db_buff; /* SMU doorbell buffer location */ + void *db_buff_remap; /* SMU doorbell buffer location remapped */ + int SMU_irq; /* SMU IRQ */ + int SMU_irq_gpio; /* SMU interrupt GPIO */ + int programmer_switch; /* SMU programmer switch GPIO */ + int programmer_irq; /* SMU programmer switch IRQ */ + int WOR_disable; + int WOR_enable; + cmd_buf_t *cmd_buf; +}; + +#define SMU_MAX 4 +static struct SMU_dev_t SMU_devices[SMU_MAX]; +static int SMU_nb; + +/* SMU low level stuff */ +static inline int cmd_stat (cmd_buf_t *cmd_buf, u8 cmd_ack) +{ + return cmd_buf->cmd == cmd_ack && cmd_buf->length != 0; +} + +static inline u8 save_ack_cmd (cmd_buf_t *cmd_buf) +{ + return (~cmd_buf->cmd) & 0xff; +} + +static void send_cmd (struct SMU_dev_t *dev) +{ + cmd_buf_t *cmd_buf; + + cmd_buf = dev->cmd_buf; + out_le32(dev->db_buff_remap, virt_to_phys(cmd_buf)); + /* Ring the SMU doorbell */ + pmac_do_feature_call(PMAC_FTR_WRITE_GPIO, NULL, dev->db_req, 4); +} + +static int cmd_done (struct SMU_dev_t *dev) +{ + unsigned long wait; + int gpio; + + /* Check the SMU doorbell */ + for (wait = jiffies + HZ; time_before(jiffies, wait); ) { + gpio = pmac_do_feature_call(PMAC_FTR_READ_GPIO, + NULL, dev->db_ack); + if ((gpio & 7) == 7) + return 0; + } + + return -1; +} + +static int do_cmd (struct SMU_dev_t *dev) +{ + int ret; + u8 cmd_ack; + + DPRINTK("SMU do_cmd %02x len=%d %02x\n", + dev->cmd_buf->cmd, dev->cmd_buf->length, dev->cmd_buf->data[0]); + cmd_ack = save_ack_cmd(dev->cmd_buf); + /* Clear cmd_buf cache lines */ + flush_inval_dcache_phys_range(virt_to_phys(dev->cmd_buf), + virt_to_phys(dev->cmd_buf + 1)); + mb(); + send_cmd(dev); + ret = cmd_done(dev); + mb(); + if (ret == 0) + ret = cmd_stat(dev->cmd_buf, cmd_ack) ? 0 : -1; + DPRINTK("SMU do_cmd %02x len=%d %02x => %d (%02x)\n", dev->cmd_buf->cmd, + dev->cmd_buf->length, dev->cmd_buf->data[0], ret, cmd_ack); + + return ret; +} + +static irqreturn_t SMU_irq_handler (int irq, void *arg, struct pt_regs *regs) +{ + /* Fake handler for now */ + // printk("SMU irq %d\n", irq); + + return 0; +} + +/* RTC low level commands */ +static inline int bcd2hex (int n) +{ + return (((n & 0xf0) >> 4) * 10) + (n & 0xf); +} + +static inline int hex2bcd (int n) +{ + return ((n / 10) << 4) + (n % 10); +} + +static inline void set_pwrup_timer_cmd (cmd_buf_t *cmd_buf) +{ + cmd_buf->cmd = 0x8e; + cmd_buf->length = 8; + cmd_buf->data[0] = 0x00; + memset(cmd_buf->data + 1, 0, 7); +} + +static inline void get_pwrup_timer_cmd (cmd_buf_t *cmd_buf) +{ + cmd_buf->cmd = 0x8e; + cmd_buf->length = 1; + cmd_buf->data[0] = 0x01; +} + +static inline void disable_pwrup_timer_cmd (cmd_buf_t *cmd_buf) +{ + cmd_buf->cmd = 0x8e; + cmd_buf->length = 1; + cmd_buf->data[0] = 0x02; +} + +static inline void set_rtc_cmd (cmd_buf_t *cmd_buf, struct rtc_time *time) +{ + cmd_buf->cmd = 0x8e; + cmd_buf->length = 8; + cmd_buf->data[0] = 0x80; + cmd_buf->data[1] = hex2bcd(time->tm_sec); + cmd_buf->data[2] = hex2bcd(time->tm_min); + cmd_buf->data[3] = hex2bcd(time->tm_hour); + cmd_buf->data[4] = time->tm_wday; + cmd_buf->data[5] = hex2bcd(time->tm_mday); + cmd_buf->data[6] = hex2bcd(time->tm_mon) + 1; + cmd_buf->data[7] = hex2bcd(time->tm_year - 100); +} + +static inline void get_rtc_cmd (cmd_buf_t *cmd_buf) +{ + cmd_buf->cmd = 0x8e; + cmd_buf->length = 1; + cmd_buf->data[0] = 0x81; +} + +/* RTC interface */ +void __pmac pmac_get_rtc_time (struct rtc_time *time) +{ + struct SMU_dev_t *dev; + cmd_buf_t *cmd_buf; + + if (SMU_nb == 0 || SMU_devices[0].cmd_buf == NULL) + return; + memset(time, 0, sizeof(struct rtc_time)); + dev = &SMU_devices[0]; + cmd_buf = dev->cmd_buf; + DPRINTK("SMU get_rtc_time %p\n", cmd_buf); + spin_lock(&dev->lock); + get_rtc_cmd(cmd_buf); + if (do_cmd(dev) == 0) { + time->tm_sec = bcd2hex(cmd_buf->data[0]); + time->tm_min = bcd2hex(cmd_buf->data[1]); + time->tm_hour = bcd2hex(cmd_buf->data[2]); + time->tm_wday = bcd2hex(cmd_buf->data[3]); + time->tm_mday = bcd2hex(cmd_buf->data[4]); + time->tm_mon = bcd2hex(cmd_buf->data[5]) - 1; + time->tm_year = bcd2hex(cmd_buf->data[6]) + 100; + } + spin_unlock(&dev->lock); + DPRINTK("SMU get_rtc_time done\n"); +} + +void __pmac pmac_set_rtc_time (struct rtc_time *time) +{ + struct SMU_dev_t *dev; + cmd_buf_t *cmd_buf; + + if (SMU_nb == 0 || SMU_devices[0].cmd_buf == NULL) + return; + DPRINTK("SMU set_rtc_time\n"); + dev = &SMU_devices[0]; + cmd_buf = dev->cmd_buf; + spin_lock(&dev->lock); + set_rtc_cmd(cmd_buf, time); + do_cmd(dev); + spin_unlock(&dev->lock); + DPRINTK("SMU set_rtc_time done\n"); +} + +void __init pmac_get_boot_time (struct rtc_time *tm) +{ + if (SMU_nb == 0 || SMU_devices[0].cmd_buf == NULL) { + printk(KERN_ERR "%s: no SMU registered\n", __func__); + return; + } + DPRINTK("SMU get_boot_time\n"); + pmac_get_rtc_time(tm); +} + +/* Misc functions */ +void smu_shutdown (void) +{ + const unsigned char *command = "SHUTDOWN"; + struct SMU_dev_t *dev; + cmd_buf_t *cmd_buf; + + if (SMU_nb == 0) + return; + dev = &SMU_devices[0]; + cmd_buf = dev->cmd_buf; + spin_lock(&dev->lock); + cmd_buf->cmd = 0xaa; + cmd_buf->length = strlen(command); + strcpy(cmd_buf->data, command); + do_cmd(dev); + /* If we get here, we got a problem */ + { + int i; + for (i = 0; i < cmd_buf->length; i++) + printk("%02x ", cmd_buf->data[i]); + printk("\n"); + } + spin_unlock(&dev->lock); +} + +void smu_restart (void) +{ + const unsigned char *command = "RESTART"; + struct SMU_dev_t *dev; + cmd_buf_t *cmd_buf; + + if (SMU_nb == 0) + return; + dev = &SMU_devices[0]; + cmd_buf = dev->cmd_buf; + spin_lock(&dev->lock); + cmd_buf->cmd = 0xaa; + cmd_buf->length = strlen(command); + strcpy(cmd_buf->data, command); + do_cmd(dev); + /* If we get here, we got a problem */ + { + int i; + for (i = 0; i < cmd_buf->length; i++) + printk("%02x ", cmd_buf->data[i]); + printk("\n"); + } + spin_unlock(&dev->lock); +} + +/* SMU initialisation */ +static int smu_register (struct device_node *np, + int db_ack, int db_req, u32 db_buff, + int SMU_irq, int SMU_irq_gpio) +{ + void *db_buff_remap; + cmd_buf_t *cmd_buf; + + ppc64_boot_msg(0x13, "register one SMU\n"); + sprintf(SMU_devices[SMU_nb].name, "SMU%d\n", SMU_nb); + if (SMU_nb == SMU_MAX) { + ppc64_boot_msg(0x13, "Too many SMUs\n"); + return -1; + } + db_buff_remap = ioremap(0x8000860C, 16); + if (db_buff_remap == NULL) { + ppc64_boot_msg(0x13, "SMU remap fail\n"); + return -1; + } + cmd_buf = alloc_bootmem(sizeof(cmd_buf_t)); + if (cmd_buf == NULL) { + ppc64_boot_msg(0x13, "SMU alloc fail\n"); + iounmap(db_buff_remap); + return -1; + } +#if O + { + unsigned long flags; + ppc64_boot_msg(0x13, "SMU IRQ\n"); + flags = SA_SHIRQ | SA_INTERRUPT; + if (request_irq(SMU_irq, &SMU_irq_handler, flags, + SMU_devices[SMU_nb].name, &SMU_devices[SMU_nb]) < 0) { + ppc64_boot_msg(0x13, "SMU IRQ fail\n"); + iounmap(db_buff_remap); + return -1; + } + } +#endif + SMU_devices[SMU_nb].np = np; + SMU_devices[0].cmd_buf = cmd_buf; + /* XXX: 0x50 should be retrieved from MacIO properties */ + SMU_devices[SMU_nb].db_ack = db_ack + 0x50; + SMU_devices[SMU_nb].db_req = db_req + 0x50; + SMU_devices[SMU_nb].db_buff = 0x8000860C; + SMU_devices[SMU_nb].db_buff0 = db_buff; + SMU_devices[SMU_nb].db_buff_remap = db_buff_remap; + SMU_devices[SMU_nb].SMU_irq = SMU_irq; + SMU_devices[SMU_nb].SMU_irq_gpio = SMU_irq_gpio; + SMU_nb++; + + return 0; +} + +static int smu_locate_resource (struct device_node **np, u32 **pp, + u32 **rp, int *nr, u32 **ip, int *ni, + struct device_node *SMU_node, + const unsigned char *name) +{ + unsigned int *r; + int l; + + r = (unsigned int *)get_property(SMU_node, name, &l); + if (l == 0) + return -1; + *np = of_find_node_by_phandle(*r); + if (*np == NULL) + return -1; + *pp = (unsigned int *)get_property(*np, name, &l); + if (l == 0) + return -1; + *rp = (unsigned int *)get_property(*np, "reg", nr); + *ip = (unsigned int *)get_property(*np, "interrupts", ni); + + return 0; +} + +int __openfirmware smu_init (void) +{ + struct device_node *SMU_node, *np; + u32 *pp, *rp, *ip; + u32 doorbell_buf; + int doorbell_ack, doorbell_req, SMU_irq, SMU_irq_gpio; + int nr, ni; + + ppc64_boot_msg(0x13, "Starting SMU probe\n"); + SMU_node = NULL; + while (1) { + SMU_node = of_find_node_by_type(SMU_node, "smu"); + if (SMU_node == NULL) + break; + /* Locate doorbell ACK and REQ */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-doorbell-ack") < 0) { + ppc64_boot_msg(0x13, "SMU 'ack'\n"); + continue; + } + if (nr == 0) { + ppc64_boot_msg(0x13, "MacIO GPIO 'ack'\n"); + continue; + } + doorbell_ack = *rp; + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-doorbell-req") < 0) { + ppc64_boot_msg(0x13, "SMU 'req'\n"); + continue; + } + if (nr == 0) { + ppc64_boot_msg(0x13, "MacIO GPIO 'req'\n"); + continue; + } + doorbell_req = *rp; + /* Locate doorbell buffer */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-doorbell-buff") < 0) { + ppc64_boot_msg(0x13, "SMU 'buff'\n"); + continue; + } + if (nr < 4) { + ppc64_boot_msg(0x13, "MacIO regs 'buff'\n"); + continue; + } + doorbell_buf = rp[1] | rp[3]; + /* Locate programmer switch */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-programmer-switch") < 0) { + ppc64_boot_msg(0x13, "SMU 'switch'\n"); + continue; + } + /* Locate SMU IRQ */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-smu-interrupt") < 0) { + ppc64_boot_msg(0x13, "SMU 'interrupt'\n"); + continue; + } + if (np == 0 || ni == 0) { + ppc64_boot_msg(0x13, "MacIO GPIO 'interrupt'\n"); + continue; + } + SMU_irq_gpio = *rp; + SMU_irq = *ip; + /* Locate wor disable/enable */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-wor-disable") < 0) { + ppc64_boot_msg(0x13, "SMU 'wor-disable'\n"); + continue; + } + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "platform-wor-enable") < 0) { + ppc64_boot_msg(0x13, "SMU 'wor-enable'\n"); + continue; + } +#if 0 + /* Locate powertune step point */ + if (smu_locate_resource(&np, &pp, &rp, &nr, &ip, &ni, + SMU_node, "powertune-step-point") < 0) { + ppc64_boot_msg(0x13, "SMU 'step-point'\n"); + continue; + } +#endif + smu_register(SMU_node, doorbell_ack, doorbell_req, doorbell_buf, + SMU_irq, SMU_irq_gpio); + } + ppc64_boot_msg(0x13, "SMU probe done\n"); + + return SMU_nb == 0 ? -1 : 0; +} diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/net/sungem.c linux-2.6.10-rc2/drivers/net/sungem.c --- /usr/src/linux-2.6.10-rc2/drivers/net/sungem.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/net/sungem.c 2004-11-22 08:30:05.000000000 +0100 @@ -109,6 +109,8 @@ static struct pci_device_id gem_pci_tbl[ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_GMAC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, {0, } }; diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/pci/pci.ids linux-2.6.10-rc2/drivers/pci/pci.ids --- /usr/src/linux-2.6.10-rc2/drivers/pci/pci.ids 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/pci/pci.ids 2004-11-22 08:30:05.000000000 +0100 @@ -2189,6 +2189,14 @@ 0049 K2 HT-PCI Bridge 004b U3 AGP 004c K2 GMAC (Sun GEM) + 004f Shasta Mac I/O + 0050 Shasta IDE + 0051 Shasta (Sun GEM) + 0052 Shasta FireWire + 0053 Shasta PCI Bridge + 0054 Shasta PCI Bridge + 0055 Shasta PCI Bridge + 0058 U3L AGP Bridge 1645 Tigon3 Gigabit Ethernet NIC (BCM5701) 106c Hyundai Electronics America 8801 Dual Pentium ISA/PCI Motherboard diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/scsi/libata-core.c linux-2.6.10-rc2/drivers/scsi/libata-core.c --- /usr/src/linux-2.6.10-rc2/drivers/scsi/libata-core.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/scsi/libata-core.c 2004-11-22 08:30:05.000000000 +0100 @@ -3271,6 +3271,9 @@ int ata_device_add(struct ata_probe_ent host_set->mmio_base = ent->mmio_base; host_set->private_data = ent->private_data; host_set->ops = ent->port_ops; + if (host_set->ops->host_start) + host_set->ops->host_start(host_set); + /* register each port bound to this device */ for (i = 0; i < ent->n_ports; i++) { diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/scsi/sata_svw.c linux-2.6.10-rc2/drivers/scsi/sata_svw.c --- /usr/src/linux-2.6.10-rc2/drivers/scsi/sata_svw.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/scsi/sata_svw.c 2004-11-22 08:30:05.000000000 +0100 @@ -75,10 +75,19 @@ #define K2_SATA_SICR1_OFFSET 0x80 #define K2_SATA_SICR2_OFFSET 0x84 #define K2_SATA_SIM_OFFSET 0x88 +#define K2_SATA_MDIO_ACCESS 0x8c /* Port stride */ #define K2_SATA_PORT_OFFSET 0x100 +/* Private structure */ +struct k2_sata_priv +{ +#ifdef CONFIG_PPC_OF + struct device_node *of_node; +#endif + int need_mdio_phy_reset; +}; static u32 k2_sata_scr_read (struct ata_port *ap, unsigned int sc_reg) { @@ -96,6 +105,41 @@ static void k2_sata_scr_write (struct at writel(val, (void *) ap->ioaddr.scr_addr + (sc_reg * 4)); } +static u16 k2_sata_mdio_read(struct ata_host_set *host_set, int reg) +{ + u16 val; + int timeout; + + writel((reg & 0x1f) | 0x4000, + host_set->mmio_base + K2_SATA_MDIO_ACCESS); + for(timeout = 10000; timeout > 0; timeout++) { + val = readl(host_set->mmio_base + K2_SATA_MDIO_ACCESS); + if (val & 0x8000) + break; + udelay(100); + } + if (timeout <= 0) { + printk(KERN_WARNING "sata_svw: timeout reading MDIO reg %d\n", reg); + return 0xffff; + } + return val >> 16; +} + +static void k2_sata_mdio_write(struct ata_host_set *host_set, int reg, u16 val) +{ + int timeout; + + writel((reg & 0x1f) | (((u32)val) << 16) | 0x2000, + host_set->mmio_base + K2_SATA_MDIO_ACCESS); + for(timeout = 10000; timeout > 0; timeout++) { + val = readl(host_set->mmio_base + K2_SATA_MDIO_ACCESS); + if (val & 0x8000) + break; + udelay(100); + } + if (timeout <= 0) + printk(KERN_WARNING "sata_svw: timeout writing MDIO reg %d\n", reg); +} static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) { @@ -220,6 +264,31 @@ static u8 k2_stat_check_status(struct at return readl((void *) ap->ioaddr.status_addr); } +static void k2_sata_mdio_phy_reset(struct ata_host_set *host_set) +{ + u16 reg; + + reg = k2_sata_mdio_read(host_set, 4); + k2_sata_mdio_write(host_set, 4, reg | 0x0008); + udelay(200); + k2_sata_mdio_write(host_set, 4, reg); + udelay(250); +} + +static void k2_sata_host_start(struct ata_host_set *host_set) +{ + struct k2_sata_priv *pp; + + pp = host_set->private_data; + + /* Some cell revs need a HW reset of the PHY layer at this point, and + * on wakeup from power management + */ + if (pp->need_mdio_phy_reset) + k2_sata_mdio_phy_reset(host_set); +} + + #ifdef CONFIG_PPC_OF /* * k2_sata_proc_info @@ -237,6 +306,7 @@ static int k2_sata_proc_info(struct Scsi { struct ata_port *ap; struct device_node *np; + struct k2_sata_priv *pp; int len, index; /* Find the ata_port */ @@ -245,7 +315,8 @@ static int k2_sata_proc_info(struct Scsi return 0; /* Find the OF node for the PCI device proper */ - np = pci_device_to_OF_node(to_pci_dev(ap->host_set->dev)); + pp = ap->host_set->private_data; + np = pp->of_node; if (np == NULL) return 0; @@ -310,6 +381,7 @@ static struct ata_port_operations k2_sat .scr_write = k2_sata_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_start = k2_sata_host_start, }; static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) @@ -338,6 +410,7 @@ static int k2_sata_init_one (struct pci_ struct ata_probe_ent *probe_ent = NULL; unsigned long base; void *mmio_base; + struct k2_sata_priv *pp = NULL; int rc; if (!printed_version++) @@ -376,9 +449,30 @@ static int k2_sata_init_one (struct pci_ } memset(probe_ent, 0, sizeof(*probe_ent)); + + pp = (struct k2_sata_priv *)kmalloc(sizeof(struct k2_sata_priv), GFP_KERNEL); + if (pp == NULL) { + rc = -ENOMEM; + goto err_out_free_ent; + } + memset(pp, 0, sizeof(struct k2_sata_priv)); + probe_ent->dev = pci_dev_to_dev(pdev); INIT_LIST_HEAD(&probe_ent->node); + probe_ent->private_data = pdev; +#ifdef CONFIG_PPC_OF + /* Find the OF node for the PCI device proper */ + pp->of_node = pci_device_to_OF_node(pdev); + + /* Check for revision 1 */ + if (pp->of_node) { + u32 *rev; + rev = (u32 *)get_property(pp->of_node, "cell-revision", NULL); + if (rev && (*rev) > 0) + pp->need_mdio_phy_reset = 1; + } +#endif /* CONFIG_PPC_OF */ mmio_base = ioremap(pci_resource_start(pdev, 5), pci_resource_len(pdev, 5)); if (mmio_base == NULL) { @@ -429,6 +523,9 @@ static int k2_sata_init_one (struct pci_ return 0; err_out_free_ent: + if (pp) + kfree(pp); + if (probe_ent) kfree(probe_ent); err_out_regions: pci_release_regions(pdev); diff -urNbBp /usr/src/linux-2.6.10-rc2/drivers/video/riva/fbdev.c linux-2.6.10-rc2/drivers/video/riva/fbdev.c --- /usr/src/linux-2.6.10-rc2/drivers/video/riva/fbdev.c 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/drivers/video/riva/fbdev.c 2004-11-22 08:30:05.000000000 +0100 @@ -192,6 +192,8 @@ static struct pci_device_id rivafb_pci_t PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_FX_GO5200, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0, } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl); diff -urNbBp /usr/src/linux-2.6.10-rc2/include/asm-ppc64/cacheflush.h linux-2.6.10-rc2/include/asm-ppc64/cacheflush.h --- /usr/src/linux-2.6.10-rc2/include/asm-ppc64/cacheflush.h 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/include/asm-ppc64/cacheflush.h 2004-11-24 09:45:25.000000000 +0100 @@ -28,6 +28,8 @@ extern void flush_icache_user_range(stru extern void flush_dcache_range(unsigned long start, unsigned long stop); extern void flush_dcache_phys_range(unsigned long start, unsigned long stop); +extern void flush_inval_dcache_phys_range(unsigned long start, + unsigned long stop); #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { memcpy(dst, src, len); \ diff -urNbBp /usr/src/linux-2.6.10-rc2/include/linux/libata.h linux-2.6.10-rc2/include/linux/libata.h --- /usr/src/linux-2.6.10-rc2/include/linux/libata.h 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/include/linux/libata.h 2004-11-22 08:30:05.000000000 +0100 @@ -356,6 +356,7 @@ struct ata_port_operations { int (*port_start) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap); + void (*host_start) (struct ata_host_set *host_set); void (*host_stop) (struct ata_host_set *host_set); }; diff -urNbBp /usr/src/linux-2.6.10-rc2/include/linux/pci_ids.h linux-2.6.10-rc2/include/linux/pci_ids.h --- /usr/src/linux-2.6.10-rc2/include/linux/pci_ids.h 2004-11-21 09:33:17.000000000 +0100 +++ linux-2.6.10-rc2/include/linux/pci_ids.h 2004-11-22 08:30:05.000000000 +0100 @@ -845,6 +845,9 @@ #define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e #define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043 #define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c +#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050 +#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 +#define PCI_DEVICE_ID_APPLE_SH_FW 0x0052 #define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 #define PCI_VENDOR_ID_YAMAHA 0x1073 @@ -1140,6 +1143,7 @@ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_FX_GO5200 0x0329 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_8849 0x8849