diff --git a/[refs] b/[refs] index f4222d92425e..8b34be16f2b7 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cdec12aebe1b10aa58bebaa05bb697843154f7f9 +refs/heads/master: 258de4badd5b7b5d168307638f755bd4df16c18e diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 18e32719d0ed..f3f7ce3d79a5 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -25,10 +25,6 @@ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -isystem $(shell $(CROSS32CC) -print-file-name=include) BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc -ifdef CONFIG_DEBUG_INFO -BOOTCFLAGS += -g -endif - ifeq ($(call cc-option-yn, -fstack-protector),y) BOOTCFLAGS += -fno-stack-protector endif diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 8662cf053fa0..b03a442b7888 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -71,7 +71,7 @@ extern void __restore_cpu_ppc970(void); #define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ PPC_FEATURE_BOOKE) -static struct cpu_spec __initdata cpu_specs[] = { +static struct cpu_spec cpu_specs[] = { #ifdef CONFIG_PPC64 { /* Power3 */ .pvr_mask = 0xffff0000, @@ -327,6 +327,14 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_user_features = COMMON_USER_POWER5_PLUS, .icache_bsize = 128, .dcache_bsize = 128, + .num_pmcs = 6, + .pmc_type = PPC_PMC_IBM, + .oprofile_cpu_type = "ppc64/power6", + .oprofile_type = PPC_OPROFILE_POWER4, + .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, + .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, + .oprofile_mmcra_clear = POWER6_MMCRA_THRM | + POWER6_MMCRA_OTHER, .platform = "power5+", }, { /* Power6 */ @@ -356,6 +364,14 @@ static struct cpu_spec __initdata cpu_specs[] = { .cpu_user_features = COMMON_USER_POWER6, .icache_bsize = 128, .dcache_bsize = 128, + .num_pmcs = 6, + .pmc_type = PPC_PMC_IBM, + .oprofile_cpu_type = "ppc64/power6", + .oprofile_type = PPC_OPROFILE_POWER4, + .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, + .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, + .oprofile_mmcra_clear = POWER6_MMCRA_THRM | + POWER6_MMCRA_OTHER, .platform = "power6", }, { /* Cell Broadband Engine */ @@ -1300,37 +1316,18 @@ static struct cpu_spec __initdata cpu_specs[] = { #endif /* CONFIG_PPC32 */ }; -static struct cpu_spec the_cpu_spec; - -struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) +struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr) { struct cpu_spec *s = cpu_specs; - struct cpu_spec *t = &the_cpu_spec; + struct cpu_spec **cur = &cur_cpu_spec; int i; s = PTRRELOC(s); - t = PTRRELOC(t); + cur = PTRRELOC(cur); for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) if ((pvr & s->pvr_mask) == s->pvr_value) { - /* - * If we are overriding a previous value derived - * from the real PVR with a new value obtained - * using a logical PVR value, don't modify the - * performance monitor fields. - */ - if (t->num_pmcs && !s->num_pmcs) { - t->cpu_name = s->cpu_name; - t->cpu_features = s->cpu_features; - t->cpu_user_features = s->cpu_user_features; - t->icache_bsize = s->icache_bsize; - t->dcache_bsize = s->dcache_bsize; - t->cpu_setup = s->cpu_setup; - t->cpu_restore = s->cpu_restore; - t->platform = s->platform; - } else - *t = *s; - *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; + *cur = cpu_specs + i; #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE) /* ppc64 and booke expect identify_cpu to also call * setup_cpu for that processor. I will consolidate diff --git a/trunk/arch/powerpc/kernel/of_platform.c b/trunk/arch/powerpc/kernel/of_platform.c index eca8ccc3fa12..f70e787d556f 100644 --- a/trunk/arch/powerpc/kernel/of_platform.c +++ b/trunk/arch/powerpc/kernel/of_platform.c @@ -19,11 +19,11 @@ #include #include #include -#include -#include #include #include +#include +#include #include #include #include @@ -70,10 +70,7 @@ postcore_initcall(of_bus_driver_init); int of_register_platform_driver(struct of_platform_driver *drv) { /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; + drv->driver.name = drv->name; drv->driver.bus = &of_platform_bus_type; /* register with core */ @@ -388,11 +385,9 @@ static struct of_device_id of_pci_phb_ids[] = { }; static struct of_platform_driver of_pci_phb_driver = { - .match_table = of_pci_phb_ids, - .probe = of_pci_phb_probe, - .driver = { - .name = "of-pci", - }, + .name = "of-pci", + .match_table = of_pci_phb_ids, + .probe = of_pci_phb_probe, }; static __init int of_pci_phb_init(void) diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 9f329a8928ea..172dcc3849a0 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -531,7 +531,10 @@ static struct ibm_pa_feature { {CPU_FTR_CTRL, 0, 0, 3, 0}, {CPU_FTR_NOEXECUTE, 0, 0, 6, 0}, {CPU_FTR_NODSISRALIGN, 0, 1, 1, 1}, +#if 0 + /* put this back once we know how to test if firmware does 64k IO */ {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, +#endif {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, }; diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index cd870a823d18..7474502dace5 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -290,8 +290,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif - if (ppc_md.setup_arch) - ppc_md.setup_arch(); + ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); paging_init(); diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 008ab6823b02..3089eaed3256 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -530,8 +530,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif - if (ppc_md.setup_arch) - ppc_md.setup_arch(); + ppc_md.setup_arch(); paging_init(); ppc64_boot_msg(0x15, "Setup Done"); diff --git a/trunk/arch/powerpc/kernel/systbl.S b/trunk/arch/powerpc/kernel/systbl.S index 93219c34af32..579de70e0b4d 100644 --- a/trunk/arch/powerpc/kernel/systbl.S +++ b/trunk/arch/powerpc/kernel/systbl.S @@ -39,8 +39,6 @@ #ifdef CONFIG_PPC64 #define sys_sigpending sys_ni_syscall #define sys_old_getrlimit sys_ni_syscall - - .p2align 3 #endif _GLOBAL(sys_call_table) diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 9368da371f36..d20947cf1735 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -108,7 +108,7 @@ static void decrementer_set_mode(enum clock_event_mode mode, static struct clock_event_device decrementer_clockevent = { .name = "decrementer", .rating = 200, - .shift = 16, + .shift = 32, .mult = 0, /* To be filled in */ .irq = 0, .set_next_event = decrementer_set_next_event, @@ -118,7 +118,6 @@ static struct clock_event_device decrementer_clockevent = { static DEFINE_PER_CPU(struct clock_event_device, decrementers); void init_decrementer_clockevent(void); -static DEFINE_PER_CPU(u64, decrementer_next_tb); #ifdef CONFIG_PPC_ISERIES static unsigned long __initdata iSeries_recal_titan; @@ -542,7 +541,6 @@ void timer_interrupt(struct pt_regs * regs) struct pt_regs *old_regs; int cpu = smp_processor_id(); struct clock_event_device *evt = &per_cpu(decrementers, cpu); - u64 now; /* Ensure a positive value is written to the decrementer, or else * some CPUs will continuue to take decrementer exceptions */ @@ -553,14 +551,6 @@ void timer_interrupt(struct pt_regs * regs) do_IRQ(regs); #endif - now = get_tb_or_rtc(); - if (now < per_cpu(decrementer_next_tb, cpu)) { - /* not time for this event yet */ - now = per_cpu(decrementer_next_tb, cpu) - now; - if (now <= DECREMENTER_MAX) - set_dec((unsigned int)now - 1); - return; - } old_regs = set_irq_regs(regs); irq_enter(); @@ -807,10 +797,6 @@ void __init clocksource_init(void) static int decrementer_set_next_event(unsigned long evt, struct clock_event_device *dev) { - __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt; - /* The decrementer interrupts on the 0 -> -1 transition */ - if (evt) - --evt; set_dec(evt); return 0; } diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 2322ba5cce4c..213fa31ac537 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -766,9 +766,7 @@ static int __init vdso_init(void) return 0; } -#ifdef CONFIG_PPC_MERGE arch_initcall(vdso_init); -#endif int in_gate_area_no_task(unsigned long addr) { diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index cb22a3557c4e..1d7b272b3737 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -48,33 +48,66 @@ static struct vio_dev vio_bus_device = { /* fake "parent" device */ .dev.bus = &vio_bus_type, }; -static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) -{ - const unsigned char *dma_window; - struct iommu_table *tbl; - unsigned long offset, size; - - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return vio_build_iommu_table_iseries(dev); - - dma_window = of_get_property(dev->dev.archdata.of_node, - "ibm,my-dma-window", NULL); - if (!dma_window) - return NULL; +#ifdef CONFIG_PPC_ISERIES +struct device *iSeries_vio_dev = &vio_bus_device.dev; +EXPORT_SYMBOL(iSeries_vio_dev); - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); +static struct iommu_table veth_iommu_table; +static struct iommu_table vio_iommu_table; - of_parse_dma_window(dev->dev.archdata.of_node, dma_window, - &tbl->it_index, &offset, &size); - - /* TCE table size - measured in tce entries */ - tbl->it_size = size >> IOMMU_PAGE_SHIFT; - /* offset for VIO should always be 0 */ - tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; - tbl->it_busno = 0; - tbl->it_type = TCE_VB; +static void __init iommu_vio_init(void) +{ + iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); + veth_iommu_table.it_size /= 2; + vio_iommu_table = veth_iommu_table; + vio_iommu_table.it_offset += veth_iommu_table.it_size; + + if (!iommu_init_table(&veth_iommu_table, -1)) + printk("Virtual Bus VETH TCE table failed.\n"); + if (!iommu_init_table(&vio_iommu_table, -1)) + printk("Virtual Bus VIO TCE table failed.\n"); + vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops; + vio_bus_device.dev.archdata.dma_data = &vio_iommu_table; +} +#else +static void __init iommu_vio_init(void) +{ +} +#endif - return iommu_init_table(tbl, -1); +static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) +{ +#ifdef CONFIG_PPC_ISERIES + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + if (strcmp(dev->type, "network") == 0) + return &veth_iommu_table; + return &vio_iommu_table; + } else +#endif + { + const unsigned char *dma_window; + struct iommu_table *tbl; + unsigned long offset, size; + + dma_window = of_get_property(dev->dev.archdata.of_node, + "ibm,my-dma-window", NULL); + if (!dma_window) + return NULL; + + tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + + of_parse_dma_window(dev->dev.archdata.of_node, dma_window, + &tbl->it_index, &offset, &size); + + /* TCE table size - measured in tce entries */ + tbl->it_size = size >> IOMMU_PAGE_SHIFT; + /* offset for VIO should always be 0 */ + tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; + tbl->it_busno = 0; + tbl->it_type = TCE_VB; + + return iommu_init_table(tbl, -1); + } } /** @@ -135,6 +168,16 @@ static int vio_bus_remove(struct device *dev) return 1; } +/* convert from struct device to struct vio_dev and pass to driver. */ +static void vio_bus_shutdown(struct device *dev) +{ + struct vio_dev *viodev = to_vio_dev(dev); + struct vio_driver *viodrv = to_vio_driver(dev->driver); + + if (dev->driver && viodrv->shutdown) + viodrv->shutdown(viodev); +} + /** * vio_register_driver: - Register a new vio driver * @drv: The vio_driver structure to be registered. @@ -247,6 +290,9 @@ static int __init vio_bus_init(void) int err; struct device_node *node_vroot; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + iommu_vio_init(); + err = bus_register(&vio_bus_type); if (err) { printk(KERN_ERR "failed to register VIO bus\n"); @@ -351,6 +397,7 @@ static struct bus_type vio_bus_type = { .match = vio_bus_match, .probe = vio_bus_probe, .remove = vio_bus_remove, + .shutdown = vio_bus_shutdown, }; /** diff --git a/trunk/arch/powerpc/oprofile/cell/pr_util.h b/trunk/arch/powerpc/oprofile/cell/pr_util.h index 22e4e8d4eb2c..e5704f00c8b4 100644 --- a/trunk/arch/powerpc/oprofile/cell/pr_util.h +++ b/trunk/arch/powerpc/oprofile/cell/pr_util.h @@ -17,9 +17,10 @@ #include #include #include -#include #include +#include "../../platforms/cell/cbe_regs.h" + /* Defines used for sync_start */ #define SKIP_GENERIC_SYNC 0 #define SYNC_START_ERROR -1 diff --git a/trunk/arch/powerpc/oprofile/op_model_cell.c b/trunk/arch/powerpc/oprofile/op_model_cell.c index bb6bff51ce48..d928b54f3a0f 100644 --- a/trunk/arch/powerpc/oprofile/op_model_cell.c +++ b/trunk/arch/powerpc/oprofile/op_model_cell.c @@ -35,9 +35,9 @@ #include #include #include -#include #include "../platforms/cell/interrupt.h" +#include "../platforms/cell/cbe_regs.h" #include "cell/pr_util.h" static void cell_global_stop_spu(void); diff --git a/trunk/arch/powerpc/platforms/40x/virtex.c b/trunk/arch/powerpc/platforms/40x/virtex.c index 14bbc328170f..b52aa94abd78 100644 --- a/trunk/arch/powerpc/platforms/40x/virtex.c +++ b/trunk/arch/powerpc/platforms/40x/virtex.c @@ -36,9 +36,14 @@ static int __init virtex_probe(void) return 1; } +static void __init virtex_setup_arch(void) +{ +} + define_machine(virtex) { .name = "Xilinx Virtex", .probe = virtex_probe, + .setup_arch = virtex_setup_arch, .init_IRQ = xilinx_intc_init_tree, .get_irq = xilinx_intc_get_irq, .calibrate_decr = generic_calibrate_decr, diff --git a/trunk/arch/powerpc/platforms/40x/walnut.c b/trunk/arch/powerpc/platforms/40x/walnut.c index eb0c136b1c44..c17fdf23b492 100644 --- a/trunk/arch/powerpc/platforms/40x/walnut.c +++ b/trunk/arch/powerpc/platforms/40x/walnut.c @@ -53,9 +53,14 @@ static int __init walnut_probe(void) return 1; } +static void __init walnut_setup_arch(void) +{ +} + define_machine(walnut) { .name = "Walnut", .probe = walnut_probe, + .setup_arch = walnut_setup_arch, .progress = udbg_progress, .init_IRQ = uic_init_tree, .get_irq = uic_get_irq, diff --git a/trunk/arch/powerpc/platforms/44x/bamboo.c b/trunk/arch/powerpc/platforms/44x/bamboo.c index 470e1a3fd755..9bc45dea078f 100644 --- a/trunk/arch/powerpc/platforms/44x/bamboo.c +++ b/trunk/arch/powerpc/platforms/44x/bamboo.c @@ -50,9 +50,14 @@ static int __init bamboo_probe(void) return 1; } +static void __init bamboo_setup_arch(void) +{ +} + define_machine(bamboo) { .name = "Bamboo", .probe = bamboo_probe, + .setup_arch = bamboo_setup_arch, .progress = udbg_progress, .init_IRQ = uic_init_tree, .get_irq = uic_get_irq, diff --git a/trunk/arch/powerpc/platforms/44x/ebony.c b/trunk/arch/powerpc/platforms/44x/ebony.c index 40e18fcb666c..5a7fec8d10d3 100644 --- a/trunk/arch/powerpc/platforms/44x/ebony.c +++ b/trunk/arch/powerpc/platforms/44x/ebony.c @@ -57,9 +57,14 @@ static int __init ebony_probe(void) return 1; } +static void __init ebony_setup_arch(void) +{ +} + define_machine(ebony) { .name = "Ebony", .probe = ebony_probe, + .setup_arch = ebony_setup_arch, .progress = udbg_progress, .init_IRQ = uic_init_tree, .get_irq = uic_get_irq, diff --git a/trunk/arch/powerpc/platforms/44x/sequoia.c b/trunk/arch/powerpc/platforms/44x/sequoia.c index 30700b31d43b..7d0d9d567d25 100644 --- a/trunk/arch/powerpc/platforms/44x/sequoia.c +++ b/trunk/arch/powerpc/platforms/44x/sequoia.c @@ -50,9 +50,14 @@ static int __init sequoia_probe(void) return 1; } +static void __init sequoia_setup_arch(void) +{ +} + define_machine(sequoia) { .name = "Sequoia", .probe = sequoia_probe, + .setup_arch = sequoia_setup_arch, .progress = udbg_progress, .init_IRQ = uic_init_tree, .get_irq = uic_get_irq, diff --git a/trunk/arch/powerpc/platforms/52xx/efika.c b/trunk/arch/powerpc/platforms/52xx/efika.c index 0b1e60a010ba..4263158b3274 100644 --- a/trunk/arch/powerpc/platforms/52xx/efika.c +++ b/trunk/arch/powerpc/platforms/52xx/efika.c @@ -197,6 +197,15 @@ static void __init efika_setup_arch(void) { rtas_initialize(); +#ifdef CONFIG_BLK_DEV_INITRD + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ + efika_pcisetup(); #ifdef CONFIG_PM diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c index 901236fa0f07..0b6e8ee85ab1 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include "cbe_regs.h" #include "cbe_cpufreq.h" static DEFINE_MUTEX(cbe_switch_mutex); diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c index 70fa7aef5edd..163263b3e1cd 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pervasive.c @@ -28,8 +28,8 @@ #include #include #include -#include +#include "cbe_regs.h" #include "cbe_cpufreq.h" /* to write to MIC register */ diff --git a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c index 6a2c1b0a9a94..fc6f38982ff4 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c @@ -27,12 +27,12 @@ #include #include #include -#include #ifdef DEBUG #include #endif +#include "cbe_regs.h" #include "cbe_cpufreq.h" static u8 pmi_slow_mode_limit[MAX_CBE]; diff --git a/trunk/arch/powerpc/platforms/cell/cbe_regs.c b/trunk/arch/powerpc/platforms/cell/cbe_regs.c index 16a9b07e7b0c..c8f7f0007422 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_regs.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_regs.c @@ -16,7 +16,8 @@ #include #include #include -#include + +#include "cbe_regs.h" /* * Current implementation uses "cpu" nodes. We build our own mapping diff --git a/trunk/include/asm-powerpc/cell-regs.h b/trunk/arch/powerpc/platforms/cell/cbe_regs.h similarity index 76% rename from trunk/include/asm-powerpc/cell-regs.h rename to trunk/arch/powerpc/platforms/cell/cbe_regs.h index fd6fd00434ef..b24025f2ac7a 100644 --- a/trunk/include/asm-powerpc/cell-regs.h +++ b/trunk/arch/powerpc/platforms/cell/cbe_regs.h @@ -244,60 +244,16 @@ struct cbe_mic_tm_regs { u64 slow_fast_timer_0; /* 0x0090 */ u64 slow_next_timer_0; /* 0x0098 */ - u8 pad_0x00a0_0x00f8[0x00f8 - 0x00a0]; /* 0x00a0 */ - u64 mic_df_ecc_address_0; /* 0x00f8 */ - - u8 pad_0x0100_0x01b8[0x01b8 - 0x0100]; /* 0x0100 */ - u64 mic_df_ecc_address_1; /* 0x01b8 */ + u8 pad_0x00a0_0x01c0[0x01c0 - 0x0a0]; /* 0x00a0 */ u64 mic_ctl_cnfg_1; /* 0x01c0 */ #define CBE_MIC_DISABLE_PWR_SAV_1 0x8000000000000000LL - u64 pad_0x01c8; /* 0x01c8 */ u64 slow_fast_timer_1; /* 0x01d0 */ u64 slow_next_timer_1; /* 0x01d8 */ - u8 pad_0x01e0_0x0208[0x0208 - 0x01e0]; /* 0x01e0 */ - u64 mic_exc; /* 0x0208 */ -#define CBE_MIC_EXC_BLOCK_SCRUB 0x0800000000000000ULL -#define CBE_MIC_EXC_FAST_SCRUB 0x0100000000000000ULL - - u64 mic_mnt_cfg; /* 0x0210 */ -#define CBE_MIC_MNT_CFG_CHAN_0_POP 0x0002000000000000ULL -#define CBE_MIC_MNT_CFG_CHAN_1_POP 0x0004000000000000ULL - - u64 mic_df_config; /* 0x0218 */ -#define CBE_MIC_ECC_DISABLE_0 0x4000000000000000ULL -#define CBE_MIC_ECC_REP_SINGLE_0 0x2000000000000000ULL -#define CBE_MIC_ECC_DISABLE_1 0x0080000000000000ULL -#define CBE_MIC_ECC_REP_SINGLE_1 0x0040000000000000ULL - - u8 pad_0x0220_0x0230[0x0230 - 0x0220]; /* 0x0220 */ - u64 mic_fir; /* 0x0230 */ -#define CBE_MIC_FIR_ECC_SINGLE_0_ERR 0x0200000000000000ULL -#define CBE_MIC_FIR_ECC_MULTI_0_ERR 0x0100000000000000ULL -#define CBE_MIC_FIR_ECC_SINGLE_1_ERR 0x0080000000000000ULL -#define CBE_MIC_FIR_ECC_MULTI_1_ERR 0x0040000000000000ULL -#define CBE_MIC_FIR_ECC_ERR_MASK 0xffff000000000000ULL -#define CBE_MIC_FIR_ECC_SINGLE_0_CTE 0x0000020000000000ULL -#define CBE_MIC_FIR_ECC_MULTI_0_CTE 0x0000010000000000ULL -#define CBE_MIC_FIR_ECC_SINGLE_1_CTE 0x0000008000000000ULL -#define CBE_MIC_FIR_ECC_MULTI_1_CTE 0x0000004000000000ULL -#define CBE_MIC_FIR_ECC_CTE_MASK 0x0000ffff00000000ULL -#define CBE_MIC_FIR_ECC_SINGLE_0_RESET 0x0000000002000000ULL -#define CBE_MIC_FIR_ECC_MULTI_0_RESET 0x0000000001000000ULL -#define CBE_MIC_FIR_ECC_SINGLE_1_RESET 0x0000000000800000ULL -#define CBE_MIC_FIR_ECC_MULTI_1_RESET 0x0000000000400000ULL -#define CBE_MIC_FIR_ECC_RESET_MASK 0x00000000ffff0000ULL -#define CBE_MIC_FIR_ECC_SINGLE_0_SET 0x0000000000000200ULL -#define CBE_MIC_FIR_ECC_MULTI_0_SET 0x0000000000000100ULL -#define CBE_MIC_FIR_ECC_SINGLE_1_SET 0x0000000000000080ULL -#define CBE_MIC_FIR_ECC_MULTI_1_SET 0x0000000000000040ULL -#define CBE_MIC_FIR_ECC_SET_MASK 0x000000000000ffffULL - u64 mic_fir_debug; /* 0x0238 */ - - u8 pad_0x0240_0x1000[0x1000 - 0x0240]; /* 0x0240 */ + u8 pad_0x01e0_0x1000[0x1000 - 0x01e0]; /* 0x01e0 */ }; extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); diff --git a/trunk/arch/powerpc/platforms/cell/cbe_thermal.c b/trunk/arch/powerpc/platforms/cell/cbe_thermal.c index 4852bf312d83..fb5eda48467d 100644 --- a/trunk/arch/powerpc/platforms/cell/cbe_thermal.c +++ b/trunk/arch/powerpc/platforms/cell/cbe_thermal.c @@ -52,8 +52,8 @@ #include #include #include -#include +#include "cbe_regs.h" #include "spu_priv1_mmio.h" #define TEMP_MIN 65 diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 151fd8b82d63..c29e634177fa 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -41,9 +41,9 @@ #include #include #include -#include #include "interrupt.h" +#include "cbe_regs.h" struct iic { struct cbe_iic_thread_regs __iomem *regs; diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index faabc3fdc130..760caa76841a 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -34,8 +34,8 @@ #include #include #include -#include +#include "cbe_regs.h" #include "interrupt.h" /* Define CELL_IOMMU_REAL_UNMAP to actually unmap non-used pages diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c index 0304589c0a80..4ede22d363fa 100644 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ b/trunk/arch/powerpc/platforms/cell/pervasive.c @@ -34,9 +34,9 @@ #include #include #include -#include #include "pervasive.h" +#include "cbe_regs.h" static int sysreset_hack; diff --git a/trunk/arch/powerpc/platforms/cell/pmu.c b/trunk/arch/powerpc/platforms/cell/pmu.c index 1ed303678887..66ca4b5a1dbc 100644 --- a/trunk/arch/powerpc/platforms/cell/pmu.c +++ b/trunk/arch/powerpc/platforms/cell/pmu.c @@ -30,8 +30,8 @@ #include #include #include -#include +#include "cbe_regs.h" #include "interrupt.h" /* diff --git a/trunk/arch/powerpc/platforms/cell/ras.c b/trunk/arch/powerpc/platforms/cell/ras.c index b2494ebcdbe9..3961a085b432 100644 --- a/trunk/arch/powerpc/platforms/cell/ras.c +++ b/trunk/arch/powerpc/platforms/cell/ras.c @@ -10,9 +10,9 @@ #include #include #include -#include #include "ras.h" +#include "cbe_regs.h" static void dump_fir(int cpu) diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index 98e7ef8e6fc6..db6654272e13 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -52,9 +52,9 @@ #include #include #include -#include #include "interrupt.h" +#include "cbe_regs.h" #include "pervasive.h" #include "ras.h" @@ -83,22 +83,12 @@ static void cell_progress(char *s, unsigned short hex) static int __init cell_publish_devices(void) { - int node; - if (!machine_is(cell)) return 0; /* Publish OF platform devices for southbridge IOs */ of_platform_bus_probe(NULL, NULL, NULL); - /* There is no device for the MIC memory controller, thus we create - * a platform device for it to attach the EDAC driver to. - */ - for_each_online_node(node) { - if (cbe_get_cpu_mic_tm_regs(cbe_node_to_cpu(node)) == NULL) - continue; - platform_device_register_simple("cbe-mic", node, NULL, 0); - } return 0; } device_initcall(cell_publish_devices); @@ -171,6 +161,11 @@ static void __init cell_setup_arch(void) /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; + if (ROOT_DEV == 0) { + printk("No ramdisk, default root is /dev/hda2\n"); + ROOT_DEV = Root_HDA2; + } + /* Find and initialize PCI host bridges */ init_pci_config_tokens(); find_and_init_phbs(); diff --git a/trunk/arch/powerpc/platforms/celleb/setup.c b/trunk/arch/powerpc/platforms/celleb/setup.c index 1769d755eff3..0f1dddb81cd2 100644 --- a/trunk/arch/powerpc/platforms/celleb/setup.c +++ b/trunk/arch/powerpc/platforms/celleb/setup.c @@ -101,6 +101,11 @@ static void __init celleb_setup_arch(void) /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; + if (ROOT_DEV == 0) { + printk("No ramdisk, default root is /dev/hda2\n"); + ROOT_DEV = Root_HDA2; + } + #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 59306261f5b2..96498ad7b943 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -290,6 +290,16 @@ void __init chrp_setup_arch(void) ppc_md.set_rtc_time = rtas_set_rtc_time; } +#ifdef CONFIG_BLK_DEV_INITRD + /* this is fine for chrp */ + initrd_below_start_ok = 1; + + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif + ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */ + /* On pegasos, enable the L2 cache if not already done by OF */ pegasos_set_l2cr(); diff --git a/trunk/arch/powerpc/platforms/iseries/Makefile b/trunk/arch/powerpc/platforms/iseries/Makefile index a65f1b44abf8..60db509638f1 100644 --- a/trunk/arch/powerpc/platforms/iseries/Makefile +++ b/trunk/arch/powerpc/platforms/iseries/Makefile @@ -7,7 +7,7 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ hvcall.o proc.o htab.o iommu.o misc.o irq.o obj-$(CONFIG_PCI) += pci.o vpdinfo.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_VIOPATH) += viopath.o vio.o +obj-$(CONFIG_VIOPATH) += viopath.o obj-$(CONFIG_MODULES) += ksyms.o quiet_cmd_dt_strings = DT_STR $@ diff --git a/trunk/arch/powerpc/platforms/iseries/dt.c b/trunk/arch/powerpc/platforms/iseries/dt.c index 4543c4bc3a56..9e8a334a518a 100644 --- a/trunk/arch/powerpc/platforms/iseries/dt.c +++ b/trunk/arch/powerpc/platforms/iseries/dt.c @@ -72,6 +72,8 @@ static char __initdata device_type_cpu[] = "cpu"; static char __initdata device_type_memory[] = "memory"; static char __initdata device_type_serial[] = "serial"; static char __initdata device_type_network[] = "network"; +static char __initdata device_type_block[] = "block"; +static char __initdata device_type_byte[] = "byte"; static char __initdata device_type_pci[] = "pci"; static char __initdata device_type_vdevice[] = "vdevice"; static char __initdata device_type_vscsi[] = "vscsi"; @@ -373,6 +375,21 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt) dt_end_node(dt); } + reg += HVMAXARCHITECTEDVIRTUALLANS; + + for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) + dt_do_vdevice(dt, "viodasd", reg, i, device_type_block, + "IBM,iSeries-viodasd", 1); + reg += HVMAXARCHITECTEDVIRTUALDISKS; + + for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) + dt_do_vdevice(dt, "viocd", reg, i, device_type_block, + "IBM,iSeries-viocd", 1); + reg += HVMAXARCHITECTEDVIRTUALCDROMS; + + for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) + dt_do_vdevice(dt, "viotape", reg, i, device_type_byte, + "IBM,iSeries-viotape", 1); dt_end_node(dt); } diff --git a/trunk/arch/powerpc/platforms/iseries/iommu.c b/trunk/arch/powerpc/platforms/iseries/iommu.c index 49e9c664ea89..3b6a9666c2c0 100644 --- a/trunk/arch/powerpc/platforms/iseries/iommu.c +++ b/trunk/arch/powerpc/platforms/iseries/iommu.c @@ -28,17 +28,14 @@ #include #include #include -#include #include -#include #include #include #include #include #include #include -#include #include static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, @@ -192,55 +189,6 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) } #endif -static struct iommu_table veth_iommu_table; -static struct iommu_table vio_iommu_table; - -void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag) -{ - return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle, - DMA_32BIT_MASK, flag, -1); -} -EXPORT_SYMBOL_GPL(iseries_hv_alloc); - -void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle) -{ - iommu_free_coherent(&vio_iommu_table, size, vaddr, dma_handle); -} -EXPORT_SYMBOL_GPL(iseries_hv_free); - -dma_addr_t iseries_hv_map(void *vaddr, size_t size, - enum dma_data_direction direction) -{ - return iommu_map_single(&vio_iommu_table, vaddr, size, - DMA_32BIT_MASK, direction); -} - -void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction) -{ - iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction); -} - -void __init iommu_vio_init(void) -{ - iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); - veth_iommu_table.it_size /= 2; - vio_iommu_table = veth_iommu_table; - vio_iommu_table.it_offset += veth_iommu_table.it_size; - - if (!iommu_init_table(&veth_iommu_table, -1)) - printk("Virtual Bus VETH TCE table failed.\n"); - if (!iommu_init_table(&vio_iommu_table, -1)) - printk("Virtual Bus VIO TCE table failed.\n"); -} - -struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev) -{ - if (strcmp(dev->type, "network") == 0) - return &veth_iommu_table; - return &vio_iommu_table; -} - void iommu_init_early_iSeries(void) { ppc_md.tce_build = tce_build_iSeries; diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index c0f2433bc16e..b1187d95e3b2 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -39,9 +39,9 @@ #include #include #include +#include #include #include -#include #include #include "setup.h" @@ -870,7 +870,8 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, if ((off + count) > 256) count = 256 - off; - dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE); + dma_addr = dma_map_single(iSeries_vio_dev, page, off + count, + DMA_FROM_DEVICE); if (dma_mapping_error(dma_addr)) return -ENOMEM; memset(page, 0, off + count); @@ -882,7 +883,8 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off, vsp_cmd.sub_data.kern.length = off + count; mb(); rc = signal_vsp_instruction(&vsp_cmd); - iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE); + dma_unmap_single(iSeries_vio_dev, dma_addr, off + count, + DMA_FROM_DEVICE); if (rc) return rc; if (vsp_cmd.result_code != 0) @@ -917,7 +919,8 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) int len = *size; dma_addr_t dma_addr; - dma_addr = iseries_hv_map(buffer, len, DMA_FROM_DEVICE); + dma_addr = dma_map_single(iSeries_vio_dev, buffer, len, + DMA_FROM_DEVICE); memset(buffer, 0, len); memset(&vsp_cmd, 0, sizeof(vsp_cmd)); vsp_cmd.cmd = 32; @@ -935,7 +938,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) rc = -ENOMEM; } - iseries_hv_unmap(dma_addr, len, DMA_FROM_DEVICE); + dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE); return rc; } @@ -1146,7 +1149,8 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, goto out; dma_addr = 0; - page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC); + page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr, + GFP_ATOMIC); ret = -ENOMEM; if (page == NULL) goto out; @@ -1166,7 +1170,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer, ret = count; out_free: - iseries_hv_free(count, page, dma_addr); + dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); out: return ret; } @@ -1186,7 +1190,8 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, goto out; dma_addr = 0; - page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC); + page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr, + GFP_ATOMIC); rc = -ENOMEM; if (page == NULL) { printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); @@ -1214,7 +1219,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, *ppos += count; rc = count; out_free: - iseries_hv_free(count, page, dma_addr); + dma_free_coherent(iSeries_vio_dev, count, page, dma_addr); out: return rc; } diff --git a/trunk/arch/powerpc/platforms/iseries/vio.c b/trunk/arch/powerpc/platforms/iseries/vio.c deleted file mode 100644 index 910b00b4703e..000000000000 --- a/trunk/arch/powerpc/platforms/iseries/vio.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * Legacy iSeries specific vio initialisation - * that needs to be built in (not a module). - * - * © Copyright 2007 IBM Corporation - * Author: Stephen Rothwell - * Some parts collected from various other files - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#define FIRST_VTY 0 -#define NUM_VTYS 1 -#define FIRST_VSCSI (FIRST_VTY + NUM_VTYS) -#define NUM_VSCSIS 1 -#define FIRST_VLAN (FIRST_VSCSI + NUM_VSCSIS) -#define NUM_VLANS HVMAXARCHITECTEDVIRTUALLANS -#define FIRST_VIODASD (FIRST_VLAN + NUM_VLANS) -#define NUM_VIODASDS HVMAXARCHITECTEDVIRTUALDISKS -#define FIRST_VIOCD (FIRST_VIODASD + NUM_VIODASDS) -#define NUM_VIOCDS HVMAXARCHITECTEDVIRTUALCDROMS -#define FIRST_VIOTAPE (FIRST_VIOCD + NUM_VIOCDS) -#define NUM_VIOTAPES HVMAXARCHITECTEDVIRTUALTAPES - -struct vio_waitevent { - struct completion com; - int rc; - u16 sub_result; -}; - -struct vio_resource { - char rsrcname[10]; - char type[4]; - char model[3]; -}; - -static struct property *new_property(const char *name, int length, - const void *value) -{ - struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length, - GFP_KERNEL); - - if (!np) - return NULL; - np->name = (char *)(np + 1); - np->value = np->name + strlen(name) + 1; - strcpy(np->name, name); - memcpy(np->value, value, length); - np->length = length; - return np; -} - -static void __init free_property(struct property *np) -{ - kfree(np); -} - -static struct device_node *new_node(const char *path, - struct device_node *parent) -{ - struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL); - - if (!np) - return NULL; - np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); - if (!np->full_name) { - kfree(np); - return NULL; - } - strcpy(np->full_name, path); - of_node_set_flag(np, OF_DYNAMIC); - kref_init(&np->kref); - np->parent = of_node_get(parent); - return np; -} - -static void free_node(struct device_node *np) -{ - struct property *next; - struct property *prop; - - next = np->properties; - while (next) { - prop = next; - next = prop->next; - free_property(prop); - } - of_node_put(np->parent); - kfree(np->full_name); - kfree(np); -} - -static int add_string_property(struct device_node *np, const char *name, - const char *value) -{ - struct property *nprop = new_property(name, strlen(value) + 1, value); - - if (!nprop) - return 0; - prom_add_property(np, nprop); - return 1; -} - -static int add_raw_property(struct device_node *np, const char *name, - int length, const void *value) -{ - struct property *nprop = new_property(name, length, value); - - if (!nprop) - return 0; - prom_add_property(np, nprop); - return 1; -} - -static struct device_node *do_device_node(struct device_node *parent, - const char *name, u32 reg, u32 unit, const char *type, - const char *compat, struct vio_resource *res) -{ - struct device_node *np; - char path[32]; - - snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg); - np = new_node(path, parent); - if (!np) - return NULL; - if (!add_string_property(np, "name", name) || - !add_string_property(np, "device_type", type) || - !add_string_property(np, "compatible", compat) || - !add_raw_property(np, "reg", sizeof(reg), ®) || - !add_raw_property(np, "linux,unit_address", - sizeof(unit), &unit)) { - goto node_free; - } - if (res) { - if (!add_raw_property(np, "linux,vio_rsrcname", - sizeof(res->rsrcname), res->rsrcname) || - !add_raw_property(np, "linux,vio_type", - sizeof(res->type), res->type) || - !add_raw_property(np, "linux,vio_model", - sizeof(res->model), res->model)) - goto node_free; - } - np->name = of_get_property(np, "name", NULL); - np->type = of_get_property(np, "device_type", NULL); - of_attach_node(np); -#ifdef CONFIG_PROC_DEVICETREE - if (parent->pde) { - struct proc_dir_entry *ent; - - ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde); - if (ent) - proc_device_tree_add_node(np, ent); - } -#endif - return np; - - node_free: - free_node(np); - return NULL; -} - -/* - * This is here so that we can dynamically add viodasd - * devices without exposing all the above infrastructure. - */ -struct vio_dev *vio_create_viodasd(u32 unit) -{ - struct device_node *vio_root; - struct device_node *np; - struct vio_dev *vdev = NULL; - - vio_root = of_find_node_by_path("/vdevice"); - if (!vio_root) - return NULL; - np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit, - "block", "IBM,iSeries-viodasd", NULL); - of_node_put(vio_root); - if (np) { - vdev = vio_register_device_node(np); - if (!vdev) - free_node(np); - } - return vdev; -} -EXPORT_SYMBOL_GPL(vio_create_viodasd); - -static void __init handle_block_event(struct HvLpEvent *event) -{ - struct vioblocklpevent *bevent = (struct vioblocklpevent *)event; - struct vio_waitevent *pwe; - - if (event == NULL) - /* Notification that a partition went away! */ - return; - /* First, we should NEVER get an int here...only acks */ - if (hvlpevent_is_int(event)) { - printk(KERN_WARNING "handle_viod_request: " - "Yikes! got an int in viodasd event handler!\n"); - if (hvlpevent_need_ack(event)) { - event->xRc = HvLpEvent_Rc_InvalidSubtype; - HvCallEvent_ackLpEvent(event); - } - return; - } - - switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) { - case vioblockopen: - /* - * Handle a response to an open request. We get all the - * disk information in the response, so update it. The - * correlation token contains a pointer to a waitevent - * structure that has a completion in it. update the - * return code in the waitevent structure and post the - * completion to wake up the guy who sent the request - */ - pwe = (struct vio_waitevent *)event->xCorrelationToken; - pwe->rc = event->xRc; - pwe->sub_result = bevent->sub_result; - complete(&pwe->com); - break; - case vioblockclose: - break; - default: - printk(KERN_WARNING "handle_viod_request: unexpected subtype!"); - if (hvlpevent_need_ack(event)) { - event->xRc = HvLpEvent_Rc_InvalidSubtype; - HvCallEvent_ackLpEvent(event); - } - } -} - -static void __init probe_disk(struct device_node *vio_root, u32 unit) -{ - HvLpEvent_Rc hvrc; - struct vio_waitevent we; - u16 flags = 0; - -retry: - init_completion(&we.com); - - /* Send the open event to OS/400 */ - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_blockio | vioblockopen, - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - (u64)(unsigned long)&we, VIOVERSION << 16, - ((u64)unit << 48) | ((u64)flags<< 32), - 0, 0, 0); - if (hvrc != 0) { - printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n", - (int)hvrc); - return; - } - - wait_for_completion(&we.com); - - if (we.rc != 0) { - if (flags != 0) - return; - /* try again with read only flag set */ - flags = vioblockflags_ro; - goto retry; - } - - /* Send the close event to OS/400. We DON'T expect a response */ - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_blockio | vioblockclose, - HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - 0, VIOVERSION << 16, - ((u64)unit << 48) | ((u64)flags << 32), - 0, 0, 0); - if (hvrc != 0) { - printk(KERN_WARNING "probe_disk: " - "bad rc sending event to OS/400 %d\n", (int)hvrc); - return; - } - - do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit, - "block", "IBM,iSeries-viodasd", NULL); -} - -static void __init get_viodasd_info(struct device_node *vio_root) -{ - int rc; - u32 unit; - - rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2); - if (rc) { - printk(KERN_WARNING "get_viodasd_info: " - "error opening path to host partition %d\n", - viopath_hostLp); - return; - } - - /* Initialize our request handler */ - vio_setHandler(viomajorsubtype_blockio, handle_block_event); - - for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++) - probe_disk(vio_root, unit); - - vio_clearHandler(viomajorsubtype_blockio); - viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2); -} - -static void __init handle_cd_event(struct HvLpEvent *event) -{ - struct viocdlpevent *bevent; - struct vio_waitevent *pwe; - - if (!event) - /* Notification that a partition went away! */ - return; - - /* First, we should NEVER get an int here...only acks */ - if (hvlpevent_is_int(event)) { - printk(KERN_WARNING "handle_cd_event: got an unexpected int\n"); - if (hvlpevent_need_ack(event)) { - event->xRc = HvLpEvent_Rc_InvalidSubtype; - HvCallEvent_ackLpEvent(event); - } - return; - } - - bevent = (struct viocdlpevent *)event; - - switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) { - case viocdgetinfo: - pwe = (struct vio_waitevent *)event->xCorrelationToken; - pwe->rc = event->xRc; - pwe->sub_result = bevent->sub_result; - complete(&pwe->com); - break; - - default: - printk(KERN_WARNING "handle_cd_event: " - "message with unexpected subtype %0x04X!\n", - event->xSubtype & VIOMINOR_SUBTYPE_MASK); - if (hvlpevent_need_ack(event)) { - event->xRc = HvLpEvent_Rc_InvalidSubtype; - HvCallEvent_ackLpEvent(event); - } - } -} - -static void __init get_viocd_info(struct device_node *vio_root) -{ - HvLpEvent_Rc hvrc; - u32 unit; - struct vio_waitevent we; - struct vio_resource *unitinfo; - dma_addr_t unitinfo_dmaaddr; - int ret; - - ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2); - if (ret) { - printk(KERN_WARNING - "get_viocd_info: error opening path to host partition %d\n", - viopath_hostLp); - return; - } - - /* Initialize our request handler */ - vio_setHandler(viomajorsubtype_cdio, handle_cd_event); - - unitinfo = iseries_hv_alloc( - sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, - &unitinfo_dmaaddr, GFP_ATOMIC); - if (!unitinfo) { - printk(KERN_WARNING - "get_viocd_info: error allocating unitinfo\n"); - goto clear_handler; - } - - memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS); - - init_completion(&we.com); - - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_cdio | viocdgetinfo, - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, - sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0); - if (hvrc != HvLpEvent_Rc_Good) { - printk(KERN_WARNING - "get_viocd_info: cdrom error sending event. rc %d\n", - (int)hvrc); - goto hv_free; - } - - wait_for_completion(&we.com); - - if (we.rc) { - printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n", - we.rc, we.sub_result); - goto hv_free; - } - - for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) && - unitinfo[unit].rsrcname[0]; unit++) { - if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit, - "block", "IBM,iSeries-viocd", &unitinfo[unit])) - break; - } - - hv_free: - iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, - unitinfo, unitinfo_dmaaddr); - clear_handler: - vio_clearHandler(viomajorsubtype_cdio); - viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2); -} - -/* Handle interrupt events for tape */ -static void __init handle_tape_event(struct HvLpEvent *event) -{ - struct vio_waitevent *we; - struct viotapelpevent *tevent = (struct viotapelpevent *)event; - - if (event == NULL) - /* Notification that a partition went away! */ - return; - - we = (struct vio_waitevent *)event->xCorrelationToken; - switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) { - case viotapegetinfo: - we->rc = tevent->sub_type_result; - complete(&we->com); - break; - default: - printk(KERN_WARNING "handle_tape_event: weird ack\n"); - } -} - -static void __init get_viotape_info(struct device_node *vio_root) -{ - HvLpEvent_Rc hvrc; - u32 unit; - struct vio_resource *unitinfo; - dma_addr_t unitinfo_dmaaddr; - size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES; - struct vio_waitevent we; - int ret; - - ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2); - if (ret) { - printk(KERN_WARNING "get_viotape_info: " - "error on viopath_open to hostlp %d\n", ret); - return; - } - - vio_setHandler(viomajorsubtype_tape, handle_tape_event); - - unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC); - if (!unitinfo) - goto clear_handler; - - memset(unitinfo, 0, len); - - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_tape | viotapegetinfo, - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - (u64)(unsigned long)&we, VIOVERSION << 16, - unitinfo_dmaaddr, len, 0, 0); - if (hvrc != HvLpEvent_Rc_Good) { - printk(KERN_WARNING "get_viotape_info: hv error on op %d\n", - (int)hvrc); - goto hv_free; - } - - wait_for_completion(&we.com); - - for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) && - unitinfo[unit].rsrcname[0]; unit++) { - if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit, - unit, "byte", "IBM,iSeries-viotape", - &unitinfo[unit])) - break; - } - - hv_free: - iseries_hv_free(len, unitinfo, unitinfo_dmaaddr); - clear_handler: - vio_clearHandler(viomajorsubtype_tape); - viopath_close(viopath_hostLp, viomajorsubtype_tape, 2); -} - -static int __init iseries_vio_init(void) -{ - struct device_node *vio_root; - - if (!firmware_has_feature(FW_FEATURE_ISERIES)) - return -ENODEV; - - iommu_vio_init(); - - vio_root = of_find_node_by_path("/vdevice"); - if (!vio_root) - return -ENODEV; - - if (viopath_hostLp == HvLpIndexInvalid) { - vio_set_hostlp(); - /* If we don't have a host, bail out */ - if (viopath_hostLp == HvLpIndexInvalid) - goto put_node; - } - - get_viodasd_info(vio_root); - get_viocd_info(vio_root); - get_viotape_info(vio_root); - - return 0; - - put_node: - of_node_put(vio_root); - return -ENODEV; -} -arch_initcall(iseries_vio_init); diff --git a/trunk/arch/powerpc/platforms/iseries/viopath.c b/trunk/arch/powerpc/platforms/iseries/viopath.c index df23331eb25c..6a0060a5f2ec 100644 --- a/trunk/arch/powerpc/platforms/iseries/viopath.c +++ b/trunk/arch/powerpc/platforms/iseries/viopath.c @@ -124,7 +124,8 @@ static int proc_viopath_show(struct seq_file *m, void *v) if (!buf) return 0; - handle = iseries_hv_map(buf, HW_PAGE_SIZE, DMA_FROM_DEVICE); + handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE, + DMA_FROM_DEVICE); hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, @@ -145,7 +146,8 @@ static int proc_viopath_show(struct seq_file *m, void *v) buf[HW_PAGE_SIZE-1] = '\0'; seq_printf(m, "%s", buf); - iseries_hv_unmap(handle, HW_PAGE_SIZE, DMA_FROM_DEVICE); + dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE, + DMA_FROM_DEVICE); kfree(buf); seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap); @@ -594,7 +596,7 @@ int viopath_close(HvLpIndex remoteLp, int subtype, int numReq) numOpen += viopathStatus[remoteLp].users[i]; if ((viopathStatus[remoteLp].isOpen) && (numOpen == 0)) { - printk(VIOPATH_KERN_INFO "closing connection to partition %d\n", + printk(VIOPATH_KERN_INFO "closing connection to partition %d", remoteLp); HvCallEvent_closeLpEventPath(remoteLp, diff --git a/trunk/arch/powerpc/platforms/pasemi/gpio_mdio.c b/trunk/arch/powerpc/platforms/pasemi/gpio_mdio.c index dae9f658122e..c91a33593bb8 100644 --- a/trunk/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/trunk/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -320,12 +320,10 @@ static struct of_device_id gpio_mdio_match[] = static struct of_platform_driver gpio_mdio_driver = { + .name = "gpio-mdio-bitbang", .match_table = gpio_mdio_match, .probe = gpio_mdio_probe, .remove = gpio_mdio_remove, - .driver = { - .name = "gpio-mdio-bitbang", - }, }; int gpio_mdio_init(void) diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 02c533096627..7ccb9236e8b4 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -387,13 +387,69 @@ static void __init pmac_setup_arch(void) #endif /* CONFIG_ADB */ } +char *bootpath; +char *bootdevice; +void *boot_host; +int boot_target; +int boot_part; +static dev_t boot_dev; + #ifdef CONFIG_SCSI void note_scsi_host(struct device_node *node, void *host) { + int l; + char *p; + + l = strlen(node->full_name); + if (bootpath != NULL && bootdevice != NULL + && strncmp(node->full_name, bootdevice, l) == 0 + && (bootdevice[l] == '/' || bootdevice[l] == 0)) { + boot_host = host; + /* + * There's a bug in OF 1.0.5. (Why am I not surprised.) + * If you pass a path like scsi/sd@1:0 to canon, it returns + * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 + * That is, the scsi target number doesn't get preserved. + * So we pick the target number out of bootpath and use that. + */ + p = strstr(bootpath, "/sd@"); + if (p != NULL) { + p += 4; + boot_target = simple_strtoul(p, NULL, 10); + p = strchr(p, ':'); + if (p != NULL) + boot_part = simple_strtoul(p + 1, NULL, 10); + } + } } EXPORT_SYMBOL(note_scsi_host); #endif +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) +static dev_t __init find_ide_boot(void) +{ + char *p; + int n; + dev_t __init pmac_find_ide_boot(char *bootdevice, int n); + + if (bootdevice == NULL) + return 0; + p = strrchr(bootdevice, '/'); + if (p == NULL) + return 0; + n = p - bootdevice; + + return pmac_find_ide_boot(bootdevice, n); +} +#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ + +static void __init find_boot_device(void) +{ +#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) + boot_dev = find_ide_boot(); +#endif +} + static int initializing = 1; static int pmac_late_init(void) @@ -410,14 +466,10 @@ static int pmac_late_init(void) late_initcall(pmac_late_init); -/* - * This is __init_refok because we check for "initializing" before - * touching any of the __init sensitive things and "initializing" - * will be false after __init time. This can't be __init because it - * can be called whenever a disk is first accessed. - */ -void __init_refok note_bootable_part(dev_t dev, int part, int goodness) +/* can't be __init - can be called whenever a disk is first accessed */ +void note_bootable_part(dev_t dev, int part, int goodness) { + static int found_boot = 0; char *p; if (!initializing) @@ -429,8 +481,15 @@ void __init_refok note_bootable_part(dev_t dev, int part, int goodness) if (p != NULL && (p == boot_command_line || p[-1] == ' ')) return; - ROOT_DEV = dev + part; - current_root_goodness = goodness; + if (!found_boot) { + find_boot_device(); + found_boot = 1; + } + if (!boot_dev || dev == boot_dev) { + ROOT_DEV = dev + part; + boot_dev = 0; + current_root_goodness = goodness; + } } #ifdef CONFIG_ADB_CUDA diff --git a/trunk/arch/powerpc/platforms/ps3/os-area.c b/trunk/arch/powerpc/platforms/ps3/os-area.c index 766685ab26f8..b70e474014f0 100644 --- a/trunk/arch/powerpc/platforms/ps3/os-area.c +++ b/trunk/arch/powerpc/platforms/ps3/os-area.c @@ -1,5 +1,5 @@ /* - * PS3 flash memory os area. + * PS3 'Other OS' area data. * * Copyright (C) 2006 Sony Computer Entertainment Inc. * Copyright 2006 Sony Corp. @@ -20,9 +20,6 @@ #include #include -#include -#include -#include #include @@ -32,7 +29,7 @@ enum { OS_AREA_SEGMENT_SIZE = 0X200, }; -enum os_area_ldr_format { +enum { HEADER_LDR_FORMAT_RAW = 0, HEADER_LDR_FORMAT_GZIP = 1, }; @@ -41,7 +38,7 @@ enum os_area_ldr_format { * struct os_area_header - os area header segment. * @magic_num: Always 'cell_ext_os_area'. * @hdr_version: Header format version number. - * @db_area_offset: Starting segment number of other os database area. + * @os_area_offset: Starting segment number of os image area. * @ldr_area_offset: Starting segment number of bootloader image area. * @ldr_format: HEADER_LDR_FORMAT flag. * @ldr_size: Size of bootloader image in bytes. @@ -53,9 +50,9 @@ enum os_area_ldr_format { */ struct os_area_header { - u8 magic_num[16]; + s8 magic_num[16]; u32 hdr_version; - u32 db_area_offset; + u32 os_area_offset; u32 ldr_area_offset; u32 _reserved_1; u32 ldr_format; @@ -63,12 +60,12 @@ struct os_area_header { u32 _reserved_2[6]; }; -enum os_area_boot_flag { +enum { PARAM_BOOT_FLAG_GAME_OS = 0, PARAM_BOOT_FLAG_OTHER_OS = 1, }; -enum os_area_ctrl_button { +enum { PARAM_CTRL_BUTTON_O_IS_YES = 0, PARAM_CTRL_BUTTON_X_IS_YES = 1, }; @@ -87,9 +84,6 @@ enum os_area_ctrl_button { * @dns_primary: User preference of static primary dns server. * @dns_secondary: User preference of static secondary dns server. * - * The ps3 rtc maintains a read-only value that approximates seconds since - * 2000-01-01 00:00:00 UTC. - * * User preference of zero for static_ip_addr means use dhcp. */ @@ -114,172 +108,45 @@ struct os_area_params { u8 _reserved_5[8]; }; -enum { - OS_AREA_DB_MAGIC_NUM = 0x2d64622dU, -}; - -/** - * struct os_area_db - Shared flash memory database. - * @magic_num: Always '-db-' = 0x2d64622d. - * @version: os_area_db format version number. - * @index_64: byte offset of the database id index for 64 bit variables. - * @count_64: number of usable 64 bit index entries - * @index_32: byte offset of the database id index for 32 bit variables. - * @count_32: number of usable 32 bit index entries - * @index_16: byte offset of the database id index for 16 bit variables. - * @count_16: number of usable 16 bit index entries - * - * Flash rom storage for exclusive use by guests running in the other os lpar. - * The current system configuration allocates 1K (two segments) for other os - * use. - */ - -struct os_area_db { - u32 magic_num; - u16 version; - u16 _reserved_1; - u16 index_64; - u16 count_64; - u16 index_32; - u16 count_32; - u16 index_16; - u16 count_16; - u32 _reserved_2; - u8 _db_data[1000]; -}; - -/** - * enum os_area_db_owner - Data owners. - */ - -enum os_area_db_owner { - OS_AREA_DB_OWNER_ANY = -1, - OS_AREA_DB_OWNER_NONE = 0, - OS_AREA_DB_OWNER_PROTOTYPE = 1, - OS_AREA_DB_OWNER_LINUX = 2, - OS_AREA_DB_OWNER_PETITBOOT = 3, - OS_AREA_DB_OWNER_MAX = 32, -}; - -enum os_area_db_key { - OS_AREA_DB_KEY_ANY = -1, - OS_AREA_DB_KEY_NONE = 0, - OS_AREA_DB_KEY_RTC_DIFF = 1, - OS_AREA_DB_KEY_VIDEO_MODE = 2, - OS_AREA_DB_KEY_MAX = 8, -}; - -struct os_area_db_id { - int owner; - int key; -}; - -static const struct os_area_db_id os_area_db_id_empty = { - .owner = OS_AREA_DB_OWNER_NONE, - .key = OS_AREA_DB_KEY_NONE -}; - -static const struct os_area_db_id os_area_db_id_any = { - .owner = OS_AREA_DB_OWNER_ANY, - .key = OS_AREA_DB_KEY_ANY -}; - -static const struct os_area_db_id os_area_db_id_rtc_diff = { - .owner = OS_AREA_DB_OWNER_LINUX, - .key = OS_AREA_DB_KEY_RTC_DIFF -}; - -static const struct os_area_db_id os_area_db_id_video_mode = { - .owner = OS_AREA_DB_OWNER_LINUX, - .key = OS_AREA_DB_KEY_VIDEO_MODE -}; - -#define SECONDS_FROM_1970_TO_2000 946684800LL - /** - * struct saved_params - Static working copies of data from the PS3 'os area'. + * struct saved_params - Static working copies of data from the 'Other OS' area. * - * The order of preference we use for the rtc_diff source: - * 1) The database value. - * 2) The game os value. - * 3) The number of seconds from 1970 to 2000. + * For the convinience of the guest, the HV makes a copy of the 'Other OS' area + * in flash to a high address in the boot memory region and then puts that RAM + * address and the byte count into the repository for retreval by the guest. + * We copy the data we want into a static variable and allow the memory setup + * by the HV to be claimed by the lmb manager. */ struct saved_params { - unsigned int valid; + /* param 0 */ s64 rtc_diff; unsigned int av_multi_out; + unsigned int ctrl_button; + /* param 1 */ + u8 static_ip_addr[4]; + u8 network_mask[4]; + u8 default_gateway[4]; + /* param 2 */ + u8 dns_primary[4]; + u8 dns_secondary[4]; } static saved_params; -static struct property property_rtc_diff = { - .name = "linux,rtc_diff", - .length = sizeof(saved_params.rtc_diff), - .value = &saved_params.rtc_diff, -}; - -static struct property property_av_multi_out = { - .name = "linux,av_multi_out", - .length = sizeof(saved_params.av_multi_out), - .value = &saved_params.av_multi_out, -}; - -/** - * os_area_set_property - Add or overwrite a saved_params value to the device tree. - * - * Overwrites an existing property. - */ - -static void os_area_set_property(struct device_node *node, - struct property *prop) -{ - int result; - struct property *tmp = of_find_property(node, prop->name, NULL); - - if (tmp) { - pr_debug("%s:%d found %s\n", __func__, __LINE__, prop->name); - prom_remove_property(node, tmp); - } - - result = prom_add_property(node, prop); - - if (result) - pr_debug("%s:%d prom_set_property failed\n", __func__, - __LINE__); -} - -/** - * os_area_get_property - Get a saved_params value from the device tree. - * - */ - -static void __init os_area_get_property(struct device_node *node, - struct property *prop) -{ - const struct property *tmp = of_find_property(node, prop->name, NULL); - - if (tmp) { - BUG_ON(prop->length != tmp->length); - memcpy(prop->value, tmp->value, prop->length); - } else - pr_debug("%s:%d not found %s\n", __func__, __LINE__, - prop->name); -} - #define dump_header(_a) _dump_header(_a, __func__, __LINE__) static void _dump_header(const struct os_area_header *h, const char *func, int line) { - pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, + pr_debug("%s:%d: h.magic_num: '%s'\n", func, line, h->magic_num); - pr_debug("%s:%d: h.hdr_version: %u\n", func, line, + pr_debug("%s:%d: h.hdr_version: %u\n", func, line, h->hdr_version); - pr_debug("%s:%d: h.db_area_offset: %u\n", func, line, - h->db_area_offset); + pr_debug("%s:%d: h.os_area_offset: %u\n", func, line, + h->os_area_offset); pr_debug("%s:%d: h.ldr_area_offset: %u\n", func, line, h->ldr_area_offset); - pr_debug("%s:%d: h.ldr_format: %u\n", func, line, + pr_debug("%s:%d: h.ldr_format: %u\n", func, line, h->ldr_format); - pr_debug("%s:%d: h.ldr_size: %xh\n", func, line, + pr_debug("%s:%d: h.ldr_size: %xh\n", func, line, h->ldr_size); } @@ -309,7 +176,7 @@ static void _dump_params(const struct os_area_params *p, const char *func, p->dns_secondary[2], p->dns_secondary[3]); } -static int verify_header(const struct os_area_header *header) +static int __init verify_header(const struct os_area_header *header) { if (memcmp(header->magic_num, "cell_ext_os_area", 16)) { pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); @@ -321,7 +188,7 @@ static int verify_header(const struct os_area_header *header) return -1; } - if (header->db_area_offset > header->ldr_area_offset) { + if (header->os_area_offset > header->ldr_area_offset) { pr_debug("%s:%d offsets failed\n", __func__, __LINE__); return -1; } @@ -329,477 +196,58 @@ static int verify_header(const struct os_area_header *header) return 0; } -static int db_verify(const struct os_area_db *db) -{ - if (db->magic_num != OS_AREA_DB_MAGIC_NUM) { - pr_debug("%s:%d magic_num failed\n", __func__, __LINE__); - return -1; - } - - if (db->version != 1) { - pr_debug("%s:%d version failed\n", __func__, __LINE__); - return -1; - } - - return 0; -} - -struct db_index { - uint8_t owner:5; - uint8_t key:3; -}; - -struct db_iterator { - const struct os_area_db *db; - struct os_area_db_id match_id; - struct db_index *idx; - struct db_index *last_idx; - union { - uint64_t *value_64; - uint32_t *value_32; - uint16_t *value_16; - }; -}; - -static unsigned int db_align_up(unsigned int val, unsigned int size) -{ - return (val + (size - 1)) & (~(size - 1)); -} - -/** - * db_for_each_64 - Iterator for 64 bit entries. - * - * A NULL value for id can be used to match all entries. - * OS_AREA_DB_OWNER_ANY and OS_AREA_DB_KEY_ANY can be used to match all. - */ - -static int db_for_each_64(const struct os_area_db *db, - const struct os_area_db_id *match_id, struct db_iterator *i) -{ -next: - if (!i->db) { - i->db = db; - i->match_id = match_id ? *match_id : os_area_db_id_any; - i->idx = (void *)db + db->index_64; - i->last_idx = i->idx + db->count_64; - i->value_64 = (void *)db + db->index_64 - + db_align_up(db->count_64, 8); - } else { - i->idx++; - i->value_64++; - } - - if (i->idx >= i->last_idx) { - pr_debug("%s:%d: reached end\n", __func__, __LINE__); - return 0; - } - - if (i->match_id.owner != OS_AREA_DB_OWNER_ANY - && i->match_id.owner != (int)i->idx->owner) - goto next; - if (i->match_id.key != OS_AREA_DB_KEY_ANY - && i->match_id.key != (int)i->idx->key) - goto next; - - return 1; -} - -static int db_delete_64(struct os_area_db *db, const struct os_area_db_id *id) -{ - struct db_iterator i; - - for (i.db = NULL; db_for_each_64(db, id, &i); ) { - - pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__, - i.idx->owner, i.idx->key, - (unsigned long long)*i.value_64); - - i.idx->owner = 0; - i.idx->key = 0; - *i.value_64 = 0; - } - return 0; -} - -static int db_set_64(struct os_area_db *db, const struct os_area_db_id *id, - uint64_t value) -{ - struct db_iterator i; - - pr_debug("%s:%d: (%d:%d) <= %llxh\n", __func__, __LINE__, - id->owner, id->key, (unsigned long long)value); - - if (!id->owner || id->owner == OS_AREA_DB_OWNER_ANY - || id->key == OS_AREA_DB_KEY_ANY) { - pr_debug("%s:%d: bad id: (%d:%d)\n", __func__, - __LINE__, id->owner, id->key); - return -1; - } - - db_delete_64(db, id); - - i.db = NULL; - if (db_for_each_64(db, &os_area_db_id_empty, &i)) { - - pr_debug("%s:%d: got (%d:%d) %llxh\n", __func__, __LINE__, - i.idx->owner, i.idx->key, - (unsigned long long)*i.value_64); - - i.idx->owner = id->owner; - i.idx->key = id->key; - *i.value_64 = value; - - pr_debug("%s:%d: set (%d:%d) <= %llxh\n", __func__, __LINE__, - i.idx->owner, i.idx->key, - (unsigned long long)*i.value_64); - return 0; - } - pr_debug("%s:%d: database full.\n", - __func__, __LINE__); - return -1; -} - -static int db_get_64(const struct os_area_db *db, - const struct os_area_db_id *id, uint64_t *value) -{ - struct db_iterator i; - - i.db = NULL; - if (db_for_each_64(db, id, &i)) { - *value = *i.value_64; - pr_debug("%s:%d: found %lld\n", __func__, __LINE__, - (long long int)*i.value_64); - return 0; - } - pr_debug("%s:%d: not found\n", __func__, __LINE__); - return -1; -} - -static int db_get_rtc_diff(const struct os_area_db *db, int64_t *rtc_diff) -{ - return db_get_64(db, &os_area_db_id_rtc_diff, (uint64_t*)rtc_diff); -} - -#define dump_db(a) _dump_db(a, __func__, __LINE__) -static void _dump_db(const struct os_area_db *db, const char *func, - int line) -{ - pr_debug("%s:%d: db.magic_num: '%s'\n", func, line, - (const char*)&db->magic_num); - pr_debug("%s:%d: db.version: %u\n", func, line, - db->version); - pr_debug("%s:%d: db.index_64: %u\n", func, line, - db->index_64); - pr_debug("%s:%d: db.count_64: %u\n", func, line, - db->count_64); - pr_debug("%s:%d: db.index_32: %u\n", func, line, - db->index_32); - pr_debug("%s:%d: db.count_32: %u\n", func, line, - db->count_32); - pr_debug("%s:%d: db.index_16: %u\n", func, line, - db->index_16); - pr_debug("%s:%d: db.count_16: %u\n", func, line, - db->count_16); -} - -static void os_area_db_init(struct os_area_db *db) -{ - enum { - HEADER_SIZE = offsetof(struct os_area_db, _db_data), - INDEX_64_COUNT = 64, - VALUES_64_COUNT = 57, - INDEX_32_COUNT = 64, - VALUES_32_COUNT = 57, - INDEX_16_COUNT = 64, - VALUES_16_COUNT = 57, - }; - - memset(db, 0, sizeof(struct os_area_db)); - - db->magic_num = OS_AREA_DB_MAGIC_NUM; - db->version = 1; - db->index_64 = HEADER_SIZE; - db->count_64 = VALUES_64_COUNT; - db->index_32 = HEADER_SIZE - + INDEX_64_COUNT * sizeof(struct db_index) - + VALUES_64_COUNT * sizeof(u64); - db->count_32 = VALUES_32_COUNT; - db->index_16 = HEADER_SIZE - + INDEX_64_COUNT * sizeof(struct db_index) - + VALUES_64_COUNT * sizeof(u64) - + INDEX_32_COUNT * sizeof(struct db_index) - + VALUES_32_COUNT * sizeof(u32); - db->count_16 = VALUES_16_COUNT; - - /* Rules to check db layout. */ - - BUILD_BUG_ON(sizeof(struct db_index) != 1); - BUILD_BUG_ON(sizeof(struct os_area_db) != 2 * OS_AREA_SEGMENT_SIZE); - BUILD_BUG_ON(INDEX_64_COUNT & 0x7); - BUILD_BUG_ON(VALUES_64_COUNT > INDEX_64_COUNT); - BUILD_BUG_ON(INDEX_32_COUNT & 0x7); - BUILD_BUG_ON(VALUES_32_COUNT > INDEX_32_COUNT); - BUILD_BUG_ON(INDEX_16_COUNT & 0x7); - BUILD_BUG_ON(VALUES_16_COUNT > INDEX_16_COUNT); - BUILD_BUG_ON(HEADER_SIZE - + INDEX_64_COUNT * sizeof(struct db_index) - + VALUES_64_COUNT * sizeof(u64) - + INDEX_32_COUNT * sizeof(struct db_index) - + VALUES_32_COUNT * sizeof(u32) - + INDEX_16_COUNT * sizeof(struct db_index) - + VALUES_16_COUNT * sizeof(u16) - > sizeof(struct os_area_db)); -} - -/** - * update_flash_db - Helper for os_area_queue_work_handler. - * - */ - -static void update_flash_db(void) -{ - int result; - int file; - off_t offset; - ssize_t count; - static const unsigned int buf_len = 8 * OS_AREA_SEGMENT_SIZE; - const struct os_area_header *header; - struct os_area_db* db; - - /* Read in header and db from flash. */ - - file = sys_open("/dev/ps3flash", O_RDWR, 0); - - if (file < 0) { - pr_debug("%s:%d sys_open failed\n", __func__, __LINE__); - goto fail_open; - } - - header = kmalloc(buf_len, GFP_KERNEL); - - if (!header) { - pr_debug("%s:%d kmalloc failed\n", __func__, __LINE__); - goto fail_malloc; - } - - offset = sys_lseek(file, 0, SEEK_SET); - - if (offset != 0) { - pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__); - goto fail_header_seek; - } - - count = sys_read(file, (char __user *)header, buf_len); - - result = count < OS_AREA_SEGMENT_SIZE || verify_header(header) - || count < header->db_area_offset * OS_AREA_SEGMENT_SIZE; - - if (result) { - pr_debug("%s:%d verify_header failed\n", __func__, __LINE__); - dump_header(header); - goto fail_header; - } - - /* Now got a good db offset and some maybe good db data. */ - - db = (void*)header + header->db_area_offset * OS_AREA_SEGMENT_SIZE; - - result = db_verify(db); - - if (result) { - printk(KERN_NOTICE "%s:%d: Verify of flash database failed, " - "formatting.\n", __func__, __LINE__); - dump_db(db); - os_area_db_init(db); - } - - /* Now got good db data. */ - - db_set_64(db, &os_area_db_id_rtc_diff, saved_params.rtc_diff); - - offset = sys_lseek(file, header->db_area_offset * OS_AREA_SEGMENT_SIZE, - SEEK_SET); - - if (offset != header->db_area_offset * OS_AREA_SEGMENT_SIZE) { - pr_debug("%s:%d sys_lseek failed\n", __func__, __LINE__); - goto fail_db_seek; - } - - count = sys_write(file, (const char __user *)db, - sizeof(struct os_area_db)); - - if (count < sizeof(struct os_area_db)) { - pr_debug("%s:%d sys_write failed\n", __func__, __LINE__); - } - -fail_db_seek: -fail_header: -fail_header_seek: - kfree(header); -fail_malloc: - sys_close(file); -fail_open: - return; -} - -/** - * os_area_queue_work_handler - Asynchronous write handler. - * - * An asynchronous write for flash memory and the device tree. Do not - * call directly, use os_area_queue_work(). - */ - -static void os_area_queue_work_handler(struct work_struct *work) -{ - struct device_node *node; - - pr_debug(" -> %s:%d\n", __func__, __LINE__); - - node = of_find_node_by_path("/"); - - if (node) { - os_area_set_property(node, &property_rtc_diff); - of_node_put(node); - } else - pr_debug("%s:%d of_find_node_by_path failed\n", - __func__, __LINE__); - -#if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) - update_flash_db(); -#else - printk(KERN_WARNING "%s:%d: No flash rom driver configured.\n", - __func__, __LINE__); -#endif - pr_debug(" <- %s:%d\n", __func__, __LINE__); -} - -static void os_area_queue_work(void) -{ - static DECLARE_WORK(q, os_area_queue_work_handler); - - wmb(); - schedule_work(&q); -} - -/** - * ps3_os_area_save_params - Copy data from os area mirror to @saved_params. - * - * For the convenience of the guest the HV makes a copy of the os area in - * flash to a high address in the boot memory region and then puts that RAM - * address and the byte count into the repository for retrieval by the guest. - * We copy the data we want into a static variable and allow the memory setup - * by the HV to be claimed by the lmb manager. - * - * The os area mirror will not be available to a second stage kernel, and - * the header verify will fail. In this case, the saved_params values will - * be set from flash memory or the passed in device tree in ps3_os_area_init(). - */ - -void __init ps3_os_area_save_params(void) +int __init ps3_os_area_init(void) { int result; u64 lpar_addr; unsigned int size; struct os_area_header *header; struct os_area_params *params; - struct os_area_db *db; - - pr_debug(" -> %s:%d\n", __func__, __LINE__); result = ps3_repository_read_boot_dat_info(&lpar_addr, &size); if (result) { pr_debug("%s:%d ps3_repository_read_boot_dat_info failed\n", __func__, __LINE__); - return; + return result; } header = (struct os_area_header *)__va(lpar_addr); - params = (struct os_area_params *)__va(lpar_addr - + OS_AREA_SEGMENT_SIZE); + params = (struct os_area_params *)__va(lpar_addr + OS_AREA_SEGMENT_SIZE); result = verify_header(header); if (result) { - /* Second stage kernels exit here. */ pr_debug("%s:%d verify_header failed\n", __func__, __LINE__); dump_header(header); - return; + return -EIO; } - db = (struct os_area_db *)__va(lpar_addr - + header->db_area_offset * OS_AREA_SEGMENT_SIZE); - dump_header(header); dump_params(params); - dump_db(db); - result = db_verify(db) || db_get_rtc_diff(db, &saved_params.rtc_diff); - if (result) - saved_params.rtc_diff = params->rtc_diff ? params->rtc_diff - : SECONDS_FROM_1970_TO_2000; + saved_params.rtc_diff = params->rtc_diff; saved_params.av_multi_out = params->av_multi_out; - saved_params.valid = 1; - - memset(header, 0, sizeof(*header)); + saved_params.ctrl_button = params->ctrl_button; + memcpy(saved_params.static_ip_addr, params->static_ip_addr, 4); + memcpy(saved_params.network_mask, params->network_mask, 4); + memcpy(saved_params.default_gateway, params->default_gateway, 4); + memcpy(saved_params.dns_secondary, params->dns_secondary, 4); - pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; } /** - * ps3_os_area_init - Setup os area device tree properties as needed. - */ - -void __init ps3_os_area_init(void) -{ - struct device_node *node; - - pr_debug(" -> %s:%d\n", __func__, __LINE__); - - node = of_find_node_by_path("/"); - - if (!saved_params.valid && node) { - /* Second stage kernels should have a dt entry. */ - os_area_get_property(node, &property_rtc_diff); - os_area_get_property(node, &property_av_multi_out); - } - - if(!saved_params.rtc_diff) - saved_params.rtc_diff = SECONDS_FROM_1970_TO_2000; - - if (node) { - os_area_set_property(node, &property_rtc_diff); - os_area_set_property(node, &property_av_multi_out); - of_node_put(node); - } else - pr_debug("%s:%d of_find_node_by_path failed\n", - __func__, __LINE__); - - pr_debug(" <- %s:%d\n", __func__, __LINE__); -} - -/** - * ps3_os_area_get_rtc_diff - Returns the rtc diff value. - */ - -u64 ps3_os_area_get_rtc_diff(void) -{ - return saved_params.rtc_diff; -} - -/** - * ps3_os_area_set_rtc_diff - Set the rtc diff value. + * ps3_os_area_rtc_diff - Returns the ps3 rtc diff value. * - * An asynchronous write is needed to support writing updates from - * the timer interrupt context. + * The ps3 rtc maintains a value that approximates seconds since + * 2000-01-01 00:00:00 UTC. Returns the exact number of seconds from 1970 to + * 2000 when saved_params.rtc_diff has not been properly set up. */ -void ps3_os_area_set_rtc_diff(u64 rtc_diff) +u64 ps3_os_area_rtc_diff(void) { - if (saved_params.rtc_diff != rtc_diff) { - saved_params.rtc_diff = rtc_diff; - os_area_queue_work(); - } + return saved_params.rtc_diff ? saved_params.rtc_diff : 946684800UL; } /** diff --git a/trunk/arch/powerpc/platforms/ps3/platform.h b/trunk/arch/powerpc/platforms/ps3/platform.h index 01f0c9506e11..27c7d099816a 100644 --- a/trunk/arch/powerpc/platforms/ps3/platform.h +++ b/trunk/arch/powerpc/platforms/ps3/platform.h @@ -62,10 +62,8 @@ int ps3_set_rtc_time(struct rtc_time *time); /* os area */ -void __init ps3_os_area_save_params(void); -void __init ps3_os_area_init(void); -u64 ps3_os_area_get_rtc_diff(void); -void ps3_os_area_set_rtc_diff(u64 rtc_diff); +int __init ps3_os_area_init(void); +u64 ps3_os_area_rtc_diff(void); /* spu */ diff --git a/trunk/arch/powerpc/platforms/ps3/setup.c b/trunk/arch/powerpc/platforms/ps3/setup.c index 5c2cbb08eb52..609945dbe394 100644 --- a/trunk/arch/powerpc/platforms/ps3/setup.c +++ b/trunk/arch/powerpc/platforms/ps3/setup.c @@ -206,7 +206,6 @@ static void __init ps3_setup_arch(void) prealloc_ps3flash_bounce_buffer(); ppc_md.power_save = ps3_power_save; - ps3_os_area_init(); DBG(" <- %s:%d\n", __func__, __LINE__); } @@ -229,7 +228,7 @@ static int __init ps3_probe(void) powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; - ps3_os_area_save_params(); + ps3_os_area_init(); ps3_mm_init(); ps3_mm_vas_create(&htab_size); ps3_hpte_init(htab_size); diff --git a/trunk/arch/powerpc/platforms/ps3/time.c b/trunk/arch/powerpc/platforms/ps3/time.c index d0daf7d6d3b2..802a9ccacb5e 100644 --- a/trunk/arch/powerpc/platforms/ps3/time.c +++ b/trunk/arch/powerpc/platforms/ps3/time.c @@ -50,6 +50,12 @@ static void __maybe_unused _dump_time(int time, const char *func, _dump_tm(&tm, func, line); } +/** + * rtc_shift - Difference in seconds between 1970 and the ps3 rtc value. + */ + +static s64 rtc_shift; + void __init ps3_calibrate_decr(void) { int result; @@ -60,6 +66,8 @@ void __init ps3_calibrate_decr(void) ppc_tb_freq = tmp; ppc_proc_freq = ppc_tb_freq * 40; + + rtc_shift = ps3_os_area_rtc_diff(); } static u64 read_rtc(void) @@ -79,18 +87,18 @@ int ps3_set_rtc_time(struct rtc_time *tm) u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - ps3_os_area_set_rtc_diff(now - read_rtc()); + rtc_shift = now - read_rtc(); return 0; } void ps3_get_rtc_time(struct rtc_time *tm) { - to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm); + to_tm(read_rtc() + rtc_shift, tm); tm->tm_year -= 1900; tm->tm_mon -= 1; } unsigned long __init ps3_get_boot_time(void) { - return read_rtc() + ps3_os_area_get_rtc_diff(); + return read_rtc() + rtc_shift; } diff --git a/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c b/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c index fc48b96c81bf..9711eb0d5496 100644 --- a/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -252,20 +252,6 @@ static struct notifier_block pseries_smp_nb = { static int __init pseries_cpu_hotplug_init(void) { - struct device_node *np; - const char *typep; - - for_each_node_by_name(np, "interrupt-controller") { - typep = of_get_property(np, "compatible", NULL); - if (strstr(typep, "open-pic")) { - of_node_put(np); - - printk(KERN_INFO "CPU Hotplug not supported on " - "systems using MPIC\n"); - return 0; - } - } - rtas_stop_self_args.token = rtas_token("stop-self"); qcss_tok = rtas_token("query-cpu-stopped-state"); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index fdb9b1c8f977..f0b7146a110f 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -257,6 +257,11 @@ static void __init pSeries_setup_arch(void) /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; + if (ROOT_DEV == 0) { + printk("No ramdisk, default root is /dev/sda2\n"); + ROOT_DEV = Root_SDA2; + } + fwnmi_init(); /* Find and initialize PCI host bridges */ diff --git a/trunk/arch/powerpc/sysdev/axonram.c b/trunk/arch/powerpc/sysdev/axonram.c index 4d3ba63bba79..ab037a3a40db 100644 --- a/trunk/arch/powerpc/sysdev/axonram.c +++ b/trunk/arch/powerpc/sysdev/axonram.c @@ -324,13 +324,11 @@ static struct of_device_id axon_ram_device_id[] = { }; static struct of_platform_driver axon_ram_driver = { + .owner = THIS_MODULE, + .name = AXON_RAM_MODULE_NAME, .match_table = axon_ram_device_id, .probe = axon_ram_probe, - .remove = axon_ram_remove, - .driver = { - .owner = THIS_MODULE, - .name = AXON_RAM_MODULE_NAME, - }, + .remove = axon_ram_remove }; /** diff --git a/trunk/arch/powerpc/sysdev/pmi.c b/trunk/arch/powerpc/sysdev/pmi.c index 20edd1e94eff..2f91b55b7754 100644 --- a/trunk/arch/powerpc/sysdev/pmi.c +++ b/trunk/arch/powerpc/sysdev/pmi.c @@ -205,12 +205,10 @@ static int pmi_of_remove(struct of_device *dev) } static struct of_platform_driver pmi_of_platform_driver = { + .name = "pmi", .match_table = pmi_match, .probe = pmi_of_probe, - .remove = pmi_of_remove, - .driver = { - .name = "pmi", - }, + .remove = pmi_of_remove }; static int __init pmi_module_init(void) diff --git a/trunk/arch/ppc/platforms/ev64360.c b/trunk/arch/ppc/platforms/ev64360.c index 6765676a5c6b..f8baf05f16ce 100644 --- a/trunk/arch/ppc/platforms/ev64360.c +++ b/trunk/arch/ppc/platforms/ev64360.c @@ -23,6 +23,9 @@ #include #include #include +#ifdef CONFIG_BOOTIMG +#include +#endif #include #include #include diff --git a/trunk/arch/ppc/platforms/katana.c b/trunk/arch/ppc/platforms/katana.c index 52f63e6f0856..c289e9f1b251 100644 --- a/trunk/arch/ppc/platforms/katana.c +++ b/trunk/arch/ppc/platforms/katana.c @@ -27,6 +27,9 @@ #include #include #include +#ifdef CONFIG_BOOTIMG +#include +#endif #include #include #include diff --git a/trunk/drivers/block/viodasd.c b/trunk/drivers/block/viodasd.c index e824b672e05a..af3969a9c963 100644 --- a/trunk/drivers/block/viodasd.c +++ b/trunk/drivers/block/viodasd.c @@ -74,9 +74,53 @@ enum { static DEFINE_SPINLOCK(viodasd_spinlock); #define VIOMAXREQ 16 +#define VIOMAXBLOCKDMA 12 #define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) +struct open_data { + u64 disk_size; + u16 max_disk; + u16 cylinders; + u16 tracks; + u16 sectors; + u16 bytes_per_sector; +}; + +struct rw_data { + u64 offset; + struct { + u32 token; + u32 reserved; + u64 len; + } dma_info[VIOMAXBLOCKDMA]; +}; + +struct vioblocklpevent { + struct HvLpEvent event; + u32 reserved; + u16 version; + u16 sub_result; + u16 disk; + u16 flags; + union { + struct open_data open_data; + struct rw_data rw_data; + u64 changed; + } u; +}; + +#define vioblockflags_ro 0x0001 + +enum vioblocksubtype { + vioblockopen = 0x0001, + vioblockclose = 0x0002, + vioblockread = 0x0003, + vioblockwrite = 0x0004, + vioblockflush = 0x0005, + vioblockcheck = 0x0007 +}; + struct viodasd_waitevent { struct completion com; int rc; @@ -385,7 +429,7 @@ static void do_viodasd_request(struct request_queue *q) * Probe a single disk and fill in the viodasd_device structure * for it. */ -static int probe_disk(struct viodasd_device *d) +static void probe_disk(struct viodasd_device *d) { HvLpEvent_Rc hvrc; struct viodasd_waitevent we; @@ -409,14 +453,14 @@ static int probe_disk(struct viodasd_device *d) 0, 0, 0); if (hvrc != 0) { printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); - return 0; + return; } wait_for_completion(&we.com); if (we.rc != 0) { if (flags != 0) - return 0; + return; /* try again with read only flag set */ flags = vioblockflags_ro; goto retry; @@ -446,32 +490,15 @@ static int probe_disk(struct viodasd_device *d) if (hvrc != 0) { printk(VIOD_KERN_WARNING "bad rc sending event to OS/400 %d\n", (int)hvrc); - return 0; - } - - if (d->dev == NULL) { - /* this is when we reprobe for new disks */ - if (vio_create_viodasd(dev_no) == NULL) { - printk(VIOD_KERN_WARNING - "cannot allocate virtual device for disk %d\n", - dev_no); - return 0; - } - /* - * The vio_create_viodasd will have recursed into this - * routine with d->dev set to the new vio device and - * will finish the setup of the disk below. - */ - return 1; + return; } - /* create the request queue for the disk */ spin_lock_init(&d->q_lock); q = blk_init_queue(do_viodasd_request, &d->q_lock); if (q == NULL) { printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", dev_no); - return 0; + return; } g = alloc_disk(1 << PARTITION_SHIFT); if (g == NULL) { @@ -479,7 +506,7 @@ static int probe_disk(struct viodasd_device *d) "cannot allocate disk structure for disk %d\n", dev_no); blk_cleanup_queue(q); - return 0; + return; } d->disk = g; @@ -511,7 +538,6 @@ static int probe_disk(struct viodasd_device *d) /* register us in the global list */ add_disk(g); - return 1; } /* returns the total number of scatterlist elements converted */ @@ -692,7 +718,8 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; d->dev = &vdev->dev; - if (!probe_disk(d)) + probe_disk(d); + if (d->disk == NULL) return -ENODEV; return 0; } diff --git a/trunk/drivers/cdrom/viocd.c b/trunk/drivers/cdrom/viocd.c index 880b5dce3a62..e51550db1575 100644 --- a/trunk/drivers/cdrom/viocd.c +++ b/trunk/drivers/cdrom/viocd.c @@ -56,6 +56,30 @@ #define VIOCD_KERN_WARNING KERN_WARNING "viocd: " #define VIOCD_KERN_INFO KERN_INFO "viocd: " +struct viocdlpevent { + struct HvLpEvent event; + u32 reserved; + u16 version; + u16 sub_result; + u16 disk; + u16 flags; + u32 token; + u64 offset; /* On open, max number of disks */ + u64 len; /* On open, size of the disk */ + u32 block_size; /* Only set on open */ + u32 media_size; /* Only set on open */ +}; + +enum viocdsubtype { + viocdopen = 0x0001, + viocdclose = 0x0002, + viocdread = 0x0003, + viocdwrite = 0x0004, + viocdlockdoor = 0x0005, + viocdgetinfo = 0x0006, + viocdcheck = 0x0007 +}; + /* * Should probably make this a module parameter....sigh */ @@ -107,13 +131,22 @@ static struct capability_entry capability_table[] __initdata = { /* These are our internal structures for keeping track of devices */ static int viocd_numdev; +struct cdrom_info { + char rsrcname[10]; + char type[4]; + char model[3]; +}; +/* + * This needs to be allocated since it is passed to the + * Hypervisor and we may be a module. + */ +static struct cdrom_info *viocd_unitinfo; +static dma_addr_t unitinfo_dmaaddr; + struct disk_info { struct gendisk *viocd_disk; struct cdrom_device_info viocd_info; struct device *dev; - const char *rsrcname; - const char *type; - const char *model; }; static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; @@ -131,9 +164,9 @@ static int proc_viocd_show(struct seq_file *m, void *v) for (i = 0; i < viocd_numdev; i++) { seq_printf(m, "viocd device %d is iSeries resource %10.10s" "type %4.4s, model %3.3s\n", - i, viocd_diskinfo[i].rsrcname, - viocd_diskinfo[i].type, - viocd_diskinfo[i].model); + i, viocd_unitinfo[i].rsrcname, + viocd_unitinfo[i].type, + viocd_unitinfo[i].model); } return 0; } @@ -183,6 +216,61 @@ struct block_device_operations viocd_fops = { .media_changed = viocd_blk_media_changed, }; +/* Get info on CD devices from OS/400 */ +static void __init get_viocd_info(void) +{ + HvLpEvent_Rc hvrc; + int i; + struct viocd_waitevent we; + + viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + &unitinfo_dmaaddr, GFP_ATOMIC); + if (viocd_unitinfo == NULL) { + printk(VIOCD_KERN_WARNING "error allocating unitinfo\n"); + return; + } + + memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD); + + init_completion(&we.com); + + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_cdio | viocdgetinfo, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0); + if (hvrc != HvLpEvent_Rc_Good) { + printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n", + (int)hvrc); + goto error_ret; + } + + wait_for_completion(&we.com); + + if (we.rc) { + const struct vio_error_entry *err = + vio_lookup_rc(viocd_err_table, we.sub_result); + printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n", + we.rc, we.sub_result, err->msg); + goto error_ret; + } + + for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) + viocd_numdev++; + +error_ret: + if (viocd_numdev == 0) { + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); + viocd_unitinfo = NULL; + } +} + static int viocd_open(struct cdrom_device_info *cdi, int purpose) { struct disk_info *diskinfo = cdi->handle; @@ -493,6 +581,7 @@ static void vio_handle_cd_event(struct HvLpEvent *event) bevent->block_size / 512); } /* FALLTHROUGH !! */ + case viocdgetinfo: case viocdlockdoor: pwe = (struct viocd_waitevent *)event->xCorrelationToken; return_complete: @@ -576,30 +665,22 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) int deviceno; struct disk_info *d; struct cdrom_device_info *c; + struct cdrom_info *ci; struct request_queue *q; - struct device_node *node = vdev->dev.archdata.of_node; deviceno = vdev->unit_address; - if (deviceno > VIOCD_MAX_CD) - return -ENODEV; - if (!node) - return -ENODEV; - if (deviceno >= viocd_numdev) - viocd_numdev = deviceno + 1; + return -ENODEV; d = &viocd_diskinfo[deviceno]; - d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL); - d->type = of_get_property(node, "linux,vio_type", NULL); - d->model = of_get_property(node, "linux,vio_model", NULL); - c = &d->viocd_info; + ci = &viocd_unitinfo[deviceno]; c->ops = &viocd_dops; c->speed = 4; c->capacity = 1; c->handle = d; - c->mask = ~find_capability(d->type); + c->mask = ~find_capability(ci->type); sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); if (register_cdrom(c) != 0) { @@ -609,7 +690,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) } printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " "type %4.4s, model %3.3s\n", - c->name, d->rsrcname, d->type, d->model); + c->name, ci->rsrcname, ci->type, ci->model); q = blk_init_queue(do_viocd_request, &viocd_reqlock); if (q == NULL) { printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n", @@ -718,6 +799,8 @@ static int __init viocd_init(void) /* Initialize our request handler */ vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); + get_viocd_info(); + spin_lock_init(&viocd_reqlock); ret = vio_register_driver(&viocd_driver); @@ -733,6 +816,9 @@ static int __init viocd_init(void) return 0; out_free_info: + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); vio_clearHandler(viomajorsubtype_cdio); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); out_unregister: @@ -744,6 +830,10 @@ static void __exit viocd_exit(void) { remove_proc_entry("iSeries/viocd", NULL); vio_unregister_driver(&viocd_driver); + if (viocd_unitinfo != NULL) + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); vio_clearHandler(viomajorsubtype_cdio); unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); diff --git a/trunk/drivers/char/viotape.c b/trunk/drivers/char/viotape.c index f1d60f0cef8f..e12275df6ea2 100644 --- a/trunk/drivers/char/viotape.c +++ b/trunk/drivers/char/viotape.c @@ -92,6 +92,47 @@ struct viot_devinfo_struct { #define VIOTAPOP_SETPART 14 #define VIOTAPOP_UNLOAD 15 +struct viotapelpevent { + struct HvLpEvent event; + u32 reserved; + u16 version; + u16 sub_type_result; + u16 tape; + u16 flags; + u32 token; + u64 len; + union { + struct { + u32 tape_op; + u32 count; + } op; + struct { + u32 type; + u32 resid; + u32 dsreg; + u32 gstat; + u32 erreg; + u32 file_no; + u32 block_no; + } get_status; + struct { + u32 block_no; + } get_pos; + } u; +}; + +enum viotapesubtype { + viotapeopen = 0x0001, + viotapeclose = 0x0002, + viotaperead = 0x0003, + viotapewrite = 0x0004, + viotapegetinfo = 0x0005, + viotapeop = 0x0006, + viotapegetpos = 0x0007, + viotapesetpos = 0x0008, + viotapegetstatus = 0x0009 +}; + enum viotaperc { viotape_InvalidRange = 0x0601, viotape_InvalidToken = 0x0602, @@ -182,11 +223,14 @@ static const struct vio_error_entry viotape_err_table[] = { #define VIOT_WRITING 2 /* Our info on the tapes */ -static struct { - const char *rsrcname; - const char *type; - const char *model; -} viotape_unitinfo[VIOTAPE_MAX_TAPE]; +struct tape_descr { + char rsrcname[10]; + char type[4]; + char model[3]; +}; + +static struct tape_descr *viotape_unitinfo; +static dma_addr_t viotape_unitinfo_token; static struct mtget viomtget[VIOTAPE_MAX_TAPE]; @@ -337,6 +381,53 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno) return -err->errno; } +/* Get info on all tapes from OS/400 */ +static int get_viotape_info(void) +{ + HvLpEvent_Rc hvrc; + int i; + size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE; + struct op_struct *op = get_op_struct(); + + if (op == NULL) + return -ENOMEM; + + viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len, + &viotape_unitinfo_token, GFP_ATOMIC); + if (viotape_unitinfo == NULL) { + free_op_struct(op); + return -ENOMEM; + } + + memset(viotape_unitinfo, 0, len); + + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_tape | viotapegetinfo, + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64) (unsigned long) op, VIOVERSION << 16, + viotape_unitinfo_token, len, 0, 0); + if (hvrc != HvLpEvent_Rc_Good) { + printk(VIOTAPE_KERN_WARN "hv error on op %d\n", + (int)hvrc); + free_op_struct(op); + return -EIO; + } + + wait_for_completion(&op->com); + + free_op_struct(op); + + for (i = 0; + ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0])); + i++) + viotape_numdev++; + return 0; +} + + /* Write */ static ssize_t viotap_write(struct file *file, const char *buf, size_t count, loff_t * ppos) @@ -808,6 +899,7 @@ static void vioHandleTapeEvent(struct HvLpEvent *event) tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; op = (struct op_struct *)event->xCorrelationToken; switch (tapeminor) { + case viotapegetinfo: case viotapeopen: case viotapeclose: op->rc = tevent->sub_type_result; @@ -850,23 +942,11 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) { int i = vdev->unit_address; int j; - struct device_node *node = vdev->dev.archdata.of_node; - - if (i > VIOTAPE_MAX_TAPE) - return -ENODEV; - if (!node) - return -ENODEV; if (i >= viotape_numdev) - viotape_numdev = i + 1; + return -ENODEV; tape_device[i] = &vdev->dev; - viotape_unitinfo[i].rsrcname = of_get_property(node, - "linux,vio_rsrcname", NULL); - viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type", - NULL); - viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model", - NULL); state[i].cur_part = 0; for (j = 0; j < MAX_PARTITIONS; ++j) @@ -964,6 +1044,11 @@ int __init viotap_init(void) goto unreg_chrdev; } + if ((ret = get_viotape_info()) < 0) { + printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information"); + goto unreg_class; + } + ret = vio_register_driver(&viotape_driver); if (ret) goto unreg_class; @@ -1017,6 +1102,10 @@ static void __exit viotap_exit(void) vio_unregister_driver(&viotape_driver); class_destroy(tape_class); unregister_chrdev(VIOTAPE_MAJOR, "viotape"); + if (viotape_unitinfo) + dma_free_coherent(iSeries_vio_dev, + sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, + viotape_unitinfo, viotape_unitinfo_token); viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); vio_clearHandler(viomajorsubtype_tape); clear_op_struct_pool(); diff --git a/trunk/drivers/video/xilinxfb.c b/trunk/drivers/video/xilinxfb.c index 4bc67ab56afa..1a5f1e429c4d 100644 --- a/trunk/drivers/video/xilinxfb.c +++ b/trunk/drivers/video/xilinxfb.c @@ -287,6 +287,11 @@ xilinxfb_drv_probe(struct device *dev) goto failed4; } + /* Put a banner in the log (for DEBUG) */ + dev_dbg(dev, "regs: phys=%x, virt=%p\n", + drvdata->regs_phys, drvdata->regs); + dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", + (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); return 0; /* success */ failed4: diff --git a/trunk/include/asm-powerpc/cputable.h b/trunk/include/asm-powerpc/cputable.h index d913f460e710..c9b8f64bbb45 100644 --- a/trunk/include/asm-powerpc/cputable.h +++ b/trunk/include/asm-powerpc/cputable.h @@ -57,7 +57,6 @@ enum powerpc_pmc_type { PPC_PMC_PA6T = 2, }; -/* NOTE WELL: Update identify_cpu() if fields are added or removed! */ struct cpu_spec { /* CPU is matched via (PVR & pvr_mask) == pvr_value */ unsigned int pvr_mask; diff --git a/trunk/include/asm-powerpc/iseries/hv_call_event.h b/trunk/include/asm-powerpc/iseries/hv_call_event.h index cc029d388e11..4cec4762076d 100644 --- a/trunk/include/asm-powerpc/iseries/hv_call_event.h +++ b/trunk/include/asm-powerpc/iseries/hv_call_event.h @@ -21,9 +21,6 @@ #ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H #define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H -#include -#include - #include #include #include @@ -116,13 +113,6 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp, eventData3, eventData4, eventData5); } -extern void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag); -extern void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle); -extern dma_addr_t iseries_hv_map(void *vaddr, size_t size, - enum dma_data_direction direction); -extern void iseries_hv_unmap(dma_addr_t dma_handle, size_t size, - enum dma_data_direction direction); - static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event) { return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event)); diff --git a/trunk/include/asm-powerpc/iseries/iommu.h b/trunk/include/asm-powerpc/iseries/iommu.h index c59ee7e4bed1..6e323a13ac30 100644 --- a/trunk/include/asm-powerpc/iseries/iommu.h +++ b/trunk/include/asm-powerpc/iseries/iommu.h @@ -22,7 +22,6 @@ */ struct pci_dev; -struct vio_dev; struct device_node; struct iommu_table; @@ -35,7 +34,4 @@ extern void iommu_table_getparms_iSeries(unsigned long busno, unsigned char slotno, unsigned char virtbus, struct iommu_table *tbl); -extern struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev); -extern void iommu_vio_init(void); - #endif /* _ASM_POWERPC_ISERIES_IOMMU_H */ diff --git a/trunk/include/asm-powerpc/iseries/vio.h b/trunk/include/asm-powerpc/iseries/vio.h index f9ac0d00b951..7a95d296abd1 100644 --- a/trunk/include/asm-powerpc/iseries/vio.h +++ b/trunk/include/asm-powerpc/iseries/vio.h @@ -51,116 +51,6 @@ */ #define VIO_MAX_SUBTYPES 8 -#define VIOMAXBLOCKDMA 12 - -struct open_data { - u64 disk_size; - u16 max_disk; - u16 cylinders; - u16 tracks; - u16 sectors; - u16 bytes_per_sector; -}; - -struct rw_data { - u64 offset; - struct { - u32 token; - u32 reserved; - u64 len; - } dma_info[VIOMAXBLOCKDMA]; -}; - -struct vioblocklpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_result; - u16 disk; - u16 flags; - union { - struct open_data open_data; - struct rw_data rw_data; - u64 changed; - } u; -}; - -#define vioblockflags_ro 0x0001 - -enum vioblocksubtype { - vioblockopen = 0x0001, - vioblockclose = 0x0002, - vioblockread = 0x0003, - vioblockwrite = 0x0004, - vioblockflush = 0x0005, - vioblockcheck = 0x0007 -}; - -struct viocdlpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_result; - u16 disk; - u16 flags; - u32 token; - u64 offset; /* On open, max number of disks */ - u64 len; /* On open, size of the disk */ - u32 block_size; /* Only set on open */ - u32 media_size; /* Only set on open */ -}; - -enum viocdsubtype { - viocdopen = 0x0001, - viocdclose = 0x0002, - viocdread = 0x0003, - viocdwrite = 0x0004, - viocdlockdoor = 0x0005, - viocdgetinfo = 0x0006, - viocdcheck = 0x0007 -}; - -struct viotapelpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_type_result; - u16 tape; - u16 flags; - u32 token; - u64 len; - union { - struct { - u32 tape_op; - u32 count; - } op; - struct { - u32 type; - u32 resid; - u32 dsreg; - u32 gstat; - u32 erreg; - u32 file_no; - u32 block_no; - } get_status; - struct { - u32 block_no; - } get_pos; - } u; -}; - -enum viotapesubtype { - viotapeopen = 0x0001, - viotapeclose = 0x0002, - viotaperead = 0x0003, - viotapewrite = 0x0004, - viotapegetinfo = 0x0005, - viotapeop = 0x0006, - viotapegetpos = 0x0007, - viotapesetpos = 0x0008, - viotapegetstatus = 0x0009 -}; - /* * Each subtype can register a handler to process their events. * The handler must have this interface. @@ -178,8 +68,6 @@ extern void vio_set_hostlp(void); extern void *vio_get_event_buffer(int subtype); extern void vio_free_event_buffer(int subtype, void *buffer); -extern struct vio_dev *vio_create_viodasd(u32 unit); - extern HvLpIndex viopath_hostLp; extern HvLpIndex viopath_ourLp; @@ -262,4 +150,8 @@ enum viochar_rc { viochar_rc_ebusy = 1 }; +struct device; + +extern struct device *iSeries_vio_dev; + #endif /* _ASM_POWERPC_ISERIES_VIO_H */ diff --git a/trunk/include/asm-powerpc/machdep.h b/trunk/include/asm-powerpc/machdep.h index cc7c17f16a9a..71c6e7eb2a26 100644 --- a/trunk/include/asm-powerpc/machdep.h +++ b/trunk/include/asm-powerpc/machdep.h @@ -99,7 +99,7 @@ struct machdep_calls { #endif /* CONFIG_PPC64 */ int (*probe)(void); - void (*setup_arch)(void); /* Optional, may be NULL */ + void (*setup_arch)(void); void (*init_early)(void); /* Optional, may be NULL. */ void (*show_cpuinfo)(struct seq_file *m); diff --git a/trunk/include/asm-powerpc/vio.h b/trunk/include/asm-powerpc/vio.h index 9204c15839c5..598d111e8098 100644 --- a/trunk/include/asm-powerpc/vio.h +++ b/trunk/include/asm-powerpc/vio.h @@ -53,12 +53,17 @@ struct vio_dev { }; struct vio_driver { + struct list_head node; const struct vio_device_id *id_table; int (*probe)(struct vio_dev *dev, const struct vio_device_id *id); int (*remove)(struct vio_dev *dev); + void (*shutdown)(struct vio_dev *dev); + unsigned long driver_data; struct device_driver driver; }; +extern struct dma_mapping_ops vio_dma_ops; + extern int vio_register_driver(struct vio_driver *drv); extern void vio_unregister_driver(struct vio_driver *drv);