From bdcff3458f5448fac585a6174ad9342f361b5135 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Tue, 26 Sep 2006 17:49:30 +0200 Subject: [WATCHDOG] Atmel AT91RM9200 rename. The new Atmel AT91SAM9261 and AT91SAM9260 processors use a different internal watchdog peripheral. This watchdog driver is therefore AT91RM9200-specific. This patch renames at91_wdt.c to at91rm9200_wdt.c, and changes the name of the configuration option. Signed-off-by: Andrew Victor Signed-off-by: Wim Van Sebroeck --- arch/arm/configs/at91rm9200dk_defconfig | 2 +- arch/arm/configs/at91rm9200ek_defconfig | 2 +- arch/arm/configs/csb337_defconfig | 2 +- arch/arm/configs/csb637_defconfig | 2 +- arch/arm/configs/kafa_defconfig | 2 +- arch/arm/configs/onearm_defconfig | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index c82e4667f45..b43041476e0 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -577,7 +577,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index b983fc59aa4..d96fc8386e2 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -558,7 +558,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig index a2d6fd398f1..20e68250d83 100644 --- a/arch/arm/configs/csb337_defconfig +++ b/arch/arm/configs/csb337_defconfig @@ -615,7 +615,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig index 2a1ac6c60ab..df8595ac031 100644 --- a/arch/arm/configs/csb637_defconfig +++ b/arch/arm/configs/csb637_defconfig @@ -615,7 +615,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # # USB-based Watchdog Cards diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig index 54fcd75779d..a4cdafc1548 100644 --- a/arch/arm/configs/kafa_defconfig +++ b/arch/arm/configs/kafa_defconfig @@ -560,7 +560,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # CONFIG_NVRAM is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig index cb1d94f9049..9b9f2155af3 100644 --- a/arch/arm/configs/onearm_defconfig +++ b/arch/arm/configs/onearm_defconfig @@ -607,7 +607,7 @@ CONFIG_WATCHDOG_NOWAYOUT=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_AT91_WATCHDOG=y +CONFIG_AT91RM9200_WATCHDOG=y # # USB-based Watchdog Cards -- cgit v1.2.3 From 48e3becbee8906b44050c9300b668227b85f0c95 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Sun, 8 Oct 2006 19:52:30 +0100 Subject: [ARM] 3889/1: [Jornada7xx] Addition of correct SDRAM params into cpu-sa1110.c This adds correct sdram params for K4S281632B-1H and sets the jornada to use them by default. Signed-off-by: Kristoffer Ericson Signed-off-by: Russell King --- arch/arm/mach-sa1100/cpu-sa1110.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 63959772993..90a4130114a 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -82,6 +82,14 @@ static struct sdram_params sdram_tbl[] __initdata = { .twr = 9, .refresh = 64000, .cas_latency = 3, + }, { /* Samsung K4S281632B-1H */ + .name = "K4S281632b-1H", + .rows = 12, + .tck = 10, + .trp = 20, + .twr = 10, + .refresh = 64000, + .cas_latency = 3, }, { /* Samsung KM416S4030CT */ .name = "KM416S4030CT", .rows = 13, @@ -366,6 +374,8 @@ static int __init sa1110_clk_init(void) if (machine_is_h3100()) name = "KM416S4030CT"; + if (machine_is_jornada720()) + name = "K4S281632B-1H"; } sdram = sa1110_find_sdram(name); -- cgit v1.2.3 From 2326eb985b8844f44e150489c76f5cb56fa381b4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 15 Oct 2006 13:48:37 +0100 Subject: [ARM] Fix fallout from IRQ regs changes Some ARM platforms were still broken as a result of the IRQ register passing changes, mostly due to a missing linux/irq.h include. Signed-off-by: Russell King --- arch/arm/mach-footbridge/dc21285.c | 1 + arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/oprofile/op_model_xscale.c | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index fa5d4976f51..1463330ed8e 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index ee80d62119d..142c33c3dff 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -397,7 +397,7 @@ static void lubbock_mmc_poll(unsigned long data) if (LUB_IRQ_SET_CLR & (1 << 0)) mod_timer(&mmc_timer, jiffies + MMC_POLL_RATE); else { - (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data, NULL); + (void) mmc_detect_int(LUBBOCK_SD_IRQ, (void *)data); enable_irq(LUBBOCK_SD_IRQ); } } diff --git a/arch/arm/oprofile/op_model_xscale.c b/arch/arm/oprofile/op_model_xscale.c index 7899d3ca75a..7c3289c2acd 100644 --- a/arch/arm/oprofile/op_model_xscale.c +++ b/arch/arm/oprofile/op_model_xscale.c @@ -20,7 +20,8 @@ #include #include #include -#include +#include + #include #include "op_counter.h" -- cgit v1.2.3 From e5267b4b376cfbdc4518abcc68d5a7fffb505638 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 10 Oct 2006 15:14:12 +1000 Subject: [POWERPC] Don't crash on cell with 2 BEs when !CONFIG_NUMA The SPU code will crash if CONFIG_NUMA is not set and SPUs are found on a non-0 node. This workaround will ignore those SPEs and just print an message in the kernel log. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index ccfd0c4db87..d0fb959e3ef 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -781,6 +781,17 @@ static int __init create_spu(struct device_node *spe) if (!spu) goto out; + spu->node = find_spu_node_id(spe); + if (spu->node >= MAX_NUMNODES) { + printk(KERN_WARNING "SPE %s on node %d ignored," + " node number too big\n", spe->full_name, spu->node); + printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); + return -ENODEV; + } + spu->nid = of_node_to_nid(spe); + if (spu->nid == -1) + spu->nid = 0; + ret = spu_map_device(spu, spe); /* try old method */ if (ret) @@ -788,10 +799,6 @@ static int __init create_spu(struct device_node *spe) if (ret) goto out_free; - spu->node = find_spu_node_id(spe); - spu->nid = of_node_to_nid(spe); - if (spu->nid == -1) - spu->nid = 0; ret = spu_map_interrupts(spu, spe); if (ret) ret = spu_map_interrupts_old(spu, spe); -- cgit v1.2.3 From 654e4aee495bec1e4fc71ba1af25735da7cadc15 Mon Sep 17 00:00:00 2001 From: "Noguchi, Masato" Date: Tue, 10 Oct 2006 10:27:29 +0200 Subject: [POWERPC] spufs: fix support for read/write on cntl This fixes a memory leak introduced by "spufs: add support for read/write oncntl", which was missing a call to simple_attr_close. Signed-off-by: Masato Noguchi Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index e0d73004526..0de8e114e6b 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -246,6 +246,7 @@ static int spufs_cntl_open(struct inode *inode, struct file *file) static struct file_operations spufs_cntl_fops = { .open = spufs_cntl_open, + .release = simple_attr_close, .read = simple_attr_read, .write = simple_attr_write, .mmap = spufs_cntl_mmap, -- cgit v1.2.3 From ee4ea82c07fa8aa46037962ec3e8b40c5144b5eb Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 10 Oct 2006 11:53:26 -0500 Subject: [POWERPC] Add DOS partition table support to mpc834x_itx_defconfig The default configuration file for the MPC8349E-mITX reference board, mpc834x_itx_defconfig, did not include support for DOS partition table types. This support is necessary because the hard drive that comes with the ITX is formatted with this partition table type. Without this config option, no partitions on the drive can be mounted. Signed-off-by: Timur Tabi Signed-off-by: Paul Mackerras --- arch/powerpc/configs/mpc834x_itx_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/configs/mpc834x_itx_defconfig b/arch/powerpc/configs/mpc834x_itx_defconfig index cd3535e1a09..0561b73a918 100644 --- a/arch/powerpc/configs/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/mpc834x_itx_defconfig @@ -1248,7 +1248,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_AMIGA_PARTITION is not set # CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set +CONFIG_MSDOS_PARTITION=y # CONFIG_LDM_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set -- cgit v1.2.3 From bb579cf1d413b930be0241987b848e0f0c1b292f Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Tue, 10 Oct 2006 14:37:29 -0700 Subject: [POWERPC] Off-by-one in /arch/ppc/platforms/mpc8* A find -iname \*.[ch] | xargs grep "> ARRAY_SIZE(" revealed several incorrect usages of ARRAY_SIZE in the mpc drivers. The last element in the array is always ARRAY_SIZE()-1, this patch modifies the bounds checks accordingly. Signed-off-by: Eric Sesterhenn Cc: Vitaly Bordug Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/platforms/mpc8272ads_setup.c | 4 ++-- arch/ppc/platforms/mpc866ads_setup.c | 4 ++-- arch/ppc/platforms/mpc885ads_setup.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c index d7b3a6afa78..1f9ea36837b 100644 --- a/arch/ppc/platforms/mpc8272ads_setup.c +++ b/arch/ppc/platforms/mpc8272ads_setup.c @@ -196,7 +196,7 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev, bd_t* bi = (void*)__res; int fs_no = fsid_fcc1+pdev->id-1; - if(fs_no > ARRAY_SIZE(mpc82xx_enet_pdata)) { + if(fs_no >= ARRAY_SIZE(mpc82xx_enet_pdata)) { return; } @@ -222,7 +222,7 @@ static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_scc2fsid(idx); /* no need to alter anything if console */ - if ((id <= num) && (!pdev->dev.platform_data)) { + if ((id < num) && (!pdev->dev.platform_data)) { pinfo = &mpc8272_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index 5f130dca377..e95d2c11174 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c @@ -259,7 +259,7 @@ static void mpc866ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) /* Get pointer to Communication Processor */ cp = cpmp; - if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { + if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); return; } @@ -305,7 +305,7 @@ static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_smc2fsid(idx); /* no need to alter anything if console */ - if ((id <= num) && (!pdev->dev.platform_data)) { + if ((id < num) && (!pdev->dev.platform_data)) { pinfo = &mpc866_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c index 02293141efb..f8161f3557f 100644 --- a/arch/ppc/platforms/mpc885ads_setup.c +++ b/arch/ppc/platforms/mpc885ads_setup.c @@ -263,7 +263,7 @@ static void mpc885ads_fixup_enet_pdata(struct platform_device *pdev, int fs_no) char *e; int i; - if(fs_no > ARRAY_SIZE(mpc8xx_enet_pdata)) { + if(fs_no >= ARRAY_SIZE(mpc8xx_enet_pdata)) { printk(KERN_ERR"No network-suitable #%d device on bus", fs_no); return; } @@ -371,7 +371,7 @@ static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev, int id = fs_uart_id_smc2fsid(idx); /* no need to alter anything if console */ - if ((id <= num) && (!pdev->dev.platform_data)) { + if ((id < num) && (!pdev->dev.platform_data)) { pinfo = &mpc885_uart_pdata[id]; pinfo->uart_clk = bd->bi_intfreq; pdev->dev.platform_data = pinfo; -- cgit v1.2.3 From 7d2bd30f67e231920091d55d0fffc3a4bf43e68a Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 11 Oct 2006 02:06:59 -0500 Subject: [POWERPC] ppc: Add missing calls to set_irq_regs In the timer_interrupt we were not calling set_irq_regs() and if we are profiling we will end up calling get_irq_regs(). This causes bad things to happen. Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/time.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index d4b2cf74da6..18ee851e33e 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -62,6 +62,7 @@ #include #include #include +#include #include @@ -129,6 +130,7 @@ void wakeup_decrementer(void) */ void timer_interrupt(struct pt_regs * regs) { + struct pt_regs *old_regs; int next_dec; unsigned long cpu = smp_processor_id(); unsigned jiffy_stamp = last_jiffy_stamp(cpu); @@ -137,6 +139,7 @@ void timer_interrupt(struct pt_regs * regs) if (atomic_read(&ppc_n_lost_interrupts) != 0) do_IRQ(regs); + old_regs = set_irq_regs(regs); irq_enter(); while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) { @@ -188,6 +191,7 @@ void timer_interrupt(struct pt_regs * regs) ppc_md.heartbeat(); irq_exit(); + set_irq_regs(old_regs); } /* -- cgit v1.2.3 From f5a37b066165f9938a93653f6940f3dc85ce751d Mon Sep 17 00:00:00 2001 From: Li Yang Date: Wed, 11 Oct 2006 19:04:22 +0800 Subject: [POWERPC] Fix MPC8360EMDS PB board support MPC8360EMDS PB support is broken as some code was missing in last submission. This patch adds missing code and makes MPC8360EMDS PB support working. Signed-off-by: Li Yang Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/83xx/Kconfig | 13 +++++++++++++ arch/powerpc/platforms/83xx/Makefile | 1 + arch/powerpc/platforms/83xx/mpc8360e_pb.c | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 0975e94ac7c..7edb6b46138 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -32,6 +32,13 @@ config MPC834x_ITX Be aware that PCI initialization is the bootloader's responsiblilty. +config MPC8360E_PB + bool "Freescale MPC8360E PB" + select DEFAULT_UIMAGE + select QUICC_ENGINE + help + This option enables support for the MPC836x EMDS Processor Board. + endchoice config PPC_MPC832x @@ -46,4 +53,10 @@ config MPC834x select PPC_INDIRECT_PCI default y if MPC834x_SYS || MPC834x_ITX +config PPC_MPC836x + bool + select PPC_UDBG_16550 + select PPC_INDIRECT_PCI + default y if MPC8360E_PB + endmenu diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index 9387a110d28..e60fd7567fc 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -5,3 +5,4 @@ obj-y := misc.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o +obj-$(CONFIG_MPC8360E_PB) += mpc8360e_pb.o diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c index c0191900fc2..1a523c81c06 100644 --- a/arch/powerpc/platforms/83xx/mpc8360e_pb.c +++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -141,6 +142,24 @@ static void __init mpc8360_sys_setup_arch(void) #endif } +static int __init mpc8360_declare_of_platform_devices(void) +{ + struct device_node *np; + + for (np = NULL; (np = of_find_compatible_node(np, "network", + "ucc_geth")) != NULL;) { + int ucc_num; + char bus_id[BUS_ID_SIZE]; + + ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; + snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); + of_platform_device_create(np, bus_id, NULL); + } + + return 0; +} +device_initcall(mpc8360_declare_of_platform_devices); + void __init mpc8360_sys_init_IRQ(void) { -- cgit v1.2.3 From 8ba738c2bb8fb83c0c99f680444d3ffd4c178ca2 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Wed, 11 Oct 2006 19:27:57 +0800 Subject: [POWERPC] Add Makefile entry for MPC832x_mds support Add missing entry in Makefile for MPC832x MDS support. It also change white space to tab in MPC8360 entry. Signed-off-by: Li Yang Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/83xx/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile index e60fd7567fc..f1aa7e24a93 100644 --- a/arch/powerpc/platforms/83xx/Makefile +++ b/arch/powerpc/platforms/83xx/Makefile @@ -5,4 +5,5 @@ obj-y := misc.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_MPC834x_SYS) += mpc834x_sys.o obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o -obj-$(CONFIG_MPC8360E_PB) += mpc8360e_pb.o +obj-$(CONFIG_MPC8360E_PB) += mpc8360e_pb.o +obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o -- cgit v1.2.3 From 60b2a46cd60c54bd6551ddfa01f0aab08ca58a5d Mon Sep 17 00:00:00 2001 From: Randy Vinson Date: Thu, 12 Oct 2006 13:36:23 -0700 Subject: [POWERPC] Fix IO Window Updates on P2P bridges. When update_bridge_base() updates the IO window on a PCI-to-PCI bridge, it fails to zero the upper 16 bits of the base and limit registers if the window size is less than 64K. This fixes it. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 9b49f8691d2..0d9ff72e285 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -441,14 +441,14 @@ update_bridge_base(struct pci_bus *bus, int i) end = res->end - off; io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK; io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK; - if (end > 0xffff) { - pci_write_config_word(dev, PCI_IO_BASE_UPPER16, - start >> 16); - pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, - end >> 16); + if (end > 0xffff) io_base_lo |= PCI_IO_RANGE_TYPE_32; - } else + else io_base_lo |= PCI_IO_RANGE_TYPE_16; + pci_write_config_word(dev, PCI_IO_BASE_UPPER16, + start >> 16); + pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, + end >> 16); pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo); pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo); -- cgit v1.2.3 From 6c4841c2b6c32a134f9f36e5e08857138cc12b10 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 13 Oct 2006 11:41:00 +1000 Subject: [POWERPC] Never panic when taking altivec exceptions from userspace At the moment we rely on a cpu feature bit or a firmware property to detect altivec. If we dont have either of these and the cpu does in fact support altivec we can cause a panic from userspace. It seems safer to always send a signal if we manage to get an 0xf20 exception from userspace. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/traps.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index d9f10f2fc37..5ed4c2ceb5c 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -900,14 +900,13 @@ void kernel_fp_unavailable_exception(struct pt_regs *regs) void altivec_unavailable_exception(struct pt_regs *regs) { -#if !defined(CONFIG_ALTIVEC) if (user_mode(regs)) { /* A user program has executed an altivec instruction, but this kernel doesn't support altivec. */ _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); return; } -#endif + printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " "%lx at %lx\n", regs->trap, regs->nip); die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); -- cgit v1.2.3 From 99f48610252b736908fa5bdea505a480368308d6 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 13 Oct 2006 12:13:12 +1000 Subject: [POWERPC] POWER6 has 6 PMCs Change ->num_pmcs to match the number of PMCs in POWER6. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 47a613cdd77..95382f99440 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -268,7 +268,7 @@ struct cpu_spec cpu_specs[] = { .cpu_user_features = COMMON_USER_POWER6, .icache_bsize = 128, .dcache_bsize = 128, - .num_pmcs = 8, + .num_pmcs = 6, .oprofile_cpu_type = "ppc64/power6", .oprofile_type = PPC_OPROFILE_POWER4, .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, -- cgit v1.2.3 From 00ae36de49cc718d4122e1c8aac96fd1a5a2553c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 13 Oct 2006 12:17:16 +1000 Subject: [POWERPC] Better check in show_instructions Instead of just checking that an address is in the right range, use the provided __kernel_text_address() helper which covers both the kernel and module text sections. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/process.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 7b2f6452ba7..f3d4dd580dd 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -341,13 +341,6 @@ struct task_struct *__switch_to(struct task_struct *prev, static int instructions_to_print = 16; -#ifdef CONFIG_PPC64 -#define BAD_PC(pc) ((REGION_ID(pc) != KERNEL_REGION_ID) && \ - (REGION_ID(pc) != VMALLOC_REGION_ID)) -#else -#define BAD_PC(pc) ((pc) < KERNELBASE) -#endif - static void show_instructions(struct pt_regs *regs) { int i; @@ -366,7 +359,8 @@ static void show_instructions(struct pt_regs *regs) * bad address because the pc *should* only be a * kernel address. */ - if (BAD_PC(pc) || __get_user(instr, (unsigned int __user *)pc)) { + if (!__kernel_text_address(pc) || + __get_user(instr, (unsigned int __user *)pc)) { printk("XXXXXXXX "); } else { if (regs->nip == pc) -- cgit v1.2.3 From 284a940675a64df253e3dffc60b09bb4bbb149e4 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 13 Oct 2006 12:26:57 +1000 Subject: [POWERPC] Check for offline nodes in pci NUMA code During boot we bring up all memory and cpu nodes. Normally a PCI device will be in one of these online nodes, however in some weird setups it may not. We have only seen this in the lab but we may as well check for the case and fallback to -1 (all nodes). Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_64.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 78d3c0fc8df..9bae8a5bf67 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -199,8 +199,14 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev) pci_setup_pci_controller(phb); phb->arch_data = dev; phb->is_dynamic = mem_init_done; - if (dev) - PHB_SET_NODE(phb, of_node_to_nid(dev)); + if (dev) { + int nid = of_node_to_nid(dev); + + if (nid < 0 || !node_online(nid)) + nid = -1; + + PHB_SET_NODE(phb, nid); + } return phb; } -- cgit v1.2.3 From d04c56f73c30a5e593202ecfcf25ed43d42363a2 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 4 Oct 2006 16:47:49 +1000 Subject: [POWERPC] Lazy interrupt disabling for 64-bit machines This implements a lazy strategy for disabling interrupts. This means that local_irq_disable() et al. just clear the 'interrupts are enabled' flag in the paca. If an interrupt comes along, the interrupt entry code notices that interrupts are supposed to be disabled, and clears the EE bit in SRR1, clears the 'interrupts are hard-enabled' flag in the paca, and returns. This means that interrupts only actually get disabled in the processor when an interrupt comes along. When interrupts are enabled by local_irq_enable() et al., the code sets the interrupts-enabled flag in the paca, and then checks whether interrupts got hard-disabled. If so, it also sets the EE bit in the MSR to hard-enable the interrupts. This has the potential to improve performance, and also makes it easier to make a kernel that can boot on iSeries and on other 64-bit machines, since this lazy-disable strategy is very similar to the soft-disable strategy that iSeries already uses. This version renames paca->proc_enabled to paca->soft_enabled, and changes a couple of soft-disables in the kexec code to hard-disables, which should fix the crash that Michael Ellerman saw. This doesn't yet use a reserved CR field for the soft_enabled and hard_enabled flags. This applies on top of Stephen Rothwell's patches to make it possible to build a combined iSeries/other kernel. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/asm-offsets.c | 3 +- arch/powerpc/kernel/crash.c | 4 +- arch/powerpc/kernel/entry_64.S | 39 ++++++------ arch/powerpc/kernel/head_64.S | 110 +++++++++++++++++++++++---------- arch/powerpc/kernel/idle_power4.S | 8 ++- arch/powerpc/kernel/irq.c | 24 ++++++- arch/powerpc/kernel/ppc_ksyms.c | 4 ++ arch/powerpc/kernel/setup_64.c | 4 +- arch/powerpc/platforms/iseries/ksyms.c | 6 -- arch/powerpc/platforms/iseries/misc.S | 35 +---------- 10 files changed, 137 insertions(+), 100 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index d06f378597b..e96521530d2 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -118,7 +118,8 @@ int main(void) DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); - DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); + DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled)); + DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled)); DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 1af41f7616d..89b03c8da9d 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -111,7 +111,7 @@ void crash_ipi_callback(struct pt_regs *regs) if (!cpu_online(cpu)) return; - local_irq_disable(); + hard_irq_disable(); if (!cpu_isset(cpu, cpus_in_crash)) crash_save_this_cpu(regs, cpu); cpu_set(cpu, cpus_in_crash); @@ -289,7 +289,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) * an SMP system. * The kernel is broken so disable interrupts. */ - local_irq_disable(); + hard_irq_disable(); for_each_irq(irq) { struct irq_desc *desc = irq_desc + irq; diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 748e74fcf54..efda48741b2 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -87,6 +87,10 @@ system_call_common: addi r9,r1,STACK_FRAME_OVERHEAD ld r11,exception_marker@toc(r2) std r11,-16(r9) /* "regshere" marker */ + li r10,1 + stb r10,PACASOFTIRQEN(r13) + stb r10,PACAHARDIRQEN(r13) + std r10,SOFTE(r1) #ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION /* Hack for handling interrupts when soft-enabling on iSeries */ @@ -94,8 +98,6 @@ BEGIN_FW_FTR_SECTION andi. r10,r12,MSR_PR /* from kernel */ crand 4*cr0+eq,4*cr1+eq,4*cr0+eq beq hardware_interrupt_entry - lbz r10,PACAPROCENABLED(r13) - std r10,SOFTE(r1) END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif mfmsr r11 @@ -460,9 +462,9 @@ _GLOBAL(ret_from_except_lite) #endif restore: + ld r5,SOFTE(r1) #ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION - ld r5,SOFTE(r1) cmpdi 0,r5,0 beq 4f /* Check for pending interrupts (iSeries) */ @@ -472,16 +474,16 @@ BEGIN_FW_FTR_SECTION beq+ 4f /* skip do_IRQ if no interrupts */ li r3,0 - stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ + stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */ ori r10,r10,MSR_EE mtmsrd r10 /* hard-enable again */ addi r3,r1,STACK_FRAME_OVERHEAD bl .do_IRQ b .ret_from_except_lite /* loop back and handle more */ - -4: stb r5,PACAPROCENABLED(r13) +4: END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif + stb r5,PACASOFTIRQEN(r13) ld r3,_MSR(r1) andi. r0,r3,MSR_RI @@ -538,25 +540,15 @@ do_work: /* Check that preempt_count() == 0 and interrupts are enabled */ lwz r8,TI_PREEMPT(r9) cmpwi cr1,r8,0 -#ifdef CONFIG_PPC_ISERIES -BEGIN_FW_FTR_SECTION ld r0,SOFTE(r1) cmpdi r0,0 -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif -BEGIN_FW_FTR_SECTION - andi. r0,r3,MSR_EE -END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) crandc eq,cr1*4+eq,eq bne restore /* here we are preempting the current task */ 1: -#ifdef CONFIG_PPC_ISERIES -BEGIN_FW_FTR_SECTION li r0,1 - stb r0,PACAPROCENABLED(r13) -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif + stb r0,PACASOFTIRQEN(r13) + stb r0,PACAHARDIRQEN(r13) ori r10,r10,MSR_EE mtmsrd r10,1 /* reenable interrupts */ bl .preempt_schedule @@ -639,8 +631,7 @@ _GLOBAL(enter_rtas) /* There is no way it is acceptable to get here with interrupts enabled, * check it with the asm equivalent of WARN_ON */ - mfmsr r6 - andi. r0,r6,MSR_EE + lbz r0,PACASOFTIRQEN(r13) 1: tdnei r0,0 .section __bug_table,"a" .llong 1b,__LINE__ + 0x1000000, 1f, 2f @@ -649,7 +640,13 @@ _GLOBAL(enter_rtas) 1: .asciz __FILE__ 2: .asciz "enter_rtas" .previous - + + /* Hard-disable interrupts */ + mfmsr r6 + rldicl r7,r6,48,1 + rotldi r7,r7,16 + mtmsrd r7,1 + /* Unfortunately, the stack pointer and the MSR are also clobbered, * so they are saved in the PACA which allows us to restore * our original state after RTAS returns. diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 645c7f10fb2..c93d9f35a12 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -35,9 +35,7 @@ #include #include -#ifdef CONFIG_PPC_ISERIES #define DO_SOFT_DISABLE -#endif /* * We layout physical memory as follows: @@ -308,7 +306,9 @@ exception_marker: std r9,_LINK(r1); \ mfctr r10; /* save CTR in stackframe */ \ std r10,_CTR(r1); \ + lbz r10,PACASOFTIRQEN(r13); \ mfspr r11,SPRN_XER; /* save XER in stackframe */ \ + std r10,SOFTE(r1); \ std r11,_XER(r1); \ li r9,(n)+1; \ std r9,_TRAP(r1); /* set trap number */ \ @@ -343,6 +343,34 @@ label##_pSeries: \ EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) +#define MASKABLE_EXCEPTION_PSERIES(n, label) \ + . = n; \ + .globl label##_pSeries; \ +label##_pSeries: \ + HMT_MEDIUM; \ + mtspr SPRN_SPRG1,r13; /* save r13 */ \ + mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ + std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ + std r10,PACA_EXGEN+EX_R10(r13); \ + lbz r10,PACASOFTIRQEN(r13); \ + mfcr r9; \ + cmpwi r10,0; \ + beq masked_interrupt; \ + mfspr r10,SPRN_SPRG1; \ + std r10,PACA_EXGEN+EX_R13(r13); \ + std r11,PACA_EXGEN+EX_R11(r13); \ + std r12,PACA_EXGEN+EX_R12(r13); \ + clrrdi r12,r13,32; /* get high part of &label */ \ + mfmsr r10; \ + mfspr r11,SPRN_SRR0; /* save SRR0 */ \ + LOAD_HANDLER(r12,label##_common) \ + ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ + mtspr SPRN_SRR0,r12; \ + mfspr r12,SPRN_SRR1; /* and SRR1 */ \ + mtspr SPRN_SRR1,r10; \ + rfid; \ + b . /* prevent speculative execution */ + #define STD_EXCEPTION_ISERIES(n, label, area) \ .globl label##_iSeries; \ label##_iSeries: \ @@ -358,40 +386,32 @@ label##_iSeries: \ HMT_MEDIUM; \ mtspr SPRN_SPRG1,r13; /* save r13 */ \ EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ - lbz r10,PACAPROCENABLED(r13); \ + lbz r10,PACASOFTIRQEN(r13); \ cmpwi 0,r10,0; \ beq- label##_iSeries_masked; \ EXCEPTION_PROLOG_ISERIES_2; \ b label##_common; \ -#ifdef DO_SOFT_DISABLE +#ifdef CONFIG_PPC_ISERIES #define DISABLE_INTS \ -BEGIN_FW_FTR_SECTION; \ - lbz r10,PACAPROCENABLED(r13); \ li r11,0; \ - std r10,SOFTE(r1); \ + stb r11,PACASOFTIRQEN(r13); \ +BEGIN_FW_FTR_SECTION; \ + stb r11,PACAHARDIRQEN(r13); \ +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ +BEGIN_FW_FTR_SECTION; \ mfmsr r10; \ - stb r11,PACAPROCENABLED(r13); \ ori r10,r10,MSR_EE; \ mtmsrd r10,1; \ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#define ENABLE_INTS \ -BEGIN_FW_FTR_SECTION; \ - lbz r10,PACAPROCENABLED(r13); \ - mfmsr r11; \ - std r10,SOFTE(r1); \ - ori r11,r11,MSR_EE; \ -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \ -BEGIN_FW_FTR_SECTION; \ - ld r12,_MSR(r1); \ - mfmsr r11; \ - rlwimi r11,r12,0,MSR_EE; \ -END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ - mtmsrd r11,1 +#else +#define DISABLE_INTS \ + li r11,0; \ + stb r11,PACASOFTIRQEN(r13); \ + stb r11,PACAHARDIRQEN(r13) -#else /* hard enable/disable interrupts */ -#define DISABLE_INTS +#endif /* CONFIG_PPC_ISERIES */ #define ENABLE_INTS \ ld r12,_MSR(r1); \ @@ -399,8 +419,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ rlwimi r11,r12,0,MSR_EE; \ mtmsrd r11,1 -#endif - #define STD_EXCEPTION_COMMON(trap, label, hdlr) \ .align 7; \ .globl label##_common; \ @@ -541,11 +559,11 @@ instruction_access_slb_pSeries: mfspr r12,SPRN_SRR1 /* and SRR1 */ b .slb_miss_realmode /* Rel. branch works in real mode */ - STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) + MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt) STD_EXCEPTION_PSERIES(0x600, alignment) STD_EXCEPTION_PSERIES(0x700, program_check) STD_EXCEPTION_PSERIES(0x800, fp_unavailable) - STD_EXCEPTION_PSERIES(0x900, decrementer) + MASKABLE_EXCEPTION_PSERIES(0x900, decrementer) STD_EXCEPTION_PSERIES(0xa00, trap_0a) STD_EXCEPTION_PSERIES(0xb00, trap_0b) @@ -597,7 +615,24 @@ system_call_pSeries: /*** pSeries interrupt support ***/ /* moved from 0xf00 */ - STD_EXCEPTION_PSERIES(., performance_monitor) + MASKABLE_EXCEPTION_PSERIES(., performance_monitor) + +/* + * An interrupt came in while soft-disabled; clear EE in SRR1, + * clear paca->hard_enabled and return. + */ +masked_interrupt: + stb r10,PACAHARDIRQEN(r13) + mtcrf 0x80,r9 + ld r9,PACA_EXGEN+EX_R9(r13) + mfspr r10,SPRN_SRR1 + rldicl r10,r10,48,1 /* clear MSR_EE */ + rotldi r10,r10,16 + mtspr SPRN_SRR1,r10 + ld r10,PACA_EXGEN+EX_R10(r13) + mfspr r13,SPRN_SPRG1 + rfid + b . .align 7 _GLOBAL(do_stab_bolted_pSeries) @@ -952,7 +987,8 @@ fast_exception_return: REST_8GPRS(2, r1) mfmsr r10 - clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ + rldicl r10,r10,48,1 /* clear EE */ + rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */ mtmsrd r10,1 mtspr SPRN_SRR1,r12 @@ -1877,11 +1913,16 @@ _GLOBAL(__secondary_start) /* enable MMU and jump to start_secondary */ LOAD_REG_ADDR(r3, .start_secondary_prolog) LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) -#ifdef DO_SOFT_DISABLE +#ifdef CONFIG_PPC_ISERIES BEGIN_FW_FTR_SECTION ori r4,r4,MSR_EE END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif +BEGIN_FW_FTR_SECTION + stb r7,PACASOFTIRQEN(r13) + stb r7,PACAHARDIRQEN(r13) +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) + mtspr SPRN_SRR0,r3 mtspr SPRN_SRR1,r4 rfid @@ -2019,15 +2060,18 @@ _STATIC(start_here_common) /* Load up the kernel context */ 5: -#ifdef DO_SOFT_DISABLE -BEGIN_FW_FTR_SECTION li r5,0 - stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ + stb r5,PACASOFTIRQEN(r13) /* Soft Disabled */ +#ifdef CONFIG_PPC_ISERIES +BEGIN_FW_FTR_SECTION mfmsr r5 ori r5,r5,MSR_EE /* Hard Enabled */ mtmsrd r5 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif +BEGIN_FW_FTR_SECTION + stb r5,PACAHARDIRQEN(r13) +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) bl .start_kernel diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 30de81da7b4..ba319547860 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S @@ -30,6 +30,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP) beqlr /* Go to NAP now */ + mfmsr r7 + rldicl r0,r7,48,1 + rotldi r0,r0,16 + mtmsrd r0,1 /* hard-disable interrupts */ + li r0,1 + stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */ + stb r0,PACAHARDIRQEN(r13) BEGIN_FTR_SECTION DSSALL sync @@ -38,7 +45,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ ori r8,r8,_TLF_NAPPING /* so when we take an exception */ std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ - mfmsr r7 ori r7,r7,MSR_EE oris r7,r7,MSR_POW@h 1: sync diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 5e37bf14ef2..67b21a008f6 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -64,8 +64,9 @@ #include #include #include -#ifdef CONFIG_PPC_ISERIES +#ifdef CONFIG_PPC64 #include +#include #endif int __irq_offset_value; @@ -95,6 +96,27 @@ extern atomic_t ipi_sent; EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; + +void local_irq_restore(unsigned long en) +{ + get_paca()->soft_enabled = en; + if (!en) + return; + + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + if (get_paca()->lppaca_ptr->int_dword.any_int) + iseries_handle_interrupts(); + return; + } + + if (get_paca()->hard_enabled) + return; + /* need to hard-enable interrupts here */ + get_paca()->hard_enabled = en; + if ((int)mfspr(SPRN_DEC) < 0) + mtspr(SPRN_DEC, 1); + hard_irq_enable(); +} #endif /* CONFIG_PPC64 */ int show_interrupts(struct seq_file *p, void *v) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 807193a3c78..9179f0739ea 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -49,6 +49,10 @@ #include #endif +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(local_irq_restore); +#endif + #ifdef CONFIG_PPC32 extern void transfer_to_handler(void); extern void do_IRQ(struct pt_regs *regs); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 4b2e32eab9d..b1b0cda3f74 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -223,8 +223,8 @@ void early_setup_secondary(void) { struct paca_struct *lpaca = get_paca(); - /* Mark enabled in PACA */ - lpaca->proc_enabled = 0; + /* Mark interrupts enabled in PACA */ + lpaca->soft_enabled = 0; /* Initialize hash table for that CPU */ htab_initialize_secondary(); diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c index a2200842f4e..2430848b98e 100644 --- a/arch/powerpc/platforms/iseries/ksyms.c +++ b/arch/powerpc/platforms/iseries/ksyms.c @@ -19,9 +19,3 @@ EXPORT_SYMBOL(HvCall4); EXPORT_SYMBOL(HvCall5); EXPORT_SYMBOL(HvCall6); EXPORT_SYMBOL(HvCall7); - -#ifdef CONFIG_SMP -EXPORT_SYMBOL(local_get_flags); -EXPORT_SYMBOL(local_irq_disable); -EXPORT_SYMBOL(local_irq_restore); -#endif diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S index 7641fc7e550..2c6ff0fdac9 100644 --- a/arch/powerpc/platforms/iseries/misc.S +++ b/arch/powerpc/platforms/iseries/misc.S @@ -19,39 +19,8 @@ .text -/* unsigned long local_save_flags(void) */ -_GLOBAL(local_get_flags) - lbz r3,PACAPROCENABLED(r13) - blr - -/* unsigned long local_irq_disable(void) */ -_GLOBAL(local_irq_disable) - lbz r3,PACAPROCENABLED(r13) - li r4,0 - stb r4,PACAPROCENABLED(r13) - blr /* Done */ - -/* void local_irq_restore(unsigned long flags) */ -_GLOBAL(local_irq_restore) - lbz r5,PACAPROCENABLED(r13) - /* Check if things are setup the way we want _already_. */ - cmpw 0,r3,r5 - beqlr - /* are we enabling interrupts? */ - cmpdi 0,r3,0 - stb r3,PACAPROCENABLED(r13) - beqlr - /* Check pending interrupts */ - /* A decrementer, IPI or PMC interrupt may have occurred - * while we were in the hypervisor (which enables) */ - ld r4,PACALPPACAPTR(r13) - ld r4,LPPACAANYINT(r4) - cmpdi r4,0 - beqlr - - /* - * Handle pending interrupts in interrupt context - */ +/* Handle pending interrupts in interrupt context */ +_GLOBAL(iseries_handle_interrupts) li r0,0x5555 sc blr -- cgit v1.2.3 From 5b43d20a4d12d94f258bbbca5fa4df8ff8a17848 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 4 Oct 2006 23:41:41 -0500 Subject: [POWERPC] powerpc: Enable DEEPNAP power savings mode on 970MP Without this patch, on an idle system I get: cpu-power-0:21.638 cpu-power-1:27.102 cpu-power-2:29.343 cpu-power-3:25.784 Total: 103.8W With this patch: cpu-power-0:11.730 cpu-power-1:17.185 cpu-power-2:18.547 cpu-power-3:17.528 Total: 65.0W If I lower HZ to 100, I can get it as low as: cpu-power-0:10.938 cpu-power-1:16.021 cpu-power-2:17.245 cpu-power-3:16.145 Total: 60.2W Another (older) Quad G5 went from 54W to 39W at HZ=250. Coming back out of Deep Nap takes 40-70 cycles longer than coming back from just Nap (which already takes quite a while). I don't think it'll be a performance issue (interrupt latency on an idle system), but in case someone does measurements feel free to report them. Signed-off-by: Olof Johansson Acked-by: Michael Buesch Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cpu_setup_ppc970.S | 16 ++++++++++++++++ arch/powerpc/kernel/cputable.c | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cpu_setup_ppc970.S b/arch/powerpc/kernel/cpu_setup_ppc970.S index 652594891d5..bf118c38575 100644 --- a/arch/powerpc/kernel/cpu_setup_ppc970.S +++ b/arch/powerpc/kernel/cpu_setup_ppc970.S @@ -83,6 +83,22 @@ _GLOBAL(__setup_cpu_ppc970) rldimi r0,r11,52,8 /* set NAP and DPM */ li r11,0 rldimi r0,r11,32,31 /* clear EN_ATTN */ + b load_hids /* Jump to shared code */ + + +_GLOBAL(__setup_cpu_ppc970MP) + /* Do nothing if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + mfspr r0,SPRN_HID0 + li r11,0x15 /* clear DOZE and SLEEP */ + rldimi r0,r11,52,6 /* set DEEPNAP, NAP and DPM */ + li r11,0 + rldimi r0,r11,32,31 /* clear EN_ATTN */ + +load_hids: mtspr SPRN_HID0,r0 mfspr r0,SPRN_HID0 mfspr r0,SPRN_HID0 diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 95382f99440..f02b402c66d 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -41,6 +41,7 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec); #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); +extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec); extern void __restore_cpu_ppc970(void); #endif /* CONFIG_PPC64 */ @@ -221,7 +222,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 8, - .cpu_setup = __setup_cpu_ppc970, + .cpu_setup = __setup_cpu_ppc970MP, .cpu_restore = __restore_cpu_ppc970, .oprofile_cpu_type = "ppc64/970", .oprofile_type = PPC_OPROFILE_POWER4, -- cgit v1.2.3 From 0f03a43b8f0fc221986a46654282ec6a1e8c6d45 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 3 Oct 2006 16:57:44 +1000 Subject: [POWERPC] Remove todc code from ARCH=powerpc Apparently we've copied the todc drivers, for various RTCs used in embedded machines from ARCH=ppc to ARCH=powerpc, despite the fact that it's never used in the latter. This patch removes it. If we ever need these drivers (which we probably shouldn't now the RTC class stuff is in), we can transfer them one by one from ARCH=ppc, removing from the hideous abomination which is the todc "infrastructure". Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 6 - arch/powerpc/sysdev/Makefile | 1 - arch/powerpc/sysdev/todc.c | 392 ------------------------------------------- 3 files changed, 399 deletions(-) delete mode 100644 arch/powerpc/sysdev/todc.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8b691046557..7107d472413 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -594,12 +594,6 @@ config TAU_AVERAGE If in doubt, say N here. -config PPC_TODC - depends on EMBEDDED6xx - bool "Generic Time-of-day Clock (TODC) support" - ---help--- - This adds support for many TODC/RTC chips. - endmenu source arch/powerpc/platforms/embedded6xx/Kconfig diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 91f052d8cce..f15af0e82f1 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_40x) += dcr.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o -obj-$(CONFIG_PPC_TODC) += todc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c deleted file mode 100644 index 0a65980efb5..00000000000 --- a/arch/powerpc/sysdev/todc.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 - * Real Time Clocks/Timekeepers. - * - * Author: Mark A. Greer - * - * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under - * the terms of the GNU General Public License version 2. This program - * is licensed "as is" without any warranty of any kind, whether express - * or implied. - */ -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Depending on the hardware on your board and your board design, the - * RTC/NVRAM may be accessed either directly (like normal memory) or via - * address/data registers. If your board uses the direct method, set - * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and - * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, - * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the - * address of the upper byte (leave NULL if using mc146818), and set - * 'nvram_data' to the address of the 8-bit data register. - * - * Note: Even though the documentation for the various RTC chips say that it - * take up to a second before it starts updating once the 'R' bit is - * cleared, they always seem to update even though we bang on it many - * times a second. This is true, except for the Dallas Semi 1746/1747 - * (possibly others). Those chips seem to have a real problem whenever - * we set the 'R' bit before reading them, they basically stop counting. - * --MAG - */ - -/* - * 'todc_info' should be initialized in your *_setup.c file to - * point to a fully initialized 'todc_info_t' structure. - * This structure holds all the register offsets for your particular - * TODC/RTC chip. - * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. - */ - -#ifdef RTC_FREQ_SELECT -#undef RTC_FREQ_SELECT -#define RTC_FREQ_SELECT control_b /* Register A */ -#endif - -#ifdef RTC_CONTROL -#undef RTC_CONTROL -#define RTC_CONTROL control_a /* Register B */ -#endif - -#ifdef RTC_INTR_FLAGS -#undef RTC_INTR_FLAGS -#define RTC_INTR_FLAGS watchdog /* Register C */ -#endif - -#ifdef RTC_VALID -#undef RTC_VALID -#define RTC_VALID interrupts /* Register D */ -#endif - -/* Access routines when RTC accessed directly (like normal memory) */ -u_char -todc_direct_read_val(int addr) -{ - return readb((void __iomem *)(todc_info->nvram_data + addr)); -} - -void -todc_direct_write_val(int addr, unsigned char val) -{ - writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); - return; -} - -/* Access routines for accessing m48txx type chips via addr/data regs */ -u_char -todc_m48txx_read_val(int addr) -{ - outb(addr, todc_info->nvram_as0); - outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); - return inb(todc_info->nvram_data); -} - -void -todc_m48txx_write_val(int addr, unsigned char val) -{ - outb(addr, todc_info->nvram_as0); - outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); - outb(val, todc_info->nvram_data); - return; -} - -/* Access routines for accessing mc146818 type chips via addr/data regs */ -u_char -todc_mc146818_read_val(int addr) -{ - outb_p(addr, todc_info->nvram_as0); - return inb_p(todc_info->nvram_data); -} - -void -todc_mc146818_write_val(int addr, unsigned char val) -{ - outb_p(addr, todc_info->nvram_as0); - outb_p(val, todc_info->nvram_data); -} - - -/* - * Routines to make RTC chips with NVRAM buried behind an addr/data pair - * have the NVRAM and clock regs appear at the same level. - * The NVRAM will appear to start at addr 0 and the clock regs will appear - * to start immediately after the NVRAM (actually, start at offset - * todc_info->nvram_size). - */ -static inline u_char -todc_read_val(int addr) -{ - u_char val; - - if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { - if (addr < todc_info->nvram_size) { /* NVRAM */ - ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); - val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); - } else { /* Clock Reg */ - addr -= todc_info->nvram_size; - val = ppc_md.rtc_read_val(addr); - } - } else - val = ppc_md.rtc_read_val(addr); - - return val; -} - -static inline void -todc_write_val(int addr, u_char val) -{ - if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { - if (addr < todc_info->nvram_size) { /* NVRAM */ - ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); - ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); - } else { /* Clock Reg */ - addr -= todc_info->nvram_size; - ppc_md.rtc_write_val(addr, val); - } - } else - ppc_md.rtc_write_val(addr, val); -} - -/* - * TODC routines - * - * There is some ugly stuff in that there are assumptions for the mc146818. - * - * Assumptions: - * - todc_info->control_a has the offset as mc146818 Register B reg - * - todc_info->control_b has the offset as mc146818 Register A reg - * - m48txx control reg's write enable or 'W' bit is same as - * mc146818 Register B 'SET' bit (i.e., 0x80) - * - * These assumptions were made to make the code simpler. - */ -long __init -todc_time_init(void) -{ - u_char cntl_b; - - if (!ppc_md.rtc_read_val) - ppc_md.rtc_read_val = ppc_md.nvram_read_val; - if (!ppc_md.rtc_write_val) - ppc_md.rtc_write_val = ppc_md.nvram_write_val; - - cntl_b = todc_read_val(todc_info->control_b); - - if (todc_info->rtc_type == TODC_TYPE_MC146818) { - if ((cntl_b & 0x70) != 0x20) { - printk(KERN_INFO "TODC real-time-clock was stopped." - " Now starting..."); - cntl_b &= ~0x70; - cntl_b |= 0x20; - } - - todc_write_val(todc_info->control_b, cntl_b); - } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { - u_char mode; - - mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); - /* Make sure countdown clear is not set */ - mode &= ~0x40; - /* Enable oscillator, extended register set */ - mode |= 0x30; - todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); - - } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { - u_char month; - - todc_info->enable_read = TODC_DS1501_CNTL_B_TE; - todc_info->enable_write = TODC_DS1501_CNTL_B_TE; - - month = todc_read_val(todc_info->month); - - if ((month & 0x80) == 0x80) { - printk(KERN_INFO "TODC %s %s\n", - "real-time-clock was stopped.", - "Now starting..."); - month &= ~0x80; - todc_write_val(todc_info->month, month); - } - - cntl_b &= ~TODC_DS1501_CNTL_B_TE; - todc_write_val(todc_info->control_b, cntl_b); - } else { /* must be a m48txx type */ - u_char cntl_a; - - todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; - todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; - - cntl_a = todc_read_val(todc_info->control_a); - - /* Check & clear STOP bit in control B register */ - if (cntl_b & TODC_MK48TXX_DAY_CB) { - printk(KERN_INFO "TODC %s %s\n", - "real-time-clock was stopped.", - "Now starting..."); - - cntl_a |= todc_info->enable_write; - cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ - - todc_write_val(todc_info->control_a, cntl_a); - todc_write_val(todc_info->control_b, cntl_b); - } - - /* Make sure READ & WRITE bits are cleared. */ - cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); - todc_write_val(todc_info->control_a, cntl_a); - } - - return 0; -} - -/* - * There is some ugly stuff in that there are assumptions that for a mc146818, - * the todc_info->control_a has the offset of the mc146818 Register B reg and - * that the register'ss 'SET' bit is the same as the m48txx's write enable - * bit in the control register of the m48txx (i.e., 0x80). - * - * It was done to make the code look simpler. - */ -void -todc_get_rtc_time(struct rtc_time *tm) -{ - uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; - uint limit, i; - u_char save_control, uip = 0; - extern void GregorianDay(struct rtc_time *); - - spin_lock(&rtc_lock); - save_control = todc_read_val(todc_info->control_a); - - if (todc_info->rtc_type != TODC_TYPE_MC146818) { - limit = 1; - - switch (todc_info->rtc_type) { - case TODC_TYPE_DS1553: - case TODC_TYPE_DS1557: - case TODC_TYPE_DS1743: - case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ - case TODC_TYPE_DS1747: - case TODC_TYPE_DS17285: - break; - default: - todc_write_val(todc_info->control_a, - (save_control | todc_info->enable_read)); - } - } else - limit = 100000000; - - for (i=0; irtc_type == TODC_TYPE_MC146818) - uip = todc_read_val(todc_info->RTC_FREQ_SELECT); - - sec = todc_read_val(todc_info->seconds) & 0x7f; - min = todc_read_val(todc_info->minutes) & 0x7f; - hour = todc_read_val(todc_info->hours) & 0x3f; - mday = todc_read_val(todc_info->day_of_month) & 0x3f; - mon = todc_read_val(todc_info->month) & 0x1f; - year = todc_read_val(todc_info->year) & 0xff; - - if (todc_info->rtc_type == TODC_TYPE_MC146818) { - uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); - if ((uip & RTC_UIP) == 0) - break; - } - } - - if (todc_info->rtc_type != TODC_TYPE_MC146818) { - switch (todc_info->rtc_type) { - case TODC_TYPE_DS1553: - case TODC_TYPE_DS1557: - case TODC_TYPE_DS1743: - case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ - case TODC_TYPE_DS1747: - case TODC_TYPE_DS17285: - break; - default: - save_control &= ~(todc_info->enable_read); - todc_write_val(todc_info->control_a, save_control); - } - } - spin_unlock(&rtc_lock); - - if ((todc_info->rtc_type != TODC_TYPE_MC146818) - || ((save_control & RTC_DM_BINARY) == 0) - || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(mday); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - - if ((year + 1900) < 1970) { - year += 100; - } - - tm->tm_sec = sec; - tm->tm_min = min; - tm->tm_hour = hour; - tm->tm_mday = mday; - tm->tm_mon = mon; - tm->tm_year = year; - - GregorianDay(tm); -} - -int -todc_set_rtc_time(struct rtc_time *tm) -{ - u_char save_control, save_freq_select = 0; - - spin_lock(&rtc_lock); - save_control = todc_read_val(todc_info->control_a); - - /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ - todc_write_val(todc_info->control_a, - (save_control | todc_info->enable_write)); - save_control &= ~(todc_info->enable_write); /* in case it was set */ - - if (todc_info->rtc_type == TODC_TYPE_MC146818) { - save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); - todc_write_val(todc_info->RTC_FREQ_SELECT, - save_freq_select | RTC_DIV_RESET2); - } - - if ((todc_info->rtc_type != TODC_TYPE_MC146818) - || ((save_control & RTC_DM_BINARY) == 0) - || RTC_ALWAYS_BCD) { - BIN_TO_BCD(tm->tm_sec); - BIN_TO_BCD(tm->tm_min); - BIN_TO_BCD(tm->tm_hour); - BIN_TO_BCD(tm->tm_mon); - BIN_TO_BCD(tm->tm_mday); - BIN_TO_BCD(tm->tm_year); - } - - todc_write_val(todc_info->seconds, tm->tm_sec); - todc_write_val(todc_info->minutes, tm->tm_min); - todc_write_val(todc_info->hours, tm->tm_hour); - todc_write_val(todc_info->month, tm->tm_mon); - todc_write_val(todc_info->day_of_month, tm->tm_mday); - todc_write_val(todc_info->year, tm->tm_year); - - todc_write_val(todc_info->control_a, save_control); - - if (todc_info->rtc_type == TODC_TYPE_MC146818) - todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); - - spin_unlock(&rtc_lock); - return 0; -} -- cgit v1.2.3 From 035223fb28791f0eb0d5719727355d3f6817d228 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 5 Oct 2006 11:35:10 -0700 Subject: [POWERPC] Make pSeries_lpar_hpte_insert static Change the powerpc hpte_insert routines now called through ppc_md to static scope. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/mm/hash_native_64.c | 2 +- arch/powerpc/platforms/pseries/lpar.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index c90f124f3c7..6f1016acdbf 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -123,7 +123,7 @@ static inline void native_unlock_hpte(hpte_t *hptep) clear_bit(HPTE_LOCK_BIT, word); } -long native_hpte_insert(unsigned long hpte_group, unsigned long va, +static long native_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) { diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 1820a0b0a8c..721436db3ef 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -282,7 +282,7 @@ void vpa_init(int cpu) } } -long pSeries_lpar_hpte_insert(unsigned long hpte_group, +static long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) @@ -506,7 +506,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie * lock. */ -void pSeries_lpar_flush_hash_range(unsigned long number, int local) +static void pSeries_lpar_flush_hash_range(unsigned long number, int local) { int i; unsigned long flags = 0; -- cgit v1.2.3 From 0f6f65f607b6d516fa001e8cdf5a2618c81372f5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 16 Oct 2006 21:14:51 +0100 Subject: [ARM] Update mach-types Signed-off-by: Russell King --- arch/arm/tools/mach-types | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index b02af1d740f..579c69ae9ff 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -4,7 +4,7 @@ # # Up to date versions of this file can be obtained from: # -# http://www.arm.linux.org.uk/developer/machines/?action=download +# http://www.arm.linux.org.uk/developer/machines/download.php # # Please do not send patches to this file; it is automatically generated! # To add an entry into this database, please see Documentation/arm/README, @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Sat Sep 23 13:20:43 2006 +# Last update: Mon Oct 16 21:13:36 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -1157,3 +1157,17 @@ adsturboxb MACH_ADSTURBOXB ADSTURBOXB 1143 oti4110 MACH_OTI4110 OTI4110 1144 hme_pxa MACH_HME_PXA HME_PXA 1145 deisterdca MACH_DEISTERDCA DEISTERDCA 1146 +ces_ssem2 MACH_CES_SSEM2 CES_SSEM2 1147 +ces_mtr MACH_CES_MTR CES_MTR 1148 +tds_avng_sbc MACH_TDS_AVNG_SBC TDS_AVNG_SBC 1149 +everest MACH_EVEREST EVEREST 1150 +pnx4010 MACH_PNX4010 PNX4010 1151 +oxnas MACH_OXNAS OXNAS 1152 +fiori MACH_FIORI FIORI 1153 +ml1200 MACH_ML1200 ML1200 1154 +cactus MACH_CACTUS CACTUS 1155 +nb2xxx MACH_NB2XXX NB2XXX 1156 +hw6900 MACH_HW6900 HW6900 1157 +cdcs_quoll MACH_CDCS_QUOLL CDCS_QUOLL 1158 +quicksilver MACH_QUICKSILVER QUICKSILVER 1159 +uplat926 MACH_UPLAT926 UPLAT926 1160 -- cgit v1.2.3 From 3f4a0b917ce72ef47e438d354c433eb645218e87 Mon Sep 17 00:00:00 2001 From: john stultz Date: Tue, 17 Oct 2006 00:09:32 -0700 Subject: [PATCH] i386 Time: Avoid PIT SMP lockups Avoid possible PIT livelock issues seen on SMP systems (and reported by Andi), by not allowing it as a clocksource on SMP boxes. However, since the PIT may no longer be present, we have to properly handle the cases where SMP systems have TSC skew and fall back from the TSC. Since the PIT isn't there, it would "fall back" to the TSC again. So this changes the jiffies rating to 1, and the TSC-bad rating value to 0. Thus you will get the following behavior priority on i386 systems: tsc [if present & stable] hpet [if present] cyclone [if present] acpi_pm [if present] pit [if UP] jiffies Rather then the current more complicated: tsc [if present & stable] hpet [if present] cyclone [if present] acpi_pm [if present] pit [if cpus < 4] tsc [if present & unstable] jiffies Signed-off-by: John Stultz Cc: Andi Kleen Cc: Ingo Molnar Cc: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/i8253.c | 2 +- arch/i386/kernel/tsc.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/i8253.c b/arch/i386/kernel/i8253.c index 477b24daff5..9a0060b92e3 100644 --- a/arch/i386/kernel/i8253.c +++ b/arch/i386/kernel/i8253.c @@ -109,7 +109,7 @@ static struct clocksource clocksource_pit = { static int __init init_pit_clocksource(void) { - if (num_possible_cpus() > 4) /* PIT does not scale! */ + if (num_possible_cpus() > 1) /* PIT does not scale! */ return 0; clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20); diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index b8fa0a8b2e4..fbc95828cd7 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -349,8 +349,8 @@ static int tsc_update_callback(void) int change = 0; /* check to see if we should switch to the safe clocksource: */ - if (clocksource_tsc.rating != 50 && check_tsc_unstable()) { - clocksource_tsc.rating = 50; + if (clocksource_tsc.rating != 0 && check_tsc_unstable()) { + clocksource_tsc.rating = 0; clocksource_reselect(); change = 1; } @@ -461,7 +461,7 @@ static int __init init_tsc_clocksource(void) clocksource_tsc.shift); /* lower the rating if we already know its unstable: */ if (check_tsc_unstable()) - clocksource_tsc.rating = 50; + clocksource_tsc.rating = 0; init_timer(&verify_tsc_freq_timer); verify_tsc_freq_timer.function = verify_tsc_freq; -- cgit v1.2.3 From a460e745e8f9c75a0525ff94154a0629f9d3e05d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 17 Oct 2006 00:10:03 -0700 Subject: [PATCH] genirq: clean up irq-flow-type naming Introduce desc->name and eliminate the handle_irq_name() hack. Add set_irq_chip_and_handler_name() to set the flow type and name at once. Signed-off-by: Ingo Molnar Acked-by: Thomas Gleixner Cc: "Eric W. Biederman" Cc: Matthew Wilcox Cc: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/i8259.c | 7 ++++--- arch/i386/kernel/io_apic.c | 17 ++++++++++------- arch/i386/kernel/irq.c | 2 +- arch/x86_64/kernel/i8259.c | 7 ++++--- arch/x86_64/kernel/io_apic.c | 15 ++++++++------- arch/x86_64/kernel/irq.c | 2 +- 6 files changed, 28 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index d53eafb6daa..62996cd1708 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -113,7 +113,8 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<name); - seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); + seq_printf(p, "-%-8s", irq_desc[i].name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index 0612a33bb89..c4ef801b765 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -178,7 +178,8 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<name); - seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); + seq_printf(p, "-%-8s", irq_desc[i].name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) -- cgit v1.2.3 From 3864c4894a7f4c03d69a90082a5bb0ab10e437ab Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 17 Oct 2006 00:10:26 -0700 Subject: [PATCH] lockdep: annotate i386 apm Lockdep doesn't like to enable interrupts when they are enabled already. BUG: warning at kernel/lockdep.c:1814/trace_hardirqs_on() (Not tainted) [] show_trace_log_lvl+0x58/0x16a [] show_trace+0xd/0x10 [] dump_stack+0x19/0x1b [] trace_hardirqs_on+0xa2/0x11e [] apm_bios_call_simple+0xcd/0xfd [] apm+0x92/0x5b1 [] kernel_thread_helper+0x5/0xb DWARF2 unwinder stuck at kernel_thread_helper+0x5/0xb Leftover inexact backtrace: [] show_trace+0xd/0x10 [] dump_stack+0x19/0x1b [] trace_hardirqs_on+0xa2/0x11e [] apm_bios_call_simple+0xcd/0xfd [] apm+0x92/0x5b1 [] kernel_thread_helper+0x5/0xb Signed-off-by: Peter Zijlstra Cc: Stephen Rothwell Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apm.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index b42f2d914af..2af65858d32 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -540,11 +540,30 @@ static inline void apm_restore_cpus(cpumask_t mask) * Also, we KNOW that for the non error case of apm_bios_call, there * is no useful data returned in the low order 8 bits of eax. */ -#define APM_DO_CLI \ - if (apm_info.allow_ints) \ - local_irq_enable(); \ - else \ + +static inline unsigned long __apm_irq_save(void) +{ + unsigned long flags; + local_save_flags(flags); + if (apm_info.allow_ints) { + if (irqs_disabled_flags(flags)) + local_irq_enable(); + } else + local_irq_disable(); + + return flags; +} + +#define apm_irq_save(flags) \ + do { flags = __apm_irq_save(); } while (0) + +static inline void apm_irq_restore(unsigned long flags) +{ + if (irqs_disabled_flags(flags)) local_irq_disable(); + else if (irqs_disabled()) + local_irq_enable(); +} #ifdef APM_ZERO_SEGS # define APM_DECL_SEGS \ @@ -596,12 +615,11 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in, save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; - local_save_flags(flags); - APM_DO_CLI; + apm_irq_save(flags); APM_DO_SAVE_SEGS; apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi); APM_DO_RESTORE_SEGS; - local_irq_restore(flags); + apm_irq_restore(flags); gdt[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); @@ -640,12 +658,11 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax) save_desc_40 = gdt[0x40 / 8]; gdt[0x40 / 8] = bad_bios_desc; - local_save_flags(flags); - APM_DO_CLI; + apm_irq_save(flags); APM_DO_SAVE_SEGS; error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax); APM_DO_RESTORE_SEGS; - local_irq_restore(flags); + apm_irq_restore(flags); gdt[0x40 / 8] = save_desc_40; put_cpu(); apm_restore_cpus(cpus); -- cgit v1.2.3 From 7281c248f797723f66244b7ecef204620f664648 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 16 Oct 2006 16:49:50 +0100 Subject: [ARM] switch to new pci_get_bus_and_slot API Signed-off-by: Alan Cox Signed-off-by: Russell King --- arch/arm/mach-ixp2000/ixdp2400.c | 6 ++++-- arch/arm/mach-ixp2000/ixdp2800.c | 6 ++++-- arch/arm/mach-ixp2000/ixdp2x00.c | 7 +++++-- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index a6f14801872..9ee63834e60 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -133,11 +133,13 @@ static void ixdp2400_pci_postinit(void) struct pci_dev *dev; if (ixdp2x00_master_npu()) { - dev = pci_find_slot(1, IXDP2400_SLAVE_ENET_DEVFN); + dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); pci_remove_bus_device(dev); + pci_dev_put(dev) } else { - dev = pci_find_slot(1, IXDP2400_MASTER_ENET_DEVFN); + dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); pci_remove_bus_device(dev); + pci_dev_put(dev) ixdp2x00_slave_pci_postinit(); } diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 91d36d91dac..70d247f09a7 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -261,14 +261,16 @@ int __init ixdp2800_pci_init(void) pci_common_init(&ixdp2800_pci); if (ixdp2x00_master_npu()) { - dev = pci_find_slot(1, IXDP2800_SLAVE_ENET_DEVFN); + dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); pci_remove_bus_device(dev); + pci_dev_put(dev); ixdp2800_master_enable_slave(); ixdp2800_master_wait_for_slave_bus_scan(); } else { - dev = pci_find_slot(1, IXDP2800_MASTER_ENET_DEVFN); + dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); pci_remove_bus_device(dev); + pci_dev_put(dev); } } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index af48cb52dfc..aa2655092d2 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -241,11 +241,14 @@ void ixdp2x00_slave_pci_postinit(void) /* * Remove PMC device is there is one */ - if((dev = pci_find_slot(1, IXDP2X00_PMC_DEVFN))) + if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { pci_remove_bus_device(dev); + pci_dev_put(dev); + } - dev = pci_find_slot(0, IXDP2X00_21555_DEVFN); + dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); pci_remove_bus_device(dev); + pci_dev_put(dev); } /************************************************************************** -- cgit v1.2.3 From 3bbe486b361b317ac7103378ed3d1aab4779715e Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 17 Oct 2006 14:28:16 -0700 Subject: [IA64] perfmon fix for global IRQ fix Missed one piece of ia64 fallout from the global IRQ patch 7d12e780e003f93433d49ce78cfedf4b4c52adc5 Perfmon interrupt handler needs to use get_irq_regs() too. Acked-by: stephane eranian Signed-off-by: Tony Luck --- arch/ia64/kernel/perfmon.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 281004ff7b0..3aaede0d698 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -5558,12 +5558,13 @@ report_spurious2: } static irqreturn_t -pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs) +pfm_interrupt_handler(int irq, void *arg) { unsigned long start_cycles, total_cycles; unsigned long min, max; int this_cpu; int ret; + struct pt_regs *regs = get_irq_regs(); this_cpu = get_cpu(); if (likely(!pfm_alt_intr_handler)) { -- cgit v1.2.3 From accaddb27a2d544e38e10ff2a2782b33bbbad913 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Mon, 16 Oct 2006 12:56:54 -0500 Subject: [IA64] - Allow IPIs in timer loop Allow pending IPIs to interrupt a timer interrupt that is looping in the do_timer() "while" loop in timer_interrupt(). (Interrupts are allowed at only 1 spot in the code). Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/kernel/time.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 41169a9bc30..39e0cd3a088 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -84,6 +84,12 @@ timer_interrupt (int irq, void *dev_id) if (time_after(new_itm, ia64_get_itc())) break; + + /* + * Allow IPIs to interrupt the timer loop. + */ + local_irq_enable(); + local_irq_disable(); } do { -- cgit v1.2.3 From c12fb1885787dcc2e20c4b88149e1e607e1293b2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 12 Oct 2006 16:20:59 -0600 Subject: [IA64] remove unused PAL_CALL_IC_OFF Linux maps PAL instructions with an ITR, but uses a DTC for PAL data. Section 11.10.2.1.3, "Making PAL Procedures Calls in Physical or Virtual Mode," of the SDM (rev 2.2), says we must therefore make all PAL calls with PSR.ic = 1 so that Linux can handle any TLB faults. PAL_CALL_IC_OFF is currently unused, and as long as we use the ITR + DTC strategy, we can't use it. So remove it. I also removed the code in ia64_pal_call_static() that conditionally cleared PSR.ic. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/pal.S | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index ebaf1e685f5..5f50e6bbc68 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -50,12 +50,10 @@ END(ia64_pal_default_handler) * * in0 Index of PAL service * in1 - in3 Remaining PAL arguments - * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic - * */ GLOBAL_ENTRY(ia64_pal_call_static) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) - alloc loc1 = ar.pfs,5,5,0,0 + .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) + alloc loc1 = ar.pfs,4,5,0,0 movl loc2 = pal_entry_point 1: { mov r28 = in0 @@ -64,7 +62,6 @@ GLOBAL_ENTRY(ia64_pal_call_static) } ;; ld8 loc2 = [loc2] // loc2 <- entry point - tbit.nz p6,p7 = in4, 0 adds r8 = 1f-1b,r8 mov loc4=ar.rsc // save RSE configuration ;; @@ -74,13 +71,11 @@ GLOBAL_ENTRY(ia64_pal_call_static) .body mov r30 = in2 -(p6) rsm psr.i | psr.ic mov r31 = in3 mov b7 = loc2 -(p7) rsm psr.i + rsm psr.i ;; -(p6) srlz.i mov rp = r8 br.cond.sptk.many b7 1: mov psr.l = loc3 -- cgit v1.2.3 From 4d5a31977cc69be8786e0033d5c148e5c62ae949 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 12 Oct 2006 16:21:17 -0600 Subject: [IA64] reformat pal.S to fit in 80 columns, fix typos Reformat to fit in 80 columns. Fix a couple typos. Remove a couple unused labels. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/pal.S | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S index 5f50e6bbc68..0b533441c3c 100644 --- a/arch/ia64/kernel/pal.S +++ b/arch/ia64/kernel/pal.S @@ -21,11 +21,12 @@ pal_entry_point: .text /* - * Set the PAL entry point address. This could be written in C code, but we do it here - * to keep it all in one module (besides, it's so trivial that it's + * Set the PAL entry point address. This could be written in C code, but we + * do it here to keep it all in one module (besides, it's so trivial that it's * not a big deal). * - * in0 Address of the PAL entry point (text address, NOT a function descriptor). + * in0 Address of the PAL entry point (text address, NOT a function + * descriptor). */ GLOBAL_ENTRY(ia64_pal_handler_init) alloc r3=ar.pfs,1,0,0,0 @@ -36,9 +37,9 @@ GLOBAL_ENTRY(ia64_pal_handler_init) END(ia64_pal_handler_init) /* - * Default PAL call handler. This needs to be coded in assembly because it uses - * the static calling convention, i.e., the RSE may not be used and calls are - * done via "br.cond" (not "br.call"). + * Default PAL call handler. This needs to be coded in assembly because it + * uses the static calling convention, i.e., the RSE may not be used and + * calls are done via "br.cond" (not "br.call"). */ GLOBAL_ENTRY(ia64_pal_default_handler) mov r8=-1 @@ -91,8 +92,8 @@ END(ia64_pal_call_static) * Make a PAL call using the stacked registers calling convention. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaning PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaining PAL arguments */ GLOBAL_ENTRY(ia64_pal_call_stacked) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4) @@ -126,18 +127,18 @@ END(ia64_pal_call_stacked) * Make a physical mode PAL call using the static registers calling convention. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaning PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaining PAL arguments * * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel. * So we don't need to clear them. */ -#define PAL_PSR_BITS_TO_CLEAR \ - (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \ - IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ +#define PAL_PSR_BITS_TO_CLEAR \ + (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT |\ + IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ IA64_PSR_DFL | IA64_PSR_DFH) -#define PAL_PSR_BITS_TO_SET \ +#define PAL_PSR_BITS_TO_SET \ (IA64_PSR_BN) @@ -173,7 +174,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) ;; andcm r16=loc3,r16 // removes bits to clear from psr br.call.sptk.many rp=ia64_switch_mode_phys -.ret1: mov rp = r8 // install return address (physical) + mov rp = r8 // install return address (physical) mov loc5 = r19 mov loc6 = r20 br.cond.sptk.many b7 @@ -183,7 +184,6 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static) mov r19=loc5 mov r20=loc6 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode -.ret2: mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 @@ -198,8 +198,8 @@ END(ia64_pal_call_phys_static) * Make a PAL call using the stacked registers in physical mode. * * Inputs: - * in0 Index of PAL service - * in2 - in3 Remaning PAL arguments + * in0 Index of PAL service + * in2 - in3 Remaining PAL arguments */ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) @@ -207,7 +207,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) movl loc2 = pal_entry_point 1: { mov r28 = in0 // copy procedure index - mov loc0 = rp // save rp + mov loc0 = rp // save rp } .body ;; @@ -240,7 +240,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) mov r16=loc3 // r16= original psr mov r19=loc5 mov r20=loc6 - br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode + br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode mov psr.l = loc3 // restore init PSR mov ar.pfs = loc1 @@ -252,10 +252,11 @@ GLOBAL_ENTRY(ia64_pal_call_phys_stacked) END(ia64_pal_call_phys_stacked) /* - * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15). + * Save scratch fp scratch regs which aren't saved in pt_regs already + * (fp10-fp15). * - * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch - * regs fp-low partition. + * NOTE: We need to do this since firmware (SAL and PAL) may use any of the + * scratch regs fp-low partition. * * Inputs: * in0 Address of stack storage for fp regs -- cgit v1.2.3 From 8611342f3dda0e13970e724129a8e2066de1362e Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 9 Oct 2006 05:24:57 -0400 Subject: [IA64] update sn2_defconfig The current sn2_defconfig is obsolete, in particular the recent ATA changes are a pain, so here's a patch to get things in sync ... at least for a day or two :) Update sn_defconfig to match current community kernel tree. Signed-off-by: Jes Sorensen Signed-off-by: Tony Luck --- arch/ia64/configs/sn2_defconfig | 219 ++++++++++++++++++++++++++++++++-------- 1 file changed, 175 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 0f14a82b856..64e951de4e5 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -1,8 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-rc3 -# Thu Apr 27 11:48:23 2006 +# Linux kernel version: 2.6.19-rc1 +# Mon Oct 9 10:53:59 2006 # +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -18,16 +19,22 @@ CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +CONFIG_TASKSTATS=y +# CONFIG_TASK_DELAY_ACCT is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_CPUSETS=y CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_TASK_XACCT=y +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -40,6 +47,8 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -58,6 +67,7 @@ CONFIG_STOP_MACHINE=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -89,7 +99,7 @@ CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_IA64_UNCACHED_ALLOCATOR=y -CONFIG_DMA_IS_DMA32=y +CONFIG_AUDIT_ARCH=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set # CONFIG_IA64_HP_ZX1 is not set @@ -116,6 +126,7 @@ CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y CONFIG_NR_CPUS=1024 # CONFIG_HOTPLUG_CPU is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_SCHED_SMT=y CONFIG_PREEMPT=y CONFIG_SELECT_MEMORY_MODEL=y @@ -128,6 +139,7 @@ CONFIG_NEED_MULTIPLE_NODES=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y +CONFIG_RESOURCES_64BIT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_DISCONTIGMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y @@ -135,15 +147,24 @@ CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=10 +CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y CONFIG_SGI_SN=y +# CONFIG_IA64_ESI is not set + +# +# SN Devices +# +CONFIG_SGI_IOC4=y +CONFIG_SGI_IOC3=y # # Firmware Drivers @@ -159,6 +180,7 @@ CONFIG_BINFMT_ELF=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set # # ACPI (Advanced Configuration and Power Interface) Support @@ -166,6 +188,7 @@ CONFIG_PM=y CONFIG_ACPI=y # CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_FAN is not set +# CONFIG_ACPI_DOCK is not set # CONFIG_ACPI_PROCESSOR is not set CONFIG_ACPI_NUMA=y CONFIG_ACPI_BLACKLIST_YEAR=0 @@ -185,7 +208,12 @@ CONFIG_ACPI_SYSTEM=y # CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +CONFIG_PCIEPORTBUS=y +CONFIG_HOTPLUG_PCI_PCIE=y +# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set +CONFIG_PCIEAER=y # CONFIG_PCI_MSI is not set +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -215,6 +243,9 @@ CONFIG_NET=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -231,19 +262,31 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=m # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_TUNNEL is not set +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -269,7 +312,6 @@ CONFIG_IPV6=m # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -298,6 +340,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker @@ -335,6 +378,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -381,6 +425,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -404,6 +449,7 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -425,12 +471,14 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transport Attributes +# SCSI Transports # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m CONFIG_SCSI_SAS_ATTRS=y +CONFIG_SCSI_SAS_LIBSAS=y +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set # # SCSI low-level drivers @@ -443,45 +491,81 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -CONFIG_SCSI_SATA=y -# CONFIG_SCSI_SATA_AHCI is not set -# CONFIG_SCSI_SATA_SVW is not set -# CONFIG_SCSI_ATA_PIIX is not set -# CONFIG_SCSI_SATA_MV is not set -# CONFIG_SCSI_SATA_NV is not set -# CONFIG_SCSI_PDC_ADMA is not set -# CONFIG_SCSI_SATA_QSTOR is not set -# CONFIG_SCSI_SATA_PROMISE is not set -# CONFIG_SCSI_SATA_SX4 is not set -# CONFIG_SCSI_SATA_SIL is not set -# CONFIG_SCSI_SATA_SIL24 is not set -# CONFIG_SCSI_SATA_SIS is not set -# CONFIG_SCSI_SATA_ULI is not set -# CONFIG_SCSI_SATA_VIA is not set -CONFIG_SCSI_SATA_VITESSE=y +# CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set CONFIG_SCSI_QLOGIC_1280=y CONFIG_SCSI_QLA_FC=y -CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE=y -# CONFIG_SCSI_QLA21XX is not set -CONFIG_SCSI_QLA22XX=y -CONFIG_SCSI_QLA2300=y -CONFIG_SCSI_QLA2322=y -# CONFIG_SCSI_QLA24XX is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +CONFIG_SATA_VITESSE=y +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + # # Multi-device support (RAID and LVM) # @@ -491,12 +575,12 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=y +CONFIG_MD_RAID456=y # CONFIG_MD_RAID5_RESHAPE is not set -# CONFIG_MD_RAID6 is not set CONFIG_MD_MULTIPATH=y # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m @@ -563,6 +647,7 @@ CONFIG_NETDEVICES=y # CONFIG_SK98LIN is not set CONFIG_TIGON3=y # CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -571,6 +656,7 @@ CONFIG_CHELSIO_T1=m # CONFIG_IXGB is not set CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -612,6 +698,7 @@ CONFIG_NET_POLL_CONTROLLER=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -646,6 +733,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -659,10 +747,12 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_N_HDLC is not set # CONFIG_SPECIALIX is not set # CONFIG_SX is not set +# CONFIG_RIO is not set # CONFIG_STALDRV is not set CONFIG_SGI_SNSC=y CONFIG_SGI_TIOCX=y CONFIG_SGI_MBCS=m +CONFIG_MSPEC=y # # Serial drivers @@ -701,6 +791,7 @@ CONFIG_EFI_RTC=y # Ftape, the floppy tape device driver # CONFIG_AGP=y +# CONFIG_AGP_SIS is not set # CONFIG_AGP_VIA is not set CONFIG_AGP_SGI_TIOCA=y # CONFIG_DRM is not set @@ -730,7 +821,6 @@ CONFIG_MMTIMER=y # # Dallas's 1-wire bus # -# CONFIG_W1 is not set # # Hardware Monitoring support @@ -741,6 +831,7 @@ CONFIG_MMTIMER=y # # Misc devices # +# CONFIG_TIFM_CORE is not set # # Multimedia devices @@ -756,6 +847,7 @@ CONFIG_MMTIMER=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -764,6 +856,7 @@ CONFIG_MMTIMER=y CONFIG_VGA_CONSOLE=y # CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -794,6 +887,7 @@ CONFIG_USB=m CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -843,6 +937,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -874,15 +969,18 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set @@ -919,18 +1017,15 @@ CONFIG_USB_MON=y CONFIG_INFINIBAND=m # CONFIG_INFINIBAND_USER_MAD is not set CONFIG_INFINIBAND_USER_ACCESS=m +CONFIG_INFINIBAND_ADDR_TRANS=y CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y +# CONFIG_INFINIBAND_AMSO1100 is not set CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_IPOIB_DEBUG=y # CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m - -# -# SN Devices -# -CONFIG_SGI_IOC4=y -CONFIG_SGI_IOC3=y +# CONFIG_INFINIBAND_ISER is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -941,6 +1036,19 @@ CONFIG_SGI_IOC3=y # # CONFIG_RTC_CLASS is not set +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + # # File systems # @@ -965,15 +1073,16 @@ CONFIG_REISERFS_FS_SECURITY=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=y -CONFIG_XFS_EXPORT=y CONFIG_XFS_QUOTA=y # CONFIG_XFS_SECURITY is not set CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y # CONFIG_QFMT_V1 is not set # CONFIG_QFMT_V2 is not set @@ -1007,8 +1116,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1046,7 +1157,7 @@ CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y +CONFIG_EXPORTFS=m CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m @@ -1056,7 +1167,9 @@ CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m # CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set # CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1128,6 +1241,10 @@ CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y +# +# Distributed Lock Manager +# + # # Library routines # @@ -1138,9 +1255,11 @@ CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=m CONFIG_ZLIB_DEFLATE=m CONFIG_GENERIC_ALLOCATOR=y +CONFIG_PLIST=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_PENDING_IRQ=y +CONFIG_IRQ_PER_CPU=y # # Instrumentation Support @@ -1152,20 +1271,26 @@ CONFIG_GENERIC_PENDING_IRQ=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=20 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_IA64_GRANULE_16MB=y @@ -1186,6 +1311,10 @@ CONFIG_SYSVIPC_COMPAT=y # Cryptographic options # CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=m CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1195,6 +1324,8 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m CONFIG_CRYPTO_DES=m # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.2.3 From 219902677351665bf0513115592a6dd665cf06e8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 29 Sep 2006 12:58:31 -0600 Subject: [IA64] remove unused acpi_kbd_controller_present, acpi_legacy_devices Nobody uses either one anymore. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/kernel/acpi.c | 9 --------- arch/ia64/sn/kernel/setup.c | 12 ------------ 2 files changed, 21 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 32c3abededc..73ef4a85b86 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -64,9 +64,6 @@ EXPORT_SYMBOL(pm_idle); void (*pm_power_off) (void); EXPORT_SYMBOL(pm_power_off); -unsigned char acpi_kbd_controller_present = 1; -unsigned char acpi_legacy_devices; - unsigned int acpi_cpei_override; unsigned int acpi_cpei_phys_cpuid; @@ -628,12 +625,6 @@ static int __init acpi_parse_fadt(unsigned long phys_addr, unsigned long size) fadt = (struct fadt_descriptor *)fadt_header; - if (!(fadt->iapc_boot_arch & BAF_8042_KEYBOARD_CONTROLLER)) - acpi_kbd_controller_present = 0; - - if (fadt->iapc_boot_arch & BAF_LEGACY_DEVICES) - acpi_legacy_devices = 1; - acpi_register_gsi(fadt->sci_int, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return 0; } diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 5f2dcba7fa8..7a2d824c5ce 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -65,7 +65,6 @@ extern void sn_timer_init(void); extern unsigned long last_time_offset; extern void (*ia64_mark_idle) (int); extern void snidle(int); -extern unsigned char acpi_kbd_controller_present; extern unsigned long long (*ia64_printk_clock)(void); unsigned long sn_rtc_cycles_per_second; @@ -452,17 +451,6 @@ void __init sn_setup(char **cmdline_p) ia64_printk_clock = ia64_sn2_printk_clock; - /* - * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard - * support here so we don't have to listen to failed keyboard probe - * messages. - */ - if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) { - printk(KERN_INFO "Disabling legacy keyboard support as prom " - "is too old and doesn't provide FADT\n"); - acpi_kbd_controller_present = 0; - } - printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); /* -- cgit v1.2.3 From 9b3377f9921766b6193861d0e3194854b1d765fe Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Mon, 16 Oct 2006 16:17:43 -0500 Subject: [IA64] Count resched interrupts Count the number of "resched" interrupts that each cpu receives. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/kernel/irq_ia64.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 68339dd0c9e..9c6dafa2d0d 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -180,7 +180,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) saved_tpr = ia64_getreg(_IA64_REG_CR_TPR); ia64_srlz_d(); while (vector != IA64_SPURIOUS_INT_VECTOR) { - if (!IS_RESCHEDULE(vector)) { + if (unlikely(IS_RESCHEDULE(vector))) + kstat_this_cpu.irqs[vector]++; + else { ia64_setreg(_IA64_REG_CR_TPR, vector); ia64_srlz_d(); @@ -225,7 +227,9 @@ void ia64_process_pending_intr(void) * Perform normal interrupt style processing */ while (vector != IA64_SPURIOUS_INT_VECTOR) { - if (!IS_RESCHEDULE(vector)) { + if (unlikely(IS_RESCHEDULE(vector))) + kstat_this_cpu.irqs[vector]++; + else { struct pt_regs *old_regs = set_irq_regs(NULL); ia64_setreg(_IA64_REG_CR_TPR, vector); @@ -258,11 +262,22 @@ void ia64_process_pending_intr(void) #ifdef CONFIG_SMP extern irqreturn_t handle_IPI (int irq, void *dev_id); +static irqreturn_t dummy_handler (int irq, void *dev_id) +{ + BUG(); +} + static struct irqaction ipi_irqaction = { .handler = handle_IPI, .flags = IRQF_DISABLED, .name = "IPI" }; + +static struct irqaction resched_irqaction = { + .handler = dummy_handler, + .flags = SA_INTERRUPT, + .name = "resched" +}; #endif void @@ -287,6 +302,7 @@ init_IRQ (void) register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL); #ifdef CONFIG_SMP register_percpu_irq(IA64_IPI_VECTOR, &ipi_irqaction); + register_percpu_irq(IA64_IPI_RESCHEDULE, &resched_irqaction); #endif #ifdef CONFIG_PERFMON pfm_init_percpu(); -- cgit v1.2.3 From b0a779debd56514b2b5de7617a1643e5dac2d4dd Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 18 Oct 2006 10:11:22 +1000 Subject: [POWERPC] Make sure interrupt enable gets restored properly The lazy IRQ disable patch missed a couple of places where the interrupt enable flags need to be restored correctly. First, we weren't restoring the paca->hard_enabled flag on interrupt exit. Instead of saving it on entry, we compute it from the MSR_EE bit in the MSR we are restoring at exit. Secondly, the MMU hash miss code was clearing both paca->soft_enabled and paca->hard_enabled but not restoring them in the case where hash_page was able to resolve the miss from the Linux page tables. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/entry_64.S | 4 ++++ arch/powerpc/kernel/head_64.S | 28 +++++++++++++++++++--------- 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index efda48741b2..86e2bdd5afd 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -489,6 +489,10 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) andi. r0,r3,MSR_RI beq- unrecov_restore + /* extract EE bit and use it to restore paca->hard_enabled */ + rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */ + stb r4,PACAHARDIRQEN(r13) + andi. r0,r3,MSR_PR /* diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index c93d9f35a12..d2890050b7e 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -961,10 +961,18 @@ bad_stack: * any task or sent any task a signal, you should use * ret_from_except or ret_from_except_lite instead of this. */ +fast_exc_return_irq: /* restores irq state too */ + ld r3,SOFTE(r1) + ld r12,_MSR(r1) + stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */ + rldicl r4,r12,49,63 /* get MSR_EE to LSB */ + stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ + b 1f + .globl fast_exception_return fast_exception_return: ld r12,_MSR(r1) - ld r11,_NIP(r1) +1: ld r11,_NIP(r1) andi. r3,r12,MSR_RI /* check if RI is set */ beq- unrecov_fer @@ -1361,6 +1369,16 @@ BEGIN_FW_FTR_SECTION * interrupts if necessary. */ beq .ret_from_except_lite +END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) +#endif +BEGIN_FW_FTR_SECTION + /* + * Here we have interrupts hard-disabled, so it is sufficient + * to restore paca->{soft,hard}_enable and get out. + */ + beq fast_exc_return_irq /* Return from exception on success */ +END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) + /* For a hash failure, we don't bother re-enabling interrupts */ ble- 12f @@ -1372,14 +1390,6 @@ BEGIN_FW_FTR_SECTION ld r3,SOFTE(r1) bl .local_irq_restore b 11f -END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) -#endif -BEGIN_FW_FTR_SECTION - beq fast_exception_return /* Return from exception on success */ - ble- 12f /* Failure return from hash_page */ - - /* fall through */ -END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* Here we have a page fault that hash_page can't handle. */ _GLOBAL(handle_page_fault) -- cgit v1.2.3 From 7341df16a1f228be833e918cb42534a34381a37e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Oct 2006 00:24:14 -0700 Subject: [SPARC]: Kill BOOTME_SINGLE. Unused, but still allow the '-s' boot option to be passed down to init. Based upon patches by Martin Habets. Signed-off-by: David S. Miller --- arch/sparc/kernel/setup.c | 2 -- arch/sparc64/kernel/setup.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index f5ee1ac834b..383526ad94f 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -103,7 +103,6 @@ void prom_sync_me(void) unsigned int boot_flags __initdata = 0; #define BOOTME_DEBUG 0x1 -#define BOOTME_SINGLE 0x2 /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size __initdata = 0; @@ -132,7 +131,6 @@ static void __init process_switch(char c) boot_flags |= BOOTME_DEBUG; break; case 's': - boot_flags |= BOOTME_SINGLE; break; case 'h': prom_printf("boot_flags_init: Halt!\n"); diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index cc8ad480a20..bf033b31d43 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c @@ -74,7 +74,6 @@ prom_console_write(struct console *con, const char *s, unsigned n) unsigned int boot_flags = 0; #define BOOTME_DEBUG 0x1 -#define BOOTME_SINGLE 0x2 /* Exported for mm/init.c:paging_init. */ unsigned long cmdline_memory_size = 0; @@ -102,7 +101,6 @@ static void __init process_switch(char c) boot_flags |= BOOTME_DEBUG; break; case 's': - boot_flags |= BOOTME_SINGLE; break; case 'h': prom_printf("boot_flags_init: Halt!\n"); -- cgit v1.2.3 From 5aee87c43e3a71a4aa4e72b0dc2180e4952c0848 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Oct 2006 19:04:44 -0700 Subject: [SPARC64]: Fix PCI memory space root resource on Hummingbird. For Hummingbird PCI controllers, we should create the root PCI memory space resource as the full 4GB area, and then allocate the IOMMU DMA translation window out of there. The old code just assumed that the IOMMU DMA translation base to the top of the 4GB area was unusable. This is not true on many systems such as SB100 and SB150, where the IOMMU DMA translation window sits at 0xc0000000->0xdfffffff. So what would happen is that any device mapped by the firmware at the top section 0xe0000000->0xffffffff would get remapped by Linux somewhere else leading to all kinds of problems and boot failures. While we're here, report more cases of OBP resource assignment conflicts. The only truly valid ones are ROM resource conflicts. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_common.c | 29 ++++++++++------------------- arch/sparc64/kernel/pci_sabre.c | 23 +++++++++++++++++++---- 2 files changed, 29 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 7a59cc72c84..827ae30aa49 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -330,19 +330,6 @@ __init get_device_resource(struct linux_prom_pci_registers *ap, return res; } -static int __init pdev_resource_collisions_expected(struct pci_dev *pdev) -{ - if (pdev->vendor != PCI_VENDOR_ID_SUN) - return 0; - - if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS || - pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 || - pdev->device == PCI_DEVICE_ID_SUN_RIO_USB) - return 1; - - return 0; -} - static void __init pdev_record_assignments(struct pci_pbm_info *pbm, struct pci_dev *pdev) { @@ -400,19 +387,23 @@ static void __init pdev_record_assignments(struct pci_pbm_info *pbm, pbm->parent->resource_adjust(pdev, res, root); if (request_resource(root, res) < 0) { + int rnum; + /* OK, there is some conflict. But this is fine * since we'll reassign it in the fixup pass. * - * We notify the user that OBP made an error if it - * is a case we don't expect. + * Do not print the warning for ROM resources + * as such a conflict is quite common and + * harmless as the ROM bar is disabled. */ - if (!pdev_resource_collisions_expected(pdev)) { - printk(KERN_ERR "PCI: Address space collision on region %ld " + rnum = (res - &pdev->resource[0]); + if (rnum != PCI_ROM_RESOURCE) + printk(KERN_ERR "PCI: Resource collision, " + "region %d " "[%016lx:%016lx] of device %s\n", - (res - &pdev->resource[0]), + rnum, res->start, res->end, pci_name(pdev)); - } } } } diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 6ec569828c2..de7f7850a84 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p, &pbm->mem_space); } -static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin) +static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_start, u32 dma_end) { struct pci_pbm_info *pbm; struct device_node *node; @@ -1261,6 +1261,8 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp node = node->sibling; } if (simbas_found == 0) { + struct resource *rp; + /* No APBs underneath, probably this is a hummingbird * system. */ @@ -1302,8 +1304,10 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL; pbm->io_space.flags = IORESOURCE_IO; - pbm->mem_space.start = p->pbm_A.controller_regs + SABRE_MEMSPACE; - pbm->mem_space.end = pbm->mem_space.start + (unsigned long)dma_begin - 1UL; + pbm->mem_space.start = + (p->pbm_A.controller_regs + SABRE_MEMSPACE); + pbm->mem_space.end = + (pbm->mem_space.start + ((1UL << 32UL) - 1UL)); pbm->mem_space.flags = IORESOURCE_MEM; if (request_resource(&ioport_resource, &pbm->io_space) < 0) { @@ -1315,6 +1319,17 @@ static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp prom_halt(); } + rp = kmalloc(sizeof(*rp), GFP_KERNEL); + if (!rp) { + prom_printf("Cannot allocate IOMMU resource.\n"); + prom_halt(); + } + rp->name = "IOMMU"; + rp->start = pbm->mem_space.start + (unsigned long) dma_start; + rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL; + rp->flags = IORESOURCE_BUSY; + request_resource(&pbm->mem_space, rp); + pci_register_legacy_regions(&pbm->io_space, &pbm->mem_space); } @@ -1450,5 +1465,5 @@ void sabre_init(struct device_node *dp, char *model_name) /* * Look for APB underneath. */ - sabre_pbm_init(p, dp, vdma[0]); + sabre_pbm_init(p, dp, vdma[0], vdma[1]); } -- cgit v1.2.3 From 9550e59c4587f637d9aa34689e32eea460e6f50c Mon Sep 17 00:00:00 2001 From: Martin Habets Date: Tue, 17 Oct 2006 19:21:48 -0700 Subject: [SPARC]: Add sparc profiling support This patch adds profiling support to the sparc architecture. It is a copy of the sparc64 implementation. Signed-off-by: Martin Habets Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 7 +++++++ arch/sparc/Makefile | 2 ++ arch/sparc/kernel/time.c | 2 ++ arch/sparc/oprofile/Kconfig | 17 +++++++++++++++++ arch/sparc/oprofile/Makefile | 9 +++++++++ arch/sparc/oprofile/init.c | 23 +++++++++++++++++++++++ 6 files changed, 60 insertions(+) create mode 100644 arch/sparc/oprofile/Kconfig create mode 100644 arch/sparc/oprofile/Makefile create mode 100644 arch/sparc/oprofile/init.c (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 9431e967aa4..2f96610a83e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -289,6 +289,13 @@ endmenu source "fs/Kconfig" +menu "Instrumentation Support" + depends on EXPERIMENTAL + +source "arch/sparc/oprofile/Kconfig" + +endmenu + source "arch/sparc/Kconfig.debug" source "security/Kconfig" diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 4cdbb2d59ed..f33c3817f01 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -30,6 +30,8 @@ HEAD_Y := $(head-y) core-y += arch/sparc/kernel/ arch/sparc/mm/ arch/sparc/math-emu/ libs-y += arch/sparc/prom/ arch/sparc/lib/ +drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ + # Export what is needed by arch/sparc/boot/Makefile # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-) INIT_Y := $(patsubst %/, %/built-in.o, $(init-y)) diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 7dcd1a16c6e..6c7aa51b590 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -95,6 +95,8 @@ unsigned long profile_pc(struct pt_regs *regs) return pc; } +EXPORT_SYMBOL(profile_pc); + __volatile__ unsigned int *master_l10_counter; __volatile__ unsigned int *master_l10_limit; diff --git a/arch/sparc/oprofile/Kconfig b/arch/sparc/oprofile/Kconfig new file mode 100644 index 00000000000..d8a84088471 --- /dev/null +++ b/arch/sparc/oprofile/Kconfig @@ -0,0 +1,17 @@ +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + diff --git a/arch/sparc/oprofile/Makefile b/arch/sparc/oprofile/Makefile new file mode 100644 index 00000000000..e9feca1ca28 --- /dev/null +++ b/arch/sparc/oprofile/Makefile @@ -0,0 +1,9 @@ +obj-$(CONFIG_OPROFILE) += oprofile.o + +DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ + oprof.o cpu_buffer.o buffer_sync.o \ + event_buffer.o oprofile_files.o \ + oprofilefs.o oprofile_stats.o \ + timer_int.o ) + +oprofile-y := $(DRIVER_OBJS) init.o diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c new file mode 100644 index 00000000000..9ab815b95b5 --- /dev/null +++ b/arch/sparc/oprofile/init.c @@ -0,0 +1,23 @@ +/** + * @file init.c + * + * @remark Copyright 2002 OProfile authors + * @remark Read the file COPYING + * + * @author John Levon + */ + +#include +#include +#include +#include + +int __init oprofile_arch_init(struct oprofile_operations * ops) +{ + return -ENODEV; +} + + +void oprofile_arch_exit(void) +{ +} -- cgit v1.2.3 From f6d7b8a7c9e21a58890a8532143e241409b78664 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Tue, 17 Oct 2006 19:23:23 -0700 Subject: [SPARC]: Sparc compilation fix with floppy enabled This patch fixes a typo to make kernel compilable when floppy driver for Sparc is build. Signed-off-by: Krzysztof Helt Signed-off-by: David S. Miller --- arch/sparc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index b3b6680a2a3..c8cb211b907 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -351,7 +351,7 @@ void handler_irq(int irq, struct pt_regs * regs) } #ifdef CONFIG_BLK_DEV_FD -extern void floppy_interrupt(int irq, void *dev_id) +extern void floppy_interrupt(int irq, void *dev_id); void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) { -- cgit v1.2.3 From 73ed9a86cd77b6a3b46beec8d353ac3b0d4f50c1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Oct 2006 19:29:41 -0700 Subject: [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index dcae559879a..2f4612fa81f 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Thu Oct 5 02:08:41 2006 +# Linux kernel version: 2.6.19-rc2 +# Tue Oct 17 19:29:20 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -217,6 +217,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -333,6 +334,12 @@ CONFIG_CDROM_PKTCDVD_BUFFERS=8 CONFIG_CDROM_PKTCDVD_WCACHE=y CONFIG_ATA_OVER_ETH=m +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -728,7 +735,6 @@ CONFIG_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -841,11 +847,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_W83627EHF is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Misc devices -# -# CONFIG_TIFM_CORE is not set - # # Multimedia devices # @@ -1104,7 +1105,6 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1150,6 +1150,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1234,6 +1235,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1361,10 +1363,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set -# -# Distributed Lock Manager -# - # # Instrumentation Support # @@ -1399,6 +1397,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_LIST is not set # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set # CONFIG_DEBUG_STACK_USAGE is not set -- cgit v1.2.3 From c888554bf95a5a0a6ac3e2389c6bf1e03e9480ba Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 16 Oct 2006 13:49:27 -0700 Subject: [POWERPC] More bootwrapper reorganization More reorganization of the bootwrapper: - Add dtb section to zImage - ft_init now called by platform_init - Pack a flat dt before calling kernel - Remove size parameter from free - printf only calls console_ops.write it its not NULL - Some cleanup Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/main.c | 27 ++++++--------------------- arch/powerpc/boot/of.c | 8 +------- arch/powerpc/boot/ops.h | 25 ++++++++++++++----------- arch/powerpc/boot/stdio.c | 3 ++- arch/powerpc/boot/wrapper | 4 ++-- arch/powerpc/boot/zImage.coff.lds.S | 4 ++++ arch/powerpc/boot/zImage.lds.S | 5 +++++ 7 files changed, 34 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index d719bb9333d..418497482b6 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -27,6 +27,8 @@ extern char _vmlinux_start[]; extern char _vmlinux_end[]; extern char _initrd_start[]; extern char _initrd_end[]; +extern char _dtb_start[]; +extern char _dtb_end[]; struct addr_range { unsigned long addr; @@ -250,10 +252,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) flush_cache((void *)vmlinux.addr, vmlinux.size); } -void __attribute__ ((weak)) ft_init(void *dt_blob) -{ -} - /* A buffer that may be edited by tools operating on a zImage binary so as to * edit the command line passed to vmlinux (by setting /chosen/bootargs). * The buffer is put in it's own section so that tools may locate it easier. @@ -285,19 +283,12 @@ static void set_cmdline(char *buf) setprop(devp, "bootargs", buf, strlen(buf) + 1); } -/* Section where ft can be tacked on after zImage is built */ -union blobspace { - struct boot_param_header hdr; - char space[8*1024]; -} dt_blob __attribute__((__section__("__builtin_ft"))); - struct platform_ops platform_ops; struct dt_ops dt_ops; struct console_ops console_ops; void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) { - int have_dt = 0; kernel_entry_t kentry; char cmdline[COMMAND_LINE_SIZE]; @@ -306,15 +297,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) memset(&dt_ops, 0, sizeof(dt_ops)); memset(&console_ops, 0, sizeof(console_ops)); - /* Override the dt_ops and device tree if there was an flat dev - * tree attached to the zImage. - */ - if (dt_blob.hdr.magic == OF_DT_HEADER) { - have_dt = 1; - ft_init(&dt_blob); - } - - if (platform_init(promptr)) + if (platform_init(promptr, _dtb_start, _dtb_end)) exit(); if (console_ops.open && (console_ops.open() < 0)) exit(); @@ -342,8 +325,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) console_ops.close(); kentry = (kernel_entry_t) vmlinux.addr; - if (have_dt) + if (_dtb_end > _dtb_start) { + dt_ops.ft_pack(); kentry(dt_ops.ft_addr(), 0, NULL); + } else /* XXX initrd addr/size should be passed in properties */ kentry(a1, a2, promptr); diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c index 3a71845afc6..0182f384f3e 100644 --- a/arch/powerpc/boot/of.c +++ b/arch/powerpc/boot/of.c @@ -256,24 +256,18 @@ static void of_console_write(char *buf, int len) call_prom("write", 3, 1, of_stdout_handle, buf, len); } -int platform_init(void *promptr) +int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end) { - platform_ops.fixups = NULL; platform_ops.image_hdr = of_image_hdr; platform_ops.malloc = of_try_claim; - platform_ops.free = NULL; platform_ops.exit = of_exit; dt_ops.finddevice = of_finddevice; dt_ops.getprop = of_getprop; dt_ops.setprop = of_setprop; - dt_ops.translate_addr = NULL; console_ops.open = of_console_open; console_ops.write = of_console_write; - console_ops.edit_cmdline = NULL; - console_ops.close = NULL; - console_ops.data = NULL; prom = (int (*)(void *))promptr; return 0; diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 135eb4bb03b..59832fb0f27 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -22,7 +22,8 @@ struct platform_ops { void (*fixups)(void); void (*image_hdr)(const void *); void * (*malloc)(u32 size); - void (*free)(void *ptr, u32 size); + void (*free)(void *ptr); + void * (*realloc)(void *ptr, unsigned long size); void (*exit)(void); }; extern struct platform_ops platform_ops; @@ -30,12 +31,11 @@ extern struct platform_ops platform_ops; /* Device Tree operations */ struct dt_ops { void * (*finddevice)(const char *name); - int (*getprop)(const void *node, const char *name, void *buf, + int (*getprop)(const void *phandle, const char *name, void *buf, const int buflen); - int (*setprop)(const void *node, const char *name, + int (*setprop)(const void *phandle, const char *name, const void *buf, const int buflen); - u64 (*translate_addr)(const char *path, const u32 *in_addr, - const u32 addr_len); + void (*ft_pack)(void); unsigned long (*ft_addr)(void); }; extern struct dt_ops dt_ops; @@ -59,10 +59,13 @@ struct serial_console_data { void (*close)(void); }; -extern int platform_init(void *promptr); -extern void simple_alloc_init(void); -extern void ft_init(void *dt_blob); -extern int serial_console_init(void); +int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end); +int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device); +int serial_console_init(void); +int ns16550_console_init(void *devp, struct serial_console_data *scdp); +void *simple_alloc_init(char *base, u32 heap_size, u32 granularity, + u32 max_allocs); + static inline void *finddevice(const char *name) { @@ -84,10 +87,10 @@ static inline void *malloc(u32 size) return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; } -static inline void free(void *ptr, u32 size) +static inline void free(void *ptr) { if (platform_ops.free) - platform_ops.free(ptr, size); + platform_ops.free(ptr); } static inline void exit(void) diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c index 6d5f6382e1c..0a9feeb9834 100644 --- a/arch/powerpc/boot/stdio.c +++ b/arch/powerpc/boot/stdio.c @@ -320,6 +320,7 @@ printf(const char *fmt, ...) va_start(args, fmt); n = vsprintf(sprint_buf, fmt, args); va_end(args); - console_ops.write(sprint_buf, n); + if (console_ops.write) + console_ops.write(sprint_buf, n); return n; } diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index eab7318729e..b5fb1fee76f 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -179,11 +179,11 @@ if [ -z "$cacheit" ]; then fi if [ -n "$initrd" ]; then - addsec $tmp "$initrd" initrd + addsec $tmp "$initrd" $isection fi if [ -n "$dtb" ]; then - addsec $tmp "$dtb" dtb + addsec $tmp "$dtb" .kernel:dtb fi if [ "$platform" != "miboot" ]; then diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S index 05f32388b95..a360905e542 100644 --- a/arch/powerpc/boot/zImage.coff.lds.S +++ b/arch/powerpc/boot/zImage.coff.lds.S @@ -21,6 +21,10 @@ SECTIONS *(.got2) __got2_end = .; + _dtb_start = .; + *(.kernel:dtb) + _dtb_end = .; + _vmlinux_start = .; *(.kernel:vmlinux.strip) _vmlinux_end = .; diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 4b6bb3ffe3d..4be3c6414b0 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -21,6 +21,11 @@ SECTIONS __got2_end = .; } + . = ALIGN(8); + _dtb_start = .; + .kernel:dtb : { *(.kernel:dtb) } + _dtb_end = .; + . = ALIGN(4096); _vmlinux_start = .; .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } -- cgit v1.2.3 From 1df23957ba2da6eb8c7a5c2ad7bb1d4732132873 Mon Sep 17 00:00:00 2001 From: Cedric Le Goater Date: Wed, 18 Oct 2006 18:30:41 +0200 Subject: [S390] fix vmlinux link when CONFIG_SYSIPC=n Fix the following compile error: CC init/version.o LD init/built-in.o LD .tmp_vmlinux1 arch/s390/kernel/built-in.o(.text+0xdba4): In function `sys32_ipc': : undefined reference to `compat_sys_semtimedop' arch/s390/kernel/built-in.o(.text+0xdbee): In function `sys32_ipc': : undefined reference to `compat_sys_semctl' arch/s390/kernel/built-in.o(.text+0xdc08): In function `sys32_ipc': : undefined reference to `compat_sys_msgsnd' arch/s390/kernel/built-in.o(.text+0xdc30): In function `sys32_ipc': : undefined reference to `compat_sys_msgrcv' arch/s390/kernel/built-in.o(.text+0xdc58): In function `sys32_ipc': : undefined reference to `compat_sys_msgctl' arch/s390/kernel/built-in.o(.text+0xdc76): In function `sys32_ipc': : undefined reference to `compat_sys_shmat' arch/s390/kernel/built-in.o(.text+0xdcb0): In function `sys32_ipc': : undefined reference to `compat_sys_shmctl' make: *** [.tmp_vmlinux1] Error 1 Signed-off-by: Cedric Le Goater Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_linux.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index e15e1489aef..2001767e1dc 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -295,6 +295,7 @@ static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) * * This is really horribly ugly. */ +#ifdef CONFIG_SYSVIPC asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) { if (call >> 16) /* hack for backward compatibility */ @@ -338,6 +339,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) return -ENOSYS; } +#endif asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) { -- cgit v1.2.3 From f5956f84072804712cb7b663c5c64e9800180833 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 18 Oct 2006 18:30:45 +0200 Subject: [S390] Wire up epoll_pwait syscall. Signed-off-by: Heiko Carstens --- arch/s390/kernel/syscalls.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index e59baec5652..a4ceae3dbcf 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -320,3 +320,4 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) +SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall) -- cgit v1.2.3 From ce9b18f5cdd628196ca13bb783e8dcd5ad29ceaa Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 18 Oct 2006 18:30:59 +0200 Subject: [S390] update default configuration Signed-off-by: Martin Schwidefsky --- arch/s390/defconfig | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/s390/defconfig b/arch/s390/defconfig index a3257398ea8..c313e9a9304 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Wed Oct 4 19:45:46 2006 +# Linux kernel version: 2.6.19-rc2 +# Wed Oct 18 17:11:10 2006 # CONFIG_MMU=y CONFIG_LOCKDEP_SUPPORT=y @@ -211,6 +211,7 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -528,6 +529,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -645,10 +647,6 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_NLS is not set -# -# Distributed Lock Manager -# - # # Instrumentation Support # @@ -669,7 +667,6 @@ CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_DETECT_SOFTLOCKUP is not set # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set CONFIG_DEBUG_PREEMPT=y @@ -690,6 +687,7 @@ CONFIG_DEBUG_FS=y # CONFIG_FRAME_POINTER is not set # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +CONFIG_HEADERS_CHECK=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set -- cgit v1.2.3 From b5e4efe7e061ff52ac97b9fa45acca529d8daeea Mon Sep 17 00:00:00 2001 From: "eiichiro.oiwa.nm@hitachi.com" Date: Thu, 28 Sep 2006 13:55:47 +0900 Subject: PCI: Turn pci_fixup_video into generic for embedded VGA pci_fixup_video turns into generic code because there are many platforms need this fixup for embedded VGA as well as x86. The Video BIOS integrates into System BIOS on a machine has embedded VGA although embedded VGA generally don't have PCI ROM. As a result, embedded VGA need the way that the sysfs rom points to the Video BIOS of System RAM (0xC0000). PCI-to-PCI Bridge Architecture specification describes the condition whether or not PCI ROM forwards VGA compatible memory address. fixup_video suits this specification. Although the Video ROM generally implements in x86 code regardless of platform, some application such as X Window System can run this code by dosemu86. Therefore, pci_fixup_video should turn into generic code. Signed-off-by: Eiichiro Oiwa Acked-by: Alan Cox Acked-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 45 --------------------------------------------- 1 file changed, 45 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index b60d7e8689e..908b410f4c9 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -342,51 +342,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_r DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk ); -/* - * Fixup to mark boot BIOS video selected by BIOS before it changes - * - * From information provided by "Jon Smirl" - * - * The standard boot ROM sequence for an x86 machine uses the BIOS - * to select an initial video card for boot display. This boot video - * card will have it's BIOS copied to C0000 in system RAM. - * IORESOURCE_ROM_SHADOW is used to associate the boot video - * card with this copy. On laptops this copy has to be used since - * the main ROM may be compressed or combined with another image. - * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW - * is marked here since the boot video device will be the only enabled - * video device at this point. - */ - -static void __devinit pci_fixup_video(struct pci_dev *pdev) -{ - struct pci_dev *bridge; - struct pci_bus *bus; - u16 config; - - if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) - return; - - /* Is VGA routed to us? */ - bus = pdev->bus; - while (bus) { - bridge = bus->self; - if (bridge) { - pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, - &config); - if (!(config & PCI_BRIDGE_CTL_VGA)) - return; - } - bus = bus->parent; - } - pci_read_config_word(pdev, PCI_COMMAND, &config); - if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { - pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; - printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); - /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. * -- cgit v1.2.3 From 6b4b78fed47e7380dfe9280b154e8b9bfcd4c86c Mon Sep 17 00:00:00 2001 From: Matt Domsch Date: Fri, 29 Sep 2006 15:23:23 -0500 Subject: PCI: optionally sort device lists breadth-first Problem: New Dell PowerEdge servers have 2 embedded ethernet ports, which are labeled NIC1 and NIC2 on the chassis, in the BIOS setup screens, and in the printed documentation. Assuming no other add-in ethernet ports in the system, Linux 2.4 kernels name these eth0 and eth1 respectively. Many people have come to expect this naming. Linux 2.6 kernels name these eth1 and eth0 respectively (backwards from expectations). I also have reports that various Sun and HP servers have similar behavior. Root cause: Linux 2.4 kernels walk the pci_devices list, which happens to be sorted in breadth-first order (or pcbios_find_device order on i386, which most often is breadth-first also). 2.6 kernels have both the pci_devices list and the pci_bus_type.klist_devices list, the latter is what is walked at driver load time to match the pci_id tables; this klist happens to be in depth-first order. On systems where, for physical routing reasons, NIC1 appears on a lower bus number than NIC2, but NIC2's bridge is discovered first in the depth-first ordering, NIC2 will be discovered before NIC1. If the list were sorted breadth-first, NIC1 would be discovered before NIC2. A PowerEdge 1955 system has the following topology which easily exhibits the difference between depth-first and breadth-first device lists. -[0000:00]-+-00.0 Intel Corporation 5000P Chipset Memory Controller Hub +-02.0-[0000:03-08]--+-00.0-[0000:04-07]--+-00.0-[0000:05-06]----00.0-[0000:06]----00.0 Broadcom Corporation NetXtreme II BCM5708S Gigabit Ethernet (labeled NIC2, 2.4 kernel name eth1, 2.6 kernel name eth0) +-1c.0-[0000:01-02]----00.0-[0000:02]----00.0 Broadcom Corporation NetXtreme II BCM5708S Gigabit Ethernet (labeled NIC1, 2.4 kernel name eth0, 2.6 kernel name eth1) Other factors, such as device driver load order and the presence of PCI slots at various points in the bus hierarchy further complicate this problem; I'm not trying to solve those here, just restore the device order, and thus basic behavior, that 2.4 kernels had. Solution: The solution can come in multiple steps. Suggested fix #1: kernel Patch below optionally sorts the two device lists into breadth-first ordering to maintain compatibility with 2.4 kernels. It adds two new command line options: pci=bfsort pci=nobfsort to force the sort order, or not, as you wish. It also adds DMI checks for the specific Dell systems which exhibit "backwards" ordering, to make them "right". Suggested fix #2: udev rules from userland Many people also have the expectation that embedded NICs are always discovered before add-in NICs (which this patch does not try to do). Using the PCI IRQ Routing Table provided by system BIOS, it's easy to determine which PCI devices are embedded, or if add-in, which PCI slot they're in. I'm working on a tool that would allow udev to name ethernet devices in ascending embedded, slot 1 .. slot N order, subsort by PCI bus/dev/fn breadth-first. It'll be possible to use it independent of udev as well for those distributions that don't use udev in their installers. Suggested fix #3: system board routing rules One can constrain the system board layout to put NIC1 ahead of NIC2 regardless of breadth-first or depth-first discovery order. This adds a significant level of complexity to board routing, and may not be possible in all instances (witness the above systems from several major manufacturers). I don't want to encourage this particular train of thought too far, at the expense of not doing #1 or #2 above. Feedback appreciated. Patch tested on a Dell PowerEdge 1955 blade with 2.6.18. You'll also note I took some liberty and temporarily break the klist abstraction to simplify and speed up the sort algorithm. I think that's both safe and appropriate in this instance. Signed-off-by: Matt Domsch Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-- arch/i386/pci/pci.h | 7 ++++++ 2 files changed, 64 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 68bce194e68..6d5ace845e4 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -20,6 +20,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; +int pci_bf_sort; int pci_routeirq; int pcibios_last_bus = -1; unsigned long pirq_table_addr; @@ -117,6 +118,20 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) pci_read_bridge_bases(b); } +/* + * Only use DMI information to set this if nothing was passed + * on the kernel command line (which was parsed earlier). + */ + +static int __devinit set_bf_sort(struct dmi_system_id *d) +{ + if (pci_bf_sort == pci_bf_sort_default) { + pci_bf_sort = pci_dmi_bf; + printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); + } + return 0; +} + /* * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) */ @@ -130,11 +145,11 @@ static int __devinit assign_all_busses(struct dmi_system_id *d) } #endif +static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { +#ifdef __i386__ /* * Laptops which need pci=assign-busses to see Cardbus cards */ -static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { -#ifdef __i386__ { .callback = assign_all_busses, .ident = "Samsung X20 Laptop", @@ -144,6 +159,38 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { }, }, #endif /* __i386__ */ + { + .callback = set_bf_sort, + .ident = "Dell PowerEdge 1950", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), + }, + }, + { + .callback = set_bf_sort, + .ident = "Dell PowerEdge 1955", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), + }, + }, + { + .callback = set_bf_sort, + .ident = "Dell PowerEdge 2900", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), + }, + }, + { + .callback = set_bf_sort, + .ident = "Dell PowerEdge 2950", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell"), + DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), + }, + }, {} }; @@ -189,6 +236,8 @@ static int __init pcibios_init(void) pcibios_resource_survey(); + if (pci_bf_sort >= pci_force_bf) + pci_sort_breadthfirst(); #ifdef CONFIG_PCI_BIOS if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); @@ -203,6 +252,12 @@ char * __devinit pcibios_setup(char *str) if (!strcmp(str, "off")) { pci_probe = 0; return NULL; + } else if (!strcmp(str, "bfsort")) { + pci_bf_sort = pci_force_bf; + return NULL; + } else if (!strcmp(str, "nobfsort")) { + pci_bf_sort = pci_force_nobf; + return NULL; } #ifdef CONFIG_PCI_BIOS else if (!strcmp(str, "bios")) { diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 1814f74569c..ad065cebd7b 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -30,6 +30,13 @@ extern unsigned int pci_probe; extern unsigned long pirq_table_addr; +enum pci_bf_sort_state { + pci_bf_sort_default, + pci_force_nobf, + pci_force_bf, + pci_dmi_bf, +}; + /* pci-i386.c */ extern unsigned int pcibios_max_latency; -- cgit v1.2.3 From 6b0022305f80cf249de69e746f6f5ccf7ffc5b7c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 12 Oct 2006 17:07:45 +0900 Subject: sh: Proper show_stack/show_trace() implementation. This splits out some of the previous show_stack() implementation which was mostly doing the show_trace() work without actually dumping any of the stack contents. This now gets split in to two sections, where we do the fetching of the stack pointer and subsequent stack dumping in show_stack(), while moving the call trace in to show_trace(). Signed-off-by: Paul Mundt --- arch/sh/kernel/process.c | 12 +---- arch/sh/kernel/traps.c | 124 ++++++++++++++++++++++++++++------------------- 2 files changed, 75 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 91516dca4a8..a52b13ac6b7 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -105,7 +105,7 @@ void show_regs(struct pt_regs * regs) { printk("\n"); printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); - print_symbol("PC is at %s\n", regs->pc); + print_symbol("PC is at %s\n", instruction_pointer(regs)); printk("PC : %08lx SP : %08lx SR : %08lx ", regs->pc, regs->regs[15], regs->sr); #ifdef CONFIG_MMU @@ -130,15 +130,7 @@ void show_regs(struct pt_regs * regs) printk("MACH: %08lx MACL: %08lx GBR : %08lx PR : %08lx\n", regs->mach, regs->macl, regs->gbr, regs->pr); - /* - * If we're in kernel mode, dump the stack too.. - */ - if (!user_mode(regs)) { - extern void show_task(unsigned long *sp); - unsigned long sp = regs->regs[15]; - - show_task((unsigned long *)sp); - } + show_trace(NULL, (unsigned long *)regs->regs[15], regs); } /* diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index c2c597e0948..ffe127f09f3 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -1,16 +1,15 @@ -/* $Id: traps.c,v 1.17 2004/05/02 01:46:30 sugioka Exp $ - * - * linux/arch/sh/traps.c +/* + * 'traps.c' handles hardware traps and faults after we have saved some + * state in 'entry.S'. * * SuperH version: Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf * Copyright (C) 2000 David Howells - * Copyright (C) 2002, 2003 Paul Mundt - */ - -/* - * 'Traps.c' handles hardware traps and faults after we have saved some - * state in 'entry.S'. + * Copyright (C) 2002 - 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include #include @@ -53,13 +52,32 @@ #define TRAP_ILLEGAL_SLOT_INST 13 #endif -/* - * These constants are for searching for possible module text - * segments. VMALLOC_OFFSET comes from mm/vmalloc.c; MODULE_RANGE is - * a guess of how much space is likely to be vmalloced. - */ -#define VMALLOC_OFFSET (8*1024*1024) -#define MODULE_RANGE (8*1024*1024) +static void dump_mem(const char *str, unsigned long bottom, unsigned long top) +{ + unsigned long p; + int i; + + printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); + + for (p = bottom & ~31; p < top; ) { + printk("%04lx: ", p & 0xffff); + + for (i = 0; i < 8; i++, p += 4) { + unsigned int val; + + if (p < bottom || p >= top) + printk(" "); + else { + if (__get_user(val, (unsigned int __user *)p)) { + printk("\n"); + return; + } + printk("%08x ", val); + } + } + printk("\n"); + } +} DEFINE_SPINLOCK(die_lock); @@ -69,14 +87,28 @@ void die(const char * str, struct pt_regs * regs, long err) console_verbose(); spin_lock_irq(&die_lock); + bust_spinlocks(1); + printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); + CHK_REMOTE_DEBUG(regs); + print_modules(); show_regs(regs); + + printk("Process: %s (pid: %d, stack limit = %p)\n", + current->comm, current->pid, task_stack_page(current) + 1); + + if (!user_mode(regs) || in_interrupt()) + dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + + (unsigned long)task_stack_page(current)); + + bust_spinlocks(0); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); } -static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) +static inline void die_if_kernel(const char *str, struct pt_regs *regs, + long err) { if (!user_mode(regs)) die(str, regs, err); @@ -93,8 +125,7 @@ static int handle_unaligned_notify_count = 10; */ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) { - if (!user_mode(regs)) - { + if (!user_mode(regs)) { const struct exception_table_entry *fixup; fixup = search_exception_tables(regs->pc); if (fixup) { @@ -734,52 +765,43 @@ void __init trap_init(void) per_cpu_trap_init(); } -void show_stack(struct task_struct *tsk, unsigned long *sp) +void show_trace(struct task_struct *tsk, unsigned long *sp, + struct pt_regs *regs) { - unsigned long *stack, addr; - unsigned long module_start = VMALLOC_START; - unsigned long module_end = VMALLOC_END; - int i = 1; + unsigned long addr; - if (!tsk) - tsk = current; - if (tsk == current) - sp = (unsigned long *)current_stack_pointer; - else - sp = (unsigned long *)tsk->thread.sp; - - stack = sp; + if (regs && user_mode(regs)) + return; printk("\nCall trace: "); #ifdef CONFIG_KALLSYMS printk("\n"); #endif - while (!kstack_end(stack)) { - addr = *stack++; - if (((addr >= (unsigned long)_text) && - (addr <= (unsigned long)_etext)) || - ((addr >= module_start) && (addr <= module_end))) { - /* - * For 80-columns display, 6 entry is maximum. - * NOTE: '[<8c00abcd>] ' consumes 13 columns . - */ -#ifndef CONFIG_KALLSYMS - if (i && ((i % 6) == 0)) - printk("\n "); -#endif - printk("[<%08lx>] ", addr); - print_symbol("%s\n", addr); - i++; - } + while (!kstack_end(sp)) { + addr = *sp++; + if (kernel_text_address(addr)) + print_ip_sym(addr); } printk("\n"); } -void show_task(unsigned long *sp) +void show_stack(struct task_struct *tsk, unsigned long *sp) { - show_stack(NULL, sp); + unsigned long stack; + + if (!tsk) + tsk = current; + if (tsk == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)tsk->thread.sp; + + stack = (unsigned long)sp; + dump_mem("Stack: ", stack, THREAD_SIZE + + (unsigned long)task_stack_page(tsk)); + show_trace(tsk, sp, NULL); } void dump_stack(void) -- cgit v1.2.3 From 082c44d20eb4c6c4aa60ae7429ea184854cb0610 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 19 Oct 2006 16:16:18 +0900 Subject: sh: Cleanup board header directories. Now with the ide.h mess sorted out, most of these boards don't need their own directory. Move the headers out, and update the driver paths. Signed-off-by: Paul Mundt --- arch/sh/boards/hp6xx/hp6xx_apm.c | 2 +- arch/sh/boards/hp6xx/pm.c | 2 +- arch/sh/boards/hp6xx/setup.c | 2 +- arch/sh/boards/renesas/hs7751rvoip/io.c | 2 +- arch/sh/boards/renesas/hs7751rvoip/irq.c | 2 +- arch/sh/boards/renesas/hs7751rvoip/setup.c | 7 +------ arch/sh/boards/renesas/r7780rp/io.c | 2 +- arch/sh/boards/renesas/r7780rp/irq.c | 3 ++- arch/sh/boards/renesas/r7780rp/setup.c | 2 +- arch/sh/boards/renesas/rts7751r2d/io.c | 4 ++-- arch/sh/boards/renesas/rts7751r2d/irq.c | 6 ++---- arch/sh/boards/renesas/rts7751r2d/led.c | 15 ++------------- arch/sh/boards/renesas/rts7751r2d/setup.c | 2 +- arch/sh/boards/shmin/setup.c | 2 +- arch/sh/cchips/voyagergx/irq.c | 22 +++++----------------- arch/sh/drivers/pci/ops-r7780rp.c | 2 +- arch/sh/drivers/pci/ops-rts7751r2d.c | 24 ++++++++++-------------- 17 files changed, 34 insertions(+), 67 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c index 219179114f0..d146cdaa0b8 100644 --- a/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #define SH7709_PGDR 0xa400012c diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c index 83d32721206..d1947732fb3 100644 --- a/arch/sh/boards/hp6xx/pm.c +++ b/arch/sh/boards/hp6xx/pm.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index 2d3a5b4faf5..b5a96649ed2 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #define SCPCR 0xa4000116 diff --git a/arch/sh/boards/renesas/hs7751rvoip/io.c b/arch/sh/boards/renesas/hs7751rvoip/io.c index 51f3f657421..bb9aa0d6285 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/io.c +++ b/arch/sh/boards/renesas/hs7751rvoip/io.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ diff --git a/arch/sh/boards/renesas/hs7751rvoip/irq.c b/arch/sh/boards/renesas/hs7751rvoip/irq.c index c617b188258..943f93aa605 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include static int mask_pos[] = {8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7}; diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c index 0414c15c345..1d997ffd793 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -10,15 +10,10 @@ #include #include #include -#include -#include -#include #include +#include #include -#include #include -#include -#include static void __init hs7751rvoip_init_irq(void) { diff --git a/arch/sh/boards/renesas/r7780rp/io.c b/arch/sh/boards/renesas/r7780rp/io.c index db92d6e6ae9..311ccccba71 100644 --- a/arch/sh/boards/renesas/r7780rp/io.c +++ b/arch/sh/boards/renesas/r7780rp/io.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c index b544772cbc7..cbb4ea28e9a 100644 --- a/arch/sh/boards/renesas/r7780rp/irq.c +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -10,7 +10,8 @@ */ #include #include -#include +#include +#include #ifdef CONFIG_SH_R7780MP static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index b941aa0aa34..c331caeb694 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c index 135aa0b5e62..f2507a80497 100644 --- a/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/arch/sh/boards/renesas/rts7751r2d/io.c @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include /* diff --git a/arch/sh/boards/renesas/rts7751r2d/irq.c b/arch/sh/boards/renesas/rts7751r2d/irq.c index c915e7a3693..cb0eb20d1b4 100644 --- a/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -8,12 +8,10 @@ * Modified for RTS7751R2D by * Atom Create Engineering Co., Ltd. 2002. */ - #include #include -#include -#include -#include +#include +#include #if defined(CONFIG_RTS7751R2D_REV11) static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; diff --git a/arch/sh/boards/renesas/rts7751r2d/led.c b/arch/sh/boards/renesas/rts7751r2d/led.c index a7ce66c1e4f..509f548bdce 100644 --- a/arch/sh/boards/renesas/rts7751r2d/led.c +++ b/arch/sh/boards/renesas/rts7751r2d/led.c @@ -8,13 +8,9 @@ * * This file contains Renesas Technology Sales RTS7751R2D specific LED code. */ - -#include -#include - -#ifdef CONFIG_HEARTBEAT - +#include #include +#include /* Cycle the LED's in the clasic Knightriger/Sun pattern */ void heartbeat_rts7751r2d(void) @@ -46,10 +42,3 @@ void heartbeat_rts7751r2d(void) else bit--; } -#endif /* CONFIG_HEARTBEAT */ - -void rts7751r2d_led(unsigned short value) -{ - ctrl_outw(value, PA_OUTPORT); -} - diff --git a/arch/sh/boards/renesas/rts7751r2d/setup.c b/arch/sh/boards/renesas/rts7751r2d/setup.c index 20597a6e670..5c042d35ec9 100644 --- a/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -12,9 +12,9 @@ #include #include #include -#include #include #include +#include #include extern void heartbeat_rts7751r2d(void); diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c index 2f0c19706cf..a31a1d1e268 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c @@ -7,7 +7,7 @@ */ #include #include -#include +#include #include #include #include diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index bf1b28feca0..f7ea700d05a 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c @@ -17,29 +17,18 @@ Copyright 2003 (c) Lineo uSolutions,Inc. */ -/* -------------------------------------------------------------------- */ - -#undef DEBUG - -#include -#include -#include -#include -#include #include #include -#include - -#include -#include +#include #include +#include static void disable_voyagergx_irq(unsigned int irq) { unsigned long val; unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); val = inl(VOYAGER_INT_MASK); val &= ~mask; outl(val, VOYAGER_INT_MASK); @@ -50,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq) unsigned long val; unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); val = inl(VOYAGER_INT_MASK); val |= mask; outl(val, VOYAGER_INT_MASK); @@ -137,7 +126,7 @@ int voyagergx_irq_demux(int irq) } else { printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); } - pr_debug("voyagergx_irq_demux %d \n", i); + pr_debug("voyagergx_irq_demux %ld\n", i); #else for (bit = 1, i = 0 ; i < VOYAGER_IRQ_NUM ; bit <<= 1, i++) if (val & bit) @@ -185,4 +174,3 @@ void __init setup_voyagergx_irq(void) setup_irq(IRQ_VOYAGER, &irq0); } - diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c index 6e3ba9c65b4..eeea1577e11 100644 --- a/arch/sh/drivers/pci/ops-r7780rp.c +++ b/arch/sh/drivers/pci/ops-r7780rp.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include "pci-sh4.h" diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c index b68824c8b81..4a518d94804 100644 --- a/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -10,28 +10,24 @@ * * PCI initialization for the Renesas SH7751R RTS7751R2D board */ - #include #include #include -#include #include -#include -#include -#include +#include +#include #include "pci-sh4.h" +static u8 rts7751r2d_irq_tab[] __initdata = { + IRQ_PCISLOT1, + IRQ_PCISLOT2, + IRQ_PCMCIA, + IRQ_PCIETH, +}; + int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - switch (slot) { - case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ - case 1: return IRQ_PCISLOT2; /* PCI Extend slot #2 */ - case 2: return IRQ_PCMCIA; /* PCI Cardbus Bridge */ - case 3: return IRQ_PCIETH; /* Realtek Ethernet controller */ - default: - printk("PCI: Bad IRQ mapping request for slot %d\n", slot); - return -1; - } + return rts7751r2d_irq_tab[slot]; } static struct resource sh7751_io_resource = { -- cgit v1.2.3 From 1f666587dbf6bc660b23d8dd8abb6c572ce3eae5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 19 Oct 2006 16:20:25 +0900 Subject: sh: Fix exception_handling_table alignment. With the recent change ripping out interrupt_table, explicit padding of the table was missing, causing bad things to happen when manually inserting handlers in to the table. This problem particularly showed up in relation to do_fpu_state_restore() which was inserted quite deeply in to the table and ended up scribbling over a slab object. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/ex.S | 9 ++++++++- arch/sh/kernel/cpu/sh4/ex.S | 9 ++++++++- arch/sh/kernel/traps.c | 43 +++++++++++++++++++++---------------------- 3 files changed, 37 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh3/ex.S b/arch/sh/kernel/cpu/sh3/ex.S index 6be46f0686b..ba3082d640b 100644 --- a/arch/sh/kernel/cpu/sh3/ex.S +++ b/arch/sh/kernel/cpu/sh3/ex.S @@ -4,7 +4,7 @@ * The SH-3 exception vector table. * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2006 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -49,3 +49,10 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ + + /* + * Pad the remainder of the table out, exceptions residing in far + * away offsets can be manually inserted in to their appropriate + * location via set_exception_table_{evt,vec}(). + */ + .balign 4096,0,4096 diff --git a/arch/sh/kernel/cpu/sh4/ex.S b/arch/sh/kernel/cpu/sh4/ex.S index 3f4cd043e90..ac8ab57413c 100644 --- a/arch/sh/kernel/cpu/sh4/ex.S +++ b/arch/sh/kernel/cpu/sh4/ex.S @@ -4,7 +4,7 @@ * The SH-4 exception vector table. * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt + * Copyright (C) 2003 - 2006 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -53,3 +53,10 @@ ENTRY(nmi_slot) #endif ENTRY(user_break_point_trap) .long break_point_trap /* 1E0 */ + + /* + * Pad the remainder of the table out, exceptions residing in far + * away offsets can be manually inserted in to their appropriate + * location via set_exception_table_{evt,vec}(). + */ + .balign 4096,0,4096 diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index ffe127f09f3..53dfa55f315 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -11,27 +11,15 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include #include -#include -#include #include -#include -#include -#include -#include #include -#include #include #include #include - +#include #include #include -#include -#include -#include -#include #ifdef CONFIG_SH_KGDB #include @@ -581,7 +569,10 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ -extern int do_fpu_inst(unsigned short, struct pt_regs*); +/* arch/sh/kernel/cpu/sh4/fpu.c */ +extern int do_fpu_inst(unsigned short, struct pt_regs *); +extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, struct pt_regs regs); asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, @@ -740,14 +731,20 @@ void __init per_cpu_trap_init(void) : "memory"); } -void __init trap_init(void) +void *set_exception_table_vec(unsigned int vec, void *handler) { extern void *exception_handling_table[]; + void *old_handler; + + old_handler = exception_handling_table[vec]; + exception_handling_table[vec] = handler; + return old_handler; +} - exception_handling_table[TRAP_RESERVED_INST] - = (void *)do_reserved_inst; - exception_handling_table[TRAP_ILLEGAL_SLOT_INST] - = (void *)do_illegal_slot_inst; +void __init trap_init(void) +{ + set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); + set_exception_table_vec(TRAP_ILLEGAL_SLOT_INST, do_illegal_slot_inst); #if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \ defined(CONFIG_SH_FPU_EMU) @@ -756,9 +753,11 @@ void __init trap_init(void) * reserved. They'll be handled in the math-emu case, or faulted on * otherwise. */ - /* entry 64 corresponds to EXPEVT=0x800 */ - exception_handling_table[64] = (void *)do_reserved_inst; - exception_handling_table[65] = (void *)do_illegal_slot_inst; + set_exception_table_evt(0x800, do_reserved_inst); + set_exception_table_evt(0x820, do_illegal_slot_inst); +#elif defined(CONFIG_SH_FPU) + set_exception_table_evt(0x800, do_fpu_state_restore); + set_exception_table_evt(0x820, do_fpu_state_restore); #endif /* Setup VBR for boot cpu */ -- cgit v1.2.3 From 709bc44c31db4eeeec7dcf7d3f3fefd057adf7fb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 19 Oct 2006 17:32:56 +0900 Subject: sh: Updates for irq-flow-type naming changes. handle_irq_name() and set_irq_chip_and_handler() disappeared, update for desc->name and set_irq_chip_and_handler_name() use. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/irq.c | 6 +++--- arch/sh/kernel/cpu/irq/intc2.c | 5 +++-- arch/sh/kernel/cpu/irq/ipr.c | 5 +++-- arch/sh/kernel/irq.c | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c index cbb4ea28e9a..aa15ec5bc69 100644 --- a/arch/sh/boards/renesas/r7780rp/irq.c +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -33,7 +33,7 @@ static void disable_r7780rp_irq(unsigned int irq) } static struct irq_chip r7780rp_irq_chip __read_mostly = { - .name = "r7780rp", + .name = "R7780RP", .mask = disable_r7780rp_irq, .unmask = enable_r7780rp_irq, .mask_ack = disable_r7780rp_irq, @@ -48,8 +48,8 @@ void __init init_r7780rp_IRQ(void) for (i = 0; i < 15; i++) { disable_irq_nosync(i); - set_irq_chip_and_handler(i, &r7780rp_irq_chip, - handle_level_irq); + set_irq_chip_and_handler_name(i, &r7780rp_irq_chip, + handle_level_irq, "level"); enable_r7780rp_irq(i); } } diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index d4b2bb7e08c..212884adca0 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -31,7 +31,7 @@ static void enable_intc2_irq(unsigned int irq) } static struct irq_chip intc2_irq_chip = { - .typename = "intc2", + .name = "INTC2", .mask = disable_intc2_irq, .unmask = enable_intc2_irq, .mask_ack = disable_intc2_irq, @@ -64,7 +64,8 @@ void make_intc2_irq(struct intc2_data *p) local_irq_restore(flags); - set_irq_chip_and_handler(p->irq, &intc2_irq_chip, handle_level_irq); + set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, + handle_level_irq, "level"); set_irq_chip_data(p->irq, p); enable_intc2_irq(p->irq); diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 8944abdf6e1..f7997312ef9 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -44,7 +44,7 @@ static void enable_ipr_irq(unsigned int irq) } static struct irq_chip ipr_irq_chip = { - .name = "ipr", + .name = "IPR", .mask = disable_ipr_irq, .unmask = enable_ipr_irq, .mask_ack = disable_ipr_irq, @@ -60,7 +60,8 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */ ipr_data.priority = priority; - set_irq_chip_and_handler(irq, &ipr_irq_chip, handle_level_irq); + set_irq_chip_and_handler_name(irq, &ipr_irq_chip, + handle_level_irq, "level"); set_irq_chip_data(irq, &ipr_data); enable_ipr_irq(irq); diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index acf2602569c..944128ce970 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -54,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); seq_printf(p, " %14s", irq_desc[i].chip->name); - seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); + seq_printf(p, "-%-8s", irq_desc[i].name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) -- cgit v1.2.3 From 55b7428303d390c53d3a1bc587de8592ce65900e Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 13 Oct 2006 13:37:35 +0200 Subject: [MIPS] Use kallsyms_lookup_size_offset() instead of kallsyms_lookup() This new routine doesn't lookup for symbol names. So we needn't to pass any char buffers or pointer since we don't care about names. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/process.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 9f307eb1a31..ec8209f3a0c 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -358,10 +358,8 @@ static int __init frame_info_init(void) unsigned long size = 0; #ifdef CONFIG_KALLSYMS unsigned long ofs; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; - kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); + kallsyms_lookup_size_offset((unsigned long)schedule, &size, &ofs); #endif schedule_mfi.func = schedule; schedule_mfi.func_size = size; @@ -403,8 +401,6 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, { unsigned long stack_page; struct mips_frame_info info; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; unsigned long size, ofs; int leaf; extern void ret_from_irq(void); @@ -433,7 +429,7 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, } return 0; } - if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) + if (!kallsyms_lookup_size_offset(pc, &size, &ofs)) return 0; /* * Return ra if an exception occured at the first instruction -- cgit v1.2.3 From 22c56c3a03b377d21d8363f737aa2a855d892458 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 15 Oct 2006 09:15:19 +0100 Subject: [MIPS] Delete unneeded pt_regs forward declaration. Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_impl.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h index 354e5449640..fa6b4aae752 100644 --- a/arch/mips/oprofile/op_impl.h +++ b/arch/mips/oprofile/op_impl.h @@ -10,8 +10,6 @@ #ifndef OP_IMPL_H #define OP_IMPL_H 1 -struct pt_regs; - extern int null_perf_irq(void); extern int (*perf_irq)(void); -- cgit v1.2.3 From ba38cdf94285a1fc6a01fd493bdc5304bc83f61e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 15 Oct 2006 09:17:43 +0100 Subject: [MIPS] Malta: Fix uninitialized regs pointer. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/malta/malta_int.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index 6244d0e2c7d..90ad5bf3e2f 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -131,7 +132,7 @@ static void corehi_irqdispatch(void) unsigned int intedge, intsteer, pcicmd, pcibadaddr; unsigned int pcimstat, intisr, inten, intpol; unsigned int intrcause,datalo,datahi; - struct pt_regs *regs; + struct pt_regs *regs = get_irq_regs(); printk("CoreHI interrupt, shouldn't happen, so we die here!!!\n"); printk("epc : %08lx\nStatus: %08lx\n" -- cgit v1.2.3 From 36d98e79b798fb27e38b9be4f36c5a96025f9281 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 15 Oct 2006 09:19:58 +0100 Subject: [MIPS] A few more pt_regs fixups. Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/dbdma.c | 2 +- arch/mips/oprofile/op_model_rm9000.c | 3 +-- arch/mips/sgi-ip32/ip32-reset.c | 2 +- arch/mips/sibyte/sb1250/bcm1250_tbprof.c | 4 ++-- arch/mips/sibyte/sb1250/bus_watcher.c | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/dbdma.c b/arch/mips/au1000/common/dbdma.c index c4fae8ff467..626de44bd88 100644 --- a/arch/mips/au1000/common/dbdma.c +++ b/arch/mips/au1000/common/dbdma.c @@ -849,7 +849,7 @@ au1xxx_dbdma_chan_free(u32 chanid) EXPORT_SYMBOL(au1xxx_dbdma_chan_free); static irqreturn_t -dbdma_interrupt(int irq, void *dev_id, struct pt_regs *regs) +dbdma_interrupt(int irq, void *dev_id) { u32 intstat; u32 chan_index; diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c index b7063fefa65..7dc9bf6f132 100644 --- a/arch/mips/oprofile/op_model_rm9000.c +++ b/arch/mips/oprofile/op_model_rm9000.c @@ -80,8 +80,7 @@ static void rm9000_cpu_stop(void *args) write_c0_perfcontrol(0); } -static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id, - struct pt_regs *regs) +static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id) { unsigned int control = read_c0_perfcontrol(); uint32_t counter1, counter2; diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index fd0932b2d52..db808441153 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c @@ -135,7 +135,7 @@ static inline void ip32_power_button(void) add_timer(&power_timer); } -static irqreturn_t ip32_rtc_int(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t ip32_rtc_int(int irq, void *dev_id) { volatile unsigned char reg_c; diff --git a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c index 992e0d8dbb6..d1a906e683b 100644 --- a/arch/mips/sibyte/sb1250/bcm1250_tbprof.c +++ b/arch/mips/sibyte/sb1250/bcm1250_tbprof.c @@ -88,7 +88,7 @@ static void arm_tb(void) sbp.tb_armed = 1; } -static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t sbprof_tb_intr(int irq, void *dev_id) { int i; DBG(printk(DEVNAME ": tb_intr\n")); @@ -138,7 +138,7 @@ static irqreturn_t sbprof_tb_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static irqreturn_t sbprof_pc_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t sbprof_pc_intr(int irq, void *dev_id) { printk(DEVNAME ": unexpected pc_intr"); return IRQ_NONE; diff --git a/arch/mips/sibyte/sb1250/bus_watcher.c b/arch/mips/sibyte/sb1250/bus_watcher.c index bb90649fbc4..45274bd3cd8 100644 --- a/arch/mips/sibyte/sb1250/bus_watcher.c +++ b/arch/mips/sibyte/sb1250/bus_watcher.c @@ -171,7 +171,7 @@ static void create_proc_decoder(struct bw_stats_struct *stats) * notes: possible re-entry due to multiple sources * should check/indicate saturation */ -static irqreturn_t sibyte_bw_int(int irq, void *data, struct pt_regs *regs) +static irqreturn_t sibyte_bw_int(int irq, void *data) { struct bw_stats_struct *stats = data; unsigned long cntr; -- cgit v1.2.3 From 53571ce47010562f5e67782ea00206f379a5cd65 Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Sun, 13 Aug 2006 00:53:29 +0100 Subject: [MIPS] Fix O32 personality(2) call with 0xffffffff argument. A sign extension bug did result in sys_personality being invoked with a 0xffffffffffffffffUL argument, so querying the current personality didn't work. Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 53f4171fc18..7a3ebbeba1f 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -1055,7 +1055,9 @@ asmlinkage long sys32_newuname(struct new_utsname __user * name) asmlinkage int sys32_personality(unsigned long personality) { int ret; - if (current->personality == PER_LINUX32 && personality == PER_LINUX) + personality &= 0xffffffff; + if (personality(current->personality) == PER_LINUX32 && + personality == PER_LINUX) personality = PER_LINUX32; ret = sys_personality(personality); if (ret == PER_LINUX32) -- cgit v1.2.3 From 089c7e7f2da7c3245de47377252683bd9edae738 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 16 Oct 2006 16:49:37 +0100 Subject: [MIPS] Use compat_sys_mount. This fixes mount problems with smbfs, ncpfs and NFSv4. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 6d9f18727ac..8c453f8ffea 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -280,7 +280,7 @@ EXPORT(sysn32_call_table) PTR sys_sync PTR sys_acct PTR sys32_settimeofday - PTR sys_mount /* 6160 */ + PTR compat_sys_mount /* 6160 */ PTR sys_umount PTR sys_swapon PTR sys_swapoff diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2e6d0673163..d105917d6d9 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -226,7 +226,7 @@ sys_call_table: PTR sys_ni_syscall /* was sys_stat */ PTR sys_lseek PTR sys_getpid /* 4020 */ - PTR sys_mount + PTR compat_sys_mount PTR sys_oldumount PTR sys_setuid PTR sys_getuid -- cgit v1.2.3 From eea32d4c6e272b6c324c8c22df4c28274fcb5a21 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 16 Oct 2006 22:48:49 +0900 Subject: [MIPS] save_context_stack fix CONFIG_KALLSYMS=n case is obviously wrong, though it is harmless since CONFIG_KALLSYMS is always enabled with CONFIG_STACKTRACE for now. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c index 4aabe526a68..a586aba337a 100644 --- a/arch/mips/kernel/stacktrace.c +++ b/arch/mips/kernel/stacktrace.c @@ -57,7 +57,7 @@ static void save_context_stack(struct stack_trace *trace, pc = unwind_stack(task, &sp, pc, &ra); } while (pc); #else - save_raw_context_stack(sp); + save_raw_context_stack(trace, sp); #endif } -- cgit v1.2.3 From 00ddf2be159e3b96ba8872b407240e1bb449b75e Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 18 Oct 2006 23:36:15 +0900 Subject: [MIPS] Update pnx8500-jbs_defconfig In the current pnx8550-jbs_defconfig CONFIG_SGI_IP22 has been selected. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/configs/pnx8550-jbs_defconfig | 384 +++++++++++++++++++++++++++----- 1 file changed, 330 insertions(+), 54 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 26b0b988349..280a8001eac 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Thu Jul 6 10:04:18 2006 +# Linux kernel version: 2.6.19-rc2 +# Sat Oct 14 23:01:16 2006 # CONFIG_MIPS=y @@ -25,8 +25,6 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -41,13 +39,13 @@ CONFIG_MIPS=y # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_V2PCI is not set -# CONFIG_PNX8550_JBS is not set +CONFIG_PNX8550_JBS=y # CONFIG_DDB5477 is not set # CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set # CONFIG_MARKEINS is not set -CONFIG_SGI_IP22=y +# CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_BIGSUR is not set @@ -67,25 +65,21 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARC=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_ARC32=y -CONFIG_BOOT_ELF32=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_PNX8550=y +CONFIG_SOC_PNX8550=y CONFIG_MIPS_L1_CACHE_SHIFT=5 -# CONFIG_ARC_CONSOLE is not set -CONFIG_ARC_PROMLIB=y # # CPU selection # -# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set # CONFIG_CPU_MIPS64_R2 is not set @@ -93,7 +87,7 @@ CONFIG_ARC_PROMLIB=y # CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set -CONFIG_CPU_R4X00=y +# CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set @@ -104,12 +98,11 @@ CONFIG_CPU_R4X00=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R4X00=y -CONFIG_SYS_HAS_CPU_R5000=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y # # Kernel type @@ -120,17 +113,17 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_IP22_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -144,12 +137,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set +CONFIG_HZ_250=y # CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y +# CONFIG_HZ_1000 is not set # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 +CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -171,16 +164,20 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -189,12 +186,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y -CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -211,6 +208,7 @@ CONFIG_KMOD=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -231,8 +229,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -CONFIG_HW_HAS_EISA=y -# CONFIG_EISA is not set +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_PCI_DEBUG is not set CONFIG_MMU=y # @@ -243,6 +243,7 @@ CONFIG_MMU=y # # PCI Hotplug Support # +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -265,6 +266,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -283,16 +285,18 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y +# CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # @@ -318,7 +322,6 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -371,13 +374,20 @@ CONFIG_FW_LOADER=y # # Block devices # +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -386,6 +396,7 @@ CONFIG_BLK_DEV_INITRD=y # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -404,8 +415,39 @@ CONFIG_BLK_DEV_IDESCSI=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_OFFBOARD=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set # CONFIG_IDEDMA_AUTO is not set # CONFIG_BLK_DEV_HD is not set @@ -414,6 +456,7 @@ CONFIG_IDE_GENERIC=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -434,21 +477,53 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transport Attributes +# SCSI Transports # # CONFIG_SCSI_SPI_ATTRS is not set CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # CONFIG_ISCSI_TCP=m -# CONFIG_SGIWD93_SCSI is not set -# CONFIG_SCSI_SATA is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + # # Multi-device support (RAID and LVM) # @@ -458,14 +533,19 @@ CONFIG_ISCSI_TCP=m # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # +# CONFIG_IEEE1394 is not set # # I2O device support # +# CONFIG_I2O is not set # # Network device support @@ -476,6 +556,11 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # PHY device support # @@ -486,20 +571,73 @@ CONFIG_NETDEVICES=y # CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set # CONFIG_DM9000 is not set -# CONFIG_SGISEEQ is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +CONFIG_8139TOO_8129=y +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_LAN_SAA9730 is not set # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -510,8 +648,11 @@ CONFIG_MII=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set +# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -531,6 +672,7 @@ CONFIG_MII=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -556,6 +698,7 @@ CONFIG_INPUT=y CONFIG_SERIO=y # CONFIG_SERIO_I8042 is not set # CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set @@ -566,7 +709,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -577,7 +720,8 @@ CONFIG_VT_HW_CONSOLE_BINDING=y # # Non-8250 serial port support # -# CONFIG_SERIAL_IP22_ZILOG is not set +# CONFIG_SERIAL_IP3106 is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -591,16 +735,17 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_RTC is not set -# CONFIG_SGI_DS1286 is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -631,35 +776,37 @@ CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # +# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # # Console display driver support # # CONFIG_VGA_CONSOLE is not set -# CONFIG_SGI_NEWPORT_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -669,14 +816,130 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set + +# +# USB DSL modem support +# + # # USB Gadget Support # @@ -703,6 +966,7 @@ CONFIG_DUMMY_CONSOLE=y # # InfiniBand support # +# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -733,10 +997,12 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -769,8 +1035,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -813,7 +1081,6 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -824,7 +1091,6 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_SGI_PARTITION=y # # Native Language Support @@ -880,6 +1146,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -893,13 +1160,17 @@ CONFIG_DEBUG_SLAB=y # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp" @@ -918,6 +1189,9 @@ CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp" # Cryptographic options # CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -927,6 +1201,8 @@ CONFIG_CRYPTO_MD5=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.2.3 From 0895b19ebdbb44d6d2eee0d7a138f07b2ddb04ec Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 18 Oct 2006 23:38:12 +0900 Subject: [MIPS] Update pnx8550-v2pci_defconfig In the current pnx8550-v2pci_defconfig CONFIG_SGI_IP22 has been selected. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/configs/pnx8550-v2pci_defconfig | 441 ++++++++++++++++++++++++++---- 1 file changed, 382 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig index e93266b37dd..64b9fbf44a6 100644 --- a/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/arch/mips/configs/pnx8550-v2pci_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Thu Jul 6 10:04:18 2006 +# Linux kernel version: 2.6.19-rc2 +# Sat Oct 14 23:12:15 2006 # CONFIG_MIPS=y @@ -25,8 +25,6 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -40,14 +38,14 @@ CONFIG_MIPS=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set +CONFIG_PNX8550_V2PCI=y # CONFIG_PNX8550_JBS is not set # CONFIG_DDB5477 is not set # CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set # CONFIG_MARKEINS is not set -CONFIG_SGI_IP22=y +# CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set # CONFIG_SIBYTE_BIGSUR is not set @@ -67,25 +65,21 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARC=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_CPU_BIG_ENDIAN=y -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y -CONFIG_IRQ_CPU=y -CONFIG_SWAP_IO_SPACE=y -CONFIG_ARC32=y -CONFIG_BOOT_ELF32=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_PNX8550=y +CONFIG_SOC_PNX8550=y CONFIG_MIPS_L1_CACHE_SHIFT=5 -# CONFIG_ARC_CONSOLE is not set -CONFIG_ARC_PROMLIB=y # # CPU selection # -# CONFIG_CPU_MIPS32_R1 is not set +CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set # CONFIG_CPU_MIPS64_R2 is not set @@ -93,7 +87,7 @@ CONFIG_ARC_PROMLIB=y # CONFIG_CPU_TX39XX is not set # CONFIG_CPU_VR41XX is not set # CONFIG_CPU_R4300 is not set -CONFIG_CPU_R4X00=y +# CONFIG_CPU_R4X00 is not set # CONFIG_CPU_TX49XX is not set # CONFIG_CPU_R5000 is not set # CONFIG_CPU_R5432 is not set @@ -104,12 +98,11 @@ CONFIG_CPU_R4X00=y # CONFIG_CPU_RM7000 is not set # CONFIG_CPU_RM9000 is not set # CONFIG_CPU_SB1 is not set -CONFIG_SYS_HAS_CPU_R4X00=y -CONFIG_SYS_HAS_CPU_R5000=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y -CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y -CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y # # Kernel type @@ -120,17 +113,17 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set -CONFIG_BOARD_SCACHE=y -CONFIG_IP22_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set # CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -144,12 +137,12 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_HZ_48 is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set +CONFIG_HZ_250=y # CONFIG_HZ_256 is not set -CONFIG_HZ_1000=y +# CONFIG_HZ_1000 is not set # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=1000 +CONFIG_HZ=250 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -171,16 +164,20 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y @@ -188,12 +185,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y -CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -210,6 +207,7 @@ CONFIG_KMOD=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -230,8 +228,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -CONFIG_HW_HAS_EISA=y -# CONFIG_EISA is not set +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set CONFIG_MMU=y # @@ -242,6 +241,7 @@ CONFIG_MMU=y # # PCI Hotplug Support # +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -264,6 +264,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -282,12 +283,14 @@ CONFIG_IP_PNP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=m -CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" # # IP: Virtual Server Configuration @@ -300,12 +303,18 @@ CONFIG_IPV6_ROUTE_INFO=y # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set +# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set CONFIG_INET6_XFRM_MODE_TRANSPORT=m CONFIG_INET6_XFRM_MODE_TUNNEL=m +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m # CONFIG_IPV6_TUNNEL is not set -CONFIG_NETWORK_SECMARK=y +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +# CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set @@ -318,9 +327,9 @@ CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m -CONFIG_NETFILTER_XT_TARGET_SECMARK=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_DCCP=m +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -329,10 +338,10 @@ CONFIG_NETFILTER_XT_MATCH_MARK=m # CONFIG_NETFILTER_XT_MATCH_POLICY is not set CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m -CONFIG_NETFILTER_XT_MATCH_QUOTA=m +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set CONFIG_NETFILTER_XT_MATCH_REALM=m CONFIG_NETFILTER_XT_MATCH_SCTP=m -CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set CONFIG_NETFILTER_XT_MATCH_STRING=m CONFIG_NETFILTER_XT_MATCH_TCPMSS=m @@ -373,7 +382,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -426,13 +434,20 @@ CONFIG_FW_LOADER=y # # Block devices # +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -441,6 +456,7 @@ CONFIG_BLK_DEV_INITRD=y # ATA/ATAPI/MFM/RLL support # CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 CONFIG_BLK_DEV_IDE=y # @@ -459,9 +475,41 @@ CONFIG_IDEDISK_MULTI_MODE=y # IDE chipset support/bugfixes # CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_BLK_DEV_GENERIC is not set +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +CONFIG_IDEDMA_PCI_AUTO=y +# CONFIG_IDEDMA_ONLYDISK is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +CONFIG_BLK_DEV_CMD64X=y +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +# CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set # CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +CONFIG_IDEDMA_AUTO=y # CONFIG_BLK_DEV_HD is not set # @@ -469,6 +517,7 @@ CONFIG_IDE_GENERIC=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -489,21 +538,58 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transport Attributes +# SCSI Transports # CONFIG_SCSI_SPI_ATTRS=m CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # CONFIG_ISCSI_TCP=m -# CONFIG_SGIWD93_SCSI is not set -# CONFIG_SCSI_SATA is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +CONFIG_SCSI_AIC7XXX=m +CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 +CONFIG_AIC7XXX_RESET_DELAY_MS=15000 +# CONFIG_AIC7XXX_DEBUG_ENABLE is not set +CONFIG_AIC7XXX_DEBUG_MASK=0 +# CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + # # Multi-device support (RAID and LVM) # @@ -513,14 +599,19 @@ CONFIG_ISCSI_TCP=m # Fusion MPT device support # # CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support # +# CONFIG_IEEE1394 is not set # # I2O device support # +# CONFIG_I2O is not set # # Network device support @@ -531,6 +622,11 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set CONFIG_TUN=m +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + # # PHY device support # @@ -541,20 +637,73 @@ CONFIG_TUN=m # CONFIG_NET_ETHERNET=y CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set # CONFIG_DM9000 is not set -# CONFIG_SGISEEQ is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +CONFIG_NATSEMI=y +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_LAN_SAA9730 is not set # # Ethernet (1000 Mbit) # +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) # +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set # # Token Ring devices # +# CONFIG_TR is not set # # Wireless LAN (non-hamradio) @@ -565,6 +714,8 @@ CONFIG_MII=y # Wan interfaces # # CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set CONFIG_PPP=m # CONFIG_PPP_MULTILINK is not set # CONFIG_PPP_FILTER is not set @@ -575,6 +726,8 @@ CONFIG_PPP_DEFLATE=m CONFIG_PPP_MPPE=m # CONFIG_PPPOE is not set # CONFIG_SLIP is not set +CONFIG_SLHC=m +# CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -594,6 +747,7 @@ CONFIG_PPP_MPPE=m # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -616,6 +770,7 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -630,6 +785,7 @@ CONFIG_MOUSE_PS2=y CONFIG_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set @@ -640,7 +796,7 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y # CONFIG_VT_CONSOLE is not set CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -650,6 +806,7 @@ CONFIG_SERIAL_NONSTANDARD=y # CONFIG_MOXA_SMARTIO is not set # CONFIG_ISI is not set # CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set # CONFIG_N_HDLC is not set # CONFIG_RISCOM8 is not set # CONFIG_SPECIALIX is not set @@ -665,7 +822,8 @@ CONFIG_SERIAL_NONSTANDARD=y # # Non-8250 serial port support # -# CONFIG_SERIAL_IP22_ZILOG is not set +# CONFIG_SERIAL_IP3106 is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -679,16 +837,17 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -# CONFIG_HW_RANDOM is not set +CONFIG_HW_RANDOM=y # CONFIG_RTC is not set -# CONFIG_SGI_DS1286 is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # +# CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set # @@ -709,14 +868,30 @@ CONFIG_I2C_CHARDEV=m CONFIG_I2C_ALGOBIT=m # CONFIG_I2C_ALGOPCF is not set # CONFIG_I2C_ALGOPCA is not set -# CONFIG_I2C_ALGO_SGI is not set # # I2C Hardware Bus support # +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set # CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set # CONFIG_I2C_PCA_ISA is not set # @@ -776,9 +951,13 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set @@ -790,23 +969,25 @@ CONFIG_HWMON=y # # Misc devices # +# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set +CONFIG_FIRMWARE_EDID=y CONFIG_FB=y +# CONFIG_FB_DDC is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set @@ -814,14 +995,32 @@ CONFIG_FB=y # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set # CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_SMIVGX is not set +# CONFIG_FB_TRIDENT is not set # CONFIG_FB_VIRTUAL is not set # # Console display driver support # # CONFIG_VGA_CONSOLE is not set -# CONFIG_SGI_NEWPORT_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y # CONFIG_FRAMEBUFFER_CONSOLE is not set @@ -839,14 +1038,128 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +CONFIG_USB_HID=y +CONFIG_USB_HIDINPUT=y +# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_HID_FF is not set +CONFIG_USB_HIDDEV=y +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + # # USB Gadget Support # @@ -873,6 +1186,7 @@ CONFIG_DUMMY_CONSOLE=y # # InfiniBand support # +# CONFIG_INFINIBAND is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -906,6 +1220,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -917,6 +1232,7 @@ CONFIG_XFS_FS=m # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -949,8 +1265,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -994,7 +1312,6 @@ CONFIG_SUNRPC=y CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1005,7 +1322,6 @@ CONFIG_SMB_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_SGI_PARTITION=y # # Native Language Support @@ -1061,11 +1377,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="" @@ -1079,6 +1397,9 @@ CONFIG_CMDLINE="" # Cryptographic options # CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1088,6 +1409,8 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.2.3 From e7a6f9c1f4e46f7fd776c6ee38bdb8f8ae131a82 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 18 Oct 2006 23:48:31 +0900 Subject: [MIPS] Update tb0287_defconfig Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/configs/tb0287_defconfig | 182 ++++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 83 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index ad7271b3f26..f7e8194809a 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Thu Jul 6 10:04:21 2006 +# Linux kernel version: 2.6.19-rc2 +# Wed Oct 18 12:57:11 2006 # CONFIG_MIPS=y @@ -25,8 +25,6 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set # CONFIG_LASAT is not set # CONFIG_MIPS_ATLAS is not set @@ -72,11 +70,11 @@ CONFIG_TANBAC_TB0287=y # CONFIG_VICTOR_MPC30X is not set # CONFIG_ZAO_CAPCELLA is not set CONFIG_PCI_VR41XX=y -# CONFIG_VRC4173 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y @@ -123,8 +121,8 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_16KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_MIPS_MT_DISABLED=y -# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_VPE_LOADER is not set CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y @@ -169,15 +167,19 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set # CONFIG_HOTPLUG is not set @@ -185,12 +187,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y -CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -208,6 +210,7 @@ CONFIG_KMOD=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_LBD is not set # CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set @@ -230,17 +233,16 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_HW_HAS_PCI=y CONFIG_PCI=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # -# CONFIG_PCCARD is not set # # PCI Hotplug Support # -# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -263,6 +265,7 @@ CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -291,13 +294,10 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_TUNNEL=m CONFIG_INET_XFRM_MODE_TRANSPORT=m CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y CONFIG_TCP_CONG_ADVANCED=y - -# -# TCP congestion control -# CONFIG_TCP_CONG_BIC=y CONFIG_TCP_CONG_CUBIC=m CONFIG_TCP_CONG_WESTWOOD=m @@ -308,7 +308,13 @@ CONFIG_TCP_CONG_HTCP=m # CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_TCP_CONG_LP is not set # CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_COMPOUND is not set +CONFIG_DEFAULT_BIC=y +# CONFIG_DEFAULT_CUBIC is not set +# CONFIG_DEFAULT_HTCP is not set +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="bic" # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -338,7 +344,6 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -355,6 +360,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_IEEE80211 is not set +CONFIG_FIB_RULES=y # # Device Drivers @@ -365,7 +371,6 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -403,6 +408,7 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -410,65 +416,14 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # ATA/ATAPI/MFM/RLL support # -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_IDEDMA_PCI_AUTO is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=y -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set +# CONFIG_IDE is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # @@ -489,12 +444,13 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transport Attributes +# SCSI Transports # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -507,27 +463,83 @@ CONFIG_BLK_DEV_SD=y # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +CONFIG_PATA_SIL680=y +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + # # Multi-device support (RAID and LVM) # @@ -632,6 +644,7 @@ CONFIG_R8169=y # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -679,6 +692,7 @@ CONFIG_R8169=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -758,7 +772,6 @@ CONFIG_GPIO_VR41XX=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -784,12 +797,12 @@ CONFIG_GPIO_VR41XX=y # # Misc devices # +# CONFIG_TIFM_CORE is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -897,13 +910,13 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set # CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_LIBUSUAL is not set # @@ -932,6 +945,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -963,16 +977,17 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set @@ -1041,6 +1056,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1052,6 +1068,7 @@ CONFIG_XFS_QUOTA=y # CONFIG_XFS_SECURITY is not set CONFIG_XFS_POSIX_ACL=y # CONFIG_XFS_RT is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=m @@ -1082,8 +1099,10 @@ CONFIG_AUTOFS4_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1123,7 +1142,6 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1150,11 +1168,13 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" @@ -1169,10 +1189,6 @@ CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" # # CONFIG_CRYPTO is not set -# -# Hardware crypto devices -# - # # Library routines # -- cgit v1.2.3 From d2bcf87d0fcdc10d1be65b03fd032bec05efe49f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 18 Oct 2006 23:52:17 +0100 Subject: [MIPS] Reserve syscall numbers for kexec_load. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 3 ++- arch/mips/kernel/scall64-64.S | 1 + arch/mips/kernel/scall64-n32.S | 1 + arch/mips/kernel/scall64-o32.S | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 61362e6fa9e..720fac3435d 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -652,7 +652,8 @@ einval: li v0, -EINVAL sys sys_vmsplice 4 sys sys_move_pages 6 sys sys_set_robust_list 2 - sys sys_get_robust_list 3 + sys sys_get_robust_list 3 /* 4310 */ + sys sys_ni_syscall 0 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 6c7b5ed0ea6..3a34f62c8b1 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -468,3 +468,4 @@ sys_call_table: PTR sys_move_pages PTR sys_set_robust_list PTR sys_get_robust_list + PTR sys_ni_syscall /* 5270 */ diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 8c453f8ffea..67b92a1d6c7 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -394,3 +394,4 @@ EXPORT(sysn32_call_table) PTR sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list + PTR sys_ni_syscall diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index d105917d6d9..2875c4a3fa5 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -516,4 +516,5 @@ sys_call_table: PTR compat_sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ + PTR sys_ni_syscall .size sys_call_table,.-sys_call_table -- cgit v1.2.3 From d89e36d8df547fde2beaea82211954868da2282d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 19 Oct 2006 14:21:47 +0100 Subject: [MIPS] Fix iounmap argument to const volatile. With the existing prototype the following code: const void __iomem *io = ioremap(); x = readb(io); iounmap(io); did result in a warning. Signed-off-by: Ralf Baechle --- arch/mips/mm/ioremap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 3101d1db559..cea7d0ea36e 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -176,7 +176,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) #define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) -void __iounmap(volatile void __iomem *addr) +void __iounmap(const volatile void __iomem *addr) { struct vm_struct *p; -- cgit v1.2.3 From e83f214e45a80459d2931ae1259ab5fae82c8a8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 Oct 2006 12:48:35 -0700 Subject: [SPARC64]: Compute dma_end argument to sabre_pbm_init() correctly. virtual-dma property layout is [start, size] not [start, end]. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sabre.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index de7f7850a84..94bb681f232 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1465,5 +1465,5 @@ void sabre_init(struct device_node *dp, char *model_name) /* * Look for APB underneath. */ - sabre_pbm_init(p, dp, vdma[0], vdma[1]); + sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]); } -- cgit v1.2.3 From 6bda57365a5fda4743d83a5987c6aab66e90771c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 Oct 2006 23:00:35 -0700 Subject: [SPARC64]: Fix of_ioremap(). Use request_mem_region() if IORESOURCE_MEM. Signed-off-by: David S. Miller --- arch/sparc64/kernel/of_device.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index d822c7c18e1..d3dfb2a36d4 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -131,8 +131,13 @@ static int of_device_resume(struct device * dev) void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name) { unsigned long ret = res->start + offset; + struct resource *r; - if (!request_region(ret, size, name)) + if (res->flags & IORESOURCE_MEM) + r = request_mem_region(ret, size, name); + else + r = request_region(ret, size, name); + if (!r) ret = 0; return (void __iomem *) ret; -- cgit v1.2.3 From 66a740572d7bcb18469e71cb014bfed3ff75a773 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 20 Oct 2006 15:30:55 +0900 Subject: sh: Convert INTC2 to IRQ table registration. Currently the INTC2 code contains a fixed IRQ table that it iterates through to set the handler type, we move this in to the CPU subtype setup code instead and allow for submitting the table that way. This drops the ST40 tables, as nothing has been happening with those processors, while converting the only existing users to use the new table directly (SH7760 and SH7780). Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/intc2.c | 164 +++++----------------------------- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 63 +++++++++++++ arch/sh/kernel/cpu/sh4/setup-sh7780.c | 27 ++++++ 3 files changed, 114 insertions(+), 140 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 212884adca0..74ca576a7ce 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -11,10 +11,9 @@ * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. */ #include -#include #include +#include #include -#include static void disable_intc2_irq(unsigned int irq) { @@ -45,151 +44,36 @@ static struct irq_chip intc2_irq_chip = { * PIO1 which is INTPRI00[19,16] and INTMSK00[13] * would be: ^ ^ ^ ^ * | | | | - * make_intc2_irq(84, 0, 16, 0, 13); + * { 84, 0, 16, 0, 13 }, + * + * in the intc2_data table. */ -void make_intc2_irq(struct intc2_data *p) +void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) { - unsigned int flags; - unsigned long ipr; - - disable_irq_nosync(p->irq); - - /* Set the priority level */ - local_irq_save(flags); - - ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); - ipr &= ~(0xf << p->ipr_shift); - ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + p->ipr_offset); - - local_irq_restore(flags); + int i; - set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, - handle_level_irq, "level"); - set_irq_chip_data(p->irq, p); + for (i = 0; i < nr_irqs; i++) { + unsigned long ipr, flags; + struct intc2_data *p = table + i; - enable_intc2_irq(p->irq); -} + disable_irq_nosync(p->irq); -static struct intc2_data intc2_irq_table[] = { -#if defined(CONFIG_CPU_SUBTYPE_ST40) - {64, 0, 0, 0, 0, 13}, /* PCI serr */ - {65, 0, 4, 0, 1, 13}, /* PCI err */ - {66, 0, 4, 0, 2, 13}, /* PCI ad */ - {67, 0, 4, 0, 3, 13}, /* PCI pwd down */ - {72, 0, 8, 0, 5, 13}, /* DMAC INT0 */ - {73, 0, 8, 0, 6, 13}, /* DMAC INT1 */ - {74, 0, 8, 0, 7, 13}, /* DMAC INT2 */ - {75, 0, 8, 0, 8, 13}, /* DMAC INT3 */ - {76, 0, 8, 0, 9, 13}, /* DMAC INT4 */ - {78, 0, 8, 0, 11, 13}, /* DMAC ERR */ - {80, 0, 12, 0, 12, 13}, /* PIO0 */ - {84, 0, 16, 0, 13, 13}, /* PIO1 */ - {88, 0, 20, 0, 14, 13}, /* PIO2 */ - {112, 4, 0, 4, 0, 13}, /* Mailbox */ - #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 - {116, 4, 4, 4, 4, 13}, /* SSC0 */ - {120, 4, 8, 4, 8, 13}, /* IR Blaster */ - {124, 4, 12, 4, 12, 13}, /* USB host */ - {128, 4, 16, 4, 16, 13}, /* Video processor BLITTER */ - {132, 4, 20, 4, 20, 13}, /* UART0 */ - {134, 4, 20, 4, 22, 13}, /* UART2 */ - {136, 4, 24, 4, 24, 13}, /* IO_PIO0 */ - {140, 4, 28, 4, 28, 13}, /* EMPI */ - {144, 8, 0, 8, 0, 13}, /* MAFE */ - {148, 8, 4, 8, 4, 13}, /* PWM */ - {152, 8, 8, 8, 8, 13}, /* SSC1 */ - {156, 8, 12, 8, 12, 13}, /* IO_PIO1 */ - {160, 8, 16, 8, 16, 13}, /* USB target */ - {164, 8, 20, 8, 20, 13}, /* UART1 */ - {168, 8, 24, 8, 24, 13}, /* Teletext */ - {172, 8, 28, 8, 28, 13}, /* VideoSync VTG */ - {173, 8, 28, 8, 29, 13}, /* VideoSync DVP0 */ - {174, 8, 28, 8, 30, 13}, /* VideoSync DVP1 */ -#endif -#elif defined(CONFIG_CPU_SUBTYPE_SH7760) -/* - * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 - */ - /* INTPRIO0 | INTMSK0 */ - {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ - {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ - {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ - {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ - /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ - /* INTPRIO4 | INTMSK0 */ - {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ - {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ - {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ - {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ - {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ - {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ - {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ - {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ - /* INTPRIO8 | INTMSK0 */ - {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ - {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ - {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ - {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ - {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ - {65, 8, 24, 0, 16, 3}, /* LCDC */ - /* 66, 67 unused */ - {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ - {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ - {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ - /* 71 unused */ - {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ - {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ - {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ - {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ - {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ - {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ - {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ - {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ - /* | INTMSK4 */ - {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ - {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ - {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ - {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ - {84, 8, 0, 4, 19, 3}, /* HSPII */ - /* INTPRIOC | INTMSK4 */ - /* 85-87 unused/reserved */ - {88, 12, 20, 4, 18, 3}, /* MMCI0 */ - {89, 12, 20, 4, 17, 3}, /* MMCI1 */ - {90, 12, 20, 4, 16, 3}, /* MMCI2 */ - {91, 12, 20, 4, 15, 3}, /* MMCI3 */ - {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ - /* 93-107 reserved/undocumented */ - {108,12, 4, 4, 1, 3}, /* ADC */ - {109,12, 0, 4, 0, 3}, /* CMTI */ - /* 110-111 reserved/unused */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, - { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + /* Set the priority level */ + local_irq_save(flags); - { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + + p->ipr_offset); + ipr &= ~(0xf << p->ipr_shift); + ipr |= p->priority << p->ipr_shift; + ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + + p->ipr_offset); - { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, - { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, - { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, - { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, - { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, -#endif -}; + local_irq_restore(flags); -void __init init_IRQ_intc2(void) -{ - int i; + set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, + handle_level_irq, "level"); + set_irq_chip_data(p->irq, p); - for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) - make_intc2_irq(intc2_irq_table + i); + enable_intc2_irq(p->irq); + } } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 97f1c9af35d..07e5377bf55 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -51,3 +51,66 @@ static int __init sh7760_devices_setup(void) ARRAY_SIZE(sh7760_devices)); } __initcall(sh7760_devices_setup); + +/* + * SH7760 INTC2-Style interrupts, vectors IRQ48-111 INTEVT 0x800-0xFE0 + */ +static struct intc2_data intc2_irq_table[] = { + /* INTPRIO0 | INTMSK0 */ + {48, 0, 28, 0, 31, 3}, /* IRQ 4 */ + {49, 0, 24, 0, 30, 3}, /* IRQ 3 */ + {50, 0, 20, 0, 29, 3}, /* IRQ 2 */ + {51, 0, 16, 0, 28, 3}, /* IRQ 1 */ + /* 52-55 (INTEVT 0x880-0x8E0) unused/reserved */ + /* INTPRIO4 | INTMSK0 */ + {56, 4, 28, 0, 25, 3}, /* HCAN2_CHAN0 */ + {57, 4, 24, 0, 24, 3}, /* HCAN2_CHAN1 */ + {58, 4, 20, 0, 23, 3}, /* I2S_CHAN0 */ + {59, 4, 16, 0, 22, 3}, /* I2S_CHAN1 */ + {60, 4, 12, 0, 21, 3}, /* AC97_CHAN0 */ + {61, 4, 8, 0, 20, 3}, /* AC97_CHAN1 */ + {62, 4, 4, 0, 19, 3}, /* I2C_CHAN0 */ + {63, 4, 0, 0, 18, 3}, /* I2C_CHAN1 */ + /* INTPRIO8 | INTMSK0 */ + {52, 8, 16, 0, 11, 3}, /* SCIF0_ERI_IRQ */ + {53, 8, 16, 0, 10, 3}, /* SCIF0_RXI_IRQ */ + {54, 8, 16, 0, 9, 3}, /* SCIF0_BRI_IRQ */ + {55, 8, 16, 0, 8, 3}, /* SCIF0_TXI_IRQ */ + {64, 8, 28, 0, 17, 3}, /* USBHI_IRQ */ + {65, 8, 24, 0, 16, 3}, /* LCDC */ + /* 66, 67 unused */ + {68, 8, 20, 0, 14, 13}, /* DMABRGI0_IRQ */ + {69, 8, 20, 0, 13, 13}, /* DMABRGI1_IRQ */ + {70, 8, 20, 0, 12, 13}, /* DMABRGI2_IRQ */ + /* 71 unused */ + {72, 8, 12, 0, 7, 3}, /* SCIF1_ERI_IRQ */ + {73, 8, 12, 0, 6, 3}, /* SCIF1_RXI_IRQ */ + {74, 8, 12, 0, 5, 3}, /* SCIF1_BRI_IRQ */ + {75, 8, 12, 0, 4, 3}, /* SCIF1_TXI_IRQ */ + {76, 8, 8, 0, 3, 3}, /* SCIF2_ERI_IRQ */ + {77, 8, 8, 0, 2, 3}, /* SCIF2_RXI_IRQ */ + {78, 8, 8, 0, 1, 3}, /* SCIF2_BRI_IRQ */ + {79, 8, 8, 0, 0, 3}, /* SCIF2_TXI_IRQ */ + /* | INTMSK4 */ + {80, 8, 4, 4, 23, 3}, /* SIM_ERI */ + {81, 8, 4, 4, 22, 3}, /* SIM_RXI */ + {82, 8, 4, 4, 21, 3}, /* SIM_TXI */ + {83, 8, 4, 4, 20, 3}, /* SIM_TEI */ + {84, 8, 0, 4, 19, 3}, /* HSPII */ + /* INTPRIOC | INTMSK4 */ + /* 85-87 unused/reserved */ + {88, 12, 20, 4, 18, 3}, /* MMCI0 */ + {89, 12, 20, 4, 17, 3}, /* MMCI1 */ + {90, 12, 20, 4, 16, 3}, /* MMCI2 */ + {91, 12, 20, 4, 15, 3}, /* MMCI3 */ + {92, 12, 12, 4, 6, 3}, /* MFI (unsure, bug? in my 7760 manual*/ + /* 93-107 reserved/undocumented */ + {108,12, 4, 4, 1, 3}, /* ADC */ + {109,12, 0, 4, 0, 3}, /* CMTI */ + /* 110-111 reserved/unused */ +}; + +void __init init_IRQ_intc2(void) +{ + make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); +} diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c index 72493f259ed..814ddb22653 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -77,3 +77,30 @@ static int __init sh7780_devices_setup(void) ARRAY_SIZE(sh7780_devices)); } __initcall(sh7780_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 }, + { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + + { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + + { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, + { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, + { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, + { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, + { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, +}; + +void __init init_IRQ_intc2(void) +{ + make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); +} -- cgit v1.2.3 From 3fcfab16c5b86eaa3db3a9a31adba550c5b67141 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 19 Oct 2006 23:28:16 -0700 Subject: [PATCH] separate bdi congestion functions from queue congestion functions Separate out the concept of "queue congestion" from "backing-dev congestion". Congestion is a backing-dev concept, not a queue concept. The blk_* congestion functions are retained, as wrappers around the core backing-dev congestion functions. This proper layering is needed so that NFS can cleanly use the congestion functions, and so that CONFIG_BLOCK=n actually links. Cc: "Thomas Maier" Cc: "Jens Axboe" Cc: Trond Myklebust Cc: David Howells Cc: Peter Osterlund Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/lib/usercopy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c index 258df6b4d7d..d22cfc9d656 100644 --- a/arch/i386/lib/usercopy.c +++ b/arch/i386/lib/usercopy.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -741,7 +742,7 @@ survive: if (retval == -ENOMEM && is_init(current)) { up_read(¤t->mm->mmap_sem); - blk_congestion_wait(WRITE, HZ/50); + congestion_wait(WRITE, HZ/50); goto survive; } -- cgit v1.2.3 From 1a3e9ad163b77a3c7504f58f2780b5a62238c0ac Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 19 Oct 2006 23:28:18 -0700 Subject: [PATCH] uml: MODE_TT is bust arch/um/sys-x86_64/ptrace.c:20:1: warning: "SC_SS" redefined In file included from arch/um/include/sysdep/ptrace.h:18, from include/asm/ptrace-generic.h:12, from include/asm/ptrace.h:15, from arch/um/sys-x86_64/ptrace.c:8: arch/um/include/sysdep/sc.h:38:1: warning: this is the location of the previous definition arch/um/sys-x86_64/ptrace.c: In function 'putreg': arch/um/sys-x86_64/ptrace.c:63: warning: implicit declaration of function 'SC_FS_BASE' arch/um/sys-x86_64/ptrace.c:63: error: invalid lvalue in unary '&' arch/um/sys-x86_64/ptrace.c:63: warning: implicit declaration of function 'SC_GS_BASE' arch/um/sys-x86_64/ptrace.c:63: error: invalid lvalue in unary '&' arch/um/sys-x86_64/ptrace.c: In function 'getreg': arch/um/sys-x86_64/ptrace.c:101: error: invalid lvalue in unary '&' arch/um/sys-x86_64/ptrace.c:101: error: invalid lvalue in unary '&' I'd have to say that the fix for this, for now, is this: Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 78fb619bdb7..50fb89e3d95 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -52,6 +52,7 @@ menu "UML-specific options" config MODE_TT bool "Tracing thread support (DEPRECATED)" default n + depends on BROKEN help This option controls whether tracing thread support is compiled into UML. This option is largely obsolete, given that skas0 provides -- cgit v1.2.3 From c13e569073b89eb75216a2551e89ae93ad1f9951 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:20 -0700 Subject: [PATCH] uml: split memory allocation prototypes out of user.h user.h is too generic a header name. I've split out allocation routines from it. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/cow_sys.h | 1 + arch/um/drivers/daemon_user.c | 1 + arch/um/drivers/fd.c | 1 + arch/um/drivers/mcast_user.c | 1 + arch/um/drivers/net_user.c | 1 + arch/um/drivers/pcap_user.c | 1 + arch/um/drivers/port_user.c | 1 + arch/um/drivers/pty.c | 1 + arch/um/drivers/slip_user.c | 1 + arch/um/drivers/tty.c | 1 + arch/um/include/um_malloc.h | 17 +++++++++++++++++ arch/um/include/user.h | 6 ------ arch/um/include/user_util.h | 1 - arch/um/kernel/irq.c | 1 + arch/um/kernel/process.c | 1 + arch/um/os-Linux/drivers/ethertap_user.c | 1 + arch/um/os-Linux/irq.c | 1 + arch/um/os-Linux/main.c | 1 + arch/um/os-Linux/sigio.c | 1 + 19 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 arch/um/include/um_malloc.h (limited to 'arch') diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h index 7a5b4afde69..c6a308464ac 100644 --- a/arch/um/drivers/cow_sys.h +++ b/arch/um/drivers/cow_sys.h @@ -5,6 +5,7 @@ #include "user_util.h" #include "os.h" #include "user.h" +#include "um_malloc.h" static inline void *cow_malloc(int size) { diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 77954ea7704..310af0f1e49 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -17,6 +17,7 @@ #include "user_util.h" #include "user.h" #include "os.h" +#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c index 108b7dafbd0..218aa0e9b79 100644 --- a/arch/um/drivers/fd.c +++ b/arch/um/drivers/fd.c @@ -12,6 +12,7 @@ #include "user_util.h" #include "chan_user.h" #include "os.h" +#include "um_malloc.h" struct fd_chan { int fd; diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 4d2bd39a85b..8138f5ea1bf 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -23,6 +23,7 @@ #include "user_util.h" #include "user.h" #include "os.h" +#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index f3a3f8a29c7..0ffd7ac295d 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -18,6 +18,7 @@ #include "kern_util.h" #include "net_user.h" #include "os.h" +#include "um_malloc.h" int tap_open_common(void *dev, char *gate_addr) { diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index 2ef641ded96..11921a7baa7 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -12,6 +12,7 @@ #include "net_user.h" #include "pcap_user.h" #include "user.h" +#include "um_malloc.h" #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index f2e8fc42ecc..bc6afaf74c1 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -19,6 +19,7 @@ #include "chan_user.h" #include "port.h" #include "os.h" +#include "um_malloc.h" struct port_chan { int raw; diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c index abec620e838..829a5eca8c0 100644 --- a/arch/um/drivers/pty.c +++ b/arch/um/drivers/pty.c @@ -13,6 +13,7 @@ #include "user_util.h" #include "kern_util.h" #include "os.h" +#include "um_malloc.h" struct pty_chan { void (*announce)(char *dev_name, int dev); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 8460285c69a..7eddacc53b6 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -15,6 +15,7 @@ #include "slip.h" #include "slip_common.h" #include "os.h" +#include "um_malloc.h" void slip_user_init(void *data, void *dev) { diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 11de3ac1eb5..d95d64309ea 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c @@ -11,6 +11,7 @@ #include "user_util.h" #include "user.h" #include "os.h" +#include "um_malloc.h" struct tty_chan { char *dev; diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h new file mode 100644 index 00000000000..0363a9b53f8 --- /dev/null +++ b/arch/um/include/um_malloc.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso + * Licensed under the GPL + */ + +#ifndef __UM_MALLOC_H__ +#define __UM_MALLOC_H__ + +extern void *um_kmalloc(int size); +extern void *um_kmalloc_atomic(int size); +extern void kfree(const void *ptr); + +extern void *um_vmalloc(int size); +extern void *um_vmalloc_atomic(int size); +extern void vfree(void *ptr); + +#endif /* __UM_MALLOC_H__ */ diff --git a/arch/um/include/user.h b/arch/um/include/user.h index 39f8c880107..acadce3f271 100644 --- a/arch/um/include/user.h +++ b/arch/um/include/user.h @@ -11,17 +11,11 @@ extern void panic(const char *fmt, ...) extern int printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); extern void schedule(void); -extern void *um_kmalloc(int size); -extern void *um_kmalloc_atomic(int size); -extern void kfree(void *ptr); extern int in_aton(char *str); extern int open_gdb_chan(void); /* These use size_t, however unsigned long is correct on both i386 and x86_64. */ extern unsigned long strlcpy(char *, const char *, unsigned long); extern unsigned long strlcat(char *, const char *, unsigned long); -extern void *um_vmalloc(int size); -extern void *um_vmalloc_atomic(int size); -extern void vfree(void *ptr); #endif diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 802d7842514..06625fefef3 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -52,7 +52,6 @@ extern int linux_main(int argc, char **argv); extern void set_cmdline(char *cmd); extern void input_cb(void (*proc)(void *), void *arg, int arg_len); extern int get_pty(void); -extern void *um_kmalloc(int size); extern int switcheroo(int fd, int prot, void *from, void *to, int size); extern void do_exec(int old_pid, int new_pid); extern void tracer_panic(char *msg, ...) diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index ef259569fd8..5c1e611f628 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -31,6 +31,7 @@ #include "irq_kern.h" #include "os.h" #include "sigio.h" +#include "um_malloc.h" #include "misc_constants.h" /* diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index fe6c64abda5..348b272bb76 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -46,6 +46,7 @@ #include "mode.h" #include "mode_kern.h" #include "choose-mode.h" +#include "um_malloc.h" /* This is a per-cpu array. A processor only modifies its entry and it only * cares about its entry, so it's OK if another processor is modifying its diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index f559bdf746e..863981ba146 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -20,6 +20,7 @@ #include "net_user.h" #include "etap.h" #include "os.h" +#include "um_malloc.h" #define MAX_PACKET ETH_MAX_PACKET diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index a97206df5b5..d46b818c131 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c @@ -18,6 +18,7 @@ #include "sigio.h" #include "irq_user.h" #include "os.h" +#include "um_malloc.h" static struct pollfd *pollfds = NULL; static int pollfds_num = 0; diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index d1c5670787d..685feaab65d 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -23,6 +23,7 @@ #include "choose-mode.h" #include "uml-config.h" #include "os.h" +#include "um_malloc.h" /* Set in set_stklim, which is called from main and __wrap_malloc. * __wrap_malloc only calls it if main hasn't started. diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index f6457765b17..925a65240cf 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c @@ -19,6 +19,7 @@ #include "user_util.h" #include "sigio.h" #include "os.h" +#include "um_malloc.h" /* Protected by sigio_lock(), also used by sigio_cleanup, which is an * exitcall. -- cgit v1.2.3 From 8b028bcd0e746ae0f2f218b911032232a32dedd5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:21 -0700 Subject: [PATCH] uml: code convention cleanup of a file Fix coding conventions violations is arch/um/os-Linux/helper.c. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/helper.c | 53 +++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index cd15b9df5b5..8a78bf03b46 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -35,18 +35,18 @@ static int helper_child(void *arg) char **argv = data->argv; int errval; - if(helper_pause){ + if (helper_pause){ signal(SIGHUP, helper_hup); pause(); } - if(data->pre_exec != NULL) + if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); execvp(argv[0], argv); errval = -errno; printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); - return(0); + return 0; } /* Returns either the pid of the child process we run or -E* on failure. @@ -58,20 +58,21 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long stack, sp; int pid, fds[2], ret, n; - if((stack_out != NULL) && (*stack_out != 0)) + if ((stack_out != NULL) && (*stack_out != 0)) stack = *stack_out; - else stack = alloc_stack(0, __cant_sleep()); - if(stack == 0) + else + stack = alloc_stack(0, __cant_sleep()); + if (stack == 0) return -ENOMEM; ret = os_pipe(fds, 1, 0); - if(ret < 0){ + if (ret < 0) { printk("run_helper : pipe failed, ret = %d\n", -ret); goto out_free; } ret = os_set_exec_close(fds[1], 1); - if(ret < 0){ + if (ret < 0) { printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", -ret); goto out_close; @@ -83,7 +84,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, data.argv = argv; data.fd = fds[1]; pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); - if(pid < 0){ + if (pid < 0) { ret = -errno; printk("run_helper : clone failed, errno = %d\n", errno); goto out_close; @@ -95,10 +96,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, /* Read the errno value from the child, if the exec failed, or get 0 if * the exec succeeded because the pipe fd was set as close-on-exec. */ n = os_read_file(fds[0], &ret, sizeof(ret)); - if(n == 0) + if (n == 0) { ret = pid; - else { - if(n < 0){ + } else { + if (n < 0) { printk("run_helper : read on pipe failed, ret = %d\n", -n); ret = n; @@ -112,10 +113,11 @@ out_close: close(fds[1]); close(fds[0]); out_free: - if(stack_out == NULL) + if (stack_out == NULL) free_stack(stack, 0); - else *stack_out = stack; - return(ret); + else + *stack_out = stack; + return ret; } int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, @@ -125,31 +127,32 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, int pid, status, err; stack = alloc_stack(stack_order, __cant_sleep()); - if(stack == 0) return(-ENOMEM); + if (stack == 0) + return -ENOMEM; sp = stack + (page_size() << stack_order) - sizeof(void *); pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); - if(pid < 0){ + if (pid < 0) { err = -errno; printk("run_helper_thread : clone failed, errno = %d\n", errno); return err; } - if(stack_out == NULL){ + if (stack_out == NULL) { CATCH_EINTR(pid = waitpid(pid, &status, 0)); - if(pid < 0){ + if (pid < 0) { err = -errno; printk("run_helper_thread - wait failed, errno = %d\n", errno); pid = err; } - if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) printk("run_helper_thread - thread returned status " "0x%x\n", status); free_stack(stack, stack_order); - } - else *stack_out = stack; - return(pid); + } else + *stack_out = stack; + return pid; } int helper_wait(int pid) @@ -157,9 +160,9 @@ int helper_wait(int pid) int ret; CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); - if(ret < 0){ + if (ret < 0) { ret = -errno; printk("helper_wait : waitpid failed, errno = %d\n", errno); } - return(ret); + return ret; } -- cgit v1.2.3 From 493e3758be1d5628b4d799fe21d68969edbe32aa Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:22 -0700 Subject: [PATCH] uml: reenable compilation of enable_timer, disabled by mistake CONFIG_MODE_TT does not work there, the UML_ prefixed version must be used - this causes a link-time failure when CONFIG_MODE_TT is enabled (i.e. always here, never by Jeff). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/time.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 38be096e750..2115b8beb54 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -16,6 +16,7 @@ #include "process.h" #include "kern_constants.h" #include "os.h" +#include "uml-config.h" int set_interval(int is_virtual) { @@ -30,7 +31,7 @@ int set_interval(int is_virtual) return 0; } -#ifdef CONFIG_MODE_TT +#ifdef UML_CONFIG_MODE_TT void enable_timer(void) { set_interval(1); -- cgit v1.2.3 From b2670eacfb013169b8bf151a5078a9ef8ef86466 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:23 -0700 Subject: [PATCH] uml: use DEFCONFIG_LIST to avoid reading host's config This should make sure that, for UML, host's configuration files are not considered, which avoids various pains to the user. Our dependency are such that the obtained Kconfig will be valid and will lead to successful compilation - however they cannot prevent an user from disabling any boot device, and if an option is not set in the read .config (say /boot/config-XXX), with make menuconfig ARCH=um, it is not set. This always disables UBD and all console I/O channels, which leads to non-working UML kernels, so this bothers users - especially now, since it will happen on almost every machine (/boot/config-`uname -r` exists almost on every machine). It can be workarounded with make defconfig ARCH=um, but it is non-obvious and can be avoided, so please _do_ merge this patch. Given the existence of options, it could be interesting to implement (additionally) "option required" - with it, Kconfig will refuse reading a .config file (from wherever it comes) if the given option is not set. With this, one could mark with it the option characteristic of the given architecture (it was an old proposal of Roman Zippel, when I pointed out our problem): config UML option required default y However this should be further discussed: *) for x86, it must support constructs like: ==arch/i386/Kconfig== config 64BIT option required default n where Kconfig must require that CONFIG_64BIT is disabled or not present in the read .config. *) do we want to do such checks only for the starting defconfig or also for .config? Which leads to: *) I may want to port a x86_64 .config to x86 and viceversa, or even among more different archs. Should that be allowed, and in which measure (the user may force skipping the check for a .config or it is only given a warning by default)? Cc: Roman Zippel Cc: Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 50fb89e3d95..5ac1f2963ae 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -1,3 +1,8 @@ +config DEFCONFIG_LIST + string + option defconfig_list + default "arch/$ARCH/defconfig" + # UML uses the generic IRQ sugsystem config GENERIC_HARDIRQS bool -- cgit v1.2.3 From d9d645f06a8f50659bbae2be64ed8367ba068fc0 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:24 -0700 Subject: [PATCH] uml: cleanup run_helper() API to fix a leak Freeing the stack is left uselessly to the caller of run_helper in some cases - this is taken from run_helper_thread, but here it is useless, so no caller needs it and the only place where this happens has a potential leak - in case of error neither run_helper() nor xterm_open() call free_stack(). At this point passing a pointer is not needed - the stack pointer should be passed directly, but this change is not done here. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/xterm.c | 2 -- arch/um/os-Linux/helper.c | 7 +++---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 386f8b95298..850221d9b4c 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c @@ -136,8 +136,6 @@ int xterm_open(int input, int output, int primary, void *d, return(pid); } - if(data->stack == 0) free_stack(stack, 0); - if (data->direct_rcv) { new = os_rcv_fd(fd, &data->helper_pid); } else { diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index 8a78bf03b46..d13299cfa31 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -50,7 +50,8 @@ static int helper_child(void *arg) } /* Returns either the pid of the child process we run or -E* on failure. - * XXX The alloc_stack here breaks if this is called in the tracing thread */ + * XXX The alloc_stack here breaks if this is called in the tracing thread, so + * we need to receive a preallocated stack (a local buffer is ok). */ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long *stack_out) { @@ -113,10 +114,8 @@ out_close: close(fds[1]); close(fds[0]); out_free: - if (stack_out == NULL) + if ((stack_out == NULL) || (*stack_out == 0)) free_stack(stack, 0); - else - *stack_out = stack; return ret; } -- cgit v1.2.3 From f43e6a5a72566675da3581dc0d7076042e6701f7 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:25 -0700 Subject: [PATCH] uml: kconfig - silence warning Silence useless warning about undefined symbol in Kconfig. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig.char | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 62d87b71179..e03e40c7aac 100644 --- a/arch/um/Kconfig.char +++ b/arch/um/Kconfig.char @@ -190,6 +190,11 @@ config HOSTAUDIO tristate default UML_SOUND +#It is selected elsewhere, so kconfig would warn without this. +config HW_RANDOM + tristate + default n + config UML_RANDOM tristate "Hardware random number generator" help -- cgit v1.2.3 From 1ba0ce6f9c19a8573832e14b418dc835dc6f3bbd Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 19 Oct 2006 23:28:26 -0700 Subject: [PATCH] uml: mmapper - remove just added but wrong "const" attribute When enabling the mmapper driver I got warnings because this "const" miscdevice structure is passed to function as non-const pointer; unlike struct tty_operations, however, I verified that misc_{de,}register _do_ modify their parameter, so this const attribute must be removed. Since the purpose of the change was to guarantee that no lock was needed, add a comment to prove this differently. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/mmapper_kern.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index 9a3b5daf625..df3516e47d4 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -95,7 +95,8 @@ static const struct file_operations mmapper_fops = { .release = mmapper_release, }; -static const struct miscdevice mmapper_dev = { +/* No locking needed - only used (and modified) by below initcall and exitcall. */ +static struct miscdevice mmapper_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "mmapper", .fops = &mmapper_fops -- cgit v1.2.3 From e51959faa61278c762389802faf8ba1a40676628 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Thu, 19 Oct 2006 23:29:04 -0700 Subject: [PATCH] Fix potential interrupts during alternative patching Interrupts must be disabled during alternative instruction patching. On systems with high timer IRQ rates, or when running in an emulator, timing differences can result in random kernel panics because of running partially patched instructions. This doesn't yet fix NMIs, which requires extricating the patch code from the late bug checking and is logically separate (and also less likely to cause problems). Signed-off-by: Zachary Amsden Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/alternative.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 28ab8064976..583c238e17f 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -344,6 +344,7 @@ void alternatives_smp_switch(int smp) void __init alternative_instructions(void) { + unsigned long flags; if (no_replacement) { printk(KERN_INFO "(SMP-)alternatives turned off\n"); free_init_pages("SMP alternatives", @@ -351,6 +352,8 @@ void __init alternative_instructions(void) (unsigned long)__smp_alt_end); return; } + + local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); /* switch to patch-once-at-boottime-only mode and free the @@ -386,4 +389,5 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif + local_irq_restore(flags); } -- cgit v1.2.3 From ac4e0aba7daf0a7c6ac20974070428481dc940f5 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 19 Oct 2006 23:29:14 -0700 Subject: [PATCH] one more ARM IRQ fix Fix one more compile breakage caused by the post -rc1 IRQ changes. Signed-off-by: Adrian Bunk Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-lh7a40x/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-lh7a40x/common.h b/arch/arm/mach-lh7a40x/common.h index 18e8bb4eb20..0ca20c6c83b 100644 --- a/arch/arm/mach-lh7a40x/common.h +++ b/arch/arm/mach-lh7a40x/common.h @@ -15,4 +15,4 @@ extern void lh7a404_init_irq (void); extern void lh7a40x_clcd_init (void); extern void lh7a40x_init_board_irq (void); -#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq), regs) +#define IRQ_DISPATCH(irq) desc_handle_irq((irq),(irq_desc + irq)) -- cgit v1.2.3 From f248b6a34fdd726dd12b549fceba907b6df2771c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:00 +0200 Subject: [PATCH] x86-64: Update defconfig Signed-off-by: Andi Kleen --- arch/x86_64/defconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 47bfba6e9dc..0f5d44e86be 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Thu Oct 5 13:04:43 2006 +# Linux kernel version: 2.6.19-rc2-git4 +# Sat Oct 21 03:38:52 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -335,8 +335,8 @@ CONFIG_IPV6=y # CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -437,6 +437,13 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_IBM_ASM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -1008,6 +1015,7 @@ CONFIG_I2C_ISA=m # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -1058,12 +1066,6 @@ CONFIG_SENSORS_SMSC47B397=m # CONFIG_SENSORS_HDAPS is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Misc devices -# -# CONFIG_IBM_ASM is not set -# CONFIG_TIFM_CORE is not set - # # Multimedia devices # @@ -1196,7 +1198,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1242,6 +1243,7 @@ CONFIG_USB_MON=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1318,6 +1320,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1341,6 +1344,7 @@ CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set +CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems @@ -1418,7 +1422,6 @@ CONFIG_SUNRPC=y # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set # CONFIG_9P_FS is not set -CONFIG_GENERIC_ACL=y # # Partition Types @@ -1470,10 +1473,6 @@ CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y -# -# Distributed Lock Manager -# - # # Instrumentation Support # @@ -1512,6 +1511,7 @@ CONFIG_DEBUG_FS=y CONFIG_UNWIND_INFO=y CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set # CONFIG_DEBUG_RODATA is not set -- cgit v1.2.3 From 13892de19eb9007ea47430c701bdbf69df71d883 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] i386: Update defconfig Signed-off-by: Andi Kleen --- arch/i386/defconfig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 60c0c02574f..97aacd6bd7d 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc1 -# Thu Oct 5 13:04:53 2006 +# Linux kernel version: 2.6.19-rc2-git4 +# Sat Oct 21 03:38:56 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -380,8 +380,8 @@ CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -482,6 +482,13 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_IBM_ASM is not set +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -1024,6 +1031,7 @@ CONFIG_HANGCHECK_TIMER=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -1031,12 +1039,6 @@ CONFIG_HANGCHECK_TIMER=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# -# Misc devices -# -# CONFIG_IBM_ASM is not set -# CONFIG_TIFM_CORE is not set - # # Multimedia devices # @@ -1169,7 +1171,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1215,6 +1216,7 @@ CONFIG_USB_MON=y # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1284,6 +1286,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1307,6 +1310,7 @@ CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set CONFIG_AUTOFS4_FS=y # CONFIG_FUSE_FS is not set +CONFIG_GENERIC_ACL=y # # CD-ROM/DVD Filesystems @@ -1384,7 +1388,6 @@ CONFIG_SUNRPC=y # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set # CONFIG_9P_FS is not set -CONFIG_GENERIC_ACL=y # # Partition Types @@ -1436,10 +1439,6 @@ CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y -# -# Distributed Lock Manager -# - # # Instrumentation Support # @@ -1480,6 +1479,7 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_UNWIND_INFO=y CONFIG_STACK_UNWIND=y # CONFIG_FORCED_INLINING is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set CONFIG_EARLY_PRINTK=y -- cgit v1.2.3 From 926fafebc48a3218fac675f12974f9a46473bd40 Mon Sep 17 00:00:00 2001 From: keith mannthey Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86-64: x86_64 hot-add memory srat.c fix This patch corrects the logic used in srat.c to figure out what parsing what action to take when registering hot-add areas. Hot-add areas should only be added to the node information for the MEMORY_HOTPLUG_RESERVE case. When booting MEMORY_HOTPLUG_SPARSE hot-add areas on everything but the last node are getting include in the node data and during kernel boot the pages are setup then the kernel dies when the pages are used. This patch fixes this issue. Signed-off-by: Keith Mannthey Signed-off-by: Andi Kleen --- arch/x86_64/mm/srat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 3cc0544e25f..1087e150a21 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c @@ -207,7 +207,7 @@ static inline int save_add_info(void) return hotadd_percent > 0; } #else -int update_end_of_memory(unsigned long end) {return 0;} +int update_end_of_memory(unsigned long end) {return -1;} static int hotadd_enough_memory(struct bootnode *nd) {return 1;} #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE static inline int save_add_info(void) {return 1;} @@ -337,7 +337,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) push_node_boundaries(node, nd->start >> PAGE_SHIFT, nd->end >> PAGE_SHIFT); - if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) { + if (ma->flags.hot_pluggable && (reserve_hotadd(node, start, end) < 0)) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; -- cgit v1.2.3 From 45edfd1db02f818b3dc7e4743ee8585af6b78f78 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86-64: typo in __assign_irq_vector when updating pos for vector and offset typo with cpu instead of new_cpu Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 49e94f7994c..b848f480851 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -651,12 +651,12 @@ next: if (vector == IA32_SYSCALL_VECTOR) goto next; for_each_cpu_mask(new_cpu, domain) - if (per_cpu(vector_irq, cpu)[vector] != -1) + if (per_cpu(vector_irq, new_cpu)[vector] != -1) goto next; /* Found one! */ for_each_cpu_mask(new_cpu, domain) { - pos[cpu].vector = vector; - pos[cpu].offset = offset; + pos[new_cpu].vector = vector; + pos[new_cpu].offset = offset; } if (old_vector >= 0) { int old_cpu; -- cgit v1.2.3 From da8604cc2d6cd4cbde873c7ba308365e402ac7bf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] i386: fix .cfi_signal_frame copy-n-paste error This was copied, pasted but not edited. Cc: Andi Kleen Cc: Jan Beulich Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 7cc0b189b82..2d9d756fdd7 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -51,8 +51,8 @@ cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) # is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) +cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) +AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) CFLAGS += $(cflags-y) -- cgit v1.2.3 From 469b1d8741a5970ad49f2b5a837811579ba0b6f2 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86-64: Fix for arch/x86_64/pci/Makefile CFLAGS The arch/x86_64/pci directory was giving problems in a wierd cross-compile environment. The exact cause is unknown, but the Makefile used CFLAGS instead of EXTRA_CFLAGS. From what I can tell from Documentation/kbuild/makefiles.txt, CFLAGS should not be used for this, it should be EXTRA_CFLAGS. And it solves the cross-compile problem. Signed-off-by: Corey Minyard Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Vojtech Pavlik Cc: Sam Ravnborg Signed-off-by: Andrew Morton --- arch/x86_64/pci/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/pci/Makefile b/arch/x86_64/pci/Makefile index 1eb18f421ed..149aba05a5b 100644 --- a/arch/x86_64/pci/Makefile +++ b/arch/x86_64/pci/Makefile @@ -3,7 +3,7 @@ # # Reuse the i386 PCI subsystem # -CFLAGS += -Iarch/i386/pci +EXTRA_CFLAGS += -Iarch/i386/pci obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o -- cgit v1.2.3 From 73bb8919b33d42cf75a0ed89bc9ca6a7128665be Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86-64: fix page align in e820 allocator Currently some code pieces assume that address returned by find_e820_area() are page aligned. But looks like find_e820_area() had no such intention and hence one might end up stomping over some of the data. One such case is bootmem allocator initialization code stomped over bss. This patch modified find_e820_area() to return page aligned address. This might be little wasteful of memory but at the same time probably it is easier to handle page aligned memory. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/kernel/e820.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index b3f0908668e..a75c829c2b0 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -54,13 +54,13 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) /* various gunk below that needed for SMP startup */ if (addr < 0x8000) { - *addrp = 0x8000; + *addrp = PAGE_ALIGN(0x8000); return 1; } /* direct mapping tables of the kernel */ if (last >= table_start<= INITRD_START && addr < INITRD_START+INITRD_SIZE) { - *addrp = INITRD_START + INITRD_SIZE; + *addrp = PAGE_ALIGN(INITRD_START + INITRD_SIZE); return 1; } #endif /* kernel code */ - if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { - *addrp = __pa_symbol(&_end); + if (last >= __pa_symbol(&_text) && addr < __pa_symbol(&_end)) { + *addrp = PAGE_ALIGN(__pa_symbol(&_end)); return 1; } if (last >= ebda_addr && addr < ebda_addr + ebda_size) { - *addrp = ebda_addr + ebda_size; + *addrp = PAGE_ALIGN(ebda_addr + ebda_size); return 1; } @@ -152,7 +152,7 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi continue; while (bad_addr(&addr, size) && addr+size <= ei->addr+ei->size) ; - last = addr + size; + last = PAGE_ALIGN(addr) + size; if (last > ei->addr + ei->size) continue; if (last > end) -- cgit v1.2.3 From cdfce1f5714fec7b24715f569b2fee1607350a6d Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:01 +0200 Subject: [PATCH] x86: Use -maccumulate-outgoing-args This avoids some problems with gcc 4.x and earlier generating invalid unwind information. In 4.1 the option is default when unwind information is enabled. And it seems to generate smaller code too, so it's probably a good thing on its own. With gcc 4.0: i386: 4683198 902112 480868 6066178 5c9002 vmlinux (before) 4449895 902112 480868 5832875 5900ab vmlinux (after) x86-64: 4939761 1449584 648216 7037561 6b6279 vmlinux (before) 4854193 1449584 648216 6951993 6a1439 vmlinux (after) On 4.1 it shouldn't make much difference because it is default when unwind is enabled anyways. Suggested by Michael Matz and Jan Beulich Cc: jbeulich@novell.com Signed-off-by: Andi Kleen --- arch/i386/Makefile | 4 ++++ arch/x86_64/Makefile | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 2d9d756fdd7..0677908dfa0 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -42,6 +42,10 @@ cflags-$(CONFIG_REGPARM) += -mregparm=3 # temporary until string.h is fixed cflags-y += -ffreestanding +# this works around some issues with generating unwind tables in older gccs +# newer gccs do it by default +cflags-y += -maccumulate-outgoing-args + # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 1c0f18d4f88..13972148058 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -54,6 +54,10 @@ endif cflags-y += $(call cc-option,-funit-at-a-time) # prevent gcc from generating any FP code by mistake cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) +# this works around some issues with generating unwind tables in older gccs +# newer gccs do it by default +cflags-y += -maccumulate-outgoing-args + # do binutils support CFI? cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -- cgit v1.2.3 From 26fd5e084e470dbe8edc6f726fc918e89b9f988c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] i386: Fix fake return address The fake return address was being set to __KERNEL_PDA, rather than 0. Push it earlier while %eax still equals 0. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Andrew Morton --- arch/i386/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index be9d883c62c..ca31f18d277 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -317,7 +317,7 @@ is386: movl $2,%ecx # set MP movl %eax,%gs lldt %ax cld # gcc2 wants the direction flag cleared at all times - pushl %eax # fake return address + pushl $0 # fake return address for unwinder #ifdef CONFIG_SMP movb ready, %cl movb $1, ready -- cgit v1.2.3 From cc7d479fe56133e79840beffe9cb4fd193af93aa Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: Fix ENOSYS in system call tracing This patch: - out of range system calls failing to return -ENOSYS under system call tracing [AK: split out from another patch by Jan as separate bugfix] Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 38a7b2d528e..038dcf733a1 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -315,6 +315,8 @@ tracesys: LOAD_ARGS ARGOFFSET /* reload args from stack in case ptrace changed it */ RESTORE_REST cmpq $__NR_syscall_max,%rax + movq $-ENOSYS,%rcx + cmova %rcx,%rax ja 1f movq %r10,%rcx /* fixup for C */ call *sys_call_table(,%rax,8) -- cgit v1.2.3 From 581910e2eb952e541b8ca9b5f551d6c124903b61 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: Revert interrupt backlink changes They break more than they fix Signed-off-by: Andi Kleen --- arch/x86_64/kernel/entry.S | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 038dcf733a1..e3eddde3d3b 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -537,8 +537,6 @@ END(stub_rt_sigreturn) 1: incl %gs:pda_irqcount cmoveq %gs:pda_irqstackptr,%rsp push %rbp # backlink for old unwinder - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbp,0 /* * We entered an interrupt context - irqs are off: */ @@ -1178,7 +1176,6 @@ ENTRY(call_softirq) incl %gs:pda_irqcount cmove %gs:pda_irqstackptr,%rsp push %rbp # backlink for old unwinder - CFI_ADJUST_CFA_OFFSET 8 call __do_softirq leaveq CFI_DEF_CFA_REGISTER rsp -- cgit v1.2.3 From a1bae67243512ca30ceda48e3e24e25b543f8ab7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] i386: Disable nmi watchdog on all ThinkPads Even newer Thinkpads have bugs in SMM code that causes hangs with NMI watchdog. Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 3e8e3adb048..eaafe233a5d 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -219,11 +219,11 @@ static int __init check_nmi_watchdog(void) int cpu; /* Enable NMI watchdog for newer systems. - Actually it should be safe for most systems before 2004 too except - for some IBM systems that corrupt registers when NMI happens - during SMM. Unfortunately we don't have more exact information - on these and use this coarse check. */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004) + Probably safe on most older systems too, but let's be careful. + IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM + which hangs the system. Disable watchdog for all thinkpads */ + if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 && + !dmi_name_in_vendors("ThinkPad")) nmi_watchdog = NMI_LOCAL_APIC; if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) -- cgit v1.2.3 From 6bf2dafad18c119beb534cbb3d882fe7a6c3f529 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: Use irq_domain in ioapic_retrigger_irq Thanks to YH Lu for spotting this. It appears I missed this function when I refactored allocate_irq_vector and introduced irq_domain, with the result that all retriggered irqs would go to cpu 0 even if we were not prepared to receive them there. While reviewing YH's patch I also noticed that this function was missing locking, and since I am now reading two values from two diffrent arrays that looks like a race we might be able to hit in the real world. Cc: Yinghai Lu Signed-off-by: Eric W. Biederman Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index b848f480851..8a9a357875b 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1255,12 +1255,15 @@ static int ioapic_retrigger_irq(unsigned int irq) { cpumask_t mask; unsigned vector; + unsigned long flags; + spin_lock_irqsave(&vector_lock, flags); vector = irq_vector[irq]; cpus_clear(mask); - cpu_set(vector >> 8, mask); + cpu_set(first_cpu(irq_domain[irq]), mask); - send_IPI_mask(mask, vector & 0xff); + send_IPI_mask(mask, vector); + spin_unlock_irqrestore(&vector_lock, flags); return 1; } -- cgit v1.2.3 From 8cf2c51927bbeefafc25193d01b91f9ed3806e96 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86: Revert new unwind kernel stack termination Jan convinced me that it was unnecessary because the assembly stubs do this already on the stack. Cc: jbeulich@novell.com Signed-off-by: Andi Kleen --- arch/i386/kernel/process.c | 6 +----- arch/x86_64/kernel/entry.S | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 57d375900af..1e1fa3e391a 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -336,7 +336,6 @@ extern void kernel_thread_helper(void); int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { struct pt_regs regs; - int err; memset(®s, 0, sizeof(regs)); @@ -351,10 +350,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ - err = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); - if (err == 0) /* terminate kernel stack */ - task_pt_regs(current)->eip = 0; - return err; + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } EXPORT_SYMBOL(kernel_thread); diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index e3eddde3d3b..7d401b00d82 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -980,11 +980,6 @@ ENTRY(kernel_thread) call do_fork movq %rax,RAX(%rsp) xorl %edi,%edi - test %rax,%rax - jnz 1f - /* terminate stack in child */ - movq %rdi,RIP(%rsp) -1: /* * It isn't worth to check for reschedule here, -- cgit v1.2.3 From 84f404f695b16bd142c8dd9910d5a398f54fb044 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: Put more than one cpu in TARGET_CPUS TARGET_CPUS is the default irq routing poicy. It specifies which cpus the kernel should aim an irq at. In physflat delivery mode we can route an irq to a single cpu. But that doesn't mean our default policy should only be a single cpu is allowed. By allowing the irq routing code to select from multiple cpus this enables systems with more irqs then we can service on a single processor to actually work. I just audited and tested the code and irqbalance doesn't care, and the io_apic.c doesn't care if we have extra cpus in the mask. Everything will use or assume we are using the lowest numbered cpu in the mask if we can't use them all. So this should result in no behavior changes except on systems that need it. Thanks for YH Lu for spotting this problem in his testing. Cc: Yinghai Lu Signed-off-by: Eric W. Biederman Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/genapic_flat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic_flat.c b/arch/x86_64/kernel/genapic_flat.c index 0dfc223c183..7c01db8fa9d 100644 --- a/arch/x86_64/kernel/genapic_flat.c +++ b/arch/x86_64/kernel/genapic_flat.c @@ -153,7 +153,7 @@ struct genapic apic_flat = { static cpumask_t physflat_target_cpus(void) { - return cpumask_of_cpu(0); + return cpu_online_map; } static cpumask_t physflat_vector_allocation_domain(int cpu) -- cgit v1.2.3 From dbaab49f92ff6ae6255762a948375e4036cbdbd2 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Sat, 21 Oct 2006 18:37:03 +0200 Subject: [PATCH] x86-64: Overlapping program headers in physical addr space fix o A recent change to vmlinux.ld.S file broke kexec as now resulting vmlinux program headers are overlapping in physical address space. o Now all the vsyscall related sections are placed after data and after that mostly init data sections are placed. To avoid physical overlap among phdrs, there are three possible solutions. - Place vsyscall sections also in data phdrs instead of user - move vsyscal sections after init data in bss. - create another phdrs say data.init and move all the sections after vsyscall into this new phdr. o This patch implements the third solution. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: Magnus Damm Cc: Andi Kleen Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/vmlinux.lds.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index b9df2ab6529..1283614c9b2 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -17,6 +17,7 @@ PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ user PT_LOAD FLAGS(7); /* RWE */ + data.init PT_LOAD FLAGS(7); /* RWE */ note PT_NOTE FLAGS(4); /* R__ */ } SECTIONS @@ -131,7 +132,7 @@ SECTIONS . = ALIGN(8192); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) - } :data + }:data.init . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { -- cgit v1.2.3 From e70ea8c09db0e25ab58f84ba7f393e5c9125a8ee Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:03 +0200 Subject: [PATCH] x86-64: Revert timer routing behaviour back to 2.6.16 state By default route the 8254 over the 8259 and only disable it on ATI boards where this causes double timer interrupts. This should unbreak some Nvidia boards where the timer doesn't seem to tick of it isn't enabled in the 8259. At least one VIA board also seemed to have a little trouble with the disabled 8259. For 2.6.20 we'll try both dynamically without black listing, but I think for .19 this is the safer approach because it has been already well tested in earlier kernels. This also makes the x86-64 behaviour the same as i386. Command line options can change all this of course. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early-quirks.c | 9 +++++---- arch/x86_64/kernel/io_apic.c | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 208e38a372c..2b1245d8625 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -61,10 +61,11 @@ static void nvidia_bugs(void) static void ati_bugs(void) { -#if 1 /* for testing */ - printk("ATI board detected\n"); -#endif - /* No bugs right now */ + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } } struct chipset { diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 8a9a357875b..b000017e4b5 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -57,7 +57,7 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; -int timer_over_8254 __initdata = 0; +int timer_over_8254 __initdata = 1; /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; -- cgit v1.2.3 From 7516795739bd53175629b90fab0ad488d7a6a9f7 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Sat, 21 Oct 2006 10:24:14 -0700 Subject: [PATCH] Reintroduce NODES_SPAN_OTHER_NODES for powerpc Reintroduce NODES_SPAN_OTHER_NODES for powerpc Revert "[PATCH] Remove SPAN_OTHER_NODES config definition" This reverts commit f62859bb6871c5e4a8e591c60befc8caaf54db8c. Revert "[PATCH] mm: remove arch independent NODES_SPAN_OTHER_NODES" This reverts commit a94b3ab7eab4edcc9b2cb474b188f774c331adf7. Also update the comments to indicate that this is still required and where its used. Signed-off-by: Andy Whitcroft Cc: Paul Mackerras Cc: Mike Kravetz Cc: Benjamin Herrenschmidt Acked-by: Mel Gorman Acked-by: Will Schmidt Cc: Christoph Lameter Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/Kconfig | 9 +++++++++ arch/powerpc/configs/pseries_defconfig | 1 + 2 files changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8b691046557..2bd9b7fb0f6 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -751,6 +751,15 @@ config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG +# Some NUMA nodes have memory ranges that span +# other nodes. Even though a pfn is valid and +# between a node's start and end pfns, it may not +# reside on that node. See memmap_init_zone() +# for details. +config NODES_SPAN_OTHER_NODES + def_bool y + depends on NEED_MULTIPLE_NODES + config PPC_64K_PAGES bool "64k page size" depends on PPC64 diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 9828663652e..d2833c1a1f3 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -184,6 +184,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y +CONFIG_NODES_SPAN_OTHER_NODES=y # CONFIG_PPC_64K_PAGES is not set CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y -- cgit v1.2.3 From 224dc50ece1b40f8cff5ecadd42a6b2691e231de Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 21 Oct 2006 02:05:20 +0100 Subject: [MIPS] Cleanup remaining references to mips_counter_frequency. Noticed by Samium Gromoff but his patch got stale in flight ... Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/generic/time.c | 2 +- arch/mips/mips-boards/sim/sim_time.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 6f8a9fe7c1e..c079e2ae02a 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -187,7 +187,7 @@ out: } /* - * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect + * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect */ static unsigned int __init estimate_cpu_frequency(void) { diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c index c566b9bd042..24a4ed00cc0 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mips-boards/sim/sim_time.c @@ -102,7 +102,7 @@ irqreturn_t sim_timer_interrupt(int irq, void *dev_id) /* - * Estimate CPU frequency. Sets mips_counter_frequency as a side-effect + * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect */ static unsigned int __init estimate_cpu_frequency(void) { -- cgit v1.2.3 From f8829caee311207afbc882794bdc5aa0db5caf33 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 21 Oct 2006 23:17:35 +0100 Subject: [MIPS] Fix aliasing bug in copy_to_user_page / copy_from_user_page The current implementation uses a sequence of a cacheflush and a copy. This is racy in case of a multithreaded debuggee and renders GDB virtually unusable. Aside this fixes a performance hog rendering access to /proc/cmdline very slow and resulting in a enough cache stalls for the 34K AP/SP programming model to make the bare metal code on the non-Linux VPE miss RT deadlines. The main part of this patch was originally written by Ralf Baechle; Atushi Nemoto did the the debugging. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/mm/init.c | 167 ++++++++++++++++++++++++++++++++++++++++++++-- arch/mips/mm/pgtable-32.c | 7 +- arch/mips/mm/pgtable-64.c | 11 +++ 3 files changed, 175 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 88b72c9a849..2de4d3c367a 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -30,11 +30,34 @@ #include #include #include +#include #include #include #include #include #include +#include + +/* Atomicity and interruptability */ +#ifdef CONFIG_MIPS_MT_SMTC + +#include + +#define ENTER_CRITICAL(flags) \ + { \ + unsigned int mvpflags; \ + local_irq_save(flags);\ + mvpflags = dvpe() +#define EXIT_CRITICAL(flags) \ + evpe(mvpflags); \ + local_irq_restore(flags); \ + } +#else + +#define ENTER_CRITICAL(flags) local_irq_save(flags) +#define EXIT_CRITICAL(flags) local_irq_restore(flags) + +#endif /* CONFIG_MIPS_MT_SMTC */ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); @@ -80,13 +103,142 @@ unsigned long setup_zero_pages(void) return 1UL << order; } -#ifdef CONFIG_HIGHMEM -pte_t *kmap_pte; -pgprot_t kmap_prot; +/* + * These are almost like kmap_atomic / kunmap_atmic except they take an + * additional address argument as the hint. + */ #define kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), (vaddr)) +#ifdef CONFIG_MIPS_MT_SMTC +static pte_t *kmap_coherent_pte; +static void __init kmap_coherent_init(void) +{ + unsigned long vaddr; + + /* cache the first coherent kmap pte */ + vaddr = __fix_to_virt(FIX_CMAP_BEGIN); + kmap_coherent_pte = kmap_get_fixmap_pte(vaddr); +} +#else +static inline void kmap_coherent_init(void) {} +#endif + +static inline void *kmap_coherent(struct page *page, unsigned long addr) +{ + enum fixed_addresses idx; + unsigned long vaddr, flags, entrylo; + unsigned long old_ctx; + pte_t pte; + int tlbidx; + + inc_preempt_count(); + idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); +#ifdef CONFIG_MIPS_MT_SMTC + idx += FIX_N_COLOURS * smp_processor_id(); +#endif + vaddr = __fix_to_virt(FIX_CMAP_END - idx); + pte = mk_pte(page, PAGE_KERNEL); +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) + entrylo = pte.pte_high; +#else + entrylo = pte_val(pte) >> 6; +#endif + + ENTER_CRITICAL(flags); + old_ctx = read_c0_entryhi(); + write_c0_entryhi(vaddr & (PAGE_MASK << 1)); + write_c0_entrylo0(entrylo); + write_c0_entrylo1(entrylo); +#ifdef CONFIG_MIPS_MT_SMTC + set_pte(kmap_coherent_pte - (FIX_CMAP_END - idx), pte); + /* preload TLB instead of local_flush_tlb_one() */ + mtc0_tlbw_hazard(); + tlb_probe(); + tlb_probe_hazard(); + tlbidx = read_c0_index(); + mtc0_tlbw_hazard(); + if (tlbidx < 0) + tlb_write_random(); + else + tlb_write_indexed(); +#else + tlbidx = read_c0_wired(); + write_c0_wired(tlbidx + 1); + write_c0_index(tlbidx); + mtc0_tlbw_hazard(); + tlb_write_indexed(); +#endif + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + EXIT_CRITICAL(flags); + + return (void*) vaddr; +} + +#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) + +static inline void kunmap_coherent(struct page *page) +{ +#ifndef CONFIG_MIPS_MT_SMTC + unsigned int wired; + unsigned long flags, old_ctx; + + ENTER_CRITICAL(flags); + old_ctx = read_c0_entryhi(); + wired = read_c0_wired() - 1; + write_c0_wired(wired); + write_c0_index(wired); + write_c0_entryhi(UNIQUE_ENTRYHI(wired)); + write_c0_entrylo0(0); + write_c0_entrylo1(0); + mtc0_tlbw_hazard(); + tlb_write_indexed(); + tlbw_use_hazard(); + write_c0_entryhi(old_ctx); + EXIT_CRITICAL(flags); +#endif + dec_preempt_count(); + preempt_check_resched(); +} + +void copy_to_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + if (cpu_has_dc_aliases) { + void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(vto, src, len); + kunmap_coherent(page); + } else + memcpy(dst, src, len); + if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc) + flush_cache_page(vma, vaddr, page_to_pfn(page)); +} + +EXPORT_SYMBOL(copy_to_user_page); + +void copy_from_user_page(struct vm_area_struct *vma, + struct page *page, unsigned long vaddr, void *dst, const void *src, + unsigned long len) +{ + if (cpu_has_dc_aliases) { + void *vfrom = + kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK); + memcpy(dst, vfrom, len); + kunmap_coherent(page); + } else + memcpy(dst, src, len); +} + +EXPORT_SYMBOL(copy_from_user_page); + + +#ifdef CONFIG_HIGHMEM +pte_t *kmap_pte; +pgprot_t kmap_prot; + static void __init kmap_init(void) { unsigned long kmap_vstart; @@ -97,11 +249,12 @@ static void __init kmap_init(void) kmap_prot = PAGE_KERNEL; } +#endif /* CONFIG_HIGHMEM */ -#ifdef CONFIG_32BIT void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base) { +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_MIPS_MT_SMTC) pgd_t *pgd; pud_t *pud; pmd_t *pmd; @@ -122,7 +275,7 @@ void __init fixrange_init(unsigned long start, unsigned long end, for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pmd(pmd, __pmd(pte)); + set_pmd(pmd, __pmd((unsigned long)pte)); if (pte != pte_offset_kernel(pmd, 0)) BUG(); } @@ -132,9 +285,8 @@ void __init fixrange_init(unsigned long start, unsigned long end, } j = 0; } +#endif } -#endif /* CONFIG_32BIT */ -#endif /* CONFIG_HIGHMEM */ #ifndef CONFIG_NEED_MULTIPLE_NODES extern void pagetable_init(void); @@ -175,6 +327,7 @@ void __init paging_init(void) #ifdef CONFIG_HIGHMEM kmap_init(); #endif + kmap_coherent_init(); max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c index 4bdaa05f485..4a61e624b0e 100644 --- a/arch/mips/mm/pgtable-32.c +++ b/arch/mips/mm/pgtable-32.c @@ -31,9 +31,10 @@ void pgd_init(unsigned long page) void __init pagetable_init(void) { -#ifdef CONFIG_HIGHMEM unsigned long vaddr; - pgd_t *pgd, *pgd_base; + pgd_t *pgd_base; +#ifdef CONFIG_HIGHMEM + pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -44,7 +45,6 @@ void __init pagetable_init(void) pgd_init((unsigned long)swapper_pg_dir + sizeof(pgd_t) * USER_PTRS_PER_PGD); -#ifdef CONFIG_HIGHMEM pgd_base = swapper_pg_dir; /* @@ -53,6 +53,7 @@ void __init pagetable_init(void) vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; fixrange_init(vaddr, 0, pgd_base); +#ifdef CONFIG_HIGHMEM /* * Permanent kmaps: */ diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 44b5e97fff6..8d600d307d5 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -8,6 +8,7 @@ */ #include #include +#include #include void pgd_init(unsigned long page) @@ -52,7 +53,17 @@ void pmd_init(unsigned long addr, unsigned long pagetable) void __init pagetable_init(void) { + unsigned long vaddr; + pgd_t *pgd_base; + /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); + + pgd_base = swapper_pg_dir; + /* + * Fixed mappings: + */ + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + fixrange_init(vaddr, 0, pgd_base); } -- cgit v1.2.3 From aa026ede513b7d672fa7d9106b2f2a475455dcf2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sun, 22 Oct 2006 00:41:15 +0200 Subject: [PATCH] x86-64: Fix C3 timer test There was a typo in the C3 latency test to decide of the TSC should be used or not. It used the C2 latency threshold, not the C3 one. Fix that. This should fix the time on various dual core laptops. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 1ba5a442ac3..88722f11ca1 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -948,7 +948,7 @@ __cpuinit int unsynchronized_tsc(void) if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) { #ifdef CONFIG_ACPI /* But TSC doesn't tick in C3 so don't use it there */ - if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100) + if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000) return 1; #endif return 0; -- cgit v1.2.3 From cb01fc720c629261b9c616b2d5fcc3d93cd8bb09 Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Sun, 22 Oct 2006 00:41:15 +0200 Subject: [PATCH] x86-64: increase PHB1 split transaction timeout This patch increases the timeout for PCI split transactions on PHB1 on the first Calgary to work around an issue with the aic94xx adapter. Fixes kernel.org bugzilla #7180 (http://bugzilla.kernel.org/show_bug.cgi?id=7180) Based on excellent debugging and a patch by Darrick J. Wong Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen Acked-by: Darrick J. Wong --- arch/x86_64/kernel/pci-calgary.c | 44 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index b3296cc2f2f..37a770859e7 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -52,7 +52,8 @@ #define ONE_BASED_CHASSIS_NUM 1 /* register offsets inside the host bridge space */ -#define PHB_CSR_OFFSET 0x0110 +#define CALGARY_CONFIG_REG 0x0108 +#define PHB_CSR_OFFSET 0x0110 /* Channel Status */ #define PHB_PLSSR_OFFSET 0x0120 #define PHB_CONFIG_RW_OFFSET 0x0160 #define PHB_IOBASE_BAR_LOW 0x0170 @@ -83,6 +84,8 @@ #define TAR_VALID 0x0000000000000008UL /* CSR (Channel/DMA Status Register) */ #define CSR_AGENT_MASK 0xffe0ffff +/* CCR (Calgary Configuration Register) */ +#define CCR_2SEC_TIMEOUT 0x000000000000000EUL #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ #define MAX_NUM_CHASSIS 8 /* max number of chassis */ @@ -732,6 +735,38 @@ static void calgary_watchdog(unsigned long data) } } +static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, + unsigned char busnum) +{ + u64 val64; + void __iomem *target; + unsigned long phb_shift = -1; + u64 mask; + + switch (busno_to_phbid(busnum)) { + case 0: phb_shift = (63 - 19); + break; + case 1: phb_shift = (63 - 23); + break; + case 2: phb_shift = (63 - 27); + break; + case 3: phb_shift = (63 - 35); + break; + default: + BUG_ON(busno_to_phbid(busnum)); + } + + target = calgary_reg(bbar, CALGARY_CONFIG_REG); + val64 = be64_to_cpu(readq(target)); + + /* zero out this PHB's timer bits */ + mask = ~(0xFUL << phb_shift); + val64 &= mask; + val64 |= (CCR_2SEC_TIMEOUT << phb_shift); + writeq(cpu_to_be64(val64), target); + readq(target); /* flush */ +} + static void __init calgary_enable_translation(struct pci_dev *dev) { u32 val32; @@ -756,6 +791,13 @@ static void __init calgary_enable_translation(struct pci_dev *dev) writel(cpu_to_be32(val32), target); readl(target); /* flush */ + /* + * Give split completion a longer timeout on bus 1 for aic94xx + * http://bugzilla.kernel.org/show_bug.cgi?id=7180 + */ + if (busnum == 1) + calgary_increase_split_completion_timeout(bbar, busnum); + init_timer(&tbl->watchdog_timer); tbl->watchdog_timer.function = &calgary_watchdog; tbl->watchdog_timer.data = (unsigned long)dev; -- cgit v1.2.3 From 6fb4efc68f5c0e095153510dcfa8b54a42e914ba Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 16 Oct 2006 13:50:05 -0700 Subject: [POWERPC] Add flatdevtree source Add the latest version of the flatdevtree code and corresponding glue. A phandle table now tracks values returned by ft_find_device(). The value returned by ft_find_device() is a phandle which is really an index into the phandle table. The phandle table contains the address of the corresponding node. When the flat dt is edited/moved, the node pointers in the phandle table are updated accordingly so no phandles kept by the caller become stale. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 3 +- arch/powerpc/boot/flatdevtree.c | 880 +++++++++++++++++++++++++++++++++++ arch/powerpc/boot/flatdevtree.h | 62 ++- arch/powerpc/boot/flatdevtree_env.h | 47 ++ arch/powerpc/boot/flatdevtree_misc.c | 56 +++ 5 files changed, 1046 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/boot/flatdevtree.c create mode 100644 arch/powerpc/boot/flatdevtree_env.h create mode 100644 arch/powerpc/boot/flatdevtree_misc.c (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 37ddfcab000..8660cc50cb1 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -40,7 +40,8 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ $(addprefix $(obj)/,$(zlibheader)) -src-wlib := string.S stdio.c main.c div64.S $(zlib) +src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c div64.S \ + $(zlib) src-plat := of.c src-boot := crt0.S $(src-wlib) $(src-plat) empty.c diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c new file mode 100644 index 00000000000..c76c194715b --- /dev/null +++ b/arch/powerpc/boot/flatdevtree.c @@ -0,0 +1,880 @@ +/* + * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright Pantelis Antoniou 2006 + * Copyright (C) IBM Corporation 2006 + * + * Authors: Pantelis Antoniou + * Hollis Blanchard + * Mark A. Greer + * Paul Mackerras + */ + +#include +#include +#include "flatdevtree.h" +#include "flatdevtree_env.h" + +#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1)) + +/* Routines for keeping node ptrs returned by ft_find_device current */ +/* First entry not used b/c it would return 0 and be taken as NULL/error */ +static void *ft_node_add(struct ft_cxt *cxt, char *node) +{ + unsigned int i; + + for (i = 1; i < cxt->nodes_used; i++) /* already there? */ + if (cxt->node_tbl[i] == node) + return (void *)i; + + if (cxt->nodes_used < cxt->node_max) { + cxt->node_tbl[cxt->nodes_used] = node; + return (void *)cxt->nodes_used++; + } + + return NULL; +} + +static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle) +{ + unsigned int i = (unsigned int)phandle; + + if (i < cxt->nodes_used) + return cxt->node_tbl[i]; + return NULL; +} + +static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift) +{ + unsigned int i; + + if (shift == 0) + return; + + for (i = 1; i < cxt->nodes_used; i++) + if (cxt->node_tbl[i] < addr) + cxt->node_tbl[i] += shift; +} + +static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift) +{ + unsigned int i; + + if (shift == 0) + return; + + for (i = 1; i < cxt->nodes_used; i++) + if (cxt->node_tbl[i] >= addr) + cxt->node_tbl[i] += shift; +} + +/* Struct used to return info from ft_next() */ +struct ft_atom { + u32 tag; + const char *name; + void *data; + u32 size; +}; + +/* Set ptrs to current one's info; return addr of next one */ +static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret) +{ + u32 sz; + + if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size) + return NULL; + + ret->tag = be32_to_cpu(*(u32 *) p); + p += 4; + + switch (ret->tag) { /* Tag */ + case OF_DT_BEGIN_NODE: + ret->name = p; + ret->data = (void *)(p - 4); /* start of node */ + p += _ALIGN(strlen(p) + 1, 4); + break; + case OF_DT_PROP: + ret->size = sz = be32_to_cpu(*(u32 *) p); + ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4)); + ret->data = (void *)(p + 8); + p += 8 + _ALIGN(sz, 4); + break; + case OF_DT_END_NODE: + case OF_DT_NOP: + break; + case OF_DT_END: + default: + p = NULL; + break; + } + + return p; +} + +#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8) +#define EXPAND_INCR 1024 /* alloc this much extra when expanding */ + +/* See if the regions are in the standard order and non-overlapping */ +static int ft_ordered(struct ft_cxt *cxt) +{ + char *p = (char *)cxt->bph + HDR_SIZE; + enum ft_rgn_id r; + + for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) { + if (p > cxt->rgn[r].start) + return 0; + p = cxt->rgn[r].start + cxt->rgn[r].size; + } + return p <= (char *)cxt->bph + cxt->max_size; +} + +/* Copy the tree to a newly-allocated region and put things in order */ +static int ft_reorder(struct ft_cxt *cxt, int nextra) +{ + unsigned long tot; + enum ft_rgn_id r; + char *p, *pend; + int stroff; + + tot = HDR_SIZE + EXPAND_INCR; + for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) + tot += cxt->rgn[r].size; + if (nextra > 0) + tot += nextra; + tot = _ALIGN(tot, 8); + + if (!cxt->realloc) + return 0; + p = cxt->realloc(NULL, tot); + if (!p) + return 0; + + memcpy(p, cxt->bph, sizeof(struct boot_param_header)); + /* offsets get fixed up later */ + + cxt->bph = (struct boot_param_header *)p; + cxt->max_size = tot; + pend = p + tot; + p += HDR_SIZE; + + memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size); + cxt->rgn[FT_RSVMAP].start = p; + p += cxt->rgn[FT_RSVMAP].size; + + memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size); + ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, + p - cxt->rgn[FT_STRUCT].start); + cxt->p += p - cxt->rgn[FT_STRUCT].start; + cxt->rgn[FT_STRUCT].start = p; + + p = pend - cxt->rgn[FT_STRINGS].size; + memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size); + stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start; + cxt->rgn[FT_STRINGS].start = p; + cxt->str_anchor = p + stroff; + + cxt->isordered = 1; + return 1; +} + +static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r) +{ + if (r > FT_RSVMAP) + return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size; + return (char *)cxt->bph + HDR_SIZE; +} + +static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r) +{ + if (r < FT_STRINGS) + return cxt->rgn[r + 1].start; + return (char *)cxt->bph + cxt->max_size; +} + +/* + * See if we can expand region rgn by nextra bytes by using up + * free space after or before the region. + */ +static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn, + int nextra) +{ + char *p = *pp; + char *rgn_start, *rgn_end; + + rgn_start = cxt->rgn[rgn].start; + rgn_end = rgn_start + cxt->rgn[rgn].size; + if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) { + /* move following stuff */ + if (p < rgn_end) { + if (nextra < 0) + memmove(p, p - nextra, rgn_end - p + nextra); + else + memmove(p + nextra, p, rgn_end - p); + if (rgn == FT_STRUCT) + ft_node_update_after(cxt, p, nextra); + } + cxt->rgn[rgn].size += nextra; + if (rgn == FT_STRINGS) + /* assumes strings only added at beginning */ + cxt->str_anchor += nextra; + return 1; + } + if (prev_end(cxt, rgn) <= rgn_start - nextra) { + /* move preceding stuff */ + if (p > rgn_start) { + memmove(rgn_start - nextra, rgn_start, p - rgn_start); + if (rgn == FT_STRUCT) + ft_node_update_before(cxt, p, -nextra); + } + *p -= nextra; + cxt->rgn[rgn].start -= nextra; + cxt->rgn[rgn].size += nextra; + return 1; + } + return 0; +} + +static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn, + int nextra) +{ + unsigned long size, ssize, tot; + char *str, *next; + enum ft_rgn_id r; + + if (!cxt->isordered && !ft_reorder(cxt, nextra)) + return 0; + if (ft_shuffle(cxt, pp, rgn, nextra)) + return 1; + + /* See if there is space after the strings section */ + ssize = cxt->rgn[FT_STRINGS].size; + if (cxt->rgn[FT_STRINGS].start + ssize + < (char *)cxt->bph + cxt->max_size) { + /* move strings up as far as possible */ + str = (char *)cxt->bph + cxt->max_size - ssize; + cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start; + memmove(str, cxt->rgn[FT_STRINGS].start, ssize); + cxt->rgn[FT_STRINGS].start = str; + /* enough space now? */ + if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra)) + return 1; + } + + /* how much total free space is there following this region? */ + tot = 0; + for (r = rgn; r < FT_STRINGS; ++r) { + char *r_end = cxt->rgn[r].start + cxt->rgn[r].size; + tot += next_start(cxt, rgn) - r_end; + } + + /* cast is to shut gcc up; we know nextra >= 0 */ + if (tot < (unsigned int)nextra) { + /* have to reallocate */ + char *newp, *new_start; + int shift; + + if (!cxt->realloc) + return 0; + size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8); + newp = cxt->realloc(cxt->bph, size); + if (!newp) + return 0; + cxt->max_size = size; + shift = newp - (char *)cxt->bph; + + if (shift) { /* realloc can return same addr */ + cxt->bph = (struct boot_param_header *)newp; + ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, + shift); + for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) { + new_start = cxt->rgn[r].start + shift; + cxt->rgn[r].start = new_start; + } + *pp += shift; + cxt->str_anchor += shift; + } + + /* move strings up to the end */ + str = newp + size - ssize; + cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start; + memmove(str, cxt->rgn[FT_STRINGS].start, ssize); + cxt->rgn[FT_STRINGS].start = str; + + if (ft_shuffle(cxt, pp, rgn, nextra)) + return 1; + } + + /* must be FT_RSVMAP and we need to move FT_STRUCT up */ + if (rgn == FT_RSVMAP) { + next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size + + nextra; + ssize = cxt->rgn[FT_STRUCT].size; + if (next + ssize >= cxt->rgn[FT_STRINGS].start) + return 0; /* "can't happen" */ + memmove(next, cxt->rgn[FT_STRUCT].start, ssize); + ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra); + cxt->rgn[FT_STRUCT].start = next; + + if (ft_shuffle(cxt, pp, rgn, nextra)) + return 1; + } + + return 0; /* "can't happen" */ +} + +static void ft_put_word(struct ft_cxt *cxt, u32 v) +{ + *(u32 *) cxt->p = cpu_to_be32(v); + cxt->p += 4; +} + +static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz) +{ + unsigned long sza = _ALIGN(sz, 4); + + /* zero out the alignment gap if necessary */ + if (sz < sza) + *(u32 *) (cxt->p + sza - 4) = 0; + + /* copy in the data */ + memcpy(cxt->p, data, sz); + + cxt->p += sza; +} + +int ft_begin_node(struct ft_cxt *cxt, const char *name) +{ + unsigned long nlen = strlen(name) + 1; + unsigned long len = 8 + _ALIGN(nlen, 4); + + if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len)) + return -1; + ft_put_word(cxt, OF_DT_BEGIN_NODE); + ft_put_bin(cxt, name, strlen(name) + 1); + return 0; +} + +void ft_end_node(struct ft_cxt *cxt) +{ + ft_put_word(cxt, OF_DT_END_NODE); +} + +void ft_nop(struct ft_cxt *cxt) +{ + if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4)) + ft_put_word(cxt, OF_DT_NOP); +} + +#define NO_STRING 0x7fffffff + +static int lookup_string(struct ft_cxt *cxt, const char *name) +{ + char *p, *end; + + p = cxt->rgn[FT_STRINGS].start; + end = p + cxt->rgn[FT_STRINGS].size; + while (p < end) { + if (strcmp(p, (char *)name) == 0) + return p - cxt->str_anchor; + p += strlen(p) + 1; + } + + return NO_STRING; +} + +/* lookup string and insert if not found */ +static int map_string(struct ft_cxt *cxt, const char *name) +{ + int off; + char *p; + + off = lookup_string(cxt, name); + if (off != NO_STRING) + return off; + p = cxt->rgn[FT_STRINGS].start; + if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1)) + return NO_STRING; + strcpy(p, name); + return p - cxt->str_anchor; +} + +int ft_prop(struct ft_cxt *cxt, const char *name, const void *data, + unsigned int sz) +{ + int off, len; + + off = lookup_string(cxt, name); + if (off == NO_STRING) + return -1; + + len = 12 + _ALIGN(sz, 4); + if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len)) + return -1; + + ft_put_word(cxt, OF_DT_PROP); + ft_put_word(cxt, sz); + ft_put_word(cxt, off); + ft_put_bin(cxt, data, sz); + return 0; +} + +int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str) +{ + return ft_prop(cxt, name, str, strlen(str) + 1); +} + +int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val) +{ + u32 v = cpu_to_be32((u32) val); + + return ft_prop(cxt, name, &v, 4); +} + +/* Calculate the size of the reserved map */ +static unsigned long rsvmap_size(struct ft_cxt *cxt) +{ + struct ft_reserve *res; + + res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start; + while (res->start || res->len) + ++res; + return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start; +} + +/* Calculate the size of the struct region by stepping through it */ +static unsigned long struct_size(struct ft_cxt *cxt) +{ + char *p = cxt->rgn[FT_STRUCT].start; + char *next; + struct ft_atom atom; + + /* make check in ft_next happy */ + if (cxt->rgn[FT_STRUCT].size == 0) + cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p; + + while ((next = ft_next(cxt, p, &atom)) != NULL) + p = next; + return p + 4 - cxt->rgn[FT_STRUCT].start; +} + +/* add `adj' on to all string offset values in the struct area */ +static void adjust_string_offsets(struct ft_cxt *cxt, int adj) +{ + char *p = cxt->rgn[FT_STRUCT].start; + char *next; + struct ft_atom atom; + int off; + + while ((next = ft_next(cxt, p, &atom)) != NULL) { + if (atom.tag == OF_DT_PROP) { + off = be32_to_cpu(*(u32 *) (p + 8)); + *(u32 *) (p + 8) = cpu_to_be32(off + adj); + } + p = next; + } +} + +/* start construction of the flat OF tree from scratch */ +void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size, + void *(*realloc_fn) (void *, unsigned long)) +{ + struct boot_param_header *bph = blob; + char *p; + struct ft_reserve *pres; + + /* clear the cxt */ + memset(cxt, 0, sizeof(*cxt)); + + cxt->bph = bph; + cxt->max_size = max_size; + cxt->realloc = realloc_fn; + cxt->isordered = 1; + + /* zero everything in the header area */ + memset(bph, 0, sizeof(*bph)); + + bph->magic = cpu_to_be32(OF_DT_HEADER); + bph->version = cpu_to_be32(0x10); + bph->last_comp_version = cpu_to_be32(0x10); + + /* start pointers */ + cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE; + cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve); + pres = (struct ft_reserve *)p; + cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve); + cxt->rgn[FT_STRUCT].size = 4; + cxt->rgn[FT_STRINGS].start = blob + max_size; + cxt->rgn[FT_STRINGS].size = 0; + + /* init rsvmap and struct */ + pres->start = 0; + pres->len = 0; + *(u32 *) p = cpu_to_be32(OF_DT_END); + + cxt->str_anchor = blob; +} + +/* open up an existing blob to be examined or modified */ +int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size, + unsigned int max_find_device, + void *(*realloc_fn) (void *, unsigned long)) +{ + struct boot_param_header *bph = blob; + + /* can't cope with version < 16 */ + if (be32_to_cpu(bph->version) < 16) + return -1; + + /* clear the cxt */ + memset(cxt, 0, sizeof(*cxt)); + + /* alloc node_tbl to track node ptrs returned by ft_find_device */ + ++max_find_device; + cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *)); + if (!cxt->node_tbl) + return -1; + memset(cxt->node_tbl, 0, max_find_device * sizeof(char *)); + cxt->node_max = max_find_device; + cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */ + + cxt->bph = bph; + cxt->max_size = max_size; + cxt->realloc = realloc_fn; + + cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap); + cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt); + cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct); + cxt->rgn[FT_STRUCT].size = struct_size(cxt); + cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings); + cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size); + /* Leave as '0' to force first ft_make_space call to do a ft_reorder + * and move dt to an area allocated by realloc. + cxt->isordered = ft_ordered(cxt); + */ + + cxt->p = cxt->rgn[FT_STRUCT].start; + cxt->str_anchor = cxt->rgn[FT_STRINGS].start; + + return 0; +} + +/* add a reserver physical area to the rsvmap */ +int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size) +{ + char *p; + struct ft_reserve *pres; + + p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size + - sizeof(struct ft_reserve); + if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve))) + return -1; + + pres = (struct ft_reserve *)p; + pres->start = cpu_to_be64(physaddr); + pres->len = cpu_to_be64(size); + + return 0; +} + +void ft_begin_tree(struct ft_cxt *cxt) +{ + cxt->p = cxt->rgn[FT_STRUCT].start; +} + +void ft_end_tree(struct ft_cxt *cxt) +{ + struct boot_param_header *bph = cxt->bph; + char *p, *oldstr, *str, *endp; + unsigned long ssize; + int adj; + + if (!cxt->isordered) + return; /* we haven't touched anything */ + + /* adjust string offsets */ + oldstr = cxt->rgn[FT_STRINGS].start; + adj = cxt->str_anchor - oldstr; + if (adj) + adjust_string_offsets(cxt, adj); + + /* make strings end on 8-byte boundary */ + ssize = cxt->rgn[FT_STRINGS].size; + endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start + + cxt->rgn[FT_STRUCT].size + ssize, 8); + str = endp - ssize; + + /* move strings down to end of structs */ + memmove(str, oldstr, ssize); + cxt->str_anchor = str; + cxt->rgn[FT_STRINGS].start = str; + + /* fill in header fields */ + p = (char *)bph; + bph->totalsize = cpu_to_be32(endp - p); + bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p); + bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p); + bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p); + bph->dt_strings_size = cpu_to_be32(ssize); +} + +void *ft_find_device(struct ft_cxt *cxt, const char *srch_path) +{ + char *node; + + /* require absolute path */ + if (srch_path[0] != '/') + return NULL; + node = ft_find_descendent(cxt, cxt->rgn[FT_STRUCT].start, srch_path); + return ft_node_add(cxt, node); +} + +void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path) +{ + struct ft_atom atom; + char *p; + const char *cp, *q; + int cl; + int depth = -1; + int dmatch = 0; + const char *path_comp[FT_MAX_DEPTH]; + + cp = srch_path; + cl = 0; + p = top; + + while ((p = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + ++depth; + if (depth != dmatch) + break; + cxt->genealogy[depth] = atom.data; + cxt->genealogy[depth + 1] = NULL; + if (depth && !(strncmp(atom.name, cp, cl) == 0 + && (atom.name[cl] == '/' + || atom.name[cl] == '\0' + || atom.name[cl] == '@'))) + break; + path_comp[dmatch] = cp; + /* it matches so far, advance to next path component */ + cp += cl; + /* skip slashes */ + while (*cp == '/') + ++cp; + /* we're done if this is the end of the string */ + if (*cp == 0) + return atom.data; + /* look for end of this component */ + q = strchr(cp, '/'); + if (q) + cl = q - cp; + else + cl = strlen(cp); + ++dmatch; + break; + case OF_DT_END_NODE: + if (depth == 0) + return NULL; + if (dmatch > depth) { + --dmatch; + cl = cp - path_comp[dmatch] - 1; + cp = path_comp[dmatch]; + while (cl > 0 && cp[cl - 1] == '/') + --cl; + } + --depth; + break; + } + } + return NULL; +} + +void *ft_get_parent(struct ft_cxt *cxt, const void *phandle) +{ + void *node; + int d; + struct ft_atom atom; + char *p; + + node = ft_node_ph2node(cxt, phandle); + if (node == NULL) + return NULL; + + for (d = 0; cxt->genealogy[d] != NULL; ++d) + if (cxt->genealogy[d] == node) + return cxt->genealogy[d > 0 ? d - 1 : 0]; + + /* have to do it the hard way... */ + p = cxt->rgn[FT_STRUCT].start; + d = 0; + while ((p = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + cxt->genealogy[d] = atom.data; + if (node == atom.data) { + /* found it */ + cxt->genealogy[d + 1] = NULL; + return d > 0 ? cxt->genealogy[d - 1] : node; + } + ++d; + break; + case OF_DT_END_NODE: + --d; + break; + } + } + return NULL; +} + +int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, + void *buf, const unsigned int buflen) +{ + struct ft_atom atom; + void *node; + char *p; + int depth; + unsigned int size; + + node = ft_node_ph2node(cxt, phandle); + if (node == NULL) + return -1; + + depth = 0; + p = (char *)node; + + while ((p = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + ++depth; + break; + case OF_DT_PROP: + if ((depth != 1) || strcmp(atom.name, propname)) + break; + size = min(atom.size, buflen); + memcpy(buf, atom.data, size); + return atom.size; + case OF_DT_END_NODE: + if (--depth <= 0) + return -1; + } + } + return -1; +} + +int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, + const void *buf, const unsigned int buflen) +{ + struct ft_atom atom; + void *node; + char *p, *next; + int nextra, depth; + + node = ft_node_ph2node(cxt, phandle); + if (node == NULL) + return -1; + + depth = 0; + p = node; + + while ((next = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + ++depth; + break; + case OF_DT_END_NODE: + if (--depth > 0) + break; + /* haven't found the property, insert here */ + cxt->p = p; + return ft_prop(cxt, propname, buf, buflen); + case OF_DT_PROP: + if ((depth != 1) || strcmp(atom.name, propname)) + break; + /* found an existing property, overwrite it */ + nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4); + cxt->p = atom.data; + if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT, + nextra)) + return -1; + *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen); + ft_put_bin(cxt, buf, buflen); + return 0; + } + p = next; + } + return -1; +} + +int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname) +{ + struct ft_atom atom; + void *node; + char *p, *next; + int size; + + node = ft_node_ph2node(cxt, phandle); + if (node == NULL) + return -1; + + p = node; + while ((next = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + case OF_DT_END_NODE: + return -1; + case OF_DT_PROP: + if (strcmp(atom.name, propname)) + break; + /* found the property, remove it */ + size = 12 + -_ALIGN(atom.size, 4); + cxt->p = p; + if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size)) + return -1; + return 0; + } + p = next; + } + return -1; +} + +void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *path) +{ + struct ft_atom atom; + char *p, *next; + int depth = 0; + + p = cxt->rgn[FT_STRUCT].start; + while ((next = ft_next(cxt, p, &atom)) != NULL) { + switch (atom.tag) { + case OF_DT_BEGIN_NODE: + ++depth; + if (depth == 1 && strcmp(atom.name, path) == 0) + /* duplicate node path, return error */ + return NULL; + break; + case OF_DT_END_NODE: + --depth; + if (depth > 0) + break; + /* end of node, insert here */ + cxt->p = p; + ft_begin_node(cxt, path); + ft_end_node(cxt); + return p; + } + p = next; + } + return NULL; +} diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h index 761c8dc8400..b9cd9f61f35 100644 --- a/arch/powerpc/boot/flatdevtree.h +++ b/arch/powerpc/boot/flatdevtree.h @@ -17,7 +17,7 @@ #ifndef FLATDEVTREE_H #define FLATDEVTREE_H -#include "types.h" +#include "flatdevtree_env.h" /* Definitions used by the flattened device tree */ #define OF_DT_HEADER 0xd00dfeed /* marker */ @@ -43,4 +43,64 @@ struct boot_param_header { u32 dt_strings_size; /* size of the DT strings block */ }; +struct ft_reserve { + u64 start; + u64 len; +}; + +struct ft_region { + char *start; + unsigned long size; +}; + +enum ft_rgn_id { + FT_RSVMAP, + FT_STRUCT, + FT_STRINGS, + FT_N_REGION +}; + +#define FT_MAX_DEPTH 50 + +struct ft_cxt { + struct boot_param_header *bph; + int max_size; /* maximum size of tree */ + int isordered; /* everything in standard order */ + void *(*realloc)(void *, unsigned long); + char *str_anchor; + char *p; /* current insertion point in structs */ + struct ft_region rgn[FT_N_REGION]; + void *genealogy[FT_MAX_DEPTH+1]; + char **node_tbl; + unsigned int node_max; + unsigned int nodes_used; +}; + +int ft_begin_node(struct ft_cxt *cxt, const char *name); +void ft_end_node(struct ft_cxt *cxt); + +void ft_begin_tree(struct ft_cxt *cxt); +void ft_end_tree(struct ft_cxt *cxt); + +void ft_nop(struct ft_cxt *cxt); +int ft_prop(struct ft_cxt *cxt, const char *name, + const void *data, unsigned int sz); +int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str); +int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val); +void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size, + void *(*realloc_fn)(void *, unsigned long)); +int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size, + unsigned int max_find_device, + void *(*realloc_fn)(void *, unsigned long)); +int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size); + +void ft_dump_blob(const void *bphp); +void ft_merge_blob(struct ft_cxt *cxt, void *blob); +void *ft_find_device(struct ft_cxt *cxt, const char *srch_path); +void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path); +int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, + void *buf, const unsigned int buflen); +int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, + const void *buf, const unsigned int buflen); + #endif /* FLATDEVTREE_H */ diff --git a/arch/powerpc/boot/flatdevtree_env.h b/arch/powerpc/boot/flatdevtree_env.h new file mode 100644 index 00000000000..83bc1c71883 --- /dev/null +++ b/arch/powerpc/boot/flatdevtree_env.h @@ -0,0 +1,47 @@ +/* + * This file adds the header file glue so that the shared files + * flatdevicetree.[ch] can compile and work in the powerpc bootwrapper. + * + * strncmp & strchr copied from + * Copyright (C) 1991, 1992 Linus Torvalds + * + * Maintained by: Mark A. Greer + */ +#ifndef _PPC_BOOT_FLATDEVTREE_ENV_H_ +#define _PPC_BOOT_FLATDEVTREE_ENV_H_ + +#include +#include +#include "types.h" +#include "string.h" +#include "stdio.h" +#include "ops.h" + +#define be16_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be32(x) (x) +#define be64_to_cpu(x) (x) +#define cpu_to_be64(x) (x) + +static inline int strncmp(const char *cs, const char *ct, size_t count) +{ + signed char __res = 0; + + while (count) { + if ((__res = *cs - *ct++) != 0 || !*cs++) + break; + count--; + } + return __res; +} + +static inline char *strchr(const char *s, int c) +{ + for (; *s != (char)c; ++s) + if (*s == '\0') + return NULL; + return (char *)s; +} + +#endif /* _PPC_BOOT_FLATDEVTREE_ENV_H_ */ diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c new file mode 100644 index 00000000000..c7f9adbf827 --- /dev/null +++ b/arch/powerpc/boot/flatdevtree_misc.c @@ -0,0 +1,56 @@ +/* + * This file does the necessary interface mapping between the bootwrapper + * device tree operations and the interface provided by shared source + * files flatdevicetree.[ch]. + * + * Author: Mark A. Greer + * + * 2006 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include "flatdevtree.h" +#include "ops.h" + +static struct ft_cxt cxt; + +static void *ft_finddevice(const char *name) +{ + return ft_find_device(&cxt, name); +} + +static int ft_getprop(const void *phandle, const char *propname, void *buf, + const int buflen) +{ + return ft_get_prop(&cxt, phandle, propname, buf, buflen); +} + +static int ft_setprop(const void *phandle, const char *propname, + const void *buf, const int buflen) +{ + return ft_set_prop(&cxt, phandle, propname, buf, buflen); +} + +static void ft_pack(void) +{ + ft_end_tree(&cxt); +} + +static unsigned long ft_addr(void) +{ + return (unsigned long)cxt.bph; +} + +int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) +{ + dt_ops.finddevice = ft_finddevice; + dt_ops.getprop = ft_getprop; + dt_ops.setprop = ft_setprop; + dt_ops.ft_pack = ft_pack; + dt_ops.ft_addr = ft_addr; + + return ft_open(&cxt, dt_blob, max_size, max_find_device, + platform_ops.realloc); +} -- cgit v1.2.3 From 0c176fa80fdfa9b4e0753e37223b056994c818d2 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 16 Oct 2006 13:52:09 -0700 Subject: [POWERPC] Add non-OF serial console support Add serial console support for non-OF systems. There is a generic serial console layer which calls a serial console driver. Included is the serial console driver for the ns16550 class of uarts. Necessary support routines are added as well. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 4 +- arch/powerpc/boot/io.h | 53 +++++++++++++++++ arch/powerpc/boot/ns16550.c | 74 +++++++++++++++++++++++ arch/powerpc/boot/serial.c | 142 ++++++++++++++++++++++++++++++++++++++++++++ arch/powerpc/boot/util.S | 88 +++++++++++++++++++++++++++ 5 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/boot/io.h create mode 100644 arch/powerpc/boot/ns16550.c create mode 100644 arch/powerpc/boot/serial.c create mode 100644 arch/powerpc/boot/util.S (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 8660cc50cb1..62435d951db 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -40,8 +40,8 @@ zliblinuxheader := zlib.h zconf.h zutil.h $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ $(addprefix $(obj)/,$(zlibheader)) -src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c div64.S \ - $(zlib) +src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ + ns16550.c serial.c div64.S util.S $(zlib) src-plat := of.c src-boot := crt0.S $(src-wlib) $(src-plat) empty.c diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h new file mode 100644 index 00000000000..32974ed49e0 --- /dev/null +++ b/arch/powerpc/boot/io.h @@ -0,0 +1,53 @@ +#ifndef _IO_H +#define __IO_H +/* + * Low-level I/O routines. + * + * Copied from (which has no copyright) + */ +static inline int in_8(const volatile unsigned char *addr) +{ + int ret; + + __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "m" (*addr)); + return ret; +} + +static inline void out_8(volatile unsigned char *addr, int val) +{ + __asm__ __volatile__("stb%U0%X0 %1,%0; sync" + : "=m" (*addr) : "r" (val)); +} + +static inline unsigned in_le32(const volatile unsigned *addr) +{ + unsigned ret; + + __asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "r" (addr), "m" (*addr)); + return ret; +} + +static inline unsigned in_be32(const volatile unsigned *addr) +{ + unsigned ret; + + __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync" + : "=r" (ret) : "m" (*addr)); + return ret; +} + +static inline void out_le32(volatile unsigned *addr, int val) +{ + __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr) + : "r" (val), "r" (addr)); +} + +static inline void out_be32(volatile unsigned *addr, int val) +{ + __asm__ __volatile__("stw%U0%X0 %1,%0; sync" + : "=m" (*addr) : "r" (val)); +} + +#endif /* _IO_H */ diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c new file mode 100644 index 00000000000..1ffe72e35cd --- /dev/null +++ b/arch/powerpc/boot/ns16550.c @@ -0,0 +1,74 @@ +/* + * 16550 serial console support. + * + * Original copied from + * (which had no copyright) + * Modifications: 2006 (c) MontaVista Software, Inc. + * + * Modified by: Mark A. Greer + */ +#include +#include +#include "types.h" +#include "string.h" +#include "stdio.h" +#include "io.h" +#include "ops.h" + +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_SCR 7 /* I/O: Scratch Register */ + +static unsigned char *reg_base; +static u32 reg_shift; + +static int ns16550_open(void) +{ + out_8(reg_base + (UART_FCR << reg_shift), 0x06); + return 0; +} + +static void ns16550_putc(unsigned char c) +{ + while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0); + out_8(reg_base, c); +} + +static unsigned char ns16550_getc(void) +{ + while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0); + return in_8(reg_base); +} + +static u8 ns16550_tstc(void) +{ + return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0); +} + +int ns16550_console_init(void *devp, struct serial_console_data *scdp) +{ + int n; + + n = getprop(devp, "virtual-reg", ®_base, sizeof(reg_base)); + if (n != sizeof(reg_base)) + return -1; + + n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); + if (n != sizeof(reg_shift)) + reg_shift = 0; + + scdp->open = ns16550_open; + scdp->putc = ns16550_putc; + scdp->getc = ns16550_getc; + scdp->tstc = ns16550_tstc; + scdp->close = NULL; + + return 0; +} diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c new file mode 100644 index 00000000000..e8de4cf59be --- /dev/null +++ b/arch/powerpc/boot/serial.c @@ -0,0 +1,142 @@ +/* + * Generic serial console support + * + * Author: Mark A. Greer + * + * Code in serial_edit_cmdline() copied from + * and was written by Matt Porter . + * + * 2001,2006 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ +#include +#include +#include "types.h" +#include "string.h" +#include "stdio.h" +#include "io.h" +#include "ops.h" + +extern void udelay(long delay); + +static int serial_open(void) +{ + struct serial_console_data *scdp = console_ops.data; + return scdp->open(); +} + +static void serial_write(char *buf, int len) +{ + struct serial_console_data *scdp = console_ops.data; + + while (*buf != '\0') + scdp->putc(*buf++); +} + +static void serial_edit_cmdline(char *buf, int len) +{ + int timer = 0, count; + char ch, *cp; + struct serial_console_data *scdp = console_ops.data; + + cp = buf; + count = strlen(buf); + cp = &buf[count]; + count++; + + while (timer++ < 5*1000) { + if (scdp->tstc()) { + while (((ch = scdp->getc()) != '\n') && (ch != '\r')) { + /* Test for backspace/delete */ + if ((ch == '\b') || (ch == '\177')) { + if (cp != buf) { + cp--; + count--; + printf("\b \b"); + } + /* Test for ^x/^u (and wipe the line) */ + } else if ((ch == '\030') || (ch == '\025')) { + while (cp != buf) { + cp--; + count--; + printf("\b \b"); + } + } else if (count < len) { + *cp++ = ch; + count++; + scdp->putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; +} + +static void serial_close(void) +{ + struct serial_console_data *scdp = console_ops.data; + + if (scdp->close) + scdp->close(); +} + +static void *serial_get_stdout_devp(void) +{ + void *devp; + char devtype[MAX_PROP_LEN]; + char path[MAX_PATH_LEN]; + + devp = finddevice("/chosen"); + if (devp == NULL) + goto err_out; + + if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) { + devp = finddevice(path); + if (devp == NULL) + goto err_out; + + if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0) + && !strcmp(devtype, "serial")) + return devp; + } +err_out: + return NULL; +} + +static struct serial_console_data serial_cd; + +/* Node's "compatible" property determines which serial driver to use */ +int serial_console_init(void) +{ + void *devp; + int rc = -1; + char compat[MAX_PROP_LEN]; + + devp = serial_get_stdout_devp(); + if (devp == NULL) + goto err_out; + + if (getprop(devp, "compatible", compat, sizeof(compat)) < 0) + goto err_out; + + if (!strcmp(compat, "ns16550")) + rc = ns16550_console_init(devp, &serial_cd); + + /* Add other serial console driver calls here */ + + if (!rc) { + console_ops.open = serial_open; + console_ops.write = serial_write; + console_ops.edit_cmdline = serial_edit_cmdline; + console_ops.close = serial_close; + console_ops.data = &serial_cd; + + return 0; + } +err_out: + return -1; +} diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S new file mode 100644 index 00000000000..427ddfc1199 --- /dev/null +++ b/arch/powerpc/boot/util.S @@ -0,0 +1,88 @@ +/* + * Copied from + * + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * kexec bits: + * Copyright (C) 2002-2003 Eric Biederman + * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz + * + * 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. + * + */ +#include "ppc_asm.h" + +#define SPRN_PVR 0x11F /* Processor Version Register */ + + .text + +/* udelay (on non-601 processors) needs to know the period of the + * timebase in nanoseconds. This used to be hardcoded to be 60ns + * (period of 66MHz/4). Now a variable is used that is initialized to + * 60 for backward compatibility, but it can be overridden as necessary + * with code something like this: + * extern unsigned long timebase_period_ns; + * timebase_period_ns = 1000000000 / bd->bi_tbfreq; + */ + .data + .globl timebase_period_ns +timebase_period_ns: + .long 60 + + .text +/* + * Delay for a number of microseconds + */ + .globl udelay +udelay: + mfspr r4,SPRN_PVR + srwi r4,r4,16 + cmpwi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + /* Change r4 to be the number of ticks using: + * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns + * timebase_period_ns defaults to 60 (16.6MHz) */ + mflr r5 + bl 0f +0: mflr r6 + mtlr r5 + lis r5,0b@ha + addi r5,r5,0b@l + subf r5,r5,r6 /* In case we're relocated */ + addis r5,r5,timebase_period_ns@ha + lwz r5,timebase_period_ns@l(r5) + add r4,r4,r5 + addi r4,r4,-1 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmpw 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmpw 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmpw 0,r6,r9 + blt 2b +3: blr -- cgit v1.2.3 From 01a6372008ed450982ba38ee5fd91028b9f5a781 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Mon, 16 Oct 2006 13:54:52 -0700 Subject: [POWERPC] Add simple memory allocator to bootwrapper Provide primitive malloc, free, and realloc functions for bootwrapper. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 2 +- arch/powerpc/boot/simple_alloc.c | 149 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/boot/simple_alloc.c (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 62435d951db..9731c25c54a 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -41,7 +41,7 @@ $(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ $(addprefix $(obj)/,$(zlibheader)) src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ - ns16550.c serial.c div64.S util.S $(zlib) + ns16550.c serial.c simple_alloc.c div64.S util.S $(zlib) src-plat := of.c src-boot := crt0.S $(src-wlib) $(src-plat) empty.c diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c new file mode 100644 index 00000000000..cfe3a7505ba --- /dev/null +++ b/arch/powerpc/boot/simple_alloc.c @@ -0,0 +1,149 @@ +/* + * Implement primitive realloc(3) functionality. + * + * Author: Mark A. Greer + * + * 2006 (c) MontaVista, Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include "types.h" +#include "page.h" +#include "string.h" +#include "ops.h" + +#define ENTRY_BEEN_USED 0x01 +#define ENTRY_IN_USE 0x02 + +static struct alloc_info { + u32 flags; + u32 base; + u32 size; +} *alloc_tbl; + +static u32 tbl_entries; +static u32 alloc_min; +static u32 next_base; +static u32 space_left; + +/* + * First time an entry is used, its base and size are set. + * An entry can be freed and re-malloc'd but its base & size don't change. + * Should be smart enough for needs of bootwrapper. + */ +static void *simple_malloc(u32 size) +{ + u32 i; + struct alloc_info *p = alloc_tbl; + + if (size == 0) + goto err_out; + + size = _ALIGN_UP(size, alloc_min); + + for (i=0; iflags & ENTRY_BEEN_USED)) { /* never been used */ + if (size <= space_left) { + p->base = next_base; + p->size = size; + p->flags = ENTRY_BEEN_USED | ENTRY_IN_USE; + next_base += size; + space_left -= size; + return (void *)p->base; + } + goto err_out; /* not enough space left */ + } + /* reuse an entry keeping same base & size */ + else if (!(p->flags & ENTRY_IN_USE) && (size <= p->size)) { + p->flags |= ENTRY_IN_USE; + return (void *)p->base; + } +err_out: + return NULL; +} + +static struct alloc_info *simple_find_entry(void *ptr) +{ + u32 i; + struct alloc_info *p = alloc_tbl; + + for (i=0; iflags & ENTRY_BEEN_USED)) + break; + if ((p->flags & ENTRY_IN_USE) && (p->base == (u32)ptr)) + return p; + } + return NULL; +} + +static void simple_free(void *ptr) +{ + struct alloc_info *p = simple_find_entry(ptr); + + if (p != NULL) + p->flags &= ~ENTRY_IN_USE; +} + +/* + * Change size of area pointed to by 'ptr' to 'size'. + * If 'ptr' is NULL, then its a malloc(). If 'size' is 0, then its a free(). + * 'ptr' must be NULL or a pointer to a non-freed area previously returned by + * simple_realloc() or simple_malloc(). + */ +static void *simple_realloc(void *ptr, unsigned long size) +{ + struct alloc_info *p; + void *new; + + if (size == 0) { + simple_free(ptr); + return NULL; + } + + if (ptr == NULL) + return simple_malloc(size); + + p = simple_find_entry(ptr); + if (p == NULL) /* ptr not from simple_malloc/simple_realloc */ + return NULL; + if (size <= p->size) /* fits in current block */ + return ptr; + + new = simple_malloc(size); + memcpy(new, ptr, p->size); + simple_free(ptr); + return new; +} + +/* + * Returns addr of first byte after heap so caller can see if it took + * too much space. If so, change args & try again. + */ +void *simple_alloc_init(char *base, u32 heap_size, u32 granularity, + u32 max_allocs) +{ + u32 heap_base, tbl_size; + + heap_size = _ALIGN_UP(heap_size, granularity); + alloc_min = granularity; + tbl_entries = max_allocs; + + tbl_size = tbl_entries * sizeof(struct alloc_info); + + alloc_tbl = (struct alloc_info *)_ALIGN_UP((unsigned long)base, 8); + memset(alloc_tbl, 0, tbl_size); + + heap_base = _ALIGN_UP((u32)alloc_tbl + tbl_size, alloc_min); + + next_base = heap_base; + space_left = heap_size; + + platform_ops.malloc = simple_malloc; + platform_ops.free = simple_free; + platform_ops.realloc = simple_realloc; + + return (void *)(heap_base + heap_size); +} -- cgit v1.2.3 From cbcdb93d4443568f17e93610d240043ec5ac067b Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 17 Oct 2006 23:08:35 +1000 Subject: [POWERPC] Simplify stolen time calculation In calculating stolen time, we were trying to actually account for time spent in the hypervisor. We don't really have enough information to do that accurately, so don't try. Instead, we now calculate stolen time as time that the current cpu thread is not actually dispatching instructions. On chips without a PURR, we cannot do this, so stolen time will always be zero. On chips with a PURR, this is merely the difference between the elapsed PURR values and the elapsed TB values. This gives us much more sane vaules from tools such as mpstat, even if they are still a bit strange e.g. 2 busy threads on one cpu will both appear to have 50% user time and 50% stolen time while 1 busy thread on a cpu will look like 100% user on one of them and 100% idle on the other. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 63 ++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 47 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 5b59bc18dfe..a1b5e4b1615 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -220,11 +220,8 @@ static void account_process_time(struct pt_regs *regs) */ struct cpu_purr_data { int initialized; /* thread is running */ - u64 tb0; /* timebase at origin time */ - u64 purr0; /* PURR at origin time */ u64 tb; /* last TB value read */ u64 purr; /* last PURR value read */ - u64 stolen; /* stolen time so far */ spinlock_t lock; }; @@ -234,10 +231,8 @@ static void snapshot_tb_and_purr(void *data) { struct cpu_purr_data *p = &__get_cpu_var(cpu_purr_data); - p->tb0 = mftb(); - p->purr0 = mfspr(SPRN_PURR); - p->tb = p->tb0; - p->purr = 0; + p->tb = mftb(); + p->purr = mfspr(SPRN_PURR); wmb(); p->initialized = 1; } @@ -258,37 +253,24 @@ void snapshot_timebases(void) void calculate_steal_time(void) { - u64 tb, purr, t0; + u64 tb, purr; s64 stolen; - struct cpu_purr_data *p0, *pme, *phim; - int cpu; + struct cpu_purr_data *pme; if (!cpu_has_feature(CPU_FTR_PURR)) return; - cpu = smp_processor_id(); - pme = &per_cpu(cpu_purr_data, cpu); + pme = &per_cpu(cpu_purr_data, smp_processor_id()); if (!pme->initialized) return; /* this can happen in early boot */ - p0 = &per_cpu(cpu_purr_data, cpu & ~1); - phim = &per_cpu(cpu_purr_data, cpu ^ 1); - spin_lock(&p0->lock); + spin_lock(&pme->lock); tb = mftb(); - purr = mfspr(SPRN_PURR) - pme->purr0; - if (!phim->initialized || !cpu_online(cpu ^ 1)) { - stolen = (tb - pme->tb) - (purr - pme->purr); - } else { - t0 = pme->tb0; - if (phim->tb0 < t0) - t0 = phim->tb0; - stolen = phim->tb - t0 - phim->purr - purr - p0->stolen; - } - if (stolen > 0) { + purr = mfspr(SPRN_PURR); + stolen = (tb - pme->tb) - (purr - pme->purr); + if (stolen > 0) account_steal_time(current, stolen); - p0->stolen += stolen; - } pme->tb = tb; pme->purr = purr; - spin_unlock(&p0->lock); + spin_unlock(&pme->lock); } /* @@ -297,30 +279,17 @@ void calculate_steal_time(void) */ static void snapshot_purr(void) { - int cpu; - u64 purr; - struct cpu_purr_data *p0, *pme, *phim; + struct cpu_purr_data *pme; unsigned long flags; if (!cpu_has_feature(CPU_FTR_PURR)) return; - cpu = smp_processor_id(); - pme = &per_cpu(cpu_purr_data, cpu); - p0 = &per_cpu(cpu_purr_data, cpu & ~1); - phim = &per_cpu(cpu_purr_data, cpu ^ 1); - spin_lock_irqsave(&p0->lock, flags); - pme->tb = pme->tb0 = mftb(); - purr = mfspr(SPRN_PURR); - if (!phim->initialized) { - pme->purr = 0; - pme->purr0 = purr; - } else { - /* set p->purr and p->purr0 for no change in p0->stolen */ - pme->purr = phim->tb - phim->tb0 - phim->purr - p0->stolen; - pme->purr0 = purr - pme->purr; - } + pme = &per_cpu(cpu_purr_data, smp_processor_id()); + spin_lock_irqsave(&pme->lock, flags); + pme->tb = mftb(); + pme->purr = mfspr(SPRN_PURR); pme->initialized = 1; - spin_unlock_irqrestore(&p0->lock, flags); + spin_unlock_irqrestore(&pme->lock, flags); } #endif /* CONFIG_PPC_SPLPAR */ -- cgit v1.2.3 From c3386e40142e9d0c077460c2a548c4653fecaf15 Mon Sep 17 00:00:00 2001 From: Zang Roy-r61911 Date: Wed, 18 Oct 2006 11:18:58 +0800 Subject: [POWERPC] Fix compiler warning message on get_property call This fixes the warning message from the return value of function get_property(), by making sure that the variable that receives the value is marked as const. Signed-off-by: Roy Zang -- Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/tsi108_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index 11de090eb90..97f37ef4bbb 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -48,7 +48,7 @@ phys_addr_t get_csrbase(void) tsi = of_find_node_by_type(NULL, "tsi-bridge"); if (tsi) { unsigned int size; - void *prop = get_property(tsi, "reg", &size); + const void *prop = get_property(tsi, "reg", &size); tsi108_csr_base = of_translate_address(tsi, prop); of_node_put(tsi); }; @@ -79,7 +79,7 @@ static int __init tsi108_eth_of_init(void) hw_info tsi_eth_data; unsigned int *id; unsigned int *phy_id; - void *mac_addr; + const void *mac_addr; phandle *ph; memset(r, 0, sizeof(r)); -- cgit v1.2.3 From 7f8c4c50bda13d27afc03679d25aa1fcac8df551 Mon Sep 17 00:00:00 2001 From: Srinivasa Ds Date: Wed, 18 Oct 2006 17:34:49 +0530 Subject: [POWERPC] Fix build breakage with CONFIG_PPC32 low_cpu_die is called from the CPU hotplug code on 32-bit powermacs, but it is only defined if CONFIG_PM || CONFIG_CPU_FREQ_PMAC. This changes the ifdef so it is defined for CONFIG_HOTPLUG_CPU on 32-bit machines. Signed-off-by: Srinivasa DS Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/sleep.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index 1174ca128ef..adee28da353 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -45,7 +45,8 @@ .section .text .align 5 -#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) +#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \ + (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)) /* This gets called by via-pmu.c late during the sleep process. * The PMU was already send the sleep command and will shut us down -- cgit v1.2.3 From 362ff7b2ac0234152b4a334dd006b77f4fa2ab23 Mon Sep 17 00:00:00 2001 From: Jake Moilanen Date: Wed, 18 Oct 2006 10:47:22 -0500 Subject: [POWERPC] Add 970GX cputable entry 970GX cputable entry from Steve Winiecki. Signed-off-by: Jake Moilanen arch/powerpc/kernel/cputable.c | 15 +++++++++++++++ arch/powerpc/oprofile/op_model_power4.c | 2 +- include/asm-powerpc/reg.h | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 15 +++++++++++++++ arch/powerpc/oprofile/op_model_power4.c | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 95382f99440..f23aad66a79 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -227,6 +227,21 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, + { /* PPC970GX */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00450000, + .cpu_name = "PPC970GX", + .cpu_features = CPU_FTRS_PPC970, + .cpu_user_features = COMMON_USER_POWER4 | + PPC_FEATURE_HAS_ALTIVEC_COMP, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 8, + .cpu_setup = __setup_cpu_ppc970, + .oprofile_cpu_type = "ppc64/970", + .oprofile_type = PPC_OPROFILE_POWER4, + .platform = "ppc970", + }, { /* Power5 GR */ .pvr_mask = 0xffff0000, .pvr_value = 0x003a0000, diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index 506f6b79f89..6a927effcc7 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c @@ -76,7 +76,7 @@ static inline int mmcra_must_set_sample(void) { if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || __is_processor(PV_970) || __is_processor(PV_970FX) || - __is_processor(PV_970MP)) + __is_processor(PV_970MP) || __is_processor(PV_970GX)) return 1; return 0; -- cgit v1.2.3 From 3688a0f484e980771c078ab90f74a2656c339106 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 18 Oct 2006 14:38:09 -0700 Subject: [POWERPC] Don't require execute perms on wrapper when building zImage.initrd Don't require that the wrapper script be executable when building zImage.initrds. This has already been fixed for zImages. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 37ddfcab000..4b2be611f77 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -115,7 +115,7 @@ endif quiet_cmd_wrap = WRAP $@ cmd_wrap =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) vmlinux quiet_cmd_wrap_initrd = WRAP $@ - cmd_wrap_initrd =$(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ + cmd_wrap_initrd =$(CONFIG_SHELL) $(wrapper) -c -o $@ -p $2 $(CROSSWRAP) \ -i $(obj)/ramdisk.image.gz vmlinux $(obj)/zImage.chrp: vmlinux $(wrapperbits) -- cgit v1.2.3 From aa7a32cbdac50bb46a75722faa359993dab07c61 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Wed, 18 Oct 2006 17:27:32 -0500 Subject: [POWERPC] Fix spelling errors in ucc_fast.c and ucc_slow.c In ucc_fast.c and ucc_slow.c, "illegal" is twice spelled "illagal". Signed-off-by: Timur Tabi Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/ucc_fast.c | 2 +- arch/powerpc/sysdev/qe_lib/ucc_slow.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index c2be7348fcb..75fa3104a43 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c @@ -163,7 +163,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc /* check if the UCC port number is in range. */ if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { - uccf_err("ucc_fast_init: Illagal UCC number!"); + uccf_err("ucc_fast_init: Illegal UCC number!"); return -EINVAL; } diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index 1fb88ef7cf0..a49da6b73ec 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c @@ -152,7 +152,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc /* check if the UCC port number is in range. */ if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { - uccs_err("ucc_slow_init: Illagal UCC number!"); + uccs_err("ucc_slow_init: Illegal UCC number!"); return -EINVAL; } -- cgit v1.2.3 From 0cfcccb4687862a34eb609d16e75b39b6cb54c80 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Fri, 13 Oct 2006 10:07:01 -0500 Subject: [POWERPC] Add mktree utility to arch/powerpc/boot This patch adds the mktree program that is needed to post process zImage wrappers for various PowerPC 4xx boards Signed-off-by: Josh Boyer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 4 +- arch/powerpc/boot/mktree.c | 152 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/boot/mktree.c (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 9731c25c54a..1e71a452b17 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -94,13 +94,13 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S $(obj)/wrapper.a: $(obj-wlib) $(call cmd,bootar) -hostprogs-y := addnote addRamDisk hack-coff +hostprogs-y := addnote addRamDisk hack-coff mktree extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ $(obj)/zImage.lds $(obj)/zImage.coff.lds wrapper :=$(srctree)/$(src)/wrapper -wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff) +wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) ############# # Bits for building various flavours of zImage diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c new file mode 100644 index 00000000000..4cb89299365 --- /dev/null +++ b/arch/powerpc/boot/mktree.c @@ -0,0 +1,152 @@ +/* + * Makes a tree bootable image for IBM Evaluation boards. + * Basically, just take a zImage, skip the ELF header, and stuff + * a 32 byte header on the front. + * + * We use htonl, which is a network macro, to make sure we're doing + * The Right Thing on an LE machine. It's non-obvious, but it should + * work on anything BSD'ish. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef __sun__ +#include +#else +#include +#endif + +/* This gets tacked on the front of the image. There are also a few + * bytes allocated after the _start label used by the boot rom (see + * head.S for details). + */ +typedef struct boot_block { + uint32_t bb_magic; /* 0x0052504F */ + uint32_t bb_dest; /* Target address of the image */ + uint32_t bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */ + uint32_t bb_debug_flag; /* Run debugger or image after load */ + uint32_t bb_entry_point; /* The image address to start */ + uint32_t bb_checksum; /* 32 bit checksum including header */ + uint32_t reserved[2]; +} boot_block_t; + +#define IMGBLK 512 +char tmpbuf[IMGBLK]; + +int main(int argc, char *argv[]) +{ + int in_fd, out_fd; + int nblks, i; + uint cksum, *cp; + struct stat st; + boot_block_t bt; + + if (argc < 3) { + fprintf(stderr, "usage: %s [entry-point]\n",argv[0]); + exit(1); + } + + if (stat(argv[1], &st) < 0) { + perror("stat"); + exit(2); + } + + nblks = (st.st_size + IMGBLK) / IMGBLK; + + bt.bb_magic = htonl(0x0052504F); + + /* If we have the optional entry point parameter, use it */ + if (argc == 4) + bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0)); + else + bt.bb_dest = bt.bb_entry_point = htonl(0x500000); + + /* We know these from the linker command. + * ...and then move it up into memory a little more so the + * relocation can happen. + */ + bt.bb_num_512blocks = htonl(nblks); + bt.bb_debug_flag = 0; + + bt.bb_checksum = 0; + + /* To be neat and tidy :-). + */ + bt.reserved[0] = 0; + bt.reserved[1] = 0; + + if ((in_fd = open(argv[1], O_RDONLY)) < 0) { + perror("zImage open"); + exit(3); + } + + if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) { + perror("bootfile open"); + exit(3); + } + + cksum = 0; + cp = (void *)&bt; + for (i=0; i 0) { + if (read(in_fd, tmpbuf, IMGBLK) < 0) { + perror("zImage read"); + exit(5); + } + cp = (uint *)tmpbuf; + for (i=0; i Date: Mon, 16 Oct 2006 16:03:33 -0500 Subject: [POWERPC] Fix up the OF functions to only do PCI stuff if PCI is actually configured The original problem that inspired this patch was solved quite some time ago (Turning off PCI didn't work), but this patch neatens things up a little (I think), by putting all the PCI stuff inside a single CONFIG_PCI block. It also removes the OF PCI bus matching entries if CONFIG_PCI is off. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_parse.c | 288 ++++++++++++++++++++------------------- 1 file changed, 148 insertions(+), 140 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 603dff3ad62..346fb7bf9a0 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -25,6 +25,12 @@ #define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ (ns) > 0) +static struct of_bus *of_match_bus(struct device_node *np); +static int __of_address_to_resource(struct device_node *dev, + const u32 *addrp, u64 size, unsigned int flags, + struct resource *r); + + /* Debug utility */ #ifdef DEBUG static void of_dump_addr(const char *s, const u32 *addr, int na) @@ -101,6 +107,7 @@ static unsigned int of_bus_default_get_flags(const u32 *addr) } +#ifdef CONFIG_PCI /* * PCI bus specific translator */ @@ -162,6 +169,145 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr) return flags; } +const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, + unsigned int *flags) +{ + const u32 *prop; + unsigned int psize; + struct device_node *parent; + struct of_bus *bus; + int onesize, i, na, ns; + + /* Get parent & match bus type */ + parent = of_get_parent(dev); + if (parent == NULL) + return NULL; + bus = of_match_bus(parent); + if (strcmp(bus->name, "pci")) { + of_node_put(parent); + return NULL; + } + bus->count_cells(dev, &na, &ns); + of_node_put(parent); + if (!OF_CHECK_COUNTS(na, ns)) + return NULL; + + /* Get "reg" or "assigned-addresses" property */ + prop = get_property(dev, bus->addresses, &psize); + if (prop == NULL) + return NULL; + psize /= 4; + + onesize = na + ns; + for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) + if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { + if (size) + *size = of_read_number(prop + na, ns); + if (flags) + *flags = bus->get_flags(prop); + return prop; + } + return NULL; +} +EXPORT_SYMBOL(of_get_pci_address); + +int of_pci_address_to_resource(struct device_node *dev, int bar, + struct resource *r) +{ + const u32 *addrp; + u64 size; + unsigned int flags; + + addrp = of_get_pci_address(dev, bar, &size, &flags); + if (addrp == NULL) + return -EINVAL; + return __of_address_to_resource(dev, addrp, size, flags, r); +} +EXPORT_SYMBOL_GPL(of_pci_address_to_resource); + +static u8 of_irq_pci_swizzle(u8 slot, u8 pin) +{ + return (((pin - 1) + slot) % 4) + 1; +} + +int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) +{ + struct device_node *dn, *ppnode; + struct pci_dev *ppdev; + u32 lspec; + u32 laddr[3]; + u8 pin; + int rc; + + /* Check if we have a device node, if yes, fallback to standard OF + * parsing + */ + dn = pci_device_to_OF_node(pdev); + if (dn) + return of_irq_map_one(dn, 0, out_irq); + + /* Ok, we don't, time to have fun. Let's start by building up an + * interrupt spec. we assume #interrupt-cells is 1, which is standard + * for PCI. If you do different, then don't use that routine. + */ + rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); + if (rc != 0) + return rc; + /* No pin, exit */ + if (pin == 0) + return -ENODEV; + + /* Now we walk up the PCI tree */ + lspec = pin; + for (;;) { + /* Get the pci_dev of our parent */ + ppdev = pdev->bus->self; + + /* Ouch, it's a host bridge... */ + if (ppdev == NULL) { +#ifdef CONFIG_PPC64 + ppnode = pci_bus_to_OF_node(pdev->bus); +#else + struct pci_controller *host; + host = pci_bus_to_host(pdev->bus); + ppnode = host ? host->arch_data : NULL; +#endif + /* No node for host bridge ? give up */ + if (ppnode == NULL) + return -EINVAL; + } else + /* We found a P2P bridge, check if it has a node */ + ppnode = pci_device_to_OF_node(ppdev); + + /* Ok, we have found a parent with a device-node, hand over to + * the OF parsing code. + * We build a unit address from the linux device to be used for + * resolution. Note that we use the linux bus number which may + * not match your firmware bus numbering. + * Fortunately, in most cases, interrupt-map-mask doesn't include + * the bus number as part of the matching. + * You should still be careful about that though if you intend + * to rely on this function (you ship a firmware that doesn't + * create device nodes for all PCI devices). + */ + if (ppnode) + break; + + /* We can only get here if we hit a P2P bridge with no node, + * let's do standard swizzling and try again + */ + lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); + pdev = ppdev; + } + + laddr[0] = (pdev->bus->number << 16) + | (pdev->devfn << 8); + laddr[1] = laddr[2] = 0; + return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); +} +EXPORT_SYMBOL_GPL(of_irq_map_pci); +#endif /* CONFIG_PCI */ + /* * ISA bus specific translator */ @@ -223,6 +369,7 @@ static unsigned int of_bus_isa_get_flags(const u32 *addr) */ static struct of_bus of_busses[] = { +#ifdef CONFIG_PCI /* PCI */ { .name = "pci", @@ -233,6 +380,7 @@ static struct of_bus of_busses[] = { .translate = of_bus_pci_translate, .get_flags = of_bus_pci_get_flags, }, +#endif /* CONFIG_PCI */ /* ISA */ { .name = "isa", @@ -445,48 +593,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, - unsigned int *flags) -{ - const u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - if (strcmp(bus->name, "pci")) { - of_node_put(parent); - return NULL; - } - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { - if (size) - *size = of_read_number(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_pci_address); - static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, u64 size, unsigned int flags, struct resource *r) @@ -529,20 +635,6 @@ int of_address_to_resource(struct device_node *dev, int index, } EXPORT_SYMBOL_GPL(of_address_to_resource); -int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r) -{ - const u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_pci_address(dev, bar, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_pci_address_to_resource); - void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, unsigned long *busno, unsigned long *phys, unsigned long *size) { @@ -898,87 +990,3 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq return res; } EXPORT_SYMBOL_GPL(of_irq_map_one); - -#ifdef CONFIG_PCI -static u8 of_irq_pci_swizzle(u8 slot, u8 pin) -{ - return (((pin - 1) + slot) % 4) + 1; -} - -int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) -{ - struct device_node *dn, *ppnode; - struct pci_dev *ppdev; - u32 lspec; - u32 laddr[3]; - u8 pin; - int rc; - - /* Check if we have a device node, if yes, fallback to standard OF - * parsing - */ - dn = pci_device_to_OF_node(pdev); - if (dn) - return of_irq_map_one(dn, 0, out_irq); - - /* Ok, we don't, time to have fun. Let's start by building up an - * interrupt spec. we assume #interrupt-cells is 1, which is standard - * for PCI. If you do different, then don't use that routine. - */ - rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin); - if (rc != 0) - return rc; - /* No pin, exit */ - if (pin == 0) - return -ENODEV; - - /* Now we walk up the PCI tree */ - lspec = pin; - for (;;) { - /* Get the pci_dev of our parent */ - ppdev = pdev->bus->self; - - /* Ouch, it's a host bridge... */ - if (ppdev == NULL) { -#ifdef CONFIG_PPC64 - ppnode = pci_bus_to_OF_node(pdev->bus); -#else - struct pci_controller *host; - host = pci_bus_to_host(pdev->bus); - ppnode = host ? host->arch_data : NULL; -#endif - /* No node for host bridge ? give up */ - if (ppnode == NULL) - return -EINVAL; - } else - /* We found a P2P bridge, check if it has a node */ - ppnode = pci_device_to_OF_node(ppdev); - - /* Ok, we have found a parent with a device-node, hand over to - * the OF parsing code. - * We build a unit address from the linux device to be used for - * resolution. Note that we use the linux bus number which may - * not match your firmware bus numbering. - * Fortunately, in most cases, interrupt-map-mask doesn't include - * the bus number as part of the matching. - * You should still be careful about that though if you intend - * to rely on this function (you ship a firmware that doesn't - * create device nodes for all PCI devices). - */ - if (ppnode) - break; - - /* We can only get here if we hit a P2P bridge with no node, - * let's do standard swizzling and try again - */ - lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec); - pdev = ppdev; - } - - laddr[0] = (pdev->bus->number << 16) - | (pdev->devfn << 8); - laddr[1] = laddr[2] = 0; - return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq); -} -EXPORT_SYMBOL_GPL(of_irq_map_pci); -#endif /* CONFIG_PCI */ -- cgit v1.2.3 From 41999295b6c25d799dacbbca089fdbc19f6d60f5 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Oct 2006 15:53:20 +1000 Subject: [POWERPC] Move iSeries initrd logic into device tree Remove the iSeries initrd logic, instead just store the initrd location and size in the device tree so generic code can do the rest for us. The iSeries code had a "feature" which the generic code lacks, ie. if the compressed initrd is bigger than the configured ram disk size, we make the ram disk size bigger. That's bogus, as the compressed size of the initrd tells us nothing about how big the ram disk needs to be. If the ram disk isn't big enough you just need to make CONFIG_BLK_DEV_RAM_SIZE larger. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/iseries/dt.c | 15 +++++++++++++-- arch/powerpc/platforms/iseries/setup.c | 32 -------------------------------- 2 files changed, 13 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c index e305deee7f4..9e8a334a518 100644 --- a/arch/powerpc/platforms/iseries/dt.c +++ b/arch/powerpc/platforms/iseries/dt.c @@ -41,6 +41,7 @@ #include "call_pci.h" #include "pci.h" #include "it_exp_vpd_panel.h" +#include "naca.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -205,13 +206,11 @@ static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name, dt_prop(dt, name, &data, sizeof(u32)); } -#ifdef notyet static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, u64 data) { dt_prop(dt, name, &data, sizeof(u64)); } -#endif static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, const char *name, u64 *data, int n) @@ -306,6 +305,17 @@ static void __init dt_model(struct iseries_flat_dt *dt) dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); } +static void __init dt_initrd(struct iseries_flat_dt *dt) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if (naca.xRamDisk) { + dt_prop_u64(dt, "linux,initrd-start", (u64)naca.xRamDisk); + dt_prop_u64(dt, "linux,initrd-end", + (u64)naca.xRamDisk + naca.xRamDiskSize * HW_PAGE_SIZE); + } +#endif +} + static void __init dt_do_vdevice(struct iseries_flat_dt *dt, const char *name, u32 reg, int unit, const char *type, const char *compat, int end) @@ -641,6 +651,7 @@ void * __init build_flat_dt(unsigned long phys_mem_size) /* /chosen */ dt_start_node(iseries_dt, "chosen"); dt_prop_str(iseries_dt, "bootargs", cmd_line); + dt_initrd(iseries_dt); dt_end_node(iseries_dt); dt_cpus(iseries_dt); diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index a0ff7ba7d66..08d14734617 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -80,8 +79,6 @@ extern void iSeries_pci_final_fixup(void); static void iSeries_pci_final_fixup(void) { } #endif -extern int rd_size; /* Defined in drivers/block/rd.c */ - extern unsigned long iSeries_recal_tb; extern unsigned long iSeries_recal_titan; @@ -295,24 +292,6 @@ static void __init iSeries_init_early(void) { DBG(" -> iSeries_init_early()\n"); -#if defined(CONFIG_BLK_DEV_INITRD) - /* - * If the init RAM disk has been configured and there is - * a non-zero starting address for it, set it up - */ - if (naca.xRamDisk) { - initrd_start = (unsigned long)__va(naca.xRamDisk); - initrd_end = initrd_start + naca.xRamDiskSize * HW_PAGE_SIZE; - initrd_below_start_ok = 1; // ramdisk in kernel space - ROOT_DEV = Root_RAM0; - if (((rd_size * 1024) / HW_PAGE_SIZE) < naca.xRamDiskSize) - rd_size = (naca.xRamDiskSize * HW_PAGE_SIZE) / 1024; - } else -#endif /* CONFIG_BLK_DEV_INITRD */ - { - /* ROOT_DEV = MKDEV(VIODASD_MAJOR, 1); */ - } - iSeries_recal_tb = get_tb(); iSeries_recal_titan = HvCallXm_loadTod(); @@ -331,17 +310,6 @@ static void __init iSeries_init_early(void) mf_init(); - /* If we were passed an initrd, set the ROOT_DEV properly if the values - * look sensible. If not, clear initrd reference. - */ -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && - initrd_end > initrd_start) - ROOT_DEV = Root_RAM0; - else - initrd_start = initrd_end = 0; -#endif /* CONFIG_BLK_DEV_INITRD */ - DBG(" <- iSeries_init_early()\n"); } -- cgit v1.2.3 From cf610ca226a484f3182a59f168402cb27dcc1c53 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 20 Oct 2006 20:16:24 +0100 Subject: [ARM] Fix breakage in 7281c248f797723f66244b7ecef204620f664648 A couple of missing semicolons. Signed-off-by: Russell King --- arch/arm/mach-ixp2000/ixdp2400.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 9ee63834e60..0fdd03ab36e 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -135,11 +135,11 @@ static void ixdp2400_pci_postinit(void) if (ixdp2x00_master_npu()) { dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev) + pci_dev_put(dev); } else { dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); pci_remove_bus_device(dev); - pci_dev_put(dev) + pci_dev_put(dev); ixdp2x00_slave_pci_postinit(); } -- cgit v1.2.3 From 52f0c67340ca306d5802b52140a186fcfa4b340e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 22 Oct 2006 16:04:29 +0100 Subject: [ARM] Comment out missing configuration symbols HAS_TOUCHSCREEN_ADS7843_LH7 and HAS_TOUCHSCREEN_ADC_LH7 are referenced but not defined in the LH7A40x configuration. Comment them out to prevent them causing warnings. Marc Singer said: Feel free to remove the Kconfig lines. I'll add it back with the rest of the config entries. Signed-off-by: Russell King --- arch/arm/mach-lh7a40x/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig index 558a34f53b1..147b01928a9 100644 --- a/arch/arm/mach-lh7a40x/Kconfig +++ b/arch/arm/mach-lh7a40x/Kconfig @@ -14,7 +14,7 @@ config MACH_LPD7A400 bool "LPD7A400 Card Engine" select ARCH_LH7A400 # select IDE_POLL - select HAS_TOUCHSCREEN_ADS7843_LH7 +# select HAS_TOUCHSCREEN_ADS7843_LH7 help Say Y here if you are using Logic Product Development's LPD7A400 CardEngine. For the time being, the LPD7A400 and @@ -24,7 +24,7 @@ config MACH_LPD7A404 bool "LPD7A404 Card Engine" select ARCH_LH7A404 # select IDE_POLL - select HAS_TOUCHSCREEN_ADC_LH7 +# select HAS_TOUCHSCREEN_ADC_LH7 help Say Y here if you are using Logic Product Development's LPD7A404 CardEngine. For the time being, the LPD7A400 and -- cgit v1.2.3 From d1752aa884ec0ac3027c1a3d456bf69bf765c8b8 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 25 Oct 2006 01:00:22 +0200 Subject: [PATCH] x86-64: Simplify the vector allocator. There is no reason to remember a per cpu position of which vector to try. Keeping a global position is simpler and more likely to result in a global vector allocation even if I don't need or require it. For level triggered interrupts this means we are less likely to acknowledge another cpus irq, and cause the level triggered irq to harmlessly refire. This simplification makes it easier to only access data structures of online cpus, by having fewer special cases to deal with. Signed-off-by: Eric W. Biederman Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index b000017e4b5..0e89ae7e7b2 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -612,10 +612,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) * Also, we've got to be careful not to trash gate * 0x80, because int 0x80 is hm, kind of importantish. ;) */ - static struct { - int vector; - int offset; - } pos[NR_CPUS] = { [ 0 ... NR_CPUS - 1] = {FIRST_DEVICE_VECTOR, 0} }; + static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0; int old_vector = -1; int cpu; @@ -631,14 +628,13 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) for_each_cpu_mask(cpu, mask) { cpumask_t domain; - int first, new_cpu; + int new_cpu; int vector, offset; domain = vector_allocation_domain(cpu); - first = first_cpu(domain); - vector = pos[first].vector; - offset = pos[first].offset; + vector = current_vector; + offset = current_offset; next: vector += 8; if (vector >= FIRST_SYSTEM_VECTOR) { @@ -646,7 +642,7 @@ next: offset = (offset + 1) % 8; vector = FIRST_DEVICE_VECTOR + offset; } - if (unlikely(pos[first].vector == vector)) + if (unlikely(current_vector == vector)) continue; if (vector == IA32_SYSCALL_VECTOR) goto next; @@ -654,10 +650,8 @@ next: if (per_cpu(vector_irq, new_cpu)[vector] != -1) goto next; /* Found one! */ - for_each_cpu_mask(new_cpu, domain) { - pos[new_cpu].vector = vector; - pos[new_cpu].offset = offset; - } + current_vector = vector; + current_offset = offset; if (old_vector >= 0) { int old_cpu; for_each_cpu_mask(old_cpu, irq_domain[irq]) -- cgit v1.2.3 From 70a0a5357db20c291d46c04011d646d5d84c868c Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 25 Oct 2006 01:00:23 +0200 Subject: [PATCH] x86-64: Only look at per_cpu data for online cpus. When I generalized __assign_irq_vector I failed to pay attention to what happens when you access a per cpu data structure for a cpu that is not online. It is an undefined case making any code that does it have undefined behavior as well. The code still needs to be able to allocate a vector across cpus that are not online to properly handle combinations like lowest priority interrupt delivery and cpu_hotplug. Not that we can do that today but the infrastructure shouldn't prevent it. So this patch updates the places where we touch per cpu data to only touch online cpus, it makes cpu vector allocation an atomic operation with respect to cpu hotplug, and it updates the cpu start code to properly initialize vector_irq so we don't have inconsistencies. Signed-off-by: Eric W. Biederman Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 42 +++++++++++++++++++++++++++++++++++++----- arch/x86_64/kernel/smpboot.c | 7 ++++++- 2 files changed, 43 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 0e89ae7e7b2..fe429e5d6b2 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -63,7 +63,7 @@ int timer_over_8254 __initdata = 1; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); +DEFINE_SPINLOCK(vector_lock); /* * # of IRQ routing registers @@ -618,6 +618,9 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); + /* Only try and allocate irqs on cpus that are present */ + cpus_and(mask, mask, cpu_online_map); + if (irq_vector[irq] > 0) old_vector = irq_vector[irq]; if (old_vector > 0) { @@ -627,11 +630,12 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) } for_each_cpu_mask(cpu, mask) { - cpumask_t domain; + cpumask_t domain, new_mask; int new_cpu; int vector, offset; domain = vector_allocation_domain(cpu); + cpus_and(new_mask, domain, cpu_online_map); vector = current_vector; offset = current_offset; @@ -646,18 +650,20 @@ next: continue; if (vector == IA32_SYSCALL_VECTOR) goto next; - for_each_cpu_mask(new_cpu, domain) + for_each_cpu_mask(new_cpu, new_mask) if (per_cpu(vector_irq, new_cpu)[vector] != -1) goto next; /* Found one! */ current_vector = vector; current_offset = offset; if (old_vector >= 0) { + cpumask_t old_mask; int old_cpu; - for_each_cpu_mask(old_cpu, irq_domain[irq]) + cpus_and(old_mask, irq_domain[irq], cpu_online_map); + for_each_cpu_mask(old_cpu, old_mask) per_cpu(vector_irq, old_cpu)[old_vector] = -1; } - for_each_cpu_mask(new_cpu, domain) + for_each_cpu_mask(new_cpu, new_mask) per_cpu(vector_irq, new_cpu)[vector] = irq; irq_vector[irq] = vector; irq_domain[irq] = domain; @@ -678,6 +684,32 @@ static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) return vector; } +void __setup_vector_irq(int cpu) +{ + /* Initialize vector_irq on a new cpu */ + /* This function must be called with vector_lock held */ + unsigned long flags; + int irq, vector; + + + /* Mark the inuse vectors */ + for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) { + if (!cpu_isset(cpu, irq_domain[irq])) + continue; + vector = irq_vector[irq]; + per_cpu(vector_irq, cpu)[vector] = irq; + } + /* Mark the free vectors */ + for (vector = 0; vector < NR_VECTORS; ++vector) { + irq = per_cpu(vector_irq, cpu)[vector]; + if (irq < 0) + continue; + if (!cpu_isset(cpu, irq_domain[irq])) + per_cpu(vector_irq, cpu)[vector] = -1; + } +} + + extern void (*interrupt[NR_IRQS])(void); static struct irq_chip ioapic_chip; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 7b7a6870288..62c2e747af5 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -581,12 +581,16 @@ void __cpuinit start_secondary(void) * smp_call_function(). */ lock_ipi_call_lock(); + spin_lock(&vector_lock); + /* Setup the per cpu irq handling data structures */ + __setup_vector_irq(smp_processor_id()); /* * Allow the master to continue. */ cpu_set(smp_processor_id(), cpu_online_map); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + spin_unlock(&vector_lock); unlock_ipi_call_lock(); cpu_idle(); @@ -799,7 +803,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) cpu, node); } - alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -1246,8 +1249,10 @@ int __cpu_disable(void) local_irq_disable(); remove_siblinginfo(cpu); + spin_lock(&vector_lock); /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); + spin_unlock(&vector_lock); remove_cpu_from_maps(); fixup_irqs(cpu_online_map); return 0; -- cgit v1.2.3 From fb20f65a01a97bdf4bb746eecfc24a08561e2648 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 20 Oct 2006 15:57:15 +0200 Subject: [POWERPC] Fix hang in start_ldr if _end or _edata is unaligned Quick fix for lack of memset(__bss_start, 0, _end-__bss_start) in load_kernel(). If edata is unaligned, the loop will overwrite all memory because r3 and r4 will never be equal. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc/boot/simple/relocate.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S index 0c021556d78..1bbbcd2f2bc 100644 --- a/arch/ppc/boot/simple/relocate.S +++ b/arch/ppc/boot/simple/relocate.S @@ -154,8 +154,8 @@ do_relocate_out: start_ldr: /* Clear all of BSS and set up stack for C calls */ - lis r3,edata@h - ori r3,r3,edata@l + lis r3,__bss_start@h + ori r3,r3,__bss_start@l lis r4,end@h ori r4,r4,end@l subi r3,r3,4 @@ -163,7 +163,7 @@ start_ldr: li r0,0 50: stwu r0,4(r3) cmpw cr0,r3,r4 - bne 50b + blt 50b 90: mr r9,r1 /* Save old stack pointer (in case it matters) */ lis r1,.stack@h ori r1,r1,.stack@l -- cgit v1.2.3 From 42c4aaadb737e0e672b3fb86b2c41ff59f0fb8bc Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 24 Oct 2006 16:42:40 +1000 Subject: [POWERPC] Consolidate feature fixup code There are currently two versions of the functions for applying the feature fixups, one for CPU features and one for firmware features. In addition, they are both in assembly and with separate implementations for 32 and 64 bits. identify_cpu() is also implemented in assembly and separately for 32 and 64 bits. This patch replaces them with a pair of C functions. The call sites are slightly moved on ppc64 as well to be called from C instead of from assembly, though it's a very small change, and thus shouldn't cause any problem. Signed-off-by: Benjamin Herrenschmidt Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 72 ++++++++++++++++++- arch/powerpc/kernel/head_64.S | 19 ----- arch/powerpc/kernel/misc_32.S | 74 -------------------- arch/powerpc/kernel/misc_64.S | 124 --------------------------------- arch/powerpc/kernel/setup_32.c | 8 ++- arch/powerpc/kernel/setup_64.c | 11 +++ arch/powerpc/platforms/iseries/setup.c | 5 ++ arch/ppc/kernel/misc.S | 74 -------------------- arch/ppc/kernel/setup.c | 10 +-- 9 files changed, 99 insertions(+), 298 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index f23aad66a79..6fdfaa4a82b 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -18,6 +18,7 @@ #include #include +#include /* for PTRRELOC on ARCH=ppc */ struct cpu_spec* cur_cpu_spec = NULL; EXPORT_SYMBOL(cur_cpu_spec); @@ -73,7 +74,7 @@ extern void __restore_cpu_ppc970(void); #define PPC_FEATURE_SPE_COMP 0 #endif -struct cpu_spec cpu_specs[] = { +static struct cpu_spec cpu_specs[] = { #ifdef CONFIG_PPC64 { /* Power3 */ .pvr_mask = 0xffff0000, @@ -1167,3 +1168,72 @@ struct cpu_spec cpu_specs[] = { #endif /* !CLASSIC_PPC */ #endif /* CONFIG_PPC32 */ }; + +struct cpu_spec *identify_cpu(unsigned long offset) +{ + struct cpu_spec *s = cpu_specs; + struct cpu_spec **cur = &cur_cpu_spec; + unsigned int pvr = mfspr(SPRN_PVR); + int i; + + s = PTRRELOC(s); + cur = PTRRELOC(cur); + + if (*cur != NULL) + return PTRRELOC(*cur); + + for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) + if ((pvr & s->pvr_mask) == s->pvr_value) { + *cur = cpu_specs + i; +#ifdef CONFIG_PPC64 + /* ppc64 expects identify_cpu to also call setup_cpu + * for that processor. I will consolidate that at a + * later time, for now, just use our friend #ifdef. + * we also don't need to PTRRELOC the function pointer + * on ppc64 as we are running at 0 in real mode. + */ + if (s->cpu_setup) { + s->cpu_setup(offset, s); + } +#endif /* CONFIG_PPC64 */ + return s; + } + BUG(); + return NULL; +} + +void do_feature_fixups(unsigned long offset, unsigned long value, + void *fixup_start, void *fixup_end) +{ + struct fixup_entry { + unsigned long mask; + unsigned long value; + unsigned int *start; + unsigned int *end; + } *fcur, *fend; + + fcur = fixup_start; + fend = fixup_end; + + for (; fcur < fend; fcur++) { + unsigned int *pstart, *pend, *p; + + if ((value & fcur->mask) == fcur->value) + continue; + + /* These PTRRELOCs will disappear once the new scheme for + * modules and vdso is implemented + */ + pstart = PTRRELOC(fcur->start); + pend = PTRRELOC(fcur->end); + + for (p = pstart; p < pend; p++) { + *p = 0x60000000u; + asm volatile ("dcbst 0, %0" : : "r" (p)); + } + asm volatile ("sync" : : : "memory"); + for (p = pstart; p < pend; p++) + asm volatile ("icbi 0,%0" : : "r" (p)); + asm volatile ("sync; isync" : : : "memory"); + } +} diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 645c7f10fb2..f12e3c55520 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1580,11 +1580,6 @@ _STATIC(__start_initialization_iSeries) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - LOAD_REG_IMMEDIATE(r3,cpu_specs) - LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) - li r5,0 - bl .identify_cpu - LOAD_REG_IMMEDIATE(r2,__toc_start) addi r2,r2,0x4000 addi r2,r2,0x4000 @@ -1964,13 +1959,6 @@ _STATIC(start_here_multiplatform) addi r2,r2,0x4000 add r2,r2,r26 - LOAD_REG_IMMEDIATE(r3, cpu_specs) - add r3,r3,r26 - LOAD_REG_IMMEDIATE(r4,cur_cpu_spec) - add r4,r4,r26 - mr r5,r26 - bl .identify_cpu - /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ @@ -2000,13 +1988,6 @@ _STATIC(start_here_common) li r0,0 stdu r0,-STACK_FRAME_OVERHEAD(r1) - /* Apply the CPUs-specific fixups (nop out sections not relevant - * to this CPU - */ - li r3,0 - bl .do_cpu_ftr_fixups - bl .do_fw_ftr_fixups - /* ptr to current */ LOAD_REG_IMMEDIATE(r4, init_task) std r4,PACACURRENT(r13) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 88fd73fdf04..412bea3cf81 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -101,80 +101,6 @@ _GLOBAL(reloc_got2) mtlr r11 blr -/* - * identify_cpu, - * called with r3 = data offset and r4 = CPU number - * doesn't change r3 - */ -_GLOBAL(identify_cpu) - addis r8,r3,cpu_specs@ha - addi r8,r8,cpu_specs@l - mfpvr r7 -1: - lwz r5,CPU_SPEC_PVR_MASK(r8) - and r5,r5,r7 - lwz r6,CPU_SPEC_PVR_VALUE(r8) - cmplw 0,r6,r5 - beq 1f - addi r8,r8,CPU_SPEC_ENTRY_SIZE - b 1b -1: - addis r6,r3,cur_cpu_spec@ha - addi r6,r6,cur_cpu_spec@l - sub r8,r8,r3 - stw r8,0(r6) - blr - -/* - * do_cpu_ftr_fixups - goes through the list of CPU feature fixups - * and writes nop's over sections of code that don't apply for this cpu. - * r3 = data offset (not changed) - */ -_GLOBAL(do_cpu_ftr_fixups) - /* Get CPU 0 features */ - addis r6,r3,cur_cpu_spec@ha - addi r6,r6,cur_cpu_spec@l - lwz r4,0(r6) - add r4,r4,r3 - lwz r4,CPU_SPEC_FEATURES(r4) - - /* Get the fixup table */ - addis r6,r3,__start___ftr_fixup@ha - addi r6,r6,__start___ftr_fixup@l - addis r7,r3,__stop___ftr_fixup@ha - addi r7,r7,__stop___ftr_fixup@l - - /* Do the fixup */ -1: cmplw 0,r6,r7 - bgelr - addi r6,r6,16 - lwz r8,-16(r6) /* mask */ - and r8,r8,r4 - lwz r9,-12(r6) /* value */ - cmplw 0,r8,r9 - beq 1b - lwz r8,-8(r6) /* section begin */ - lwz r9,-4(r6) /* section end */ - subf. r9,r8,r9 - beq 1b - /* write nops over the section of code */ - /* todo: if large section, add a branch at the start of it */ - srwi r9,r9,2 - mtctr r9 - add r8,r8,r3 - lis r0,0x60000000@h /* nop */ -3: stw r0,0(r8) - andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l - beq 2f - dcbst 0,r8 /* suboptimal, but simpler */ - sync - icbi 0,r8 -2: addi r8,r8,4 - bdnz 3b - sync /* additional sync needed on g4 */ - isync - b 1b - /* * call_setup_cpu - call the setup_cpu function for this cpu * r3 = data offset, r24 = cpu number diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index c70e20708a1..21fd2c662a9 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -246,130 +246,6 @@ _GLOBAL(__flush_dcache_icache) isync blr -/* - * identify_cpu and calls setup_cpu - * In: r3 = base of the cpu_specs array - * r4 = address of cur_cpu_spec - * r5 = relocation offset - */ -_GLOBAL(identify_cpu) - mfpvr r7 -1: - lwz r8,CPU_SPEC_PVR_MASK(r3) - and r8,r8,r7 - lwz r9,CPU_SPEC_PVR_VALUE(r3) - cmplw 0,r9,r8 - beq 1f - addi r3,r3,CPU_SPEC_ENTRY_SIZE - b 1b -1: - sub r0,r3,r5 - std r0,0(r4) - ld r4,CPU_SPEC_SETUP(r3) - cmpdi 0,r4,0 - add r4,r4,r5 - beqlr - ld r4,0(r4) - add r4,r4,r5 - mtctr r4 - /* Calling convention for cpu setup is r3=offset, r4=cur_cpu_spec */ - mr r4,r3 - mr r3,r5 - bctr - -/* - * do_cpu_ftr_fixups - goes through the list of CPU feature fixups - * and writes nop's over sections of code that don't apply for this cpu. - * r3 = data offset (not changed) - */ -_GLOBAL(do_cpu_ftr_fixups) - /* Get CPU 0 features */ - LOAD_REG_IMMEDIATE(r6,cur_cpu_spec) - sub r6,r6,r3 - ld r4,0(r6) - sub r4,r4,r3 - ld r4,CPU_SPEC_FEATURES(r4) - /* Get the fixup table */ - LOAD_REG_IMMEDIATE(r6,__start___ftr_fixup) - sub r6,r6,r3 - LOAD_REG_IMMEDIATE(r7,__stop___ftr_fixup) - sub r7,r7,r3 - /* Do the fixup */ -1: cmpld r6,r7 - bgelr - addi r6,r6,32 - ld r8,-32(r6) /* mask */ - and r8,r8,r4 - ld r9,-24(r6) /* value */ - cmpld r8,r9 - beq 1b - ld r8,-16(r6) /* section begin */ - ld r9,-8(r6) /* section end */ - subf. r9,r8,r9 - beq 1b - /* write nops over the section of code */ - /* todo: if large section, add a branch at the start of it */ - srwi r9,r9,2 - mtctr r9 - sub r8,r8,r3 - lis r0,0x60000000@h /* nop */ -3: stw r0,0(r8) - andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l - beq 2f - dcbst 0,r8 /* suboptimal, but simpler */ - sync - icbi 0,r8 -2: addi r8,r8,4 - bdnz 3b - sync /* additional sync needed on g4 */ - isync - b 1b - -/* - * do_fw_ftr_fixups - goes through the list of firmware feature fixups - * and writes nop's over sections of code that don't apply for this firmware. - * r3 = data offset (not changed) - */ -_GLOBAL(do_fw_ftr_fixups) - /* Get firmware features */ - LOAD_REG_IMMEDIATE(r6,powerpc_firmware_features) - sub r6,r6,r3 - ld r4,0(r6) - /* Get the fixup table */ - LOAD_REG_IMMEDIATE(r6,__start___fw_ftr_fixup) - sub r6,r6,r3 - LOAD_REG_IMMEDIATE(r7,__stop___fw_ftr_fixup) - sub r7,r7,r3 - /* Do the fixup */ -1: cmpld r6,r7 - bgelr - addi r6,r6,32 - ld r8,-32(r6) /* mask */ - and r8,r8,r4 - ld r9,-24(r6) /* value */ - cmpld r8,r9 - beq 1b - ld r8,-16(r6) /* section begin */ - ld r9,-8(r6) /* section end */ - subf. r9,r8,r9 - beq 1b - /* write nops over the section of code */ - /* todo: if large section, add a branch at the start of it */ - srwi r9,r9,2 - mtctr r9 - sub r8,r8,r3 - lis r0,0x60000000@h /* nop */ -3: stw r0,0(r8) -BEGIN_FTR_SECTION - dcbst 0,r8 /* suboptimal, but simpler */ - sync - icbi 0,r8 -END_FTR_SECTION_IFSET(CPU_FTR_SPLIT_ID_CACHE) - addi r8,r8,4 - bdnz 3b - sync /* additional sync needed on g4 */ - isync - b 1b #if defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) /* diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 191d0ab0922..769e511783b 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -91,6 +91,7 @@ int ucache_bsize; unsigned long __init early_init(unsigned long dt_ptr) { unsigned long offset = reloc_offset(); + struct cpu_spec *spec; /* First zero the BSS -- use memset_io, some platforms don't have * caches on yet */ @@ -100,8 +101,11 @@ unsigned long __init early_init(unsigned long dt_ptr) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - identify_cpu(offset, 0); - do_cpu_ftr_fixups(offset); + spec = identify_cpu(offset); + + do_feature_fixups(offset, spec->cpu_features, + PTRRELOC(&__start___ftr_fixup), + PTRRELOC(&__stop___ftr_fixup)); return KERNELBASE + offset; } diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 4b2e32eab9d..1969b5686ee 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -170,6 +170,9 @@ void __init setup_paca(int cpu) void __init early_setup(unsigned long dt_ptr) { + /* Identify CPU type */ + identify_cpu(0); + /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ setup_paca(0); @@ -348,6 +351,14 @@ void __init setup_system(void) { DBG(" -> setup_system()\n"); + /* Apply the CPUs-specific and firmware specific fixups to kernel + * text (nop out sections not relevant to this CPU or this firmware) + */ + do_feature_fixups(0, cur_cpu_spec->cpu_features, + &__start___ftr_fixup, &__stop___ftr_fixup); + do_feature_fixups(0, powerpc_firmware_features, + &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); + /* * Unflatten the device-tree passed by prom_init or kexec */ diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index a0ff7ba7d66..6f73469fd3b 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -694,6 +694,11 @@ void * __init iSeries_early_setup(void) { unsigned long phys_mem_size; + /* Identify CPU type. This is done again by the common code later + * on but calling this function multiple times is fine. + */ + identify_cpu(0); + powerpc_firmware_features |= FW_FEATURE_ISERIES; powerpc_firmware_features |= FW_FEATURE_LPAR; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 5f6684012de..d319f9ba237 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -109,80 +109,6 @@ _GLOBAL(reloc_got2) mtlr r11 blr -/* - * identify_cpu, - * called with r3 = data offset and r4 = CPU number - * doesn't change r3 - */ -_GLOBAL(identify_cpu) - addis r8,r3,cpu_specs@ha - addi r8,r8,cpu_specs@l - mfpvr r7 -1: - lwz r5,CPU_SPEC_PVR_MASK(r8) - and r5,r5,r7 - lwz r6,CPU_SPEC_PVR_VALUE(r8) - cmplw 0,r6,r5 - beq 1f - addi r8,r8,CPU_SPEC_ENTRY_SIZE - b 1b -1: - addis r6,r3,cur_cpu_spec@ha - addi r6,r6,cur_cpu_spec@l - sub r8,r8,r3 - stw r8,0(r6) - blr - -/* - * do_cpu_ftr_fixups - goes through the list of CPU feature fixups - * and writes nop's over sections of code that don't apply for this cpu. - * r3 = data offset (not changed) - */ -_GLOBAL(do_cpu_ftr_fixups) - /* Get CPU 0 features */ - addis r6,r3,cur_cpu_spec@ha - addi r6,r6,cur_cpu_spec@l - lwz r4,0(r6) - add r4,r4,r3 - lwz r4,CPU_SPEC_FEATURES(r4) - - /* Get the fixup table */ - addis r6,r3,__start___ftr_fixup@ha - addi r6,r6,__start___ftr_fixup@l - addis r7,r3,__stop___ftr_fixup@ha - addi r7,r7,__stop___ftr_fixup@l - - /* Do the fixup */ -1: cmplw 0,r6,r7 - bgelr - addi r6,r6,16 - lwz r8,-16(r6) /* mask */ - and r8,r8,r4 - lwz r9,-12(r6) /* value */ - cmplw 0,r8,r9 - beq 1b - lwz r8,-8(r6) /* section begin */ - lwz r9,-4(r6) /* section end */ - subf. r9,r8,r9 - beq 1b - /* write nops over the section of code */ - /* todo: if large section, add a branch at the start of it */ - srwi r9,r9,2 - mtctr r9 - add r8,r8,r3 - lis r0,0x60000000@h /* nop */ -3: stw r0,0(r8) - andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l - beq 2f - dcbst 0,r8 /* suboptimal, but simpler */ - sync - icbi 0,r8 -2: addi r8,r8,4 - bdnz 3b - sync /* additional sync needed on g4 */ - isync - b 1b - /* * call_setup_cpu - call the setup_cpu function for this cpu * r3 = data offset, r24 = cpu number diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 75fe13815be..41a640f16bd 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -38,6 +38,7 @@ #include #include #include +#include #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ @@ -53,8 +54,6 @@ extern void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); -extern void identify_cpu(unsigned long offset, unsigned long cpu); -extern void do_cpu_ftr_fixups(unsigned long offset); extern void reloc_got2(unsigned long offset); extern void ppc6xx_idle(void); @@ -301,6 +300,7 @@ early_init(int r3, int r4, int r5) { unsigned long phys; unsigned long offset = reloc_offset(); + struct cpu_spec *spec; /* Default */ phys = offset + KERNELBASE; @@ -313,8 +313,10 @@ early_init(int r3, int r4, int r5) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - identify_cpu(offset, 0); - do_cpu_ftr_fixups(offset); + spec = identify_cpu(offset); + do_feature_fixups(offset, spec->cpu_features, + PTRRELOC(&__start___ftr_fixup), + PTRRELOC(&__stop___ftr_fixup)); return phys; } -- cgit v1.2.3 From 0909c8c2d547e45ca50e2492b08ec93a37b35237 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 20 Oct 2006 11:47:18 +1000 Subject: [POWERPC] Support feature fixups in vdso's This patch reworks the feature fixup mecanism so vdso's can be fixed up. The main issue was that the construct: .long label (or .llong on 64 bits) will not work in the case of a shared library like the vdso. It will generate an empty placeholder in the fixup table along with a reloc, which is not something we can deal with in the vdso. The idea here (thanks Alan Modra !) is to instead use something like: 1: .long label - 1b That is, the feature fixup tables no longer contain addresses of bits of code to patch, but offsets of such code from the fixup table entry itself. That is properly resolved by ld when building the .so's. I've modified the fixup mecanism generically to use that method for the rest of the kernel as well. Another trick is that the 32 bits vDSO included in the 64 bits kernel need to have a table in the 64 bits format. However, gas does not support 32 bits code with a statement of the form: .llong label - 1b (Or even just .llong label) That is, it cannot emit the right fixup/relocation for the linker to use to assign a 32 bits address to an .llong field. Thus, in the specific case of the 32 bits vdso built as part of the 64 bits kernel, we are using a modified macro that generates: .long 0xffffffff .llong label - 1b Note that is assumes that the value is negative which is enforced by the .lds (those offsets are always negative as the .text is always before the fixup table and gas doesn't support emiting the reloc the other way around). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 11 ++++----- arch/powerpc/kernel/setup_32.c | 2 +- arch/powerpc/kernel/setup_64.c | 4 +-- arch/powerpc/kernel/vdso.c | 43 +++++++++++++++++++++++++++++++++ arch/powerpc/kernel/vdso32/vdso32.lds.S | 12 +++++++++ arch/powerpc/kernel/vdso64/vdso64.lds.S | 10 ++++++++ arch/ppc/kernel/setup.c | 2 +- 7 files changed, 74 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6fdfaa4a82b..bfd499ee375 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1202,14 +1202,13 @@ struct cpu_spec *identify_cpu(unsigned long offset) return NULL; } -void do_feature_fixups(unsigned long offset, unsigned long value, - void *fixup_start, void *fixup_end) +void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end) { struct fixup_entry { unsigned long mask; unsigned long value; - unsigned int *start; - unsigned int *end; + long start_off; + long end_off; } *fcur, *fend; fcur = fixup_start; @@ -1224,8 +1223,8 @@ void do_feature_fixups(unsigned long offset, unsigned long value, /* These PTRRELOCs will disappear once the new scheme for * modules and vdso is implemented */ - pstart = PTRRELOC(fcur->start); - pend = PTRRELOC(fcur->end); + pstart = ((unsigned int *)fcur) + (fcur->start_off / 4); + pend = ((unsigned int *)fcur) + (fcur->end_off / 4); for (p = pstart; p < pend; p++) { *p = 0x60000000u; diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 769e511783b..a4c2964a3ca 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -103,7 +103,7 @@ unsigned long __init early_init(unsigned long dt_ptr) */ spec = identify_cpu(offset); - do_feature_fixups(offset, spec->cpu_features, + do_feature_fixups(spec->cpu_features, PTRRELOC(&__start___ftr_fixup), PTRRELOC(&__stop___ftr_fixup)); diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 1969b5686ee..16278968dab 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -354,9 +354,9 @@ void __init setup_system(void) /* Apply the CPUs-specific and firmware specific fixups to kernel * text (nop out sections not relevant to this CPU or this firmware) */ - do_feature_fixups(0, cur_cpu_spec->cpu_features, + do_feature_fixups(cur_cpu_spec->cpu_features, &__start___ftr_fixup, &__stop___ftr_fixup); - do_feature_fixups(0, powerpc_firmware_features, + do_feature_fixups(powerpc_firmware_features, &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); /* diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index 1a7e19cdab3..c913ad5cad2 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -36,6 +36,8 @@ #include #include +#include "setup.h" + #undef DEBUG #ifdef DEBUG @@ -586,6 +588,43 @@ static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32, return 0; } + +static __init int vdso_fixup_features(struct lib32_elfinfo *v32, + struct lib64_elfinfo *v64) +{ + void *start32; + unsigned long size32; + +#ifdef CONFIG_PPC64 + void *start64; + unsigned long size64; + + start64 = find_section64(v64->hdr, "__ftr_fixup", &size64); + if (start64) + do_feature_fixups(cur_cpu_spec->cpu_features, + start64, start64 + size64); + + start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64); + if (start64) + do_feature_fixups(powerpc_firmware_features, + start64, start64 + size64); +#endif /* CONFIG_PPC64 */ + + start32 = find_section32(v32->hdr, "__ftr_fixup", &size32); + if (start32) + do_feature_fixups(cur_cpu_spec->cpu_features, + start32, start32 + size32); + +#ifdef CONFIG_PPC64 + start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32); + if (start32) + do_feature_fixups(powerpc_firmware_features, + start32, start32 + size32); +#endif /* CONFIG_PPC64 */ + + return 0; +} + static __init int vdso_fixup_alt_funcs(struct lib32_elfinfo *v32, struct lib64_elfinfo *v64) { @@ -634,6 +673,9 @@ static __init int vdso_setup(void) if (vdso_fixup_datapage(&v32, &v64)) return -1; + if (vdso_fixup_features(&v32, &v64)) + return -1; + if (vdso_fixup_alt_funcs(&v32, &v64)) return -1; @@ -714,6 +756,7 @@ void __init vdso_init(void) * Setup the syscall map in the vDOS */ vdso_setup_syscall_map(); + /* * Initialize the vDSO images in memory, that is do necessary * fixups of vDSO symbols, locate trampolines, etc... diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index 6187af2d54c..26e138c4ce1 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S @@ -32,6 +32,18 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); + . = ALIGN(8); + __ftr_fixup : { + *(__ftr_fixup) + } + +#ifdef CONFIG_PPC64 + . = ALIGN(8); + __fw_ftr_fixup : { + *(__fw_ftr_fixup) + } +#endif + /* Other stuff is appended to the text segment: */ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index 4a2b6dc0960..2d70f35d50b 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S @@ -31,6 +31,16 @@ SECTIONS PROVIDE (_etext = .); PROVIDE (etext = .); + . = ALIGN(8); + __ftr_fixup : { + *(__ftr_fixup) + } + + . = ALIGN(8); + __fw_ftr_fixup : { + *(__fw_ftr_fixup) + } + /* Other stuff is appended to the text segment: */ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } .rodata1 : { *(.rodata1) } diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 41a640f16bd..27faeca2c7a 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -314,7 +314,7 @@ early_init(int r3, int r4, int r5) * that depend on which cpu we have. */ spec = identify_cpu(offset); - do_feature_fixups(offset, spec->cpu_features, + do_feature_fixups(spec->cpu_features, PTRRELOC(&__start___ftr_fixup), PTRRELOC(&__stop___ftr_fixup)); -- cgit v1.2.3 From 21c4ff80cba5e24932f3ef79c8482c0491630b2b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 20 Oct 2006 11:47:19 +1000 Subject: [POWERPC] Support feature fixups in modules This patch adds support for feature fixups in modules. This involves adding support for R_PPC64_REL64 relocs to the 64 bits module loader. It also modifies modpost.c to ignore the powerpc fixup sections (or it would warn when used in .init.text). Signed-off-by: Benjamin Herrenschmidt Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/module_32.c | 39 +++++++++++++++++++++++--------- arch/powerpc/kernel/module_64.c | 49 +++++++++++++++++++++++++++++++++-------- 2 files changed, 69 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 92f4e5f64f0..e2c3c6a85f3 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -24,6 +24,8 @@ #include #include +#include "setup.h" + #if 0 #define DEBUGP printk #else @@ -269,33 +271,50 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, return 0; } +static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + const char *name) +{ + char *secstrings; + unsigned int i; + + secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + for (i = 1; i < hdr->e_shnum; i++) + if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) + return &sechdrs[i]; + return NULL; +} + int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - char *secstrings; - unsigned int i; + const Elf_Shdr *sect; me->arch.bug_table = NULL; me->arch.num_bugs = 0; /* Find the __bug_table section, if present */ - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) { - if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) - continue; - me->arch.bug_table = (void *) sechdrs[i].sh_addr; - me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); - break; + sect = find_section(hdr, sechdrs, "__bug_table"); + if (sect != NULL) { + me->arch.bug_table = (void *) sect->sh_addr; + me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); } - /* + /* * Strictly speaking this should have a spinlock to protect against * traversals, but since we only traverse on BUG()s, a spinlock * could potentially lead to deadlock and thus be counter-productive. */ list_add(&me->arch.bug_list, &module_bug_list); + /* Apply feature fixups */ + sect = find_section(hdr, sechdrs, "__ftr_fixup"); + if (sect != NULL) + do_feature_fixups(cur_cpu_spec->cpu_features, + (void *)sect->sh_addr, + (void *)sect->sh_addr + sect->sh_size); + return 0; } diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index ba34001fca8..8dd1f0aae5d 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -22,6 +22,9 @@ #include #include #include +#include + +#include "setup.h" /* FIXME: We don't do .init separately. To do this, we'd need to have a separate r2 value in the init and core section, and stub between @@ -400,6 +403,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, | (value & 0x03fffffc); break; + case R_PPC64_REL64: + /* 64 bits relative (used by features fixups) */ + *location = value - (unsigned long)location; + break; + default: printk("%s: Unknown ADD relocation: %lu\n", me->name, @@ -413,23 +421,33 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, LIST_HEAD(module_bug_list); -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, struct module *me) +static const Elf_Shdr *find_section(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, + const char *name) { char *secstrings; unsigned int i; + secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + for (i = 1; i < hdr->e_shnum; i++) + if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0) + return &sechdrs[i]; + return NULL; +} + +int module_finalize(const Elf_Ehdr *hdr, + const Elf_Shdr *sechdrs, struct module *me) +{ + const Elf_Shdr *sect; + me->arch.bug_table = NULL; me->arch.num_bugs = 0; /* Find the __bug_table section, if present */ - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) { - if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) - continue; - me->arch.bug_table = (void *) sechdrs[i].sh_addr; - me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); - break; + sect = find_section(hdr, sechdrs, "__bug_table"); + if (sect != NULL) { + me->arch.bug_table = (void *) sect->sh_addr; + me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); } /* @@ -439,6 +457,19 @@ int module_finalize(const Elf_Ehdr *hdr, */ list_add(&me->arch.bug_list, &module_bug_list); + /* Apply feature fixups */ + sect = find_section(hdr, sechdrs, "__ftr_fixup"); + if (sect != NULL) + do_feature_fixups(cur_cpu_spec->cpu_features, + (void *)sect->sh_addr, + (void *)sect->sh_addr + sect->sh_size); + + sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); + if (sect != NULL) + do_feature_fixups(powerpc_firmware_features, + (void *)sect->sh_addr, + (void *)sect->sh_addr + sect->sh_size); + return 0; } -- cgit v1.2.3 From 859deea949c382d9ccb6397fe33df3703ecef45d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 20 Oct 2006 14:37:05 +1000 Subject: [POWERPC] Cell timebase bug workaround The Cell CPU timebase has an erratum. When reading the entire 64 bits of the timebase with one mftb instruction, there is a handful of cycles window during which one might read a value with the low order 32 bits already reset to 0x00000000 but the high order bits not yet incremeted by one. This fixes it by reading the timebase again until the low order 32 bits is no longer 0. That might introduce occasional latencies if hitting mftb just at the wrong time, but no more than 70ns on a cell blade, and that was considered acceptable. Signed-off-by: Benjamin Herrenschmidt Acked-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/vdso64/gettimeofday.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index 56e76ff5498..40ffd9b6cef 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S @@ -229,8 +229,10 @@ V_FUNCTION_BEGIN(__do_get_xsec) xor r0,r8,r8 /* create dependency */ add r3,r3,r0 - /* Get TB & offset it */ - mftb r7 + /* Get TB & offset it. We use the MFTB macro which will generate + * workaround code for Cell. + */ + MFTB(r7) ld r9,CFG_TB_ORIG_STAMP(r3) subf r7,r9,r7 -- cgit v1.2.3 From e2100efb266c9335925191afe79f81f8d0a5807e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 20 Oct 2006 11:49:54 +1000 Subject: [POWERPC] Fix device_is_compatible() const warning Fix a const'ification related warning with device_is_compatible() and friends related to get_property() not properly having const on it's input device node argument. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 865b9648d0d..bdb412d4b74 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1014,7 +1014,7 @@ EXPORT_SYMBOL(find_all_nodes); /** Checks if the given "compat" string matches one of the strings in * the device's "compatible" property */ -int device_is_compatible(struct device_node *device, const char *compat) +int device_is_compatible(const struct device_node *device, const char *compat) { const char* cp; int cplen, l; @@ -1491,7 +1491,8 @@ static int __init prom_reconfig_setup(void) __initcall(prom_reconfig_setup); #endif -struct property *of_find_property(struct device_node *np, const char *name, +struct property *of_find_property(const struct device_node *np, + const char *name, int *lenp) { struct property *pp; @@ -1512,7 +1513,8 @@ struct property *of_find_property(struct device_node *np, const char *name, * Find a property with a given name for a given node * and return the value. */ -const void *get_property(struct device_node *np, const char *name, int *lenp) +const void *get_property(const struct device_node *np, const char *name, + int *lenp) { struct property *pp = of_find_property(np,name,lenp); return pp ? pp->value : NULL; -- cgit v1.2.3 From f6b301b89b7bf0bb872da4f37dc28240413cbae7 Mon Sep 17 00:00:00 2001 From: Dwayne Grant Mcconnell Date: Tue, 24 Oct 2006 18:27:30 +0200 Subject: [POWERPC] spufs: fix signal2 file to report signal2 This fixes the /signal2 file to actually give signal2 data. Signed-off-by: Dwayne Grant Mcconnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/hw_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index efc452e71ab..d805ffed892 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -147,7 +147,7 @@ static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) static u32 spu_hw_signal2_read(struct spu_context *ctx) { - return in_be32(&ctx->spu->problem->signal_notify1); + return in_be32(&ctx->spu->problem->signal_notify2); } static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) -- cgit v1.2.3 From 274cef5e9d0e494ad84dbc28513b0bb6e3d847ae Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 24 Oct 2006 18:01:42 +0200 Subject: [POWERPC] spufs: fix another off-by-one bug in spufs_mbox_read Currently, spufs_mbox_read transfers more bytes than requested on a read. If you ask for four bytes, you get eight. This fixes it to transfer the largest multiple of four bytes that is less than or equal to the number you asked for. Note: one nasty property of this file in spufs is that you can only read multiples of four bytes in the first place, since there is no way to atomically put back a few bytes into the hardware register. Thus, reading less than four bytes returns -EINVAL. Asking for more than four returns the largest possible multiple of four. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 0de8e114e6b..533e2723e18 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -385,7 +385,7 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf, udata = (void __user *)buf; spu_acquire(ctx); - for (count = 0; count <= len; count += 4, udata++) { + for (count = 0; (count + 4) <= len; count += 4, udata++) { int ret; ret = ctx->ops->mbox_read(ctx, &mbox_data); if (ret == 0) -- cgit v1.2.3 From b910ecf6bf221bb06f37e44765307c42b20db205 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 24 Oct 2006 18:01:43 +0200 Subject: [POWERPC] cell: update defconfig =================================================================== Signed-off-by: Paul Mackerras --- arch/powerpc/configs/cell_defconfig | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 892d5dd3254..0aba06d7d2e 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -254,6 +254,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -275,7 +276,9 @@ CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y +# CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +# CONFIG_IPV6_SIT is not set CONFIG_IPV6_TUNNEL=m # CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set @@ -405,6 +408,12 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -738,7 +747,6 @@ CONFIG_GEN_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -802,6 +810,7 @@ CONFIG_I2C_ALGOBIT=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -809,15 +818,10 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# -# Misc devices -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -923,6 +927,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -930,6 +935,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1129,6 +1135,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set # CONFIG_FORCED_INLINING is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set -- cgit v1.2.3 From f84c39da766b4c8f13872282f58286a57ad05b3e Mon Sep 17 00:00:00 2001 From: Liu Dave-r63238 Date: Wed, 18 Oct 2006 16:36:56 +0800 Subject: [POWERPC] Fix the UCC rx/tx clock of QE MPC8323EMDS board ethernet interface with RMII uses the CLK16 divisor for the rx and tx clock, but the ucc_set_qe_mux_rxtx() function doesn't handle the CLK16 setting of the CMXUCR3 and CMXUCR4 registers. This fixes it. Signed-off-by: Dave Liu Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/ucc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/sysdev/qe_lib/ucc.c b/arch/powerpc/sysdev/qe_lib/ucc.c index 916c9e5df57..ac12a44d516 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc.c +++ b/arch/powerpc/sysdev/qe_lib/ucc.c @@ -207,6 +207,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) case QE_CLK18: source = 8; break; case QE_CLK7: source = 9; break; case QE_CLK8: source = 10; break; + case QE_CLK16: source = 11; break; default: source = -1; break; } break; @@ -222,6 +223,7 @@ int ucc_set_qe_mux_rxtx(int ucc_num, enum qe_clock clock, enum comm_dir mode) case QE_CLK22: source = 8; break; case QE_CLK7: source = 9; break; case QE_CLK8: source = 10; break; + case QE_CLK16: source = 11; break; default: source = -1; break; } break; -- cgit v1.2.3 From f49196a5f53aa62a964b08ffa2c59699a0c8eb53 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 23 Oct 2006 11:35:22 -0500 Subject: [POWERPC] IPIC: Fix spinlock recursion in set_irq_handler This causes ipic_set_irq_type to set the handler directly rather than call set_irq_handler, which causes spinlock recursion because the lock is already held when ipic_set_irq_type is called. I'm also not convinced that ipic_set_irq_type should be changing the handler at all. There seem to be several controllers that don't and several that do. Those that do would break what appears to be a common usage of calling set_irq_chip_and_handler followed by set_irq_type, if a non-standard handler were to be used. OTOH, irq_create_of_mapping() doesn't set the handler, but only calls set_irq_type(). This patch gets things working in the spinlock-debugging-enabled case, but I'm curious as to where the handler setting is ideally supposed to be done. I don't see any documentation on set_irq_type() that clarifies what the semantics are supposed to be. Signed-off-by: Scott Wood Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/ipic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index bc4d4a7f965..746f78c1537 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -473,9 +473,9 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; if (flow_type & IRQ_TYPE_LEVEL_LOW) { desc->status |= IRQ_LEVEL; - set_irq_handler(virq, handle_level_irq); + desc->handle_irq = handle_level_irq; } else { - set_irq_handler(virq, handle_edge_irq); + desc->handle_irq = handle_edge_irq; } /* only EXT IRQ senses are programmable on ipic -- cgit v1.2.3 From f4d4c354bca18210296cc0a8f592c0cdb720bf20 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 25 Oct 2006 13:22:27 +1000 Subject: [POWERPC] Fix CHRP platforms with only 8259 On CHRP platforms with only a 8259 controller, we should set the default IRQ host to the 8259 driver's one for the IRQ probing fallbacks to work in case the IRQ tree is incorrect (like on Pegasos for example). Without this fix, we get a bunch of WARN_ON's during boot. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/chrp/setup.c | 4 +++- arch/powerpc/sysdev/i8259.c | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index cae3d13229b..49b8dabcbc9 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -477,8 +477,10 @@ static void __init chrp_find_8259(void) " address, polling\n"); i8259_init(pic, chrp_int_ack); - if (ppc_md.get_irq == NULL) + if (ppc_md.get_irq == NULL) { ppc_md.get_irq = i8259_irq; + irq_set_default_host(i8259_get_host()); + } if (chrp_mpic != NULL) { cascade_irq = irq_of_parse_and_map(pic, 0); if (cascade_irq == NO_IRQ) diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c index 0450265d73b..ad87adc975b 100644 --- a/arch/powerpc/sysdev/i8259.c +++ b/arch/powerpc/sysdev/i8259.c @@ -224,6 +224,11 @@ static struct irq_host_ops i8259_host_ops = { .xlate = i8259_host_xlate, }; +struct irq_host *i8259_get_host(void) +{ + return i8259_host; +} + /** * i8259_init - Initialize the legacy controller * @node: device node of the legacy PIC (can be NULL, but then, it will match -- cgit v1.2.3 From a0f467261ae041864414103b8dd6fc4487a3c7de Mon Sep 17 00:00:00 2001 From: Matthew McClintock Date: Mon, 23 Oct 2006 14:26:57 -0500 Subject: [POWERPC] Fixed some missing files to be deleted when running make clean Fixed some missing files to be deleted when running make clean Signed-off-by: Matthew McClintock Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 1e71a452b17..789def38af4 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -75,7 +75,7 @@ $(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S @cp $< $@ clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ - $(obj)/empty.c + empty.c zImage.coff.lds zImage.lds zImage.sandpoint quiet_cmd_bootcc = BOOTCC $@ cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< -- cgit v1.2.3 From 5414c6be57dd02e089c3eba1f5134f441733d013 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Oct 2006 13:37:34 +1000 Subject: [POWERPC] Make irq_dispose_mapping(NO_IRQ) a nop It makes for a friendlier API if irq_dispose_mapping(NO_IRQ) is a nop, rather than triggering a WARN_ON. Signed-off-by: Michael Ellerman Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 67b21a008f6..eb9fc621e05 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -648,10 +648,14 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); void irq_dispose_mapping(unsigned int virq) { - struct irq_host *host = irq_map[virq].host; + struct irq_host *host; irq_hw_number_t hwirq; unsigned long flags; + if (virq == NO_IRQ) + return; + + host = irq_map[virq].host; WARN_ON (host == NULL); if (host == NULL) return; -- cgit v1.2.3 From 24f43b33f74c8e8c8aabc40b728eaf9137802942 Mon Sep 17 00:00:00 2001 From: Masato Noguchi Date: Tue, 24 Oct 2006 18:31:14 +0200 Subject: [POWERPC] spufs: wrap mfc sdr access SPRN_SDR1 and the SPE's MFC SDR are hypervisor resources and are not accessible from a logical partition. This change adds an access wrapper. When running on bare H/W, the spufs needs to only set the SPE's MFC SDR to the value of the PPE's SPRN_SDR1 once at SPE initialization, so this change renames mfc_sdr_set() to mfc_sdr_setup() and moves the access of SPRN_SDR1 into the mmio wrapper. It also removes the now unneeded member mfc_sdr_RW from struct spu_priv1_collapsed. Signed-off-by: Masato Noguchi Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann -- Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 2 +- arch/powerpc/platforms/cell/spu_priv1_mmio.c | 6 +++--- arch/powerpc/platforms/cell/spufs/switch.c | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d0fb959e3ef..d41ad1d6c04 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -805,7 +805,7 @@ static int __init create_spu(struct device_node *spe) if (ret) goto out_unmap; spin_lock_init(&spu->register_lock); - spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); + spu_mfc_sdr_setup(spu); spu_mfc_sr1_set(spu, 0x33); mutex_lock(&spu_mutex); diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 71b69f0a1a4..90011f9aab3 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -84,9 +84,9 @@ static void mfc_dsisr_set(struct spu *spu, u64 dsisr) out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); } -static void mfc_sdr_set(struct spu *spu, u64 sdr) +static void mfc_sdr_setup(struct spu *spu) { - out_be64(&spu->priv1->mfc_sdr_RW, sdr); + out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); } static void mfc_sr1_set(struct spu *spu, u64 sr1) @@ -146,7 +146,7 @@ const struct spu_priv1_ops spu_priv1_mmio_ops = .mfc_dar_get = mfc_dar_get, .mfc_dsisr_get = mfc_dsisr_get, .mfc_dsisr_set = mfc_dsisr_set, - .mfc_sdr_set = mfc_sdr_set, + .mfc_sdr_setup = mfc_sdr_setup, .mfc_sr1_set = mfc_sr1_set, .mfc_sr1_get = mfc_sr1_get, .mfc_tclass_id_set = mfc_tclass_id_set, diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 0f782ca662b..b85347ff6b2 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -2165,9 +2165,6 @@ static void init_priv1(struct spu_state *csa) MFC_STATE1_PROBLEM_STATE_MASK | MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK; - /* Set storage description. */ - csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1); - /* Enable OS-specific set of interrupts. */ csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR | CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR | -- cgit v1.2.3 From cc21a66d7f727ab97b27af9cf763bc0b51510ffa Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 24 Oct 2006 18:31:15 +0200 Subject: [POWERPC] cell: remove unused struct spu variable Remove the mostly unused variable isrc from struct spu and a forgotten function declaration. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d41ad1d6c04..f6c94087db4 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -364,8 +364,7 @@ struct spu *spu_alloc_node(int node) if (!list_empty(&spu_list[node])) { spu = list_entry(spu_list[node].next, struct spu, list); list_del_init(&spu->list); - pr_debug("Got SPU %x %d %d\n", - spu->isrc, spu->number, spu->node); + pr_debug("Got SPU %d %d\n", spu->number, spu->node); spu_init_channels(spu); } mutex_unlock(&spu_mutex); @@ -591,7 +590,6 @@ static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np /* Add the node number */ isrc |= spu->node << IIC_IRQ_NODE_SHIFT; - spu->isrc = isrc; /* Now map interrupts of all 3 classes */ spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); @@ -733,16 +731,6 @@ struct sysdev_class spu_sysdev_class = { set_kset_name("spu") }; -static ssize_t spu_show_isrc(struct sys_device *sysdev, char *buf) -{ - struct spu *spu = container_of(sysdev, struct spu, sysdev); - return sprintf(buf, "%d\n", spu->isrc); - -} -static SYSDEV_ATTR(isrc, 0400, spu_show_isrc, NULL); - -extern int attach_sysdev_to_node(struct sys_device *dev, int nid); - static int spu_create_sysdev(struct spu *spu) { int ret; @@ -756,8 +744,6 @@ static int spu_create_sysdev(struct spu *spu) return ret; } - if (spu->isrc != 0) - sysdev_create_file(&spu->sysdev, &attr_isrc); sysfs_add_device_to_node(&spu->sysdev, spu->nid); return 0; @@ -765,7 +751,6 @@ static int spu_create_sysdev(struct spu *spu) static void spu_destroy_sysdev(struct spu *spu) { - sysdev_remove_file(&spu->sysdev, &attr_isrc); sysfs_remove_device_from_node(&spu->sysdev, spu->nid); sysdev_unregister(&spu->sysdev); } @@ -821,8 +806,8 @@ static int __init create_spu(struct device_node *spe) list_add(&spu->list, &spu_list[spu->node]); mutex_unlock(&spu_mutex); - pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", - spu->name, spu->isrc, spu->local_store, + pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", + spu->name, spu->local_store, spu->problem, spu->priv1, spu->priv2, spu->number); goto out; -- cgit v1.2.3 From 5737edd1ddbde5ab7f63bb3cb36015edbdb7c295 Mon Sep 17 00:00:00 2001 From: Mark Nutter Date: Tue, 24 Oct 2006 18:31:16 +0200 Subject: [POWERPC] spufs: add support for nonschedulable contexts This adds two new flags to spu_create: SPU_CREATE_NONSCHED: create a context that is never moved away from an SPE once it has started running. This flag can only be used by tasks with the CAP_SYS_NICE capability. SPU_CREATE_ISOLATED: create a nonschedulable context that enters isolation mode upon first run. This requires the SPU_CREATE_NONSCHED flag. Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 22 +++++++++++++ arch/powerpc/platforms/cell/spufs/hw_ops.c | 5 ++- arch/powerpc/platforms/cell/spufs/inode.c | 17 +++++++++- arch/powerpc/platforms/cell/spufs/run.c | 10 ++++-- arch/powerpc/platforms/cell/spufs/spufs.h | 1 + arch/powerpc/platforms/cell/spufs/switch.c | 50 ++++++++++++++++++++++++++++-- 6 files changed, 99 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 0de8e114e6b..8ca330671ad 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1531,3 +1531,25 @@ struct tree_descr spufs_dir_contents[] = { { "object-id", &spufs_object_id_ops, 0666, }, {}, }; + +struct tree_descr spufs_dir_nosched_contents[] = { + { "mem", &spufs_mem_fops, 0666, }, + { "mbox", &spufs_mbox_fops, 0444, }, + { "ibox", &spufs_ibox_fops, 0444, }, + { "wbox", &spufs_wbox_fops, 0222, }, + { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, + { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, + { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, + { "signal1", &spufs_signal1_fops, 0666, }, + { "signal2", &spufs_signal2_fops, 0666, }, + { "signal1_type", &spufs_signal1_type, 0666, }, + { "signal2_type", &spufs_signal2_type, 0666, }, + { "mss", &spufs_mss_fops, 0666, }, + { "mfc", &spufs_mfc_fops, 0666, }, + { "cntl", &spufs_cntl_fops, 0666, }, + { "npc", &spufs_npc_ops, 0666, }, + { "psmap", &spufs_psmap_fops, 0666, }, + { "phys-id", &spufs_id_ops, 0666, }, + { "object-id", &spufs_object_id_ops, 0666, }, + {}, +}; diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index efc452e71ab..2ad534a04be 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -219,8 +219,11 @@ static char *spu_hw_get_ls(struct spu_context *ctx) static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) { - eieio(); + spin_lock_irq(&ctx->spu->register_lock); + if (val & SPU_RUNCNTL_ISOLATE) + out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL); out_be32(&ctx->spu->problem->spu_runcntl_RW, val); + spin_unlock_irq(&ctx->spu->register_lock); } static void spu_hw_runcntl_stop(struct spu_context *ctx) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 427d00a4f6a..787ae71a685 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -258,7 +258,12 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, inode->i_op = &spufs_dir_inode_operations; inode->i_fop = &simple_dir_operations; - ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); + if (flags & SPU_CREATE_NOSCHED) + ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents, + mode, ctx); + else + ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); + if (ret) goto out_free_ctx; @@ -307,6 +312,16 @@ static int spufs_create_context(struct inode *inode, { int ret; + ret = -EPERM; + if ((flags & SPU_CREATE_NOSCHED) && + !capable(CAP_SYS_NICE)) + goto out_unlock; + + ret = -EINVAL; + if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE)) + == SPU_CREATE_ISOLATE) + goto out_unlock; + ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); if (ret) goto out_unlock; diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 63df8cf4ba1..0c03a04b6a3 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -51,11 +51,17 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat) static inline int spu_run_init(struct spu_context *ctx, u32 * npc) { int ret; + unsigned long runcntl = SPU_RUNCNTL_RUNNABLE; if ((ret = spu_acquire_runnable(ctx)) != 0) return ret; - ctx->ops->npc_write(ctx, *npc); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); + + if (ctx->flags & SPU_CREATE_ISOLATE) + runcntl |= SPU_RUNCNTL_ISOLATE; + else + ctx->ops->npc_write(ctx, *npc); + + ctx->ops->runcntl_write(ctx, runcntl); return 0; } diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index a0f55ca2d48..b17b809ecd7 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -135,6 +135,7 @@ struct spufs_inode_info { container_of(inode, struct spufs_inode_info, vfs_inode) extern struct tree_descr spufs_dir_contents[]; +extern struct tree_descr spufs_dir_nosched_contents[]; /* system call implementation */ long spufs_run_spu(struct file *file, diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index b85347ff6b2..b47fb50ac2c 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -1916,6 +1916,51 @@ static void save_lscsa(struct spu_state *prev, struct spu *spu) wait_spu_stopped(prev, spu); /* Step 57. */ } +static void force_spu_isolate_exit(struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + struct spu_priv2 __iomem *priv2 = spu->priv2; + + /* Stop SPE execution and wait for completion. */ + out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); + iobarrier_rw(); + POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); + + /* Restart SPE master runcntl. */ + spu_mfc_sr1_set(spu, MFC_STATE1_MASTER_RUN_CONTROL_MASK); + iobarrier_w(); + + /* Initiate isolate exit request and wait for completion. */ + out_be64(&priv2->spu_privcntl_RW, 4LL); + iobarrier_w(); + out_be32(&prob->spu_runcntl_RW, 2); + iobarrier_rw(); + POLL_WHILE_FALSE((in_be32(&prob->spu_status_R) + & SPU_STATUS_STOPPED_BY_STOP)); + + /* Reset load request to normal. */ + out_be64(&priv2->spu_privcntl_RW, SPU_PRIVCNT_LOAD_REQUEST_NORMAL); + iobarrier_w(); +} + +/** + * stop_spu_isolate + * Check SPU run-control state and force isolated + * exit function as necessary. + */ +static void stop_spu_isolate(struct spu *spu) +{ + struct spu_problem __iomem *prob = spu->problem; + + if (in_be32(&prob->spu_status_R) & SPU_STATUS_ISOLATED_STATE) { + /* The SPU is in isolated state; the only way + * to get it out is to perform an isolated + * exit (clean) operation. + */ + force_spu_isolate_exit(spu); + } +} + static void harvest(struct spu_state *prev, struct spu *spu) { /* @@ -1928,6 +1973,7 @@ static void harvest(struct spu_state *prev, struct spu *spu) inhibit_user_access(prev, spu); /* Step 3. */ terminate_spu_app(prev, spu); /* Step 4. */ set_switch_pending(prev, spu); /* Step 5. */ + stop_spu_isolate(spu); /* NEW. */ remove_other_spu_access(prev, spu); /* Step 6. */ suspend_mfc(prev, spu); /* Step 7. */ wait_suspend_mfc_complete(prev, spu); /* Step 8. */ @@ -2096,11 +2142,11 @@ int spu_save(struct spu_state *prev, struct spu *spu) acquire_spu_lock(spu); /* Step 1. */ rc = __do_spu_save(prev, spu); /* Steps 2-53. */ release_spu_lock(spu); - if (rc) { + if (rc != 0 && rc != 2 && rc != 6) { panic("%s failed on SPU[%d], rc=%d.\n", __func__, spu->number, rc); } - return rc; + return 0; } EXPORT_SYMBOL_GPL(spu_save); -- cgit v1.2.3 From eb758ce5b0d84e13cb643b6cc7cb429f6fa28258 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 24 Oct 2006 18:31:17 +0200 Subject: [POWERPC] spufs: "stautus" isnt a word. Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/switch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index b47fb50ac2c..c08981ff7fc 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -102,7 +102,7 @@ static inline int check_spu_isolate(struct spu_state *csa, struct spu *spu) * saved at this time. */ isolate_state = SPU_STATUS_ISOLATED_STATE | - SPU_STATUS_ISOLATED_LOAD_STAUTUS | SPU_STATUS_ISOLATED_EXIT_STAUTUS; + SPU_STATUS_ISOLATED_LOAD_STATUS | SPU_STATUS_ISOLATED_EXIT_STATUS; return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0; } @@ -1046,12 +1046,12 @@ static inline int suspend_spe(struct spu_state *csa, struct spu *spu) */ if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) { if (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_EXIT_STAUTUS) { + SPU_STATUS_ISOLATED_EXIT_STATUS) { POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); } if ((in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_LOAD_STAUTUS) + SPU_STATUS_ISOLATED_LOAD_STATUS) || (in_be32(&prob->spu_status_R) & SPU_STATUS_ISOLATED_STATE)) { out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); @@ -1085,7 +1085,7 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) */ if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) { if (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_EXIT_STAUTUS) { + SPU_STATUS_ISOLATED_EXIT_STATUS) { spu_mfc_sr1_set(spu, MFC_STATE1_MASTER_RUN_CONTROL_MASK); eieio(); @@ -1095,7 +1095,7 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) SPU_STATUS_RUNNING); } if ((in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_LOAD_STAUTUS) + SPU_STATUS_ISOLATED_LOAD_STATUS) || (in_be32(&prob->spu_status_R) & SPU_STATUS_ISOLATED_STATE)) { spu_mfc_sr1_set(spu, -- cgit v1.2.3 From 0afacde3df4c9980f505d9afd7cb0058389732ca Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 24 Oct 2006 18:31:18 +0200 Subject: [POWERPC] spufs: allow isolated mode apps by starting the SPE loader This patch adds general support for isolated mode SPE apps. Isolated apps are started indirectly, by a dedicated loader "kernel". This patch starts the loader when spe_create is invoked with the ISOLATE flag. We do this at spe_create time to allow libspe to pass the isolated app in before calling spe_run. The loader is read from the device tree, at the location "/spu-isolation/loader". If the loader is not present, an attempt to start an isolated SPE binary will fail with -ENODEV. Update: loader needs to be correctly aligned - copy to a kmalloced buf. Update: remove workaround for systemsim/spurom 'L-bit' bug, which has been fixed. Update: don't write to runcntl on spu_run_init: SPU is already running. Update: do spu_setup_isolated earlier Tested on systemsim. Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 35 ++++++--- arch/powerpc/platforms/cell/spufs/inode.c | 117 ++++++++++++++++++++++++++++++ arch/powerpc/platforms/cell/spufs/run.c | 12 +-- 3 files changed, 148 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index f6c94087db4..d78b0af038e 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -89,7 +89,30 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) printk("%s: invalid access during switch!\n", __func__); return 1; } - if (!mm || (REGION_ID(ea) != USER_REGION_ID)) { + esid = (ea & ESID_MASK) | SLB_ESID_V; + + switch(REGION_ID(ea)) { + case USER_REGION_ID: +#ifdef CONFIG_HUGETLB_PAGE + if (in_hugepage_area(mm->context, ea)) + llp = mmu_psize_defs[mmu_huge_psize].sllp; + else +#endif + llp = mmu_psize_defs[mmu_virtual_psize].sllp; + vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | + SLB_VSID_USER | llp; + break; + case VMALLOC_REGION_ID: + llp = mmu_psize_defs[mmu_virtual_psize].sllp; + vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | + SLB_VSID_KERNEL | llp; + break; + case KERNEL_REGION_ID: + llp = mmu_psize_defs[mmu_linear_psize].sllp; + vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | + SLB_VSID_KERNEL | llp; + break; + default: /* Future: support kernel segments so that drivers * can use SPUs. */ @@ -97,16 +120,6 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) return 1; } - esid = (ea & ESID_MASK) | SLB_ESID_V; -#ifdef CONFIG_HUGETLB_PAGE - if (in_hugepage_area(mm->context, ea)) - llp = mmu_psize_defs[mmu_huge_psize].sllp; - else -#endif - llp = mmu_psize_defs[mmu_virtual_psize].sllp; - vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | - SLB_VSID_USER | llp; - out_be64(&priv2->slb_index_W, spu->slb_replace); out_be64(&priv2->slb_vsid_RW, vsid); out_be64(&priv2->slb_esid_RW, esid); diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 787ae71a685..c8751936672 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -33,6 +33,8 @@ #include #include +#include +#include #include #include #include @@ -41,6 +43,7 @@ #include "spufs.h" static kmem_cache_t *spufs_inode_cache; +static char *isolated_loader; static struct inode * spufs_alloc_inode(struct super_block *sb) @@ -232,6 +235,89 @@ struct file_operations spufs_context_fops = { .fsync = simple_sync_file, }; +static int spu_setup_isolated(struct spu_context *ctx) +{ + int ret; + u64 __iomem *mfc_cntl; + u64 sr1; + u32 status; + unsigned long timeout; + const u32 status_loading = SPU_STATUS_RUNNING + | SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS; + + if (!isolated_loader) + return -ENODEV; + + if ((ret = spu_acquire_runnable(ctx)) != 0) + return ret; + + mfc_cntl = &ctx->spu->priv2->mfc_control_RW; + + /* purge the MFC DMA queue to ensure no spurious accesses before we + * enter kernel mode */ + timeout = jiffies + HZ; + out_be64(mfc_cntl, MFC_CNTL_PURGE_DMA_REQUEST); + while ((in_be64(mfc_cntl) & MFC_CNTL_PURGE_DMA_STATUS_MASK) + != MFC_CNTL_PURGE_DMA_COMPLETE) { + if (time_after(jiffies, timeout)) { + printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n", + __FUNCTION__); + ret = -EIO; + goto out_unlock; + } + cond_resched(); + } + + /* put the SPE in kernel mode to allow access to the loader */ + sr1 = spu_mfc_sr1_get(ctx->spu); + sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK; + spu_mfc_sr1_set(ctx->spu, sr1); + + /* start the loader */ + ctx->ops->signal1_write(ctx, (unsigned long)isolated_loader >> 32); + ctx->ops->signal2_write(ctx, + (unsigned long)isolated_loader & 0xffffffff); + + ctx->ops->runcntl_write(ctx, + SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); + + ret = 0; + timeout = jiffies + HZ; + while (((status = ctx->ops->status_read(ctx)) & status_loading) == + status_loading) { + if (time_after(jiffies, timeout)) { + printk(KERN_ERR "%s: timeout waiting for loader\n", + __FUNCTION__); + ret = -EIO; + goto out_drop_priv; + } + cond_resched(); + } + + if (!(status & SPU_STATUS_RUNNING)) { + /* If isolated LOAD has failed: run SPU, we will get a stop-and + * signal later. */ + pr_debug("%s: isolated LOAD failed\n", __FUNCTION__); + ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); + ret = -EACCES; + + } else if (!(status & SPU_STATUS_ISOLATED_STATE)) { + /* This isn't allowed by the CBEA, but check anyway */ + pr_debug("%s: SPU fell out of isolated mode?\n", __FUNCTION__); + ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_STOP); + ret = -EINVAL; + } + +out_drop_priv: + /* Finished accessing the loader. Drop kernel mode */ + sr1 |= MFC_STATE1_PROBLEM_STATE_MASK; + spu_mfc_sr1_set(ctx->spu, sr1); + +out_unlock: + up_write(&ctx->state_sema); + return ret; +} + static int spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, int mode) @@ -255,6 +341,11 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, goto out_iput; ctx->flags = flags; + if (flags & SPU_CREATE_ISOLATE) { + ret = spu_setup_isolated(ctx); + if (ret) + goto out_iput; + } inode->i_op = &spufs_dir_inode_operations; inode->i_fop = &simple_dir_operations; @@ -555,6 +646,30 @@ spufs_parse_options(char *options, struct inode *root) return 1; } +static void +spufs_init_isolated_loader(void) +{ + struct device_node *dn; + const char *loader; + int size; + + dn = of_find_node_by_path("/spu-isolation"); + if (!dn) + return; + + loader = get_property(dn, "loader", &size); + if (!loader) + return; + + /* kmalloc should align on a 16 byte boundary..* */ + isolated_loader = kmalloc(size, GFP_KERNEL); + if (!isolated_loader) + return; + + memcpy(isolated_loader, loader, size); + printk(KERN_INFO "spufs: SPU isolation mode enabled\n"); +} + static int spufs_create_root(struct super_block *sb, void *data) { @@ -640,6 +755,8 @@ static int __init spufs_init(void) ret = register_spu_syscalls(&spufs_calls); if (ret) goto out_fs; + + spufs_init_isolated_loader(); return 0; out_fs: unregister_filesystem(&spufs_type); diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 0c03a04b6a3..a4a0080c223 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -1,3 +1,5 @@ +#define DEBUG + #include #include @@ -56,12 +58,12 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc) if ((ret = spu_acquire_runnable(ctx)) != 0) return ret; - if (ctx->flags & SPU_CREATE_ISOLATE) - runcntl |= SPU_RUNCNTL_ISOLATE; - else + /* if we're in isolated mode, we would have started the SPU + * earlier, so don't do it again now. */ + if (!(ctx->flags & SPU_CREATE_ISOLATE)) { ctx->ops->npc_write(ctx, *npc); - - ctx->ops->runcntl_write(ctx, runcntl); + ctx->ops->runcntl_write(ctx, runcntl); + } return 0; } -- cgit v1.2.3 From 099814bb1f9bd9081d7c85867f8eb8c049abc1b9 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 24 Oct 2006 18:31:19 +0200 Subject: [POWERPC] spufs: Add isolated-mode SPE recycling support When in isolated mode, SPEs have access to an area of persistent storage, which is per-SPE. In order for isolated-mode apps to communicate arbitrary data through this storage, we need to ensure that isolated physical SPEs can be reused for subsequent applications. Add a file ("recycle") in a spethread dir to enable isolated-mode recycling. By writing to this file, the kernel will reload the isolated-mode loader kernel, allowing a new app to be run on the same physical SPE. This requires the spu_acquire_exclusive function to enforce exclusive access to the SPE while the loader is initialised. Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/context.c | 27 ++++++++++++++++++++++++ arch/powerpc/platforms/cell/spufs/file.c | 32 +++++++++++++++++++++++++++++ arch/powerpc/platforms/cell/spufs/inode.c | 23 +++++++++++++-------- arch/powerpc/platforms/cell/spufs/spufs.h | 7 +++++++ 4 files changed, 81 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 034cf6af53a..48eb050bcf4 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -120,6 +120,33 @@ void spu_unmap_mappings(struct spu_context *ctx) unmap_mapping_range(ctx->signal2, 0, 0x4000, 1); } +int spu_acquire_exclusive(struct spu_context *ctx) +{ + int ret = 0; + + down_write(&ctx->state_sema); + /* ctx is about to be freed, can't acquire any more */ + if (!ctx->owner) { + ret = -EINVAL; + goto out; + } + + if (ctx->state == SPU_STATE_SAVED) { + ret = spu_activate(ctx, 0); + if (ret) + goto out; + ctx->state = SPU_STATE_RUNNABLE; + } else { + /* We need to exclude userspace access to the context. */ + spu_unmap_mappings(ctx); + } + +out: + if (ret) + up_write(&ctx->state_sema); + return ret; +} + int spu_acquire_runnable(struct spu_context *ctx) { int ret = 0; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 8ca330671ad..5b8ba6c3aa3 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1343,6 +1343,37 @@ static struct file_operations spufs_mfc_fops = { .mmap = spufs_mfc_mmap, }; + +static int spufs_recycle_open(struct inode *inode, struct file *file) +{ + file->private_data = SPUFS_I(inode)->i_ctx; + return nonseekable_open(inode, file); +} + +static ssize_t spufs_recycle_write(struct file *file, + const char __user *buffer, size_t size, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int ret; + + if (!(ctx->flags & SPU_CREATE_ISOLATE)) + return -EINVAL; + + if (size < 1) + return -EINVAL; + + ret = spu_recycle_isolated(ctx); + + if (ret) + return ret; + return size; +} + +static struct file_operations spufs_recycle_fops = { + .open = spufs_recycle_open, + .write = spufs_recycle_write, +}; + static void spufs_npc_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1551,5 +1582,6 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "psmap", &spufs_psmap_fops, 0666, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, + { "recycle", &spufs_recycle_fops, 0222, }, {}, }; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index c8751936672..9e457be140e 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -248,7 +248,7 @@ static int spu_setup_isolated(struct spu_context *ctx) if (!isolated_loader) return -ENODEV; - if ((ret = spu_acquire_runnable(ctx)) != 0) + if ((ret = spu_acquire_exclusive(ctx)) != 0) return ret; mfc_cntl = &ctx->spu->priv2->mfc_control_RW; @@ -314,10 +314,16 @@ out_drop_priv: spu_mfc_sr1_set(ctx->spu, sr1); out_unlock: - up_write(&ctx->state_sema); + spu_release_exclusive(ctx); return ret; } +int spu_recycle_isolated(struct spu_context *ctx) +{ + ctx->ops->runcntl_stop(ctx); + return spu_setup_isolated(ctx); +} + static int spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, int mode) @@ -341,12 +347,6 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, goto out_iput; ctx->flags = flags; - if (flags & SPU_CREATE_ISOLATE) { - ret = spu_setup_isolated(ctx); - if (ret) - goto out_iput; - } - inode->i_op = &spufs_dir_inode_operations; inode->i_fop = &simple_dir_operations; if (flags & SPU_CREATE_NOSCHED) @@ -432,6 +432,13 @@ static int spufs_create_context(struct inode *inode, out_unlock: mutex_unlock(&inode->i_mutex); out: + if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) { + int setup_err = spu_setup_isolated( + SPUFS_I(dentry->d_inode)->i_ctx); + if (setup_err) + ret = setup_err; + } + dput(dentry); return ret; } diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index b17b809ecd7..f438f0b8525 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -163,6 +163,12 @@ void spu_acquire(struct spu_context *ctx); void spu_release(struct spu_context *ctx); int spu_acquire_runnable(struct spu_context *ctx); void spu_acquire_saved(struct spu_context *ctx); +int spu_acquire_exclusive(struct spu_context *ctx); + +static inline void spu_release_exclusive(struct spu_context *ctx) +{ + up_write(&ctx->state_sema); +} int spu_activate(struct spu_context *ctx, u64 flags); void spu_deactivate(struct spu_context *ctx); @@ -170,6 +176,7 @@ void spu_yield(struct spu_context *ctx); int __init spu_sched_init(void); void __exit spu_sched_exit(void); +int spu_recycle_isolated(struct spu_context *ctx); /* * spufs_wait * Same as wait_event_interruptible(), except that here -- cgit v1.2.3 From 22b8c9f5baeb440a716ea760ff05290221565b4c Mon Sep 17 00:00:00 2001 From: David Erb Date: Tue, 24 Oct 2006 18:31:20 +0200 Subject: [POWERPC] cell: update Cell BE register definitions There are a few definitions that are required by subsequent patches, so add them here. The original patch is from David Erb, but is significantly cleaned up by Kevon Corry. Cc: Kevin Corry Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_regs.c | 44 ++++++++- arch/powerpc/platforms/cell/cbe_regs.h | 161 +++++++++++++++++++++++++------- arch/powerpc/platforms/cell/pervasive.c | 6 +- 3 files changed, 170 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index 2f194ba2989..5e3e0e925e4 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -16,8 +17,6 @@ #include "cbe_regs.h" -#define MAX_CBE 2 - /* * Current implementation uses "cpu" nodes. We build our own mapping * array of cpu numbers to cpu nodes locally for now to allow interrupt @@ -30,6 +29,7 @@ static struct cbe_regs_map struct device_node *cpu_node; struct cbe_pmd_regs __iomem *pmd_regs; struct cbe_iic_regs __iomem *iic_regs; + struct cbe_mic_tm_regs __iomem *mic_tm_regs; } cbe_regs_maps[MAX_CBE]; static int cbe_regs_map_count; @@ -42,6 +42,19 @@ static struct cbe_thread_map static struct cbe_regs_map *cbe_find_map(struct device_node *np) { int i; + struct device_node *tmp_np; + + if (strcasecmp(np->type, "spe") == 0) { + if (np->data == NULL) { + /* walk up path until cpu node was found */ + tmp_np = np->parent; + while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0) + tmp_np = tmp_np->parent; + + np->data = cbe_find_map(tmp_np); + } + return np->data; + } for (i = 0; i < cbe_regs_map_count; i++) if (cbe_regs_maps[i].cpu_node == np) @@ -56,6 +69,7 @@ struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) return NULL; return map->pmd_regs; } +EXPORT_SYMBOL_GPL(cbe_get_pmd_regs); struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) { @@ -64,7 +78,7 @@ struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) return NULL; return map->pmd_regs; } - +EXPORT_SYMBOL_GPL(cbe_get_cpu_pmd_regs); struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) { @@ -73,6 +87,7 @@ struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) return NULL; return map->iic_regs; } + struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) { struct cbe_regs_map *map = cbe_thread_map[cpu].regs; @@ -81,6 +96,24 @@ struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) return map->iic_regs; } +struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np) +{ + struct cbe_regs_map *map = cbe_find_map(np); + if (map == NULL) + return NULL; + return map->mic_tm_regs; +} + +struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu) +{ + struct cbe_regs_map *map = cbe_thread_map[cpu].regs; + if (map == NULL) + return NULL; + return map->mic_tm_regs; +} +EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs); + + void __init cbe_regs_init(void) { int i; @@ -119,6 +152,11 @@ void __init cbe_regs_init(void) prop = get_property(cpu, "iic", NULL); if (prop != NULL) map->iic_regs = ioremap(prop->address, prop->len); + + prop = (struct address_prop *)get_property(cpu, "mic-tm", + NULL); + if (prop != NULL) + map->mic_tm_regs = ioremap(prop->address, prop->len); } } diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index e76e4a6af5b..02bdbc1cd6e 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -4,6 +4,11 @@ * This file is intended to hold the various register definitions for CBE * on-chip system devices (memory controller, IO controller, etc...) * + * (C) Copyright IBM Corporation 2001,2006 + * + * Authors: Maximino Aguilar (maguilar@us.ibm.com) + * David J. Erb (djerb@us.ibm.com) + * * (c) 2006 Benjamin Herrenschmidt , IBM Corp. */ @@ -22,6 +27,7 @@ #define HID0_CBE_THERM_INT_EN 0x0000000400000000ul #define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul +#define MAX_CBE 2 /* * @@ -29,45 +35,86 @@ * */ +union spe_reg { + u64 val; + u8 spe[8]; +}; + +union ppe_spe_reg { + u64 val; + struct { + u32 ppe; + u32 spe; + }; +}; + + struct cbe_pmd_regs { - u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ + /* Debug Bus Control */ + u64 pad_0x0000; /* 0x0000 */ + + u64 group_control; /* 0x0008 */ + + u8 pad_0x0010_0x00a8 [0x00a8 - 0x0010]; /* 0x0010 */ + + u64 debug_bus_control; /* 0x00a8 */ + + u8 pad_0x00b0_0x0100 [0x0100 - 0x00b0]; /* 0x00b0 */ + + u64 trace_aux_data; /* 0x0100 */ + u64 trace_buffer_0_63; /* 0x0108 */ + u64 trace_buffer_64_127; /* 0x0110 */ + u64 trace_address; /* 0x0118 */ + u64 ext_tr_timer; /* 0x0120 */ + + u8 pad_0x0128_0x0400 [0x0400 - 0x0128]; /* 0x0128 */ + + /* Performance Monitor */ + u64 pm_status; /* 0x0400 */ + u64 pm_control; /* 0x0408 */ + u64 pm_interval; /* 0x0410 */ + u64 pm_ctr[4]; /* 0x0418 */ + u64 pm_start_stop; /* 0x0438 */ + u64 pm07_control[8]; /* 0x0440 */ + + u8 pad_0x0480_0x0800 [0x0800 - 0x0480]; /* 0x0480 */ /* Thermal Sensor Registers */ - u64 ts_ctsr1; /* 0x0800 */ - u64 ts_ctsr2; /* 0x0808 */ - u64 ts_mtsr1; /* 0x0810 */ - u64 ts_mtsr2; /* 0x0818 */ - u64 ts_itr1; /* 0x0820 */ - u64 ts_itr2; /* 0x0828 */ - u64 ts_gitr; /* 0x0830 */ - u64 ts_isr; /* 0x0838 */ - u64 ts_imr; /* 0x0840 */ - u64 tm_cr1; /* 0x0848 */ - u64 tm_cr2; /* 0x0850 */ - u64 tm_simr; /* 0x0858 */ - u64 tm_tpr; /* 0x0860 */ - u64 tm_str1; /* 0x0868 */ - u64 tm_str2; /* 0x0870 */ - u64 tm_tsr; /* 0x0878 */ + union spe_reg ts_ctsr1; /* 0x0800 */ + u64 ts_ctsr2; /* 0x0808 */ + union spe_reg ts_mtsr1; /* 0x0810 */ + u64 ts_mtsr2; /* 0x0818 */ + union spe_reg ts_itr1; /* 0x0820 */ + u64 ts_itr2; /* 0x0828 */ + u64 ts_gitr; /* 0x0830 */ + u64 ts_isr; /* 0x0838 */ + u64 ts_imr; /* 0x0840 */ + union spe_reg tm_cr1; /* 0x0848 */ + u64 tm_cr2; /* 0x0850 */ + u64 tm_simr; /* 0x0858 */ + union ppe_spe_reg tm_tpr; /* 0x0860 */ + union spe_reg tm_str1; /* 0x0868 */ + u64 tm_str2; /* 0x0870 */ + union ppe_spe_reg tm_tsr; /* 0x0878 */ /* Power Management */ - u64 pm_control; /* 0x0880 */ -#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000 - u64 pm_status; /* 0x0888 */ + u64 pmcr; /* 0x0880 */ +#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000 + u64 pmsr; /* 0x0888 */ /* Time Base Register */ - u64 tbr; /* 0x0890 */ + u64 tbr; /* 0x0890 */ - u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */ + u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */ /* Fault Isolation Registers */ - u64 checkstop_fir; /* 0x0c00 */ - u64 recoverable_fir; - u64 spec_att_mchk_fir; - u64 fir_mode_reg; - u64 fir_enable_mask; + u64 checkstop_fir; /* 0x0c00 */ + u64 recoverable_fir; /* 0x0c08 */ + u64 spec_att_mchk_fir; /* 0x0c10 */ + u64 fir_mode_reg; /* 0x0c18 */ + u64 fir_enable_mask; /* 0x0c20 */ - u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ + u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ }; extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); @@ -102,18 +149,20 @@ struct cbe_iic_regs { /* IIC interrupt registers */ struct cbe_iic_thread_regs thread[2]; /* 0x0400 */ - u64 iic_ir; /* 0x0440 */ - u64 iic_is; /* 0x0448 */ + + u64 iic_ir; /* 0x0440 */ + u64 iic_is; /* 0x0448 */ +#define CBE_IIC_IS_PMI 0x2 u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */ /* IOC FIR */ u64 ioc_fir_reset; /* 0x0500 */ - u64 ioc_fir_set; - u64 ioc_checkstop_enable; - u64 ioc_fir_error_mask; - u64 ioc_syserr_enable; - u64 ioc_fir; + u64 ioc_fir_set; /* 0x0508 */ + u64 ioc_checkstop_enable; /* 0x0510 */ + u64 ioc_fir_error_mask; /* 0x0518 */ + u64 ioc_syserr_enable; /* 0x0520 */ + u64 ioc_fir; /* 0x0528 */ u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */ }; @@ -122,6 +171,48 @@ extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np); extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu); +struct cbe_mic_tm_regs { + u8 pad_0x0000_0x0040[0x0040 - 0x0000]; /* 0x0000 */ + + u64 mic_ctl_cnfg2; /* 0x0040 */ +#define CBE_MIC_ENABLE_AUX_TRC 0x8000000000000000LL +#define CBE_MIC_DISABLE_PWR_SAV_2 0x0200000000000000LL +#define CBE_MIC_DISABLE_AUX_TRC_WRAP 0x0100000000000000LL +#define CBE_MIC_ENABLE_AUX_TRC_INT 0x0080000000000000LL + + u64 pad_0x0048; /* 0x0048 */ + + u64 mic_aux_trc_base; /* 0x0050 */ + u64 mic_aux_trc_max_addr; /* 0x0058 */ + u64 mic_aux_trc_cur_addr; /* 0x0060 */ + u64 mic_aux_trc_grf_addr; /* 0x0068 */ + u64 mic_aux_trc_grf_data; /* 0x0070 */ + + u64 pad_0x0078; /* 0x0078 */ + + u64 mic_ctl_cnfg_0; /* 0x0080 */ +#define CBE_MIC_DISABLE_PWR_SAV_0 0x8000000000000000LL + + u64 pad_0x0088; /* 0x0088 */ + + u64 slow_fast_timer_0; /* 0x0090 */ + u64 slow_next_timer_0; /* 0x0098 */ + + 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_0x1000[0x1000 - 0x01e0]; /* 0x01e0 */ +}; + +extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np); +extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu); + /* Init this module early */ extern void cbe_regs_init(void); diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 9f2e4ed20a5..fdcd89e99f1 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -54,9 +54,9 @@ static void __init cbe_enable_pause_zero(void) pr_debug("Power Management: CPU %d\n", smp_processor_id()); /* Enable Pause(0) control bit */ - temp_register = in_be64(&pregs->pm_control); + temp_register = in_be64(&pregs->pmcr); - out_be64(&pregs->pm_control, + out_be64(&pregs->pmcr, temp_register | CBE_PMD_PAUSE_ZERO_CONTROL); /* Enable DEC and EE interrupt request */ @@ -87,7 +87,7 @@ static void cbe_idle(void) unsigned long ctrl; /* Why do we do that on every idle ? Couldn't that be done once for - * all or do we lose the state some way ? Also, the pm_control + * all or do we lose the state some way ? Also, the pmcr * register setting, that can't be set once at boot ? We really want * to move that away in order to implement a simple powersave */ -- cgit v1.2.3 From bffd4927ba4377aa38be5450e20e0fecd2523fe3 Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Tue, 24 Oct 2006 18:31:21 +0200 Subject: [POWERPC] cell: add shadow registers for pmd_reg Many of the registers in the performance monitoring unit are write-only. We need to save a "shadow" copy when we write to those registers so we can retrieve the values if we need them later. The new cbe_pmd_shadow_regs structure is added to the cbe_regs_map structure so we have the appropriate per-node copies of these shadow values. Signed-off-by: Kevin Corry Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_regs.c | 17 +++++++++++++++++ arch/powerpc/platforms/cell/cbe_regs.h | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index 5e3e0e925e4..5a91b75c2f0 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c @@ -30,6 +30,7 @@ static struct cbe_regs_map struct cbe_pmd_regs __iomem *pmd_regs; struct cbe_iic_regs __iomem *iic_regs; struct cbe_mic_tm_regs __iomem *mic_tm_regs; + struct cbe_pmd_shadow_regs pmd_shadow_regs; } cbe_regs_maps[MAX_CBE]; static int cbe_regs_map_count; @@ -80,6 +81,22 @@ struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) } EXPORT_SYMBOL_GPL(cbe_get_cpu_pmd_regs); +struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np) +{ + struct cbe_regs_map *map = cbe_find_map(np); + if (map == NULL) + return NULL; + return &map->pmd_shadow_regs; +} + +struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu) +{ + struct cbe_regs_map *map = cbe_thread_map[cpu].regs; + if (map == NULL) + return NULL; + return &map->pmd_shadow_regs; +} + struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) { struct cbe_regs_map *map = cbe_find_map(np); diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index 02bdbc1cd6e..d352f110ef9 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -120,6 +120,41 @@ struct cbe_pmd_regs { extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu); +/* + * PMU shadow registers + * + * Many of the registers in the performance monitoring unit are write-only, + * so we need to save a copy of what we write to those registers. + * + * The actual data counters are read/write. However, writing to the counters + * only takes effect if the PMU is enabled. Otherwise the value is stored in + * a hardware latch until the next time the PMU is enabled. So we save a copy + * of the counter values if we need to read them back while the PMU is + * disabled. The counter_value_in_latch field is a bitmap indicating which + * counters currently have a value waiting to be written. + */ + +#define NR_PHYS_CTRS 4 +#define NR_CTRS (NR_PHYS_CTRS * 2) + +struct cbe_pmd_shadow_regs { + u32 group_control; + u32 debug_bus_control; + u32 trace_address; + u32 ext_tr_timer; + u32 pm_status; + u32 pm_control; + u32 pm_interval; + u32 pm_start_stop; + u32 pm07_control[NR_CTRS]; + + u32 pm_ctr[NR_PHYS_CTRS]; + u32 counter_value_in_latch; +}; + +extern struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np); +extern struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu); + /* * * IIC unit register definitions -- cgit v1.2.3 From d8bf96e0793f9576da545bac333b2de304958d68 Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Tue, 24 Oct 2006 18:31:22 +0200 Subject: [POWERPC] cell: add low-level performance monitoring code Add routines for accessing the registers and counters in the performance monitoring unit. Signed-off-by: Kevin Corry Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/Makefile | 3 +- arch/powerpc/platforms/cell/cbe_regs.h | 5 + arch/powerpc/platforms/cell/pmu.c | 328 +++++++++++++++++++++++++++++++++ arch/powerpc/platforms/cell/pmu.h | 57 ++++++ 4 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/cell/pmu.c create mode 100644 arch/powerpc/platforms/cell/pmu.h (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index c89cdd67383..412649b3529 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ - cbe_regs.o spider-pic.o pervasive.o + cbe_regs.o spider-pic.o pervasive.o \ + pmu.o obj-$(CONFIG_CBE_RAS) += ras.o ifeq ($(CONFIG_SMP),y) diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index d352f110ef9..91083f51a0c 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -35,6 +35,11 @@ * */ +/* Macros for the pm_control register. */ +#define CBE_PM_16BIT_CTR(ctr) (1 << (24 - ((ctr) & (NR_PHYS_CTRS - 1)))) +#define CBE_PM_ENABLE_PERF_MON 0x80000000 + + union spe_reg { u64 val; u8 spe[8]; diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c new file mode 100644 index 00000000000..30d17ce236a --- /dev/null +++ b/arch/powerpc/platforms/cell/pmu.c @@ -0,0 +1,328 @@ +/* + * Cell Broadband Engine Performance Monitor + * + * (C) Copyright IBM Corporation 2001,2006 + * + * Author: + * David Erb (djerb@us.ibm.com) + * Kevin Corry (kevcorry@us.ibm.com) + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include "cbe_regs.h" +#include "interrupt.h" +#include "pmu.h" + +/* + * When writing to write-only mmio addresses, save a shadow copy. All of the + * registers are 32-bit, but stored in the upper-half of a 64-bit field in + * pmd_regs. + */ + +#define WRITE_WO_MMIO(reg, x) \ + do { \ + u32 _x = (x); \ + struct cbe_pmd_regs __iomem *pmd_regs; \ + struct cbe_pmd_shadow_regs *shadow_regs; \ + pmd_regs = cbe_get_cpu_pmd_regs(cpu); \ + shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \ + out_be64(&(pmd_regs->reg), (((u64)_x) << 32)); \ + shadow_regs->reg = _x; \ + } while (0) + +#define READ_SHADOW_REG(val, reg) \ + do { \ + struct cbe_pmd_shadow_regs *shadow_regs; \ + shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \ + (val) = shadow_regs->reg; \ + } while (0) + +#define READ_MMIO_UPPER32(val, reg) \ + do { \ + struct cbe_pmd_regs __iomem *pmd_regs; \ + pmd_regs = cbe_get_cpu_pmd_regs(cpu); \ + (val) = (u32)(in_be64(&pmd_regs->reg) >> 32); \ + } while (0) + +/* + * Physical counter registers. + * Each physical counter can act as one 32-bit counter or two 16-bit counters. + */ + +u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr) +{ + u32 val_in_latch, val = 0; + + if (phys_ctr < NR_PHYS_CTRS) { + READ_SHADOW_REG(val_in_latch, counter_value_in_latch); + + /* Read the latch or the actual counter, whichever is newer. */ + if (val_in_latch & (1 << phys_ctr)) { + READ_SHADOW_REG(val, pm_ctr[phys_ctr]); + } else { + READ_MMIO_UPPER32(val, pm_ctr[phys_ctr]); + } + } + + return val; +} + +void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) +{ + struct cbe_pmd_shadow_regs *shadow_regs; + u32 pm_ctrl; + + if (phys_ctr < NR_PHYS_CTRS) { + /* Writing to a counter only writes to a hardware latch. + * The new value is not propagated to the actual counter + * until the performance monitor is enabled. + */ + WRITE_WO_MMIO(pm_ctr[phys_ctr], val); + + pm_ctrl = cbe_read_pm(cpu, pm_control); + if (pm_ctrl & CBE_PM_ENABLE_PERF_MON) { + /* The counters are already active, so we need to + * rewrite the pm_control register to "re-enable" + * the PMU. + */ + cbe_write_pm(cpu, pm_control, pm_ctrl); + } else { + shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); + shadow_regs->counter_value_in_latch |= (1 << phys_ctr); + } + } +} + +/* + * "Logical" counter registers. + * These will read/write 16-bits or 32-bits depending on the + * current size of the counter. Counters 4 - 7 are always 16-bit. + */ + +u32 cbe_read_ctr(u32 cpu, u32 ctr) +{ + u32 val; + u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1); + + val = cbe_read_phys_ctr(cpu, phys_ctr); + + if (cbe_get_ctr_size(cpu, phys_ctr) == 16) + val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff); + + return val; +} + +void cbe_write_ctr(u32 cpu, u32 ctr, u32 val) +{ + u32 phys_ctr; + u32 phys_val; + + phys_ctr = ctr & (NR_PHYS_CTRS - 1); + + if (cbe_get_ctr_size(cpu, phys_ctr) == 16) { + phys_val = cbe_read_phys_ctr(cpu, phys_ctr); + + if (ctr < NR_PHYS_CTRS) + val = (val << 16) | (phys_val & 0xffff); + else + val = (val & 0xffff) | (phys_val & 0xffff0000); + } + + cbe_write_phys_ctr(cpu, phys_ctr, val); +} + +/* + * Counter-control registers. + * Each "logical" counter has a corresponding control register. + */ + +u32 cbe_read_pm07_control(u32 cpu, u32 ctr) +{ + u32 pm07_control = 0; + + if (ctr < NR_CTRS) + READ_SHADOW_REG(pm07_control, pm07_control[ctr]); + + return pm07_control; +} + +void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val) +{ + if (ctr < NR_CTRS) + WRITE_WO_MMIO(pm07_control[ctr], val); +} + +/* + * Other PMU control registers. Most of these are write-only. + */ + +u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg) +{ + u32 val = 0; + + switch (reg) { + case group_control: + READ_SHADOW_REG(val, group_control); + break; + + case debug_bus_control: + READ_SHADOW_REG(val, debug_bus_control); + break; + + case trace_address: + READ_MMIO_UPPER32(val, trace_address); + break; + + case ext_tr_timer: + READ_SHADOW_REG(val, ext_tr_timer); + break; + + case pm_status: + READ_MMIO_UPPER32(val, pm_status); + break; + + case pm_control: + READ_SHADOW_REG(val, pm_control); + break; + + case pm_interval: + READ_SHADOW_REG(val, pm_interval); + break; + + case pm_start_stop: + READ_SHADOW_REG(val, pm_start_stop); + break; + } + + return val; +} + +void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) +{ + switch (reg) { + case group_control: + WRITE_WO_MMIO(group_control, val); + break; + + case debug_bus_control: + WRITE_WO_MMIO(debug_bus_control, val); + break; + + case trace_address: + WRITE_WO_MMIO(trace_address, val); + break; + + case ext_tr_timer: + WRITE_WO_MMIO(ext_tr_timer, val); + break; + + case pm_status: + WRITE_WO_MMIO(pm_status, val); + break; + + case pm_control: + WRITE_WO_MMIO(pm_control, val); + break; + + case pm_interval: + WRITE_WO_MMIO(pm_interval, val); + break; + + case pm_start_stop: + WRITE_WO_MMIO(pm_start_stop, val); + break; + } +} + +/* + * Get/set the size of a physical counter to either 16 or 32 bits. + */ + +u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr) +{ + u32 pm_ctrl, size = 0; + + if (phys_ctr < NR_PHYS_CTRS) { + pm_ctrl = cbe_read_pm(cpu, pm_control); + size = (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32; + } + + return size; +} + +void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) +{ + u32 pm_ctrl; + + if (phys_ctr < NR_PHYS_CTRS) { + pm_ctrl = cbe_read_pm(cpu, pm_control); + switch (ctr_size) { + case 16: + pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr); + break; + + case 32: + pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr); + break; + } + cbe_write_pm(cpu, pm_control, pm_ctrl); + } +} + +/* + * Enable/disable the entire performance monitoring unit. + * When we enable the PMU, all pending writes to counters get committed. + */ + +void cbe_enable_pm(u32 cpu) +{ + struct cbe_pmd_shadow_regs *shadow_regs; + u32 pm_ctrl; + + shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); + shadow_regs->counter_value_in_latch = 0; + + pm_ctrl = cbe_read_pm(cpu, pm_control) | CBE_PM_ENABLE_PERF_MON; + cbe_write_pm(cpu, pm_control, pm_ctrl); +} + +void cbe_disable_pm(u32 cpu) +{ + u32 pm_ctrl; + pm_ctrl = cbe_read_pm(cpu, pm_control) & ~CBE_PM_ENABLE_PERF_MON; + cbe_write_pm(cpu, pm_control, pm_ctrl); +} + +/* + * Reading from the trace_buffer. + * The trace buffer is two 64-bit registers. Reading from + * the second half automatically increments the trace_address. + */ + +void cbe_read_trace_buffer(u32 cpu, u64 *buf) +{ + struct cbe_pmd_regs __iomem *pmd_regs = cbe_get_cpu_pmd_regs(cpu); + + *buf++ = in_be64(&pmd_regs->trace_buffer_0_63); + *buf++ = in_be64(&pmd_regs->trace_buffer_64_127); +} + diff --git a/arch/powerpc/platforms/cell/pmu.h b/arch/powerpc/platforms/cell/pmu.h new file mode 100644 index 00000000000..eb1e8e0af91 --- /dev/null +++ b/arch/powerpc/platforms/cell/pmu.h @@ -0,0 +1,57 @@ +/* + * Cell Broadband Engine Performance Monitor + * + * (C) Copyright IBM Corporation 2001,2006 + * + * Author: + * David Erb (djerb@us.ibm.com) + * Kevin Corry (kevcorry@us.ibm.com) + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PERFMON_H__ +#define __PERFMON_H__ + +enum pm_reg_name { + group_control, + debug_bus_control, + trace_address, + ext_tr_timer, + pm_status, + pm_control, + pm_interval, + pm_start_stop, +}; + +extern u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr); +extern void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val); +extern u32 cbe_read_ctr(u32 cpu, u32 ctr); +extern void cbe_write_ctr(u32 cpu, u32 ctr, u32 val); + +extern u32 cbe_read_pm07_control(u32 cpu, u32 ctr); +extern void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val); +extern u32 cbe_read_pm (u32 cpu, enum pm_reg_name reg); +extern void cbe_write_pm (u32 cpu, enum pm_reg_name reg, u32 val); + +extern u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr); +extern void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size); + +extern void cbe_enable_pm(u32 cpu); +extern void cbe_disable_pm(u32 cpu); + +extern void cbe_read_trace_buffer(u32 cpu, u64 *buf); + +#endif -- cgit v1.2.3 From e570beb6bb1a623849901efbf939063ec4775c9e Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Tue, 24 Oct 2006 18:31:23 +0200 Subject: [POWERPC] cell: add support for registering sysfs attributes to spus In order to add sysfs attributes to all spu's, there is a need for a list of all available spu's. Adding the device_node makes also sense, as it is needed for proper register access. This patch also adds two functions to create and remove sysfs attributes and attribute_groups to all spus. That allows to group spu attributes in a subdirectory like: /sys/devices/system/spu/spuX/group_name/what_ever This will be used by cbe_thermal to group all attributes dealing with thermal support in one directory. Signed-off-by: Christian Krafft Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d78b0af038e..b75b091098e 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -333,6 +333,7 @@ static void spu_free_irqs(struct spu *spu) } static struct list_head spu_list[MAX_NUMNODES]; +static LIST_HEAD(spu_full_list); static DEFINE_MUTEX(spu_mutex); static void spu_init_channels(struct spu *spu) @@ -744,6 +745,57 @@ struct sysdev_class spu_sysdev_class = { set_kset_name("spu") }; +int spu_add_sysdev_attr(struct sysdev_attribute *attr) +{ + struct spu *spu; + mutex_lock(&spu_mutex); + + list_for_each_entry(spu, &spu_full_list, full_list) + sysdev_create_file(&spu->sysdev, attr); + + mutex_unlock(&spu_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(spu_add_sysdev_attr); + +int spu_add_sysdev_attr_group(struct attribute_group *attrs) +{ + struct spu *spu; + mutex_lock(&spu_mutex); + + list_for_each_entry(spu, &spu_full_list, full_list) + sysfs_create_group(&spu->sysdev.kobj, attrs); + + mutex_unlock(&spu_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group); + + +void spu_remove_sysdev_attr(struct sysdev_attribute *attr) +{ + struct spu *spu; + mutex_lock(&spu_mutex); + + list_for_each_entry(spu, &spu_full_list, full_list) + sysdev_remove_file(&spu->sysdev, attr); + + mutex_unlock(&spu_mutex); +} +EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr); + +void spu_remove_sysdev_attr_group(struct attribute_group *attrs) +{ + struct spu *spu; + mutex_lock(&spu_mutex); + + list_for_each_entry(spu, &spu_full_list, full_list) + sysfs_remove_group(&spu->sysdev.kobj, attrs); + + mutex_unlock(&spu_mutex); +} +EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr_group); + static int spu_create_sysdev(struct spu *spu) { int ret; @@ -817,6 +869,9 @@ static int __init create_spu(struct device_node *spe) goto out_free_irqs; list_add(&spu->list, &spu_list[spu->node]); + list_add(&spu->full_list, &spu_full_list); + spu->devnode = of_node_get(spe); + mutex_unlock(&spu_mutex); pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", @@ -839,6 +894,9 @@ out: static void destroy_spu(struct spu *spu) { list_del_init(&spu->list); + list_del_init(&spu->full_list); + + of_node_put(spu->devnode); spu_destroy_sysdev(spu); spu_free_irqs(spu); -- cgit v1.2.3 From 0344c6c5387ba335bba5a66fd44714b94c98573f Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Tue, 24 Oct 2006 18:31:24 +0200 Subject: [POWERPC] sysfs: add support for adding/removing spu sysfs attributes This patch adds two functions to create and remove sysfs attributes and attribute_group to all cpus. That allows to register sysfs attributes in a subdirectory like: /sys/devices/system/cpu/cpuX/group_name/what_ever This will be used by cbe_thermal to group all attributes dealing with thermal support in one directory. Signed-of-by: Christian Krafft Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/sysfs.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index d45a168bdac..cda21a27490 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -299,6 +299,72 @@ static struct notifier_block __cpuinitdata sysfs_cpu_nb = { .notifier_call = sysfs_cpu_notify, }; +static DEFINE_MUTEX(cpu_mutex); + +int cpu_add_sysdev_attr(struct sysdev_attribute *attr) +{ + int cpu; + + mutex_lock(&cpu_mutex); + + for_each_possible_cpu(cpu) { + sysdev_create_file(get_cpu_sysdev(cpu), attr); + } + + mutex_unlock(&cpu_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr); + +int cpu_add_sysdev_attr_group(struct attribute_group *attrs) +{ + int cpu; + struct sys_device *sysdev; + + mutex_lock(&cpu_mutex); + + for_each_possible_cpu(cpu) { + sysdev = get_cpu_sysdev(cpu); + sysfs_create_group(&sysdev->kobj, attrs); + } + + mutex_unlock(&cpu_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr_group); + + +void cpu_remove_sysdev_attr(struct sysdev_attribute *attr) +{ + int cpu; + + mutex_lock(&cpu_mutex); + + for_each_possible_cpu(cpu) { + sysdev_remove_file(get_cpu_sysdev(cpu), attr); + } + + mutex_unlock(&cpu_mutex); +} +EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr); + +void cpu_remove_sysdev_attr_group(struct attribute_group *attrs) +{ + int cpu; + struct sys_device *sysdev; + + mutex_lock(&cpu_mutex); + + for_each_possible_cpu(cpu) { + sysdev = get_cpu_sysdev(cpu); + sysfs_remove_group(&sysdev->kobj, attrs); + } + + mutex_unlock(&cpu_mutex); +} +EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr_group); + + /* NUMA stuff */ #ifdef CONFIG_NUMA -- cgit v1.2.3 From b3d7dc1967d1303d4897ff9537d29f6e077de147 Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Tue, 24 Oct 2006 18:31:25 +0200 Subject: [POWERPC] cell: add temperature to SPU and CPU sysfs entries This patch adds a module that registers sysfs attributes to CPU and SPU containing the temperature of the CBE. They can be found under /sys/devices/system/spu/cpuX/thermal/temperature[0|1] /sys/devices/system/spu/spuX/thermal/temperature The temperature is read from the on-chip temperature sensors. Signed-off-by: Christian Krafft Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/configs/cell_defconfig | 1 + arch/powerpc/platforms/cell/Kconfig | 5 + arch/powerpc/platforms/cell/Makefile | 2 + arch/powerpc/platforms/cell/cbe_thermal.c | 225 ++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 arch/powerpc/platforms/cell/cbe_thermal.c (limited to 'arch') diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 892d5dd3254..910a33193d9 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -149,6 +149,7 @@ CONFIG_MMIO_NVRAM=y CONFIG_SPU_FS=m CONFIG_SPU_BASE=y CONFIG_CBE_RAS=y +CONFIG_CBE_THERM=m # # Kernel options diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 3e430b489bb..77ae619c758 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -20,4 +20,9 @@ config CBE_RAS bool "RAS features for bare metal Cell BE" default y +config CBE_THERM + tristate "CBE thermal support" + default m + depends on CBE_RAS + endmenu diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 412649b3529..90e131451af 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -3,6 +3,8 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ pmu.o obj-$(CONFIG_CBE_RAS) += ras.o +obj-$(CONFIG_CBE_THERM) += cbe_thermal.o + ifeq ($(CONFIG_SMP),y) obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o endif diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c new file mode 100644 index 00000000000..17831a92d91 --- /dev/null +++ b/arch/powerpc/platforms/cell/cbe_thermal.c @@ -0,0 +1,225 @@ +/* + * thermal support for the cell processor + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Christian Krafft + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "cbe_regs.h" + +static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev) +{ + struct spu *spu; + + spu = container_of(sysdev, struct spu, sysdev); + + return cbe_get_pmd_regs(spu->devnode); +} + +/* returns the value for a given spu in a given register */ +static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iomem *reg) +{ + unsigned int *id; + union spe_reg value; + struct spu *spu; + + /* getting the id from the reg attribute will not work on future device-tree layouts + * in future we should store the id to the spu struct and use it here */ + spu = container_of(sysdev, struct spu, sysdev); + id = (unsigned int *)get_property(spu->devnode, "reg", NULL); + value.val = in_be64(®->val); + + return value.spe[*id]; +} + +static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf) +{ + int value; + struct cbe_pmd_regs __iomem *pmd_regs; + + pmd_regs = get_pmd_regs(sysdev); + + value = spu_read_register_value(sysdev, &pmd_regs->ts_ctsr1); + /* clear all other bits */ + value &= 0x3F; + /* temp is stored in steps of 2 degrees */ + value *= 2; + /* base temp is 65 degrees */ + value += 65; + + return sprintf(buf, "%d\n", (int) value); +} + +static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos) +{ + struct cbe_pmd_regs __iomem *pmd_regs; + u64 value; + + pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id); + value = in_be64(&pmd_regs->ts_ctsr2); + + /* access the corresponding byte */ + value >>= pos; + /* clear all other bits */ + value &= 0x3F; + /* temp is stored in steps of 2 degrees */ + value *= 2; + /* base temp is 65 degrees */ + value += 65; + + return sprintf(buf, "%d\n", (int) value); +} + + +/* shows the temperature of the DTS on the PPE, + * located near the linear thermal sensor */ +static ssize_t ppe_show_temp0(struct sys_device *sysdev, char *buf) +{ + return ppe_show_temp(sysdev, buf, 32); +} + +/* shows the temperature of the second DTS on the PPE */ +static ssize_t ppe_show_temp1(struct sys_device *sysdev, char *buf) +{ + return ppe_show_temp(sysdev, buf, 0); +} + +static struct sysdev_attribute attr_spu_temperature = { + .attr = {.name = "temperature", .mode = 0400 }, + .show = spu_show_temp, +}; + +static struct attribute *spu_attributes[] = { + &attr_spu_temperature.attr, +}; + +static struct attribute_group spu_attribute_group = { + .name = "thermal", + .attrs = spu_attributes, +}; + +static struct sysdev_attribute attr_ppe_temperature0 = { + .attr = {.name = "temperature0", .mode = 0400 }, + .show = ppe_show_temp0, +}; + +static struct sysdev_attribute attr_ppe_temperature1 = { + .attr = {.name = "temperature1", .mode = 0400 }, + .show = ppe_show_temp1, +}; + +static struct attribute *ppe_attributes[] = { + &attr_ppe_temperature0.attr, + &attr_ppe_temperature1.attr, +}; + +static struct attribute_group ppe_attribute_group = { + .name = "thermal", + .attrs = ppe_attributes, +}; + +/* + * initialize throttling with default values + */ +static void __init init_default_values(void) +{ + int cpu; + struct cbe_pmd_regs __iomem *pmd_regs; + struct sys_device *sysdev; + union ppe_spe_reg tpr; + union spe_reg str1; + u64 str2; + union spe_reg cr1; + u64 cr2; + + /* TPR defaults */ + /* ppe + * 1F - no full stop + * 08 - dynamic throttling starts if over 80 degrees + * 03 - dynamic throttling ceases if below 70 degrees */ + tpr.ppe = 0x1F0803; + /* spe + * 10 - full stopped when over 96 degrees + * 08 - dynamic throttling starts if over 80 degrees + * 03 - dynamic throttling ceases if below 70 degrees + */ + tpr.spe = 0x100803; + + /* STR defaults */ + /* str1 + * 10 - stop 16 of 32 cycles + */ + str1.val = 0x1010101010101010ull; + /* str2 + * 10 - stop 16 of 32 cycles + */ + str2 = 0x10; + + /* CR defaults */ + /* cr1 + * 4 - normal operation + */ + cr1.val = 0x0404040404040404ull; + /* cr2 + * 4 - normal operation + */ + cr2 = 0x04; + + for_each_possible_cpu (cpu) { + pr_debug("processing cpu %d\n", cpu); + sysdev = get_cpu_sysdev(cpu); + pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id); + + out_be64(&pmd_regs->tm_str2, str2); + out_be64(&pmd_regs->tm_str1.val, str1.val); + out_be64(&pmd_regs->tm_tpr.val, tpr.val); + out_be64(&pmd_regs->tm_cr1.val, cr1.val); + out_be64(&pmd_regs->tm_cr2, cr2); + } +} + + +static int __init thermal_init(void) +{ + init_default_values(); + + spu_add_sysdev_attr_group(&spu_attribute_group); + cpu_add_sysdev_attr_group(&ppe_attribute_group); + + return 0; +} +module_init(thermal_init); + +static void __exit thermal_exit(void) +{ + spu_remove_sysdev_attr_group(&spu_attribute_group); + cpu_remove_sysdev_attr_group(&ppe_attribute_group); +} +module_exit(thermal_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christian Krafft "); + -- cgit v1.2.3 From 302eca184fb844670fb128c69e22a8a28bbce48a Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 24 Oct 2006 18:31:26 +0200 Subject: [POWERPC] cell: use ppc_md->power_save instead of cbe_idle_loop This moves the cell idle function to use the default cpu_idle with a special power_save callback, like all other platforms except iSeries already do. It also makes it possible to disable this power_save function with a new powerpc-specific boot option "powersave=off". Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/idle.c | 7 +++ arch/powerpc/platforms/cell/pervasive.c | 96 ++++++++++----------------------- 2 files changed, 34 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index 4180c3998b3..8994af327b4 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c @@ -39,6 +39,13 @@ #define cpu_should_die() 0 #endif +static int __init powersave_off(char *arg) +{ + ppc_md.power_save = NULL; + return 0; +} +__setup("powersave=off", powersave_off); + /* * The body of the idle task. */ diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index fdcd89e99f1..c68fabdc787 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -38,32 +38,16 @@ #include "pervasive.h" #include "cbe_regs.h" -static DEFINE_SPINLOCK(cbe_pervasive_lock); - -static void __init cbe_enable_pause_zero(void) +static void cbe_power_save(void) { - unsigned long thread_switch_control; - unsigned long temp_register; - struct cbe_pmd_regs __iomem *pregs; - - spin_lock_irq(&cbe_pervasive_lock); - pregs = cbe_get_cpu_pmd_regs(smp_processor_id()); - if (pregs == NULL) - goto out; - - pr_debug("Power Management: CPU %d\n", smp_processor_id()); - - /* Enable Pause(0) control bit */ - temp_register = in_be64(&pregs->pmcr); - - out_be64(&pregs->pmcr, - temp_register | CBE_PMD_PAUSE_ZERO_CONTROL); + unsigned long ctrl, thread_switch_control; + ctrl = mfspr(SPRN_CTRLF); /* Enable DEC and EE interrupt request */ thread_switch_control = mfspr(SPRN_TSC_CELL); thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST; - switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { + switch (ctrl & CTRL_CT) { case CTRL_CT0: thread_switch_control |= TSC_CELL_DEC_ENABLE_0; break; @@ -75,58 +59,21 @@ static void __init cbe_enable_pause_zero(void) __FUNCTION__); break; } - mtspr(SPRN_TSC_CELL, thread_switch_control); -out: - spin_unlock_irq(&cbe_pervasive_lock); -} - -static void cbe_idle(void) -{ - unsigned long ctrl; - - /* Why do we do that on every idle ? Couldn't that be done once for - * all or do we lose the state some way ? Also, the pmcr - * register setting, that can't be set once at boot ? We really want - * to move that away in order to implement a simple powersave + /* + * go into low thread priority, medium priority will be + * restored for us after wake-up. */ - cbe_enable_pause_zero(); - - while (1) { - if (!need_resched()) { - local_irq_disable(); - while (!need_resched()) { - /* go into low thread priority */ - HMT_low(); - - /* - * atomically disable thread execution - * and runlatch. - * External and Decrementer exceptions - * are still handled when the thread - * is disabled but now enter in - * cbe_system_reset_exception() - */ - ctrl = mfspr(SPRN_CTRLF); - ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); - mtspr(SPRN_CTRLT, ctrl); - } - /* restore thread prio */ - HMT_medium(); - local_irq_enable(); - } + HMT_low(); - /* - * turn runlatch on again before scheduling the - * process we just woke up - */ - ppc64_runlatch_on(); - - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } + /* + * atomically disable thread execution and runlatch. + * External and Decrementer exceptions are still handled when the + * thread is disabled but now enter in cbe_system_reset_exception() + */ + ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); + mtspr(SPRN_CTRLT, ctrl); } static int cbe_system_reset_exception(struct pt_regs *regs) @@ -158,9 +105,20 @@ static int cbe_system_reset_exception(struct pt_regs *regs) void __init cbe_pervasive_init(void) { + int cpu; if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) return; - ppc_md.idle_loop = cbe_idle; + for_each_possible_cpu(cpu) { + struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu); + if (!regs) + continue; + + /* Enable Pause(0) control bit */ + out_be64(®s->pmcr, in_be64(®s->pmcr) | + CBE_PMD_PAUSE_ZERO_CONTROL); + } + + ppc_md.power_save = cbe_power_save; ppc_md.system_reset_exception = cbe_system_reset_exception; } -- cgit v1.2.3 From ff8a8f25976aa58bbae7883405b00dcbaf4cc823 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Oct 2006 18:31:27 +0200 Subject: [POWERPC] add support for stopping spus from xmon This patch adds support for stopping, and restarting, spus from xmon. We use the spu master runcntl bit to stop execution, this is apparently the "right" way to control spu execution and spufs will be changed in the future to use this bit. Testing has shown that to restart execution we have to turn the master runcntl bit on and also rewrite the spu runcntl bit, even if it is already set to 1 (running). Stopping spus is triggered by the xmon command 'ss' - "spus stop" perhaps. Restarting them is triggered via 'sr'. Restart doesn't start execution on spus unless they were running prior to being stopped by xmon. Walking the spu->full_list in xmon after a panic, would mean corruption of any spu struct would make all the others inaccessible. To avoid this, and also to make the next patch easier, we cache pointers to all spus during boot. We attempt to catch and recover from errors while stopping and restarting the spus, but as with most xmon functionality there are no guarantees that performing these operations won't crash xmon itself. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 4 + arch/powerpc/xmon/xmon.c | 142 ++++++++++++++++++++++++++++++++- 2 files changed, 144 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index b75b091098e..032bc923342 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "interrupt.h" @@ -943,6 +944,9 @@ static int __init init_spu_base(void) break; } } + + xmon_register_spus(&spu_full_list); + return ret; } module_init(init_spu_base); diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f56ffef4def..6a2ed8b319f 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #ifdef CONFIG_PPC64 #include @@ -147,6 +149,8 @@ static void xmon_print_symbol(unsigned long address, const char *mid, const char *after); static const char *getvecname(unsigned long vec); +static int do_spu_cmd(void); + int xmon_no_auto_backtrace; extern int print_insn_powerpc(unsigned long, unsigned long, int); @@ -209,8 +213,12 @@ Commands:\n\ mi show information about memory allocation\n\ p call a procedure\n\ r print registers\n\ - s single step\n\ - S print special registers\n\ + s single step\n" +#ifdef CONFIG_PPC_CELL +" ss stop execution on all spus\n\ + sr restore execution on stopped spus\n" +#endif +" S print special registers\n\ t print backtrace\n\ x exit monitor and recover\n\ X exit monitor and dont recover\n" @@ -518,6 +526,7 @@ int xmon(struct pt_regs *excp) xmon_save_regs(®s); excp = ®s; } + return xmon_core(excp, 0); } EXPORT_SYMBOL(xmon); @@ -809,6 +818,8 @@ cmds(struct pt_regs *excp) cacheflush(); break; case 's': + if (do_spu_cmd() == 0) + break; if (do_step(excp)) return cmd; break; @@ -2630,3 +2641,130 @@ void __init xmon_setup(void) if (xmon_early) debugger(NULL); } + +#ifdef CONFIG_PPC_CELL + +struct spu_info { + struct spu *spu; + u64 saved_mfc_sr1_RW; + u32 saved_spu_runcntl_RW; + u8 stopped_ok; +}; + +#define XMON_NUM_SPUS 16 /* Enough for current hardware */ + +static struct spu_info spu_info[XMON_NUM_SPUS]; + +void xmon_register_spus(struct list_head *list) +{ + struct spu *spu; + + list_for_each_entry(spu, list, full_list) { + if (spu->number >= XMON_NUM_SPUS) { + WARN_ON(1); + continue; + } + + spu_info[spu->number].spu = spu; + spu_info[spu->number].stopped_ok = 0; + } +} + +static void stop_spus(void) +{ + struct spu *spu; + int i; + u64 tmp; + + for (i = 0; i < XMON_NUM_SPUS; i++) { + if (!spu_info[i].spu) + continue; + + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + + spu = spu_info[i].spu; + + spu_info[i].saved_spu_runcntl_RW = + in_be32(&spu->problem->spu_runcntl_RW); + + tmp = spu_mfc_sr1_get(spu); + spu_info[i].saved_mfc_sr1_RW = tmp; + + tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; + spu_mfc_sr1_set(spu, tmp); + + sync(); + __delay(200); + + spu_info[i].stopped_ok = 1; + printf("Stopped spu %.2d\n", i); + } else { + catch_memory_errors = 0; + printf("*** Error stopping spu %.2d\n", i); + } + catch_memory_errors = 0; + } +} + +static void restart_spus(void) +{ + struct spu *spu; + int i; + + for (i = 0; i < XMON_NUM_SPUS; i++) { + if (!spu_info[i].spu) + continue; + + if (!spu_info[i].stopped_ok) { + printf("*** Error, spu %d was not successfully stopped" + ", not restarting\n", i); + continue; + } + + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + + spu = spu_info[i].spu; + spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW); + out_be32(&spu->problem->spu_runcntl_RW, + spu_info[i].saved_spu_runcntl_RW); + + sync(); + __delay(200); + + printf("Restarted spu %.2d\n", i); + } else { + catch_memory_errors = 0; + printf("*** Error restarting spu %.2d\n", i); + } + catch_memory_errors = 0; + } +} + +static int do_spu_cmd(void) +{ + int cmd; + + cmd = inchar(); + switch (cmd) { + case 's': + stop_spus(); + break; + case 'r': + restart_spus(); + break; + default: + return -1; + } + + return 0; +} +#else /* ! CONFIG_PPC_CELL */ +static int do_spu_cmd(void) +{ + return -1; +} +#endif -- cgit v1.2.3 From a898497088f46252e6750405504064e2dce53117 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 24 Oct 2006 18:31:28 +0200 Subject: [POWERPC] add support for dumping spu info from xmon This patch adds a command to xmon for dumping information about spu structs. The command is 'sf' for "spu fields" perhaps, and takes the spu number as an argument. This is the same value as the spu->number field, or the "phys-id" value of a context when it is bound to a physical spu. We try to catch memory errors as we dump each field, hopefully this will make the command reasonably robust, but YMMV. If people see a need we can easily add more fields to the dump in future. Output looks something like this: 0:mon> sf 0 Dumping spu fields at address c00000001ffd9e80: number = 0x0 name = spe devnode->full_name = /cpus/PowerPC,BE@0/spes/spe@0 nid = 0x0 local_store_phys = 0x20000000000 local_store = 0xd0000800801e0000 ls_size = 0x0 isrc = 0x4 node = 0x0 flags = 0x0 dar = 0x0 dsisr = 0x0 class_0_pending = 0 irqs[0] = 0x16 irqs[1] = 0x17 irqs[2] = 0x24 slb_replace = 0x0 pid = 0 prio = 0 mm = 0x0000000000000000 ctx = 0x0000000000000000 rq = 0x0000000000000000 timestamp = 0x0000000000000000 problem_phys = 0x20000040000 problem = 0xd000080080220000 problem->spu_runcntl_RW = 0x0 problem->spu_status_R = 0x0 problem->spu_npc_RW = 0x0 priv1 = 0xd000080080240000 priv1->mfc_sr1_RW = 0x33 priv2 = 0xd000080080250000 Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/xmon/xmon.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 6a2ed8b319f..0689c084577 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -216,7 +216,8 @@ Commands:\n\ s single step\n" #ifdef CONFIG_PPC_CELL " ss stop execution on all spus\n\ - sr restore execution on stopped spus\n" + sr restore execution on stopped spus\n\ + sf # dump spu fields for spu # (in hex)\n" #endif " S print special registers\n\ t print backtrace\n\ @@ -2744,8 +2745,66 @@ static void restart_spus(void) } } +#define DUMP_WIDTH 23 +#define DUMP_FIELD(obj, format, field) \ +do { \ + if (setjmp(bus_error_jmp) == 0) { \ + catch_memory_errors = 1; \ + sync(); \ + printf(" %-*s = "format"\n", DUMP_WIDTH, \ + #field, obj->field); \ + sync(); \ + __delay(200); \ + } else { \ + catch_memory_errors = 0; \ + printf(" %-*s = *** Error reading field.\n", \ + DUMP_WIDTH, #field); \ + } \ + catch_memory_errors = 0; \ +} while (0) + +static void dump_spu_fields(struct spu *spu) +{ + printf("Dumping spu fields at address %p:\n", spu); + + DUMP_FIELD(spu, "0x%x", number); + DUMP_FIELD(spu, "%s", name); + DUMP_FIELD(spu, "%s", devnode->full_name); + DUMP_FIELD(spu, "0x%x", nid); + DUMP_FIELD(spu, "0x%lx", local_store_phys); + DUMP_FIELD(spu, "0x%p", local_store); + DUMP_FIELD(spu, "0x%lx", ls_size); + DUMP_FIELD(spu, "0x%x", node); + DUMP_FIELD(spu, "0x%lx", flags); + DUMP_FIELD(spu, "0x%lx", dar); + DUMP_FIELD(spu, "0x%lx", dsisr); + DUMP_FIELD(spu, "%d", class_0_pending); + DUMP_FIELD(spu, "0x%lx", irqs[0]); + DUMP_FIELD(spu, "0x%lx", irqs[1]); + DUMP_FIELD(spu, "0x%lx", irqs[2]); + DUMP_FIELD(spu, "0x%x", slb_replace); + DUMP_FIELD(spu, "%d", pid); + DUMP_FIELD(spu, "%d", prio); + DUMP_FIELD(spu, "0x%p", mm); + DUMP_FIELD(spu, "0x%p", ctx); + DUMP_FIELD(spu, "0x%p", rq); + DUMP_FIELD(spu, "0x%p", timestamp); + DUMP_FIELD(spu, "0x%lx", problem_phys); + DUMP_FIELD(spu, "0x%p", problem); + DUMP_FIELD(spu, "0x%x", problem->spu_runcntl_RW); + DUMP_FIELD(spu, "0x%x", problem->spu_status_R); + DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW); + DUMP_FIELD(spu, "0x%p", priv1); + + if (spu->priv1) + DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW); + + DUMP_FIELD(spu, "0x%p", priv2); +} + static int do_spu_cmd(void) { + unsigned long num = 0; int cmd; cmd = inchar(); @@ -2756,6 +2815,12 @@ static int do_spu_cmd(void) case 'r': restart_spus(); break; + case 'f': + if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu) + dump_spu_fields(spu_info[num].spu); + else + printf("*** Error: invalid spu number\n"); + break; default: return -1; } -- cgit v1.2.3 From 36ca4ba4b9728f3c420a589a3322c2fbd7ec88b7 Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Tue, 24 Oct 2006 18:39:45 +0200 Subject: [POWERPC] cell: add cpufreq driver for Cell BE processor This patch adds a cpufreq backend driver to enable frequency scaling on cell. Signed-off-by: Christian Krafft Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/configs/cell_defconfig | 15 +- arch/powerpc/kernel/prom.c | 1 + arch/powerpc/kernel/smp.c | 1 + arch/powerpc/platforms/cell/Kconfig | 9 ++ arch/powerpc/platforms/cell/Makefile | 1 + arch/powerpc/platforms/cell/cbe_cpufreq.c | 248 ++++++++++++++++++++++++++++++ 6 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/cell/cbe_cpufreq.c (limited to 'arch') diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 910a33193d9..c5c54f49ae5 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -139,7 +139,19 @@ CONFIG_RTAS_FLASH=y CONFIG_MMIO_NVRAM=y # CONFIG_PPC_MPC106 is not set # CONFIG_PPC_970_NAP is not set -# CONFIG_CPU_FREQ is not set +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_DEBUG=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_PMAC64 is not set # CONFIG_WANT_EARLY_SERIAL is not set # CONFIG_MPIC is not set @@ -150,6 +162,7 @@ CONFIG_SPU_FS=m CONFIG_SPU_BASE=y CONFIG_CBE_RAS=y CONFIG_CBE_THERM=m +CONFIG_CBE_CPUFREQ=m # # Kernel options diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 865b9648d0d..f8e44c029d9 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -1672,6 +1672,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) } return NULL; } +EXPORT_SYMBOL(of_get_cpu_node); #ifdef DEBUG static struct debugfs_blob_wrapper flat_dt_blob; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 35c6309bdb7..9b28c238b6c 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -65,6 +65,7 @@ cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(cpu_possible_map); +EXPORT_SYMBOL(cpu_sibling_map); /* SMP operations for this machine */ struct smp_ops_t *smp_ops; diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 77ae619c758..06a85b70433 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig @@ -25,4 +25,13 @@ config CBE_THERM default m depends on CBE_RAS +config CBE_CPUFREQ + tristate "CBE frequency scaling" + depends on CBE_RAS && CPU_FREQ + default m + help + This adds the cpufreq driver for Cell BE processors. + For details, take a look at . + If you don't have such processor, say N + endmenu diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 90e131451af..0f31db7a50a 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ obj-$(CONFIG_CBE_RAS) += ras.o obj-$(CONFIG_CBE_THERM) += cbe_thermal.o +obj-$(CONFIG_CBE_CPUFREQ) += cbe_cpufreq.o ifeq ($(CONFIG_SMP),y) obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c new file mode 100644 index 00000000000..a3850fd1e94 --- /dev/null +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c @@ -0,0 +1,248 @@ +/* + * cpufreq driver for the cell processor + * + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 + * + * Author: Christian Krafft + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include "cbe_regs.h" + +static DEFINE_MUTEX(cbe_switch_mutex); + + +/* the CBE supports an 8 step frequency scaling */ +static struct cpufreq_frequency_table cbe_freqs[] = { + {1, 0}, + {2, 0}, + {3, 0}, + {4, 0}, + {5, 0}, + {6, 0}, + {8, 0}, + {10, 0}, + {0, CPUFREQ_TABLE_END}, +}; + +/* to write to MIC register */ +static u64 MIC_Slow_Fast_Timer_table[] = { + [0 ... 7] = 0x007fc00000000000ull, +}; + +/* more values for the MIC */ +static u64 MIC_Slow_Next_Timer_table[] = { + 0x0000240000000000ull, + 0x0000268000000000ull, + 0x000029C000000000ull, + 0x00002D0000000000ull, + 0x0000300000000000ull, + 0x0000334000000000ull, + 0x000039C000000000ull, + 0x00003FC000000000ull, +}; + +/* + * hardware specific functions + */ + +static int get_pmode(int cpu) +{ + int ret; + struct cbe_pmd_regs __iomem *pmd_regs; + + pmd_regs = cbe_get_cpu_pmd_regs(cpu); + ret = in_be64(&pmd_regs->pmsr) & 0x07; + + return ret; +} + +static int set_pmode(int cpu, unsigned int pmode) +{ + struct cbe_pmd_regs __iomem *pmd_regs; + struct cbe_mic_tm_regs __iomem *mic_tm_regs; + u64 flags; + u64 value; + + local_irq_save(flags); + + mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu); + pmd_regs = cbe_get_cpu_pmd_regs(cpu); + + pr_debug("pm register is mapped at %p\n", &pmd_regs->pmcr); + pr_debug("mic register is mapped at %p\n", &mic_tm_regs->slow_fast_timer_0); + + out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]); + out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]); + + out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]); + out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]); + + value = in_be64(&pmd_regs->pmcr); + /* set bits to zero */ + value &= 0xFFFFFFFFFFFFFFF8ull; + /* set bits to next pmode */ + value |= pmode; + + out_be64(&pmd_regs->pmcr, value); + + /* wait until new pmode appears in status register */ + value = in_be64(&pmd_regs->pmsr) & 0x07; + while(value != pmode) { + cpu_relax(); + value = in_be64(&pmd_regs->pmsr) & 0x07; + } + + local_irq_restore(flags); + + return 0; +} + +/* + * cpufreq functions + */ + +static int cbe_cpufreq_cpu_init (struct cpufreq_policy *policy) +{ + u32 *max_freq; + int i, cur_pmode; + struct device_node *cpu; + + cpu = of_get_cpu_node(policy->cpu, NULL); + + if(!cpu) + return -ENODEV; + + pr_debug("init cpufreq on CPU %d\n", policy->cpu); + + max_freq = (u32*) get_property(cpu, "clock-frequency", NULL); + + if(!max_freq) + return -EINVAL; + + // we need the freq in kHz + *max_freq /= 1000; + + pr_debug("max clock-frequency is at %u kHz\n", *max_freq); + pr_debug("initializing frequency table\n"); + + // initialize frequency table + for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) { + cbe_freqs[i].frequency = *max_freq / cbe_freqs[i].index; + pr_debug("%d: %d\n", i, cbe_freqs[i].frequency); + } + + policy->governor = CPUFREQ_DEFAULT_GOVERNOR; + /* if DEBUG is enabled set_pmode() measures the correct latency of a transition */ + policy->cpuinfo.transition_latency = 25000; + + cur_pmode = get_pmode(policy->cpu); + pr_debug("current pmode is at %d\n",cur_pmode); + + policy->cur = cbe_freqs[cur_pmode].frequency; + +#ifdef CONFIG_SMP + policy->cpus = cpu_sibling_map[policy->cpu]; +#endif + + cpufreq_frequency_table_get_attr (cbe_freqs, policy->cpu); + + /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ + return cpufreq_frequency_table_cpuinfo (policy, cbe_freqs); +} + +static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) +{ + cpufreq_frequency_table_put_attr(policy->cpu); + return 0; +} + +static int cbe_cpufreq_verify(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, cbe_freqs); +} + + +static int cbe_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, + unsigned int relation) +{ + int rc; + struct cpufreq_freqs freqs; + int cbe_pmode_new; + + cpufreq_frequency_table_target(policy, + cbe_freqs, + target_freq, + relation, + &cbe_pmode_new); + + freqs.old = policy->cur; + freqs.new = cbe_freqs[cbe_pmode_new].frequency; + freqs.cpu = policy->cpu; + + mutex_lock (&cbe_switch_mutex); + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n", + policy->cpu, + cbe_freqs[cbe_pmode_new].frequency, + cbe_freqs[cbe_pmode_new].index); + + rc = set_pmode(policy->cpu, cbe_pmode_new); + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + mutex_unlock(&cbe_switch_mutex); + + return rc; +} + +static struct cpufreq_driver cbe_cpufreq_driver = { + .verify = cbe_cpufreq_verify, + .target = cbe_cpufreq_target, + .init = cbe_cpufreq_cpu_init, + .exit = cbe_cpufreq_cpu_exit, + .name = "cbe-cpufreq", + .owner = THIS_MODULE, + .flags = CPUFREQ_CONST_LOOPS, +}; + +/* + * module init and destoy + */ + +static int __init cbe_cpufreq_init(void) +{ + return cpufreq_register_driver(&cbe_cpufreq_driver); +} + +static void __exit cbe_cpufreq_exit(void) +{ + cpufreq_unregister_driver(&cbe_cpufreq_driver); +} + +module_init(cbe_cpufreq_init); +module_exit(cbe_cpufreq_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Christian Krafft "); -- cgit v1.2.3 From 3a51237dc11efe283b40ea0248f4e26ab935dbd1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 24 Oct 2006 11:15:29 +0100 Subject: [PATCH] uml: mconsole fixes * when we have stop/sysrq/go, we get pt_regs of whatever executes mc_work_proc(). Would be better to see what we had at the time of interrupt that got us stop. * stop/stop/stop..... will give stack overflow. Shouldn't allow stop from mconsole_stop(). * stop/stop/go leaves us inside mconsole_stop() with os_set_fd_block(req->originating_fd, 0); reactivate_fd(req->originating_fd, MCONSOLE_IRQ); just done by nested mconsole_stop(). Ditto. * once we'd seen stop, there's a period when INTR commands are executed out of order (as they should; we might have the things stuck badly enough to never reach mconsole_stop(), but still not badly enough to block mconsole_interrupt(); in that situation we _want_ things like "cad" to be executed immediately). Once we enter monsole_stop(), all INTR commands will be executed in order, mixed with PROC ones. We'd better let user see that such change of behaviour has happened. (Suggested by lennert). * stack footprint of monsole_interrupt() is an atrocity; AFAICS we can safely make struct mc_request req; static in function there. Signed-off-by: Al Viro Acked-by: Jeff Dike Signed-off-by: Linus Torvalds --- arch/um/drivers/mconsole_kern.c | 23 +++++++++++++++++------ arch/um/drivers/mconsole_user.c | 1 + arch/um/include/mconsole.h | 1 + 3 files changed, 19 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index d08bd036ccb..7b172160fe0 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -79,7 +79,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) /* long to avoid size mismatch warnings from gcc */ long fd; struct mconsole_entry *new; - struct mc_request req; + static struct mc_request req; /* that's OK */ fd = (long) dev_id; while (mconsole_get_request(fd, &req)){ @@ -91,6 +91,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) mconsole_reply(&req, "Out of memory", 1, 0); else { new->request = req; + new->request.regs = get_irq_regs()->regs; list_add(&new->list, &mc_requests); } } @@ -314,9 +315,21 @@ void mconsole_stop(struct mc_request *req) { deactivate_fd(req->originating_fd, MCONSOLE_IRQ); os_set_fd_block(req->originating_fd, 1); - mconsole_reply(req, "", 0, 0); - while(mconsole_get_request(req->originating_fd, req)){ - if(req->cmd->handler == mconsole_go) break; + mconsole_reply(req, "stopped", 0, 0); + while (mconsole_get_request(req->originating_fd, req)) { + if (req->cmd->handler == mconsole_go) + break; + if (req->cmd->handler == mconsole_stop) { + mconsole_reply(req, "Already stopped", 1, 0); + continue; + } + if (req->cmd->handler == mconsole_sysrq) { + struct pt_regs *old_regs; + old_regs = set_irq_regs((struct pt_regs *)&req->regs); + mconsole_sysrq(req); + set_irq_regs(old_regs); + continue; + } (*req->cmd->handler)(req); } os_set_fd_block(req->originating_fd, 0); @@ -673,9 +686,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), static void sysrq_proc(void *arg) { char *op = arg; - struct pt_regs *old_regs = set_irq_regs(¤t->thread.regs); handle_sysrq(*op, NULL); - set_irq_regs(old_regs); } void mconsole_sysrq(struct mc_request *req) diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 17068eb746c..75aef6f7ef6 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c @@ -14,6 +14,7 @@ #include #include #include "user.h" +#include "sysdep/ptrace.h" #include "mconsole.h" #include "umid.h" #include "user_util.h" diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 58f67d39110..2666815b6af 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -61,6 +61,7 @@ struct mc_request struct mconsole_request request; struct mconsole_command *cmd; + union uml_pt_regs regs; }; extern char mconsole_socket_name[]; -- cgit v1.2.3 From 190a24f5605d95b786c92280bf7a51ebef43f29f Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 25 Oct 2006 17:32:40 -0500 Subject: [POWERPC] Make sure __cpu_preinit_ppc970 gets called on 970GX processors Add check for 970GX for __cpu_preinit_ppc970. Signed-off-by: Olof Johansson Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/head_64.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index f12e3c55520..291e3629b50 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -1641,6 +1641,8 @@ _GLOBAL(__start_initialization_multiplatform) cmpwi r0,0x3c /* 970FX */ beq 1f cmpwi r0,0x44 /* 970MP */ + beq 1f + cmpwi r0,0x45 /* 970GX */ bne 2f 1: bl .__cpu_preinit_ppc970 2: -- cgit v1.2.3 From 0430fb20a2a9f06262cb5ccc98869d54cdaa3963 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:39 +0200 Subject: [PATCH] AVR32: Minor Makefile cleanup Don't generate listing by default, remove unused LIBGCC variable and rename generated disassembly and listing files to vmlinux.{s,lst}. Also make sure that files generated during the build are actually removed with make clean. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/Makefile | 21 +++++++++++++-------- arch/avr32/boot/images/Makefile | 4 +--- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/avr32/Makefile b/arch/avr32/Makefile index cefc95a7398..7b842e98efe 100644 --- a/arch/avr32/Makefile +++ b/arch/avr32/Makefile @@ -7,7 +7,7 @@ # Default target when executing plain make .PHONY: all -all: uImage vmlinux.elf linux.lst +all: uImage vmlinux.elf KBUILD_DEFCONFIG := atstk1002_defconfig @@ -21,9 +21,7 @@ cpuflags-$(CONFIG_CPU_AP7000) += -mcpu=ap7000 CFLAGS += $(cpuflags-y) AFLAGS += $(cpuflags-y) -CHECKFLAGS += -D__avr32__ - -LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +CHECKFLAGS += -D__avr32__ -D__BIG_ENDIAN head-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/head.o head-y += arch/avr32/kernel/head.o @@ -32,7 +30,7 @@ core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/ core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/ core-y += arch/avr32/kernel/ core-y += arch/avr32/mm/ -libs-y += arch/avr32/lib/ #$(LIBGCC) +libs-y += arch/avr32/lib/ archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap @@ -48,6 +46,8 @@ endif archprepare: include/asm-avr32/.arch +CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch + BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec .PHONY: $(BOOT_TARGETS) install @@ -71,14 +71,19 @@ vmlinux.elf vmlinux.bin uImage.srec uImage vmlinux.cso: vmlinux install: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ -linux.s: vmlinux +vmlinux.s: vmlinux $(call if_changed,disasm) -linux.lst: vmlinux +vmlinux.lst: vmlinux $(call if_changed,listing) +CLEAN_FILES += vmlinux.s vmlinux.lst + +archclean: + $(Q)$(MAKE) $(clean)=$(boot) + define archhelp @echo '* vmlinux.elf - ELF image with load address 0' @echo ' vmlinux.cso - PathFinder CSO image' - @echo ' uImage - Create a bootable image for U-Boot' + @echo '* uImage - Create a bootable image for U-Boot' endef diff --git a/arch/avr32/boot/images/Makefile b/arch/avr32/boot/images/Makefile index ccd74eeecec..219720a47bf 100644 --- a/arch/avr32/boot/images/Makefile +++ b/arch/avr32/boot/images/Makefile @@ -37,14 +37,12 @@ OBJCOPYFLAGS_vmlinux.elf := --change-section-lma .text-0x80000000 \ --change-section-lma .data-0x80000000 \ --change-section-lma .init-0x80000000 \ --change-section-lma .bss-0x80000000 \ - --change-section-lma .initrd-0x80000000 \ --change-section-lma __param-0x80000000 \ --change-section-lma __ksymtab-0x80000000 \ --change-section-lma __ksymtab_gpl-0x80000000 \ --change-section-lma __kcrctab-0x80000000 \ --change-section-lma __kcrctab_gpl-0x80000000 \ --change-section-lma __ksymtab_strings-0x80000000 \ - --change-section-lma .got-0x80000000 \ --set-start 0xa0000000 $(obj)/vmlinux.elf: vmlinux FORCE $(call if_changed,objcopy) @@ -59,4 +57,4 @@ install: $(BOOTIMAGE) sh $(srctree)/install-kernel.sh $< # Generated files to be removed upon make clean -clean-files := vmlinux* uImage uImage.srec +clean-files := vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec -- cgit v1.2.3 From 6ea850b5eb17f6d21ac1b3d99406d213a10c64e9 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:40 +0200 Subject: [PATCH] AVR32: Silence some compile warnings Silence a few compile warnings which are basically harmless, but easy to fix. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/kernel/kprobes.c | 2 +- arch/avr32/kernel/module.c | 4 ++-- arch/avr32/kernel/ptrace.c | 2 +- arch/avr32/mm/init.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c index 6caf9e8d808..ca41fc1edbe 100644 --- a/arch/avr32/kernel/kprobes.c +++ b/arch/avr32/kernel/kprobes.c @@ -109,7 +109,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) void *addr = (void *)regs->pc; int ret = 0; - pr_debug("kprobe_handler: kprobe_running=%d\n", + pr_debug("kprobe_handler: kprobe_running=%p\n", kprobe_running()); /* diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c index dfc32f2817b..b599eae6457 100644 --- a/arch/avr32/kernel/module.c +++ b/arch/avr32/kernel/module.c @@ -263,7 +263,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, * value of PC. Just subtract the value of * GOT, and we're done. */ - pr_debug("GOTPC: PC=0x%lx, got_offset=0x%lx, core=0x%p\n", + pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n", relocation, module->arch.got_offset, module->module_core); relocation -= ((unsigned long)module->module_core @@ -282,7 +282,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, && (relocation & 0xffff0000) != 0xffff0000) return reloc_overflow(module, "R_AVR32_GOT16S", relocation); - pr_debug("GOT reloc @ 0x%lx -> %lu\n", + pr_debug("GOT reloc @ 0x%x -> %u\n", rel->r_offset, relocation); value = *location; value = ((value & 0xffff0000) diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c index 3c89e59029a..f2e81cd7900 100644 --- a/arch/avr32/kernel/ptrace.c +++ b/arch/avr32/kernel/ptrace.c @@ -157,7 +157,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned long tmp; int ret; - pr_debug("arch_ptrace(%ld, %ld, %#lx, %#lx)\n", + pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n", request, child->pid, addr, data); pr_debug("ptrace: Enabling monitor mode...\n"); diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 3e6c4103980..70da6894acc 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c @@ -206,7 +206,7 @@ void __init setup_bootmem(void) if (mem_ramdisk) { #ifdef CONFIG_BLK_DEV_INITRD - initrd_start = __va(mem_ramdisk->addr); + initrd_start = (unsigned long)__va(mem_ramdisk->addr); initrd_end = initrd_start + mem_ramdisk->size; print_memory_map("RAMDISK images", mem_ramdisk); -- cgit v1.2.3 From bee8ce809fb1c877388be032b468574a1cfff9ef Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:41 +0200 Subject: [PATCH] AVR32: Don't try to iounmap P2 segment addresses While ioremap() will happily map a physical address through the P2 (uncached) segment when appropriate, iounmap() doesn't know how to handle those mappings. This patch makes iounmap() do the right thing, i.e. nothing, for such mappings. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/mm/ioremap.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c index 8cfec65e37f..3437c82434a 100644 --- a/arch/avr32/mm/ioremap.c +++ b/arch/avr32/mm/ioremap.c @@ -77,6 +77,8 @@ void __iounmap(void __iomem *addr) if ((unsigned long)addr >= P4SEG) return; + if (PXSEG(addr) == P2SEG) + return; p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr)); if (unlikely(!p)) { -- cgit v1.2.3 From d68041cc9fde550fe6b6a6de1d7a110daff3cb60 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:44 +0200 Subject: [PATCH] AVR32: Implement and export __raw_{read,write}s[bwl] Implement __raw_readsb and __raw_writesb. Export __raw_reads[bwl] and __raw_writes[bwl] for use by modules. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/kernel/avr32_ksyms.c | 9 +++++++ arch/avr32/lib/Makefile | 1 + arch/avr32/lib/io-readsb.S | 47 +++++++++++++++++++++++++++++++++++++ arch/avr32/lib/io-writesb.S | 52 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 109 insertions(+) create mode 100644 arch/avr32/lib/io-readsb.S create mode 100644 arch/avr32/lib/io-writesb.S (limited to 'arch') diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index 04f767a272b..372e3f8b241 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include @@ -53,3 +54,11 @@ EXPORT_SYMBOL(find_next_zero_bit); EXPORT_SYMBOL(find_first_bit); EXPORT_SYMBOL(find_next_bit); EXPORT_SYMBOL(generic_find_next_zero_le_bit); + +/* I/O primitives (lib/io-*.S) */ +EXPORT_SYMBOL(__raw_readsb); +EXPORT_SYMBOL(__raw_readsw); +EXPORT_SYMBOL(__raw_readsl); +EXPORT_SYMBOL(__raw_writesb); +EXPORT_SYMBOL(__raw_writesw); +EXPORT_SYMBOL(__raw_writesl); diff --git a/arch/avr32/lib/Makefile b/arch/avr32/lib/Makefile index 09ac43e4052..084d95bac5e 100644 --- a/arch/avr32/lib/Makefile +++ b/arch/avr32/lib/Makefile @@ -7,4 +7,5 @@ lib-y += strncpy_from_user.o strnlen_user.o lib-y += delay.o memset.o memcpy.o findbit.o lib-y += csum_partial.o csum_partial_copy_generic.o lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o +lib-y += io-readsb.o io-writesb.o lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o diff --git a/arch/avr32/lib/io-readsb.S b/arch/avr32/lib/io-readsb.S new file mode 100644 index 00000000000..b319d5e7174 --- /dev/null +++ b/arch/avr32/lib/io-readsb.S @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + .text +.Lnot_word_aligned: +1: ld.ub r8, r12[0] + sub r10, 1 + st.b r11++, r8 + reteq r12 + tst r11, r9 + brne 1b + + /* fall through */ + + .global __raw_readsb + .type __raw_readsb,@function +__raw_readsb: + cp.w r10, 0 + mov r9, 3 + reteq r12 + + tst r11, r9 + brne .Lnot_word_aligned + + sub r10, 4 + brlt 2f + +1: ldins.b r8:t, r12[0] + ldins.b r8:u, r12[0] + ldins.b r8:l, r12[0] + ldins.b r8:b, r12[0] + st.w r11++, r8 + sub r10, 4 + brge 1b + +2: sub r10, -4 + reteq r12 + +3: ld.uh r8, r12[0] + sub r10, 1 + st.b r11++, r8 + brne 3b diff --git a/arch/avr32/lib/io-writesb.S b/arch/avr32/lib/io-writesb.S new file mode 100644 index 00000000000..b4ebaacccf6 --- /dev/null +++ b/arch/avr32/lib/io-writesb.S @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2004-2006 Atmel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + + .text +.Lnot_word_aligned: +1: ld.ub r8, r11++ + sub r10, 1 + st.b r12[0], r8 + reteq r12 + tst r11, r9 + brne 1b + + /* fall through */ + + .global __raw_writesb + .type __raw_writesb,@function +__raw_writesb: + cp.w r10, 0 + mov r9, 3 + reteq r12 + + tst r11, r9 + brne .Lnot_word_aligned + + sub r10, 4 + brlt 2f + +1: ld.w r8, r11++ + bfextu r9, r8, 24, 8 + st.b r12[0], r9 + bfextu r9, r8, 16, 8 + st.b r12[0], r9 + bfextu r9, r8, 8, 8 + st.b r12[0], r9 + st.b r12[0], r8 + sub r10, 4 + brge 1b + +2: sub r10, -4 + reteq r12 + +3: ld.ub r8, r11++ + sub r10, 1 + st.b r12[0], r8 + brne 3b + + retal r12 -- cgit v1.2.3 From 452976b29864f9adcdd6d4ea81001aa5483592c2 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:45 +0200 Subject: [PATCH] AVR32: Use __raw MMIO access for internal peripherals The read[bwl] and write[bwl] functions are meant for accessing PCI devices. How this is achieved on AVR32 is unknown, as there are no systems with a PCI bridge available yet. On-chip peripheral access, however, should not depend on how we end up implementing PCI access, so using __raw_read[bwl]/__raw_write[bwl] is the right thing to do for on-chip peripherals. This patch converts the drivers for the static memory controller, interrupt controller, PIO controller and system manager to use __raw MMIO access. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/mach-at32ap/hsmc.h | 4 ++-- arch/avr32/mach-at32ap/intc.h | 6 ++++-- arch/avr32/mach-at32ap/pio.h | 6 ++++-- arch/avr32/mach-at32ap/sm.h | 6 ++++-- 4 files changed, 14 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/hsmc.h b/arch/avr32/mach-at32ap/hsmc.h index 5681276fafd..d1d48e26e39 100644 --- a/arch/avr32/mach-at32ap/hsmc.h +++ b/arch/avr32/mach-at32ap/hsmc.h @@ -120,8 +120,8 @@ /* Register access macros */ #define hsmc_readl(port,reg) \ - readl((port)->regs + HSMC_##reg) + __raw_readl((port)->regs + HSMC_##reg) #define hsmc_writel(port,reg,value) \ - writel((value), (port)->regs + HSMC_##reg) + __raw_writel((value), (port)->regs + HSMC_##reg) #endif /* __ASM_AVR32_HSMC_H__ */ diff --git a/arch/avr32/mach-at32ap/intc.h b/arch/avr32/mach-at32ap/intc.h index d289ca2fff1..4d3664e43a8 100644 --- a/arch/avr32/mach-at32ap/intc.h +++ b/arch/avr32/mach-at32ap/intc.h @@ -321,7 +321,9 @@ #define INTC_MKBF(name, value) (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET) #define INTC_GETBF(name, value) (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1)) -#define intc_readl(port,reg) readl((port)->regs + INTC_##reg) -#define intc_writel(port,reg,value) writel((value), (port)->regs + INTC_##reg) +#define intc_readl(port,reg) \ + __raw_readl((port)->regs + INTC_##reg) +#define intc_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + INTC_##reg) #endif /* __ASM_AVR32_PERIHP_INTC_H__ */ diff --git a/arch/avr32/mach-at32ap/pio.h b/arch/avr32/mach-at32ap/pio.h index cfea1235159..50fa3aca32c 100644 --- a/arch/avr32/mach-at32ap/pio.h +++ b/arch/avr32/mach-at32ap/pio.h @@ -170,8 +170,10 @@ #define PIO_BFINS(name,value,old) (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value)) /* Register access macros */ -#define pio_readl(port,reg) readl((port)->regs + PIO_##reg) -#define pio_writel(port,reg,value) writel((value), (port)->regs + PIO_##reg) +#define pio_readl(port,reg) \ + __raw_readl((port)->regs + PIO_##reg) +#define pio_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + PIO_##reg) void at32_init_pio(struct platform_device *pdev); diff --git a/arch/avr32/mach-at32ap/sm.h b/arch/avr32/mach-at32ap/sm.h index 27565822ae2..cad02b512bc 100644 --- a/arch/avr32/mach-at32ap/sm.h +++ b/arch/avr32/mach-at32ap/sm.h @@ -234,7 +234,9 @@ #define SM_BFINS(name,value,old) (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value)) /* Register access macros */ -#define sm_readl(port,reg) readl((port)->regs + SM_##reg) -#define sm_writel(port,reg,value) writel((value), (port)->regs + SM_##reg) +#define sm_readl(port,reg) \ + __raw_readl((port)->regs + SM_##reg) +#define sm_writel(port,reg,value) \ + __raw_writel((value), (port)->regs + SM_##reg) #endif /* __ASM_AVR32_SM_H__ */ -- cgit v1.2.3 From 291b58d663862c3d42d2e8092f8b0dd3f15a94f8 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 24 Oct 2006 10:12:46 +0200 Subject: [PATCH] AVR32: Update defconfig Sync atstk1002_defconfig with latest git, turn off non-existent drivers and enable a few more userspace-visible options like SysV IPC and inotify support. Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/avr32/configs/atstk1002_defconfig | 253 +++++++++++++++++++++------------ 1 file changed, 159 insertions(+), 94 deletions(-) (limited to 'arch') diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig index 6c2c5e00dfc..ae92a14ef9a 100644 --- a/arch/avr32/configs/atstk1002_defconfig +++ b/arch/avr32/configs/atstk1002_defconfig @@ -1,13 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Tue Jul 11 12:41:36 2006 +# Linux kernel version: 2.6.19-rc2 +# Fri Oct 20 11:52:37 2006 # CONFIG_AVR32=y CONFIG_GENERIC_HARDIRQS=y CONFIG_HARDIRQS_SW_RESEND=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_TIME=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" @@ -25,16 +26,23 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y -# CONFIG_SYSVIPC is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_TASKSTATS=y +CONFIG_TASK_DELAY_ACCT=y +# CONFIG_UTS_NS is not set +CONFIG_AUDIT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set +CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_TASK_XACCT is not set +CONFIG_SYSCTL=y CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -43,14 +51,15 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y # CONFIG_BASE_FULL is not set -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set +CONFIG_FUTEX=y +CONFIG_EPOLL=y CONFIG_SHMEM=y -# CONFIG_SLAB is not set -# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=1 -CONFIG_SLOB=y +# CONFIG_SLOB is not set # # Loadable module support @@ -65,6 +74,7 @@ CONFIG_MODULE_UNLOAD=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -166,10 +176,12 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -199,7 +211,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -212,7 +223,6 @@ CONFIG_TCP_CONG_BIC=y # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -239,7 +249,84 @@ CONFIG_STANDALONE=y # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x8000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set # # Parallel port support @@ -260,10 +347,17 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -274,6 +368,12 @@ CONFIG_BLK_DEV_INITRD=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set # # Multi-device support (RAID and LVM) @@ -305,14 +405,11 @@ CONFIG_TUN=m # # PHY device support # -# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_MACB=y +# CONFIG_NET_ETHERNET is not set # # Ethernet (1000 Mbit) @@ -341,10 +438,11 @@ CONFIG_PPP=m CONFIG_PPP_ASYNC=m # CONFIG_PPP_SYNC_TTY is not set CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPP_BSDCOMP=m # CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set +CONFIG_SLHC=m # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set @@ -417,7 +515,6 @@ CONFIG_UNIX98_PTYS=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -427,23 +524,13 @@ CONFIG_UNIX98_PTYS=y # # SPI support # -CONFIG_SPI=y -# CONFIG_SPI_DEBUG is not set -CONFIG_SPI_MASTER=y - -# -# SPI Master Controller Drivers -# -CONFIG_SPI_ATMEL=m -# CONFIG_SPI_BITBANG is not set - -# -# SPI Protocol Masters -# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -451,15 +538,10 @@ CONFIG_SPI_ATMEL=m # CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# -# Misc devices -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -470,28 +552,8 @@ CONFIG_VIDEO_V4L2=y # Graphics support # # CONFIG_FIRMWARE_EDID is not set -CONFIG_FB=m -CONFIG_FB_CFB_FILLRECT=m -CONFIG_FB_CFB_COPYAREA=m -CONFIG_FB_CFB_IMAGEBLIT=m -# CONFIG_FB_MACMODES is not set -# CONFIG_FB_BACKLIGHT is not set -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_SIDSA=m -CONFIG_FB_SIDSA_DEFAULT_BPP=24 -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -CONFIG_BACKLIGHT_LCD_SUPPORT=y -# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -CONFIG_LCD_CLASS_DEVICE=m -CONFIG_LCD_DEVICE=y -CONFIG_LCD_LTV350QV=m +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -561,18 +623,21 @@ CONFIG_LCD_LTV350QV=m # # File systems # -CONFIG_EXT2_FS=y +CONFIG_EXT2_FS=m # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=m -CONFIG_ROMFS_FS=m -# CONFIG_INOTIFY is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set @@ -600,8 +665,10 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y CONFIG_CONFIGFS_FS=m @@ -616,6 +683,16 @@ CONFIG_CONFIGFS_FS=m # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set # CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set @@ -626,26 +703,10 @@ CONFIG_CONFIGFS_FS=m # # Network File Systems # -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFS_FS is not set # CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set -CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -665,7 +726,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_850 is not set # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -705,13 +766,17 @@ CONFIG_NLS_UTF8=m # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_PRINTK_TIME=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set @@ -722,11 +787,13 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y # CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set -CONFIG_KPROBES=y +# CONFIG_KPROBES is not set # # Security options @@ -739,16 +806,14 @@ CONFIG_KPROBES=y # # CONFIG_CRYPTO is not set -# -# Hardware crypto devices -# - # # Library routines # CONFIG_CRC_CCITT=m # CONFIG_CRC16 is not set -CONFIG_CRC32=m +CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m +CONFIG_AUDIT_GENERIC=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y -- cgit v1.2.3 From 4130a4b206e7c628482aa12ec30949382c8cdc5e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 25 Oct 2006 22:31:06 -0700 Subject: [SPARC64]: Fix central/FHC bus handling on Ex000 systems. 1) probe_other_fhcs() wants to see only non-central FHC busses, so skip FHCs that don't sit off the root 2) Like SBUS, FHC can lack the appropriate address and size cell count properties, so add an of_busses[] entry and handlers for that. 3) Central FHC irq translator probing was buggy. We were trying to use dp->child in irq_trans_init but that linkage is not setup at this point. So instead, pass in the parent of "dp" and look for the child "fhc" with parent "central". Thanks to the tireless assistence of Ben Collins in tracking down these problems and testing out these fixes. Signed-off-by: David S. Miller --- arch/sparc64/kernel/central.c | 4 ++++ arch/sparc64/kernel/of_device.c | 33 ++++++++++++++++++++++++--------- arch/sparc64/kernel/prom.c | 30 +++++++++++++++--------------- 3 files changed, 43 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c index b66336db00e..e724c54af02 100644 --- a/arch/sparc64/kernel/central.c +++ b/arch/sparc64/kernel/central.c @@ -126,6 +126,10 @@ static void probe_other_fhcs(void) int board; u32 tmp; + if (dp->parent && + dp->parent->parent != NULL) + continue; + fhc = (struct linux_fhc *) central_alloc_bootmem(sizeof(struct linux_fhc)); if (fhc == NULL) diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index d3dfb2a36d4..983ca5f485c 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -402,16 +402,22 @@ static void of_bus_sbus_count_cells(struct device_node *child, *sizec = 1; } -static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) -{ - return of_bus_default_map(addr, range, na, ns, pna); -} - -static unsigned int of_bus_sbus_get_flags(u32 *addr) +/* + * FHC/Central bus specific translator. + * + * This is just needed to hard-code the address and size cell + * counts. 'fhc' and 'central' nodes lack the #address-cells and + * #size-cells properties, and if you walk to the root on such + * Enterprise boxes all you'll get is a #size-cells of 2 which is + * not what we want to use. + */ +static int of_bus_fhc_match(struct device_node *np) { - return IORESOURCE_MEM; + return !strcmp(np->name, "fhc") || + !strcmp(np->name, "central"); } +#define of_bus_fhc_count_cells of_bus_sbus_count_cells /* * Array of bus specific translators @@ -433,8 +439,17 @@ static struct of_bus of_busses[] = { .addr_prop_name = "reg", .match = of_bus_sbus_match, .count_cells = of_bus_sbus_count_cells, - .map = of_bus_sbus_map, - .get_flags = of_bus_sbus_get_flags, + .map = of_bus_default_map, + .get_flags = of_bus_default_get_flags, + }, + /* FHC */ + { + .name = "fhc", + .addr_prop_name = "reg", + .match = of_bus_fhc_match, + .count_cells = of_bus_fhc_count_cells, + .map = of_bus_default_map, + .get_flags = of_bus_default_get_flags, }, /* Default */ { diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index e21cd6afa70..c60efb3cb22 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -1079,23 +1079,22 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp) static void irq_trans_init(struct device_node *dp) { - const char *model; #ifdef CONFIG_PCI + const char *model; int i; #endif +#ifdef CONFIG_PCI model = of_get_property(dp, "model", NULL); if (!model) model = of_get_property(dp, "compatible", NULL); - if (!model) - return; - -#ifdef CONFIG_PCI - for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { - struct irq_trans *t = &pci_irq_trans_table[i]; + if (model) { + for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) { + struct irq_trans *t = &pci_irq_trans_table[i]; - if (!strcmp(model, t->name)) - return t->init(dp); + if (!strcmp(model, t->name)) + return t->init(dp); + } } #endif #ifdef CONFIG_SBUS @@ -1103,8 +1102,9 @@ static void irq_trans_init(struct device_node *dp) !strcmp(dp->name, "sbi")) return sbus_irq_trans_init(dp); #endif - if (!strcmp(dp->name, "central")) - return central_irq_trans_init(dp->child); + if (!strcmp(dp->name, "fhc") && + !strcmp(dp->parent->name, "central")) + return central_irq_trans_init(dp); if (!strcmp(dp->name, "virtual-devices")) return sun4v_vdev_irq_trans_init(dp); } @@ -1516,7 +1516,7 @@ static char * __init get_one_property(phandle node, const char *name) return buf; } -static struct device_node * __init create_node(phandle node) +static struct device_node * __init create_node(phandle node, struct device_node *parent) { struct device_node *dp; @@ -1525,6 +1525,7 @@ static struct device_node * __init create_node(phandle node) dp = prom_early_alloc(sizeof(*dp)); dp->unique_id = unique_id++; + dp->parent = parent; kref_init(&dp->kref); @@ -1543,12 +1544,11 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl { struct device_node *dp; - dp = create_node(node); + dp = create_node(node, parent); if (dp) { *(*nextp) = dp; *nextp = &dp->allnext; - dp->parent = parent; dp->path_component_name = build_path_component(dp); dp->full_name = build_full_name(dp); @@ -1564,7 +1564,7 @@ void __init prom_build_devicetree(void) { struct device_node **nextp; - allnodes = create_node(prom_root_node); + allnodes = create_node(prom_root_node, NULL); allnodes->path_component_name = ""; allnodes->full_name = "/"; -- cgit v1.2.3 From 012d64ff68f304df1c35ce5902f5023dc14b643f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 25 Oct 2006 22:33:07 -0700 Subject: [SPARC64]: Fix memory corruption in pci_4u_free_consistent(). The second argument to free_npages() was being incorrectly calculated, which would thus access far past the end of the arena->map[] bitmap. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 82e5455134c..2e7f1427088 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -281,7 +281,7 @@ static void pci_4u_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, spin_lock_irqsave(&iommu->lock, flags); - free_npages(iommu, dvma, npages); + free_npages(iommu, dvma - iommu->page_table_map_base, npages); spin_unlock_irqrestore(&iommu->lock, flags); -- cgit v1.2.3 From f5ef9d11fd255b30b455d18f8d721bc44cd1296b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 27 Oct 2006 01:03:31 -0700 Subject: [SPARC]: Fix bus_id[] string overflow. dp->path_component_name can be larger than ->bus_id[] so use a different naming scheme for this stuff. Noticed by Jurij Smakov. Signed-off-by: David S. Miller --- arch/sparc/kernel/ebus.c | 8 ++++---- arch/sparc/kernel/of_device.c | 2 +- arch/sparc64/kernel/ebus.c | 8 ++++---- arch/sparc64/kernel/isa.c | 8 ++++---- arch/sparc64/kernel/of_device.c | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c index 75ac24d229b..ba58c3a061f 100644 --- a/arch/sparc/kernel/ebus.c +++ b/arch/sparc/kernel/ebus.c @@ -237,12 +237,12 @@ void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *d dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; - strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); + sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); /* Register with core */ if (of_device_register(&dev->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dev->ofdev.dev.bus_id); + dp->path_component_name); if ((dp = dp->child) != NULL) { dev->children = (struct linux_ebus_child *) @@ -332,12 +332,12 @@ void __init ebus_init(void) ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; ebus->ofdev.dev.bus = &ebus_bus_type; - strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); + sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); /* Register with core */ if (of_device_register(&ebus->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - ebus->ofdev.dev.bus_id); + dp->path_component_name); nd = dp->child; diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 74bef2a2d37..46200c43ffb 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -651,7 +651,7 @@ build_resources: if (!parent) strcpy(op->dev.bus_id, "root"); else - strcpy(op->dev.bus_id, dp->path_component_name); + sprintf(op->dev.bus_id, "%08x", dp->node); if (of_device_register(op)) { printk("%s: Could not register of device.\n", diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 2df25c2b407..35bf895fdee 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -389,12 +389,12 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de dev->ofdev.node = dp; dev->ofdev.dev.parent = &dev->bus->ofdev.dev; dev->ofdev.dev.bus = &ebus_bus_type; - strcpy(dev->ofdev.dev.bus_id, dp->path_component_name); + sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); /* Register with core */ if (of_device_register(&dev->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dev->ofdev.dev.bus_id); + dp->path_component_name); dp = dp->child; if (dp) { @@ -494,12 +494,12 @@ void __init ebus_init(void) ebus->ofdev.node = dp; ebus->ofdev.dev.parent = &pdev->dev; ebus->ofdev.dev.bus = &ebus_bus_type; - strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name); + sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); /* Register with core */ if (of_device_register(&ebus->ofdev) != 0) printk(KERN_DEBUG "ebus: device registration error for %s!\n", - ebus->ofdev.dev.bus_id); + dp->path_component_name); child = dp->child; diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index 0f3aec72ef5..f028e68b23f 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -115,12 +115,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; isa_dev->ofdev.dev.bus = &isa_bus_type; - strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name); + sprintf(isa_dev->ofdev.dev.bus_id, "isa[%08x]", dp->node); /* Register with core */ if (of_device_register(&isa_dev->ofdev) != 0) { printk(KERN_DEBUG "isa: device registration error for %s!\n", - isa_dev->ofdev.dev.bus_id); + dp->path_component_name); kfree(isa_dev); goto next_sibling; } @@ -191,12 +191,12 @@ void __init isa_init(void) isa_br->ofdev.node = dp; isa_br->ofdev.dev.parent = &pdev->dev; isa_br->ofdev.dev.bus = &isa_bus_type; - strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name); + sprintf(isa_br->ofdev.dev.bus_id, "isa%d", index); /* Register with core */ if (of_device_register(&isa_br->ofdev) != 0) { printk(KERN_DEBUG "isa: device registration error for %s!\n", - isa_br->ofdev.dev.bus_id); + dp->path_component_name); kfree(isa_br); return; } diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 983ca5f485c..8cc14fc6b6f 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -861,7 +861,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, if (!parent) strcpy(op->dev.bus_id, "root"); else - sprintf(op->dev.bus_id, "%s@%08x", dp->name, dp->node); + sprintf(op->dev.bus_id, "%08x", dp->node); if (of_device_register(op)) { printk("%s: Could not register of device.\n", -- cgit v1.2.3 From f4880391860f2e38bb6ff400a0bd6c85443c5b9e Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 27 Oct 2006 12:39:10 +0200 Subject: [S390] sys_getcpu compat wrapper. Looking at the new syscall additions, I noticed that sys_getcpu_wrapper wraps in to sys_tee, in what appears to be a copy and paste error. Switch it to point to sys_getcpu.. Signed-off-by: Paul Mundt Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_wrapper.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index cb0efae6802..71e54ef0931 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S @@ -1664,4 +1664,4 @@ sys_getcpu_wrapper: llgtr %r2,%r2 # unsigned * llgtr %r3,%r3 # unsigned * llgtr %r4,%r4 # struct getcpu_cache * - jg sys_tee + jg sys_getcpu -- cgit v1.2.3 From 95425f19beed99cb9b0a79f69731eda907d9db99 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Fri, 27 Oct 2006 12:39:13 +0200 Subject: [S390] Initialize interval value to 0. sscanf() could leave the interval value unchanged in which case it would be used uninitialized. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/appldata/appldata_base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 45c9fa7d754..af1e8fc7d98 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -310,6 +310,7 @@ appldata_interval_handler(ctl_table *ctl, int write, struct file *filp, if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) { return -EFAULT; } + interval = 0; sscanf(buf, "%i", &interval); if (interval <= 0) { P_ERROR("Timer CPU interval has to be > 0!\n"); -- cgit v1.2.3 From 12bae23507129a7337378e6433bff6f8696bdb45 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 27 Oct 2006 12:39:22 +0200 Subject: [S390] uaccess error handling. Consider return values for all user space access function and return -EFAULT on error. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_linux.c | 4 +++- arch/s390/kernel/compat_signal.c | 12 ++++++------ arch/s390/kernel/signal.c | 12 ++++++------ arch/s390/kernel/traps.c | 20 +++++++++++++------- 4 files changed, 28 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 2001767e1dc..5b33f823863 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -757,7 +757,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp))) error = -EFAULT; } - copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); + if (copy_to_user(args->__unused, tmp.__unused, + sizeof(tmp.__unused))) + error = -EFAULT; } return error; } diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index d49b876a83b..861888ab8c1 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -169,12 +169,12 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act, compat_old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(sa_handler, &act->sa_handler) || - __get_user(sa_restorer, &act->sa_restorer)) + __get_user(sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) return -EFAULT; new_ka.sa.sa_handler = (__sighandler_t) sa_handler; new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -185,10 +185,10 @@ sys32_sigaction(int sig, const struct old_sigaction32 __user *act, sa_restorer = (unsigned long) old_ka.sa.sa_restorer; if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(sa_handler, &oact->sa_handler) || - __put_user(sa_restorer, &oact->sa_restorer)) + __put_user(sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 4392a77cbae..4c8a7954ef4 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -80,10 +80,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, old_sigset_t mask; if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(new_ka.sa.sa_handler, &act->sa_handler) || - __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) + __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags) || + __get_user(mask, &act->sa_mask)) return -EFAULT; - __get_user(new_ka.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); siginitset(&new_ka.sa.sa_mask, mask); } @@ -92,10 +92,10 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, if (!ret && oact) { if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) + __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; - __put_user(old_ka.sa.sa_flags, &oact->sa_flags); - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 66375a5e3d1..92ecffbc8d8 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -462,7 +462,8 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) local_irq_enable(); if (regs->psw.mask & PSW_MASK_PSTATE) { - get_user(*((__u16 *) opcode), (__u16 __user *) location); + if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) + return; if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) { if (current->ptrace & PT_PTRACED) force_sig(SIGTRAP, current); @@ -470,20 +471,25 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) signal = SIGILL; #ifdef CONFIG_MATHEMU } else if (opcode[0] == 0xb3) { - get_user(*((__u16 *) (opcode+2)), location+1); + if (get_user(*((__u16 *) (opcode+2)), location+1)) + return; signal = math_emu_b3(opcode, regs); } else if (opcode[0] == 0xed) { - get_user(*((__u32 *) (opcode+2)), - (__u32 __user *)(location+1)); + if (get_user(*((__u32 *) (opcode+2)), + (__u32 __user *)(location+1))) + return; signal = math_emu_ed(opcode, regs); } else if (*((__u16 *) opcode) == 0xb299) { - get_user(*((__u16 *) (opcode+2)), location+1); + if (get_user(*((__u16 *) (opcode+2)), location+1)) + return; signal = math_emu_srnm(opcode, regs); } else if (*((__u16 *) opcode) == 0xb29c) { - get_user(*((__u16 *) (opcode+2)), location+1); + if (get_user(*((__u16 *) (opcode+2)), location+1)) + return; signal = math_emu_stfpc(opcode, regs); } else if (*((__u16 *) opcode) == 0xb29d) { - get_user(*((__u16 *) (opcode+2)), location+1); + if (get_user(*((__u16 *) (opcode+2)), location+1)) + return; signal = math_emu_lfpc(opcode, regs); #endif } else -- cgit v1.2.3 From 6b5c76b8e2ff204fa8d7201acce461188873bf2b Mon Sep 17 00:00:00 2001 From: Eiichiro Oiwa Date: Mon, 23 Oct 2006 15:14:07 +0900 Subject: PCI: fix pci_fixup_video as it blows up on sparc64 This reverts much of the original pci_fixup_video change and makes it work for all arches that need it. fixed, and tested on x86, x86_64 and IA64 dig. Signed-off-by: Eiichiro Oiwa Acked-by: David Miller Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 55 ++++++++++++++++++++++++++++++++++++++++ arch/ia64/pci/Makefile | 2 +- arch/ia64/pci/fixup.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 arch/ia64/pci/fixup.c (limited to 'arch') diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index 908b410f4c9..c1949ff38d6 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -342,6 +342,61 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PB1, pcie_r DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC, pcie_rootport_aspm_quirk ); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_MCH_PC1, pcie_rootport_aspm_quirk ); +/* + * Fixup to mark boot BIOS video selected by BIOS before it changes + * + * From information provided by "Jon Smirl" + * + * The standard boot ROM sequence for an x86 machine uses the BIOS + * to select an initial video card for boot display. This boot video + * card will have it's BIOS copied to C0000 in system RAM. + * IORESOURCE_ROM_SHADOW is used to associate the boot video + * card with this copy. On laptops this copy has to be used since + * the main ROM may be compressed or combined with another image. + * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW + * is marked here since the boot video device will be the only enabled + * video device at this point. + */ + +static void __devinit pci_fixup_video(struct pci_dev *pdev) +{ + struct pci_dev *bridge; + struct pci_bus *bus; + u16 config; + + if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) + return; + + /* Is VGA routed to us? */ + bus = pdev->bus; + while (bus) { + bridge = bus->self; + + /* + * From information provided by + * "David Miller" + * The bridge control register is valid for PCI header + * type BRIDGE, or CARDBUS. Host to PCI controllers use + * PCI header type NORMAL. + */ + if (bridge + &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) + ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { + pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, + &config); + if (!(config & PCI_BRIDGE_CTL_VGA)) + return; + } + bus = bus->parent; + } + pci_read_config_word(pdev, PCI_COMMAND, &config); + if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; + printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); + /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. * diff --git a/arch/ia64/pci/Makefile b/arch/ia64/pci/Makefile index e66889e6922..fb14dc520d2 100644 --- a/arch/ia64/pci/Makefile +++ b/arch/ia64/pci/Makefile @@ -1,4 +1,4 @@ # # Makefile for the ia64-specific parts of the pci bus # -obj-y := pci.o +obj-y := pci.o fixup.o diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c new file mode 100644 index 00000000000..245dc1fedc2 --- /dev/null +++ b/arch/ia64/pci/fixup.c @@ -0,0 +1,69 @@ +/* + * Exceptions for specific devices. Usually work-arounds for fatal design flaws. + * Derived from fixup.c of i386 tree. + */ + +#include +#include + +#include + +/* + * Fixup to mark boot BIOS video selected by BIOS before it changes + * + * From information provided by "Jon Smirl" + * + * The standard boot ROM sequence for an x86 machine uses the BIOS + * to select an initial video card for boot display. This boot video + * card will have it's BIOS copied to C0000 in system RAM. + * IORESOURCE_ROM_SHADOW is used to associate the boot video + * card with this copy. On laptops this copy has to be used since + * the main ROM may be compressed or combined with another image. + * See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW + * is marked here since the boot video device will be the only enabled + * video device at this point. + */ + +static void __devinit pci_fixup_video(struct pci_dev *pdev) +{ + struct pci_dev *bridge; + struct pci_bus *bus; + u16 config; + + if ((strcmp(platform_name, "dig") != 0) + && (strcmp(platform_name, "hpzx1") != 0)) + return; + /* Maybe, this machine supports legacy memory map. */ + + if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) + return; + + /* Is VGA routed to us? */ + bus = pdev->bus; + while (bus) { + bridge = bus->self; + + /* + * From information provided by + * "David Miller" + * The bridge control register is valid for PCI header + * type BRIDGE, or CARDBUS. Host to PCI controllers use + * PCI header type NORMAL. + */ + if (bridge + &&((bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE) + ||(bridge->hdr_type == PCI_HEADER_TYPE_CARDBUS))) { + pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, + &config); + if (!(config & PCI_BRIDGE_CTL_VGA)) + return; + } + bus = bus->parent; + } + pci_read_config_word(pdev, PCI_COMMAND, &config); + if (config & (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) { + pdev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_SHADOW; + printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); -- cgit v1.2.3 From 3095fc0c9772b4afb3c81f76664f341ef716d380 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Fri, 20 Oct 2006 14:45:33 -0700 Subject: PCI: x86-64: mmconfig missing printk levels Signed-off-by: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/x86_64/pci/mmconfig.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 7732f4254d2..e61093b34c2 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -220,7 +220,7 @@ void __init pci_mmcfg_init(int type) pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { - printk("PCI: Can not allocate memory for mmconfig structures\n"); + printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n"); return; } for (i = 0; i < pci_mmcfg_config_num; ++i) { @@ -228,7 +228,8 @@ void __init pci_mmcfg_init(int type) pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_MAX); if (!pci_mmcfg_virt[i].virt) { - printk("PCI: Cannot map mmconfig aperture for segment %d\n", + printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " + "segment %d\n", pci_mmcfg_config[i].pci_segment_group_number); return; } -- cgit v1.2.3 From 61ce1efe6e40233663d27ab8ac9ba9710eebcaad Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 27 Oct 2006 11:41:44 -0700 Subject: [PATCH] vmlinux.lds: consolidate initcall sections Add a vmlinux.lds.h helper macro for defining the eight-level initcall table, teach all the architectures to use it. This is a prerequisite for a patch which performs initcall synchronisation for multithreaded-probing. Cc: Greg KH Signed-off-by: Andrew Morton [ Added AVR32 as well ] Signed-off-by: Haavard Skinnemoen Signed-off-by: Linus Torvalds --- arch/alpha/kernel/vmlinux.lds.S | 8 +------- arch/arm/kernel/vmlinux.lds.S | 8 +------- arch/avr32/kernel/vmlinux.lds.c | 8 +------- arch/frv/kernel/vmlinux.lds.S | 8 +------- arch/h8300/kernel/vmlinux.lds.S | 8 +------- arch/i386/kernel/vmlinux.lds.S | 8 +------- arch/ia64/kernel/vmlinux.lds.S | 8 +------- arch/m32r/kernel/vmlinux.lds.S | 8 +------- arch/m68knommu/kernel/vmlinux.lds.S | 8 +------- arch/mips/kernel/vmlinux.lds.S | 8 +------- arch/parisc/kernel/vmlinux.lds.S | 8 +------- arch/powerpc/kernel/vmlinux.lds.S | 8 +------- arch/ppc/kernel/vmlinux.lds.S | 8 +------- arch/s390/kernel/vmlinux.lds.S | 8 +------- arch/sh/kernel/vmlinux.lds.S | 8 +------- arch/sh64/kernel/vmlinux.lds.S | 8 +------- arch/sparc/kernel/vmlinux.lds.S | 8 +------- arch/sparc64/kernel/vmlinux.lds.S | 8 +------- arch/v850/kernel/vmlinux.lds.S | 8 +------- arch/x86_64/kernel/vmlinux.lds.S | 8 +------- arch/xtensa/kernel/vmlinux.lds.S | 8 +------- 21 files changed, 21 insertions(+), 147 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 71470e9d93b..76bf071e376 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -48,13 +48,7 @@ SECTIONS . = ALIGN(8); __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 3ca574ee277..a8fa75ea07a 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -45,13 +45,7 @@ SECTIONS *(.early_param.init) __early_end = .; __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/avr32/kernel/vmlinux.lds.c b/arch/avr32/kernel/vmlinux.lds.c index cdd627c6b7d..5c4424e362b 100644 --- a/arch/avr32/kernel/vmlinux.lds.c +++ b/arch/avr32/kernel/vmlinux.lds.c @@ -38,13 +38,7 @@ SECTIONS __setup_end = .; . = ALIGN(4); __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/frv/kernel/vmlinux.lds.S b/arch/frv/kernel/vmlinux.lds.S index f474534ba78..9c1fb12367f 100644 --- a/arch/frv/kernel/vmlinux.lds.S +++ b/arch/frv/kernel/vmlinux.lds.S @@ -44,13 +44,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S index 6406c388f88..756325dd480 100644 --- a/arch/h8300/kernel/vmlinux.lds.S +++ b/arch/h8300/kernel/vmlinux.lds.S @@ -118,13 +118,7 @@ SECTIONS . = ALIGN(0x4) ; ___setup_end = .; ___initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS ___initcall_end = .; ___con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 1e7ac1c44dd..adc1f232afe 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -126,13 +126,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S index b3b2e389d6b..d6083a0936f 100644 --- a/arch/ia64/kernel/vmlinux.lds.S +++ b/arch/ia64/kernel/vmlinux.lds.S @@ -128,13 +128,7 @@ SECTIONS .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; } diff --git a/arch/m32r/kernel/vmlinux.lds.S b/arch/m32r/kernel/vmlinux.lds.S index 13c7bb698e3..358b9cee2c6 100644 --- a/arch/m32r/kernel/vmlinux.lds.S +++ b/arch/m32r/kernel/vmlinux.lds.S @@ -83,13 +83,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index ccd2ceb05cf..58afa8be604 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S @@ -140,13 +140,7 @@ SECTIONS { *(.init.setup) __setup_end = .; __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; __con_initcall_start = .; *(.con_initcall.init) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 0bb9cd88945..25ed3337ce3 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -91,13 +91,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index b3677fc8eef..7b943b45f7c 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -153,13 +153,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index cb0e8d46c3e..e8342d86753 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -108,13 +108,7 @@ SECTIONS .initcall.init : { __initcall_start = .; - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS __initcall_end = .; } diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 095fd332332..16e8661e1fe 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -115,13 +115,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index af9e69a0301..fe0f2e97ba7 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -83,13 +83,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 5eb93091818..77b4026d568 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -76,13 +76,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sh64/kernel/vmlinux.lds.S b/arch/sh64/kernel/vmlinux.lds.S index a8fcc3a7158..95c4d753e35 100644 --- a/arch/sh64/kernel/vmlinux.lds.S +++ b/arch/sh64/kernel/vmlinux.lds.S @@ -108,13 +108,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : C_PHYS(.initcall.init) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 1dd78c84888..5cc5ff7f882 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -49,13 +49,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index b097379a49a..bd9de8c2a2a 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -57,13 +57,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S index 63399219cd9..88d087f527c 100644 --- a/arch/v850/kernel/vmlinux.lds.S +++ b/arch/v850/kernel/vmlinux.lds.S @@ -140,13 +140,7 @@ ___setup_end = . ; \ ___initcall_start = . ; \ *(.initcall.init) \ - *(.initcall1.init) \ - *(.initcall2.init) \ - *(.initcall3.init) \ - *(.initcall4.init) \ - *(.initcall5.init) \ - *(.initcall6.init) \ - *(.initcall7.init) \ + INITCALLS \ . = ALIGN (4) ; \ ___initcall_end = . ; \ ___con_initcall_start = .; \ diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 1283614c9b2..edb24aa714b 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -175,13 +175,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index ab6cdbd5eb6..cfe75f52872 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -184,13 +184,7 @@ SECTIONS __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; -- cgit v1.2.3 From c97d4869a23c439d2bc23cb26c1147c099f9ff78 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 25 Oct 2006 13:59:16 +0100 Subject: [ARM] Fix SMP irqflags support The IRQ changes a while back broke the build for SMP machines. Fix up the SMP code to use set_irq_regs/get_irq_regs as appropriate. Also, fix a warning in arch/arm/kernel/time.c where 'regs' becomes unused for SMP builds. Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 20 +++++++++++++------- arch/arm/kernel/time.c | 3 +-- 2 files changed, 14 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 421329f5e18..a07d202143c 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -7,6 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include @@ -474,25 +476,26 @@ void show_local_irqs(struct seq_file *p) seq_putc(p, '\n'); } -static void ipi_timer(struct pt_regs *regs) +static void ipi_timer(void) { - int user = user_mode(regs); - irq_enter(); - profile_tick(CPU_PROFILING, regs); - update_process_times(user); + profile_tick(CPU_PROFILING); + update_process_times(user_mode(get_irq_regs())); irq_exit(); } #ifdef CONFIG_LOCAL_TIMERS asmlinkage void do_local_timer(struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); int cpu = smp_processor_id(); if (local_timer_ack()) { irq_stat[cpu].local_timer_irqs++; - ipi_timer(regs); + ipi_timer(); } + + set_irq_regs(old_regs); } #endif @@ -551,6 +554,7 @@ asmlinkage void do_IPI(struct pt_regs *regs) { unsigned int cpu = smp_processor_id(); struct ipi_data *ipi = &per_cpu(ipi_data, cpu); + struct pt_regs *old_regs = set_irq_regs(regs); ipi->ipi_count++; @@ -574,7 +578,7 @@ asmlinkage void do_IPI(struct pt_regs *regs) switch (nextmsg) { case IPI_TIMER: - ipi_timer(regs); + ipi_timer(); break; case IPI_RESCHEDULE: @@ -599,6 +603,8 @@ asmlinkage void do_IPI(struct pt_regs *regs) } } while (msgs); } + + set_irq_regs(old_regs); } void smp_send_reschedule(int cpu) diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index c03cab5c4c7..0c5a6091a93 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -327,13 +327,12 @@ EXPORT_SYMBOL(restore_time_delta); */ void timer_tick(void) { - struct pt_regs *regs = get_irq_regs(); profile_tick(CPU_PROFILING); do_leds(); do_set_rtc(); do_timer(1); #ifndef CONFIG_SMP - update_process_times(user_mode(regs)); + update_process_times(user_mode(get_irq_regs())); #endif } -- cgit v1.2.3 From a233bf9ee819c726c581af48010e0c0f1cdde245 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 25 Oct 2006 14:25:52 +0100 Subject: [ARM] Add realview SMP default configuration Signed-off-by: Russell King --- arch/arm/configs/realview-smp_defconfig | 994 ++++++++++++++++++++++++++++++++ 1 file changed, 994 insertions(+) create mode 100644 arch/arm/configs/realview-smp_defconfig (limited to 'arch') diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig new file mode 100644 index 00000000000..ffd905ff19f --- /dev/null +++ b/arch/arm/configs/realview-smp_defconfig @@ -0,0 +1,994 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc3 +# Wed Oct 25 14:12:00 2006 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_STOP_MACHINE=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_REALVIEW=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# RealView platform type +# +CONFIG_MACH_REALVIEW_EB=y +CONFIG_REALVIEW_MPCORE=y + +# +# Processor Type +# +CONFIG_CPU_32=y +# CONFIG_CPU_ARM926T is not set +CONFIG_CPU_V6=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v6=y +CONFIG_CPU_ABRT_EV6=y +CONFIG_CPU_CACHE_V6=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_HAS_TLS_REG=y +CONFIG_ARM_GIC=y +CONFIG_ICST307=y + +# +# Bus support +# +CONFIG_ARM_AMBA=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_SMP=y +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCAL_TIMERS=y +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_ARM_INTEGRATOR=y +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_SMC91X=y +# CONFIG_DM9000 is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_LKKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +CONFIG_INPUT_MOUSE=y +CONFIG_MOUSE_PS2=y +# CONFIG_MOUSE_SERIAL is not set +# CONFIG_MOUSE_VSXXXAA is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_SERPORT is not set +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_AMBA_PL010 is not set +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=16 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_VIRTUAL is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +CONFIG_LOGO=y +# CONFIG_LOGO_LINUX_MONO is not set +# CONFIG_LOGO_LINUX_VGA16 is not set +CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +CONFIG_SOUND=y + +# +# Advanced Linux Sound Architecture +# +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +# CONFIG_SND_SEQUENCER is not set +CONFIG_SND_OSSEMUL=y +CONFIG_SND_MIXER_OSS=y +CONFIG_SND_PCM_OSS=y +CONFIG_SND_PCM_OSS_PLUGINS=y +# CONFIG_SND_DYNAMIC_MINORS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_BUS=m +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# ALSA ARM devices +# +CONFIG_SND_ARMAACI=m + +# +# Open Sound System +# +# CONFIG_SOUND_PRIME is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_ARMMMCI=y +# CONFIG_MMC_TIFM_SD is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +CONFIG_RTC_INTF_DEV_UIE_EMUL=y + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_PL031=y +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_INOTIFY_USER is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RWSEMS=y +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y -- cgit v1.2.3 From e816d71a50a714b532e3965364f3f53c23a53d42 Mon Sep 17 00:00:00 2001 From: Takashi Ohmasa Date: Mon, 23 Oct 2006 08:30:35 +0100 Subject: [ARM] 3899/1: Fix the normalization of the denormal double precision number. The significand should be shifted until the value of bit [62] is 1 to normalize the denormal double number. Signed-off-by: Takashi Ohmasa Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 4fc05ee0a2e..e44b9ed0f81 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -56,7 +56,7 @@ static void vfp_double_normalise_denormal(struct vfp_double *vd) { int bits = 31 - fls(vd->significand >> 32); if (bits == 31) - bits = 62 - fls(vd->significand); + bits = 63 - fls(vd->significand); vfp_double_dump("normalise_denormal: in", vd); -- cgit v1.2.3 From e0f205d9c656da9dad6340f75e33a96014b7d23f Mon Sep 17 00:00:00 2001 From: Takashi Ohmasa Date: Mon, 23 Oct 2006 11:19:40 +0100 Subject: [ARM] 3900/1: Fix VFP Division by Zero exception handling. The SIGFPE signal should be generated if Division by Zero exception is detected. Signed-off-by: Takashi Ohmasa Signed-off-by: Russell King --- arch/arm/vfp/vfpmodule.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index a657a28f08d..f08eafbddcc 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -148,6 +148,7 @@ static void vfp_raise_exceptions(u32 exceptions, u32 inst, u32 fpscr, struct pt_ /* * These are arranged in priority order, least to highest. */ + RAISE(FPSCR_DZC, FPSCR_DZE, FPE_FLTDIV); RAISE(FPSCR_IXC, FPSCR_IXE, FPE_FLTRES); RAISE(FPSCR_UFC, FPSCR_UFE, FPE_FLTUND); RAISE(FPSCR_OFC, FPSCR_OFE, FPE_FLTOVF); -- cgit v1.2.3 From ae74589cb381cc2838107f92d4e0e1f178c6825d Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Sat, 28 Oct 2006 10:38:29 -0700 Subject: [PATCH] fix efi_memory_present_wrapper() efi_memory_present_wrapper() parameter start/end is physical address, but function memory_present parameter is PFN, this patch converts physical address to PFN. Signed-off-by: bibo, mao Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 519e63c3c13..141041dde74 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -846,7 +846,7 @@ efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) static int __init efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) { - memory_present(0, start, end); + memory_present(0, PFN_UP(start), PFN_DOWN(end)); return 0; } -- cgit v1.2.3 From 08d892f11aae7125fe078cf93ec5cf6af288c5e7 Mon Sep 17 00:00:00 2001 From: Andrey Panin Date: Sat, 28 Oct 2006 10:38:35 -0700 Subject: [PATCH] visws build fix Fix this: > Subject : CONFIG_X86_VISWS=3Dy, CONFIG_SMP=3Dn compile error > References : http://lkml.org/lkml/2006/10/7/51 > Submitter : Jesper Juhl > Caused-By : David Howells > commit 7d12e780e003f93433d49ce78cfedf4b4c52adc5 > Status : unknown Via undescribed means. Signed-off-by: Andrey Panin Cc: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mach-visws/visws_apic.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/mach-visws/visws_apic.c b/arch/i386/mach-visws/visws_apic.c index 07097ed4889..38c2b13124d 100644 --- a/arch/i386/mach-visws/visws_apic.c +++ b/arch/i386/mach-visws/visws_apic.c @@ -122,7 +122,7 @@ static void end_cobalt_irq(unsigned int irq) spin_unlock_irqrestore(&cobalt_lock, flags); } -static struct hw_interrupt_type cobalt_irq_type = { +static struct irq_chip cobalt_irq_type = { .typename = "Cobalt-APIC", .startup = startup_cobalt_irq, .shutdown = disable_cobalt_irq, @@ -159,7 +159,7 @@ static void end_piix4_master_irq(unsigned int irq) spin_unlock_irqrestore(&cobalt_lock, flags); } -static struct hw_interrupt_type piix4_master_irq_type = { +static struct irq_chip piix4_master_irq_type = { .typename = "PIIX4-master", .startup = startup_piix4_master_irq, .ack = ack_cobalt_irq, @@ -167,9 +167,8 @@ static struct hw_interrupt_type piix4_master_irq_type = { }; -static struct hw_interrupt_type piix4_virtual_irq_type = { +static struct irq_chip piix4_virtual_irq_type = { .typename = "PIIX4-virtual", - .startup = startup_8259A_irq, .shutdown = disable_8259A_irq, .enable = enable_8259A_irq, .disable = disable_8259A_irq, -- cgit v1.2.3 From 51342d7126342e1f1a40cd96a5798a3cfd6136eb Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Oct 2006 12:51:05 +0000 Subject: [ARM] Add KBUILD_IMAGE target support Add support for KBUILD_IMAGE on ARM. This takes the usual target specifiers (zImage/Image/etc) in the same way that powerpc does (iow, without the arch/arm/boot prefix). Signed-off-by: Russell King --- arch/arm/Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 2a0b2c8a1fe..6f4f8bf3607 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -174,11 +174,13 @@ libs-y := arch/arm/lib/ $(libs-y) # Default target when executing plain make ifeq ($(CONFIG_XIP_KERNEL),y) -all: xipImage +KBUILD_IMAGE := xipImage else -all: zImage +KBUILD_IMAGE := zImage endif +all: $(KBUILD_IMAGE) + boot := arch/arm/boot # Update machine arch and proc symlinks if something which affects -- cgit v1.2.3 From 811c9a4b618ffc7de097490f8dc61b43b8464b9c Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 29 Oct 2006 14:15:10 +0100 Subject: [ARM] 3913/1: n2100: fix IRQ routing for second ethernet port The second ethernet port on the Thecus n2100 was incorrectly assigned to XINT1 instead of the correct XINT3 (PCI INTB instead of INTD), which caused that port to be non-functional. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-iop32x/n2100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index a2c94a47b2b..2499a7707e3 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c @@ -85,7 +85,7 @@ n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) irq = IRQ_IOP32X_XINT0; } else if (PCI_SLOT(dev->devfn) == 2) { /* RTL8110SB #2 */ - irq = IRQ_IOP32X_XINT1; + irq = IRQ_IOP32X_XINT3; } else if (PCI_SLOT(dev->devfn) == 3) { /* Sil3512 */ irq = IRQ_IOP32X_XINT2; -- cgit v1.2.3 From 5fdb51a10f3ab4320c3170b79d66ce34a6e65a67 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 29 Oct 2006 11:21:51 +0100 Subject: [PATCH] m68k: consolidate initcall sections Commit 61ce1efe6e40233663d27ab8ac9ba9710eebcaad missed the m68k initcall sections. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/vmlinux-std.lds | 8 +------- arch/m68k/kernel/vmlinux-sun3.lds | 8 +------- 2 files changed, 2 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 69d1d3d30c7..d2794452b19 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds @@ -54,13 +54,7 @@ SECTIONS __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index 65cc39c2418..2550b4ae273 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -48,13 +48,7 @@ __init_begin = .; __setup_end = .; __initcall_start = .; .initcall.init : { - *(.initcall1.init) - *(.initcall2.init) - *(.initcall3.init) - *(.initcall4.init) - *(.initcall5.init) - *(.initcall6.init) - *(.initcall7.init) + INITCALLS } __initcall_end = .; __con_initcall_start = .; -- cgit v1.2.3 From 9f0f9313cec8c76c89bc8a68653f928fa12fab96 Mon Sep 17 00:00:00 2001 From: Kristoffer Ericson Date: Sun, 29 Oct 2006 22:38:08 +0100 Subject: [ARM] 3914/1: [Jornada7xx] - Typo Fix in cpu-sa1110.c (b != B) "K4S281632b-1H" should read "K4S281632B-1H" (As it does everywhere else). No more coffe! Signed-off-by: Kristoffer Ericson Signed-off-by: Russell King --- arch/arm/mach-sa1100/cpu-sa1110.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 90a4130114a..78f4c134604 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -83,7 +83,7 @@ static struct sdram_params sdram_tbl[] __initdata = { .refresh = 64000, .cas_latency = 3, }, { /* Samsung K4S281632B-1H */ - .name = "K4S281632b-1H", + .name = "K4S281632B-1H", .rows = 12, .tck = 10, .trp = 20, -- cgit v1.2.3 From f8da1f746588ba997734274b4aadc5ae501fbd88 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 29 Oct 2006 22:46:39 -0800 Subject: [PATCH] cryptocop: double spin_lock_irqsave() Signed-off-by: Alexey Dobriyan Cc: Mikael Starvik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/arch-v32/drivers/cryptocop.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c index ba096ebb0b1..2449637e6fc 100644 --- a/arch/cris/arch-v32/drivers/cryptocop.c +++ b/arch/cris/arch-v32/drivers/cryptocop.c @@ -2051,7 +2051,6 @@ static void cryptocop_job_queue_close(void) spin_lock_irqsave(&cryptocop_process_lock, process_flags); /* Empty the job queue. */ - spin_lock_irqsave(&cryptocop_process_lock, process_flags); for (i = 0; i < cryptocop_prio_no_prios; i++){ if (!list_empty(&(cryptocop_job_queues[i].jobs))){ list_for_each_safe(node, tmp, &(cryptocop_job_queues[i].jobs)) { -- cgit v1.2.3 From b428b51ed9a4ff8445ea50769961f948480c1d36 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sun, 29 Oct 2006 22:46:41 -0800 Subject: [PATCH] Fix "Remove the use of _syscallX macros in UML" Fix commit 5f4c6bc1f369f20807a8e753c2308d1629478c61: it spits out warnings about missing syscall prototype (it is in ) and it does not recognize that two uses of _syscallX are to be resolved against kernel headers in the source tree, not against _syscallX; they in fact do not compile and would not work anyway. If _syscallX macros will be removed from the kernel tree altogether, the only reasonable solution for that piece of code is switching to open-coded inline assembly (it's remapping the whole executable from memory, except the page containing this code). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/sys-i386/tls.c | 3 +++ arch/um/os-Linux/tls.c | 1 + arch/um/sys-i386/unmap.c | 11 +++++++---- arch/um/sys-x86_64/unmap.c | 11 +++++++---- 4 files changed, 18 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c index 6e945ab4584..256532034c6 100644 --- a/arch/um/os-Linux/sys-i386/tls.c +++ b/arch/um/os-Linux/sys-i386/tls.c @@ -1,6 +1,9 @@ #include #include + #include +#include + #include "sysdep/tls.h" #include "user_util.h" diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index a2de2580b8a..9f7999f27c7 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "sysdep/tls.h" #include "uml-config.h" diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c index 8e55cd5d3d0..1b0ad0e4adc 100644 --- a/arch/um/sys-i386/unmap.c +++ b/arch/um/sys-i386/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ + if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c index 57c9286a701..f4a4bffd8a1 100644 --- a/arch/um/sys-x86_64/unmap.c +++ b/arch/um/sys-x86_64/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); -- cgit v1.2.3 From d45e44d4be60ef508579001792f33753b5cb6d36 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Sun, 29 Oct 2006 22:46:42 -0800 Subject: [PATCH] uml: fix compilation options for USER_OBJS From: Jeff Dike , Paolo Giarrusso Make sure that when compiling USER_OBJS the correct compilation options are passed; since they are compiled with USER_CFLAGS which is derived from CFLAGS, make sure it is a recursively evaluated variable, so that changes to CFLAGS done afterwards the inclusion of arch/$(ARCH)/Makefile are reflected in USER_CFLAGS. For instance, without this patch userspace objects are never compiled with debug info active. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Makefile | 21 +++++++++++---------- arch/um/Makefile-i386 | 4 +--- arch/um/Makefile-x86_64 | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/um/Makefile b/arch/um/Makefile index c8016a98483..5d5ed726faa 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -64,9 +64,14 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ AFLAGS += $(ARCH_INCLUDE) -USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) -USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ - $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64 +USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ + $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ + -D_FILE_OFFSET_BITS=64 + +include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) + +#This will adjust *FLAGS accordingly to the platform. +include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) # -Derrno=kernel_errno - This turns all kernel references to errno into # kernel_errno to separate them from the libc errno. This allows -fno-common @@ -74,15 +79,11 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ # errnos. # These apply to kernelspace only. -CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ - -Dmktime=kernel_mktime +KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ + -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES) +CFLAGS += $(KERNEL_DEFINES) CFLAGS += $(call cc-option,-fno-unit-at-a-time,) -include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) - -#This will adjust *FLAGS accordingly to the platform. -include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) - # These are needed for clean and mrproper, since in that case .config is not # included; the values here are meaningless diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index b65ca115ef7..c9f1c5b24c9 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -16,7 +16,6 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S ifeq ("$(origin SUBARCH)", "command line") ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") CFLAGS += $(call cc-option,-m32) -USER_CFLAGS += $(call cc-option,-m32) AFLAGS += $(call cc-option,-m32) LINK-y += $(call cc-option,-m32) UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) @@ -25,7 +24,7 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS endif endif -CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) +ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH) # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. include $(srctree)/arch/i386/Makefile.cpu @@ -38,4 +37,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) cflags-y += -ffreestanding CFLAGS += $(cflags-y) -USER_CFLAGS += $(cflags-y) diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index d278682dd79..69ecea63fda 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 @@ -8,8 +8,8 @@ _extra_flags_ = -fno-builtin -m64 #We #undef __x86_64__ for kernelspace, not for userspace where #it's needed for headers to work! -CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_) -USER_CFLAGS += $(_extra_flags_) +ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__ +CFLAGS += $(_extra_flags_) CHECKFLAGS += -m64 AFLAGS += -m64 -- cgit v1.2.3 From 3f4b23e9833f0816b57d07401eac5e184b627fd7 Mon Sep 17 00:00:00 2001 From: Kristian Mueller Date: Sun, 29 Oct 2006 22:46:46 -0800 Subject: [PATCH] APM: URL of APM 1.2 specs has changed APM BIOS Interface Secification can now be found at http://www.microsoft.com/whdc/archive/amp_12.mspx Signed-off-by: Kristian Mueller Acked-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 2af65858d32..a60358fe9a4 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -198,7 +198,7 @@ * (APM) BIOS Interface Specification, Revision 1.2, February 1996. * * [This document is available from Microsoft at: - * http://www.microsoft.com/hwdev/busbios/amp_12.htm] + * http://www.microsoft.com/whdc/archive/amp_12.mspx] */ #include -- cgit v1.2.3 From a7aacdf9ea45bf6139cfd750e558a3dcbc6f16c3 Mon Sep 17 00:00:00 2001 From: Albert Cahalan Date: Sun, 29 Oct 2006 22:26:17 -0500 Subject: [PATCH] fix i386 regparm=3 RT signal handlers on x86_64 The recent change to make x86_64 support i386 binaries compiled with -mregparm=3 only covered signal handlers without SA_SIGINFO. (the 3-arg "real-time" ones) This is useful for klibc at least. Signed-off-by: Albert Cahalan Signed-off-by: Linus Torvalds --- arch/x86_64/ia32/ia32_signal.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index a6ba9951e86..0e0a266d976 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -579,6 +579,11 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->rsp = (unsigned long) frame; regs->rip = (unsigned long) ka->sa.sa_handler; + /* Make -mregparm=3 work */ + regs->rax = sig; + regs->rdx = (unsigned long) &frame->info; + regs->rcx = (unsigned long) &frame->uc; + asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); -- cgit v1.2.3 From be609f3546d3dd96afd7df8856a91fa2b8825fbc Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 23 Oct 2006 13:22:06 +0100 Subject: [MIPS] Oprofile: fix on non-VSMP / non-SMTC SMP configurations. Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_mipsxx.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index dd0aec9c3ce..ebce715f076 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -31,16 +31,18 @@ #define M_COUNTER_OVERFLOW (1UL << 31) #ifdef CONFIG_MIPS_MT_SMP -#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) +#define WHAT (M_TC_EN_VPE | M_PERFCTL_VPEID(smp_processor_id())) +#define vpe_id() smp_processor_id() #else -#define WHAT 0 +#define WHAT 0 +#define vpe_id() smp_processor_id() #endif #define __define_perf_accessors(r, n, np) \ \ static inline unsigned int r_c0_ ## r ## n(void) \ { \ - unsigned int cpu = smp_processor_id(); \ + unsigned int cpu = vpe_id(); \ \ switch (cpu) { \ case 0: \ @@ -55,7 +57,7 @@ static inline unsigned int r_c0_ ## r ## n(void) \ \ static inline void w_c0_ ## r ## n(unsigned int value) \ { \ - unsigned int cpu = smp_processor_id(); \ + unsigned int cpu = vpe_id(); \ \ switch (cpu) { \ case 0: \ -- cgit v1.2.3 From 53c1b192ece077e1c3892e6afb453ab6f009af81 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 3 Sep 2006 22:17:10 +0400 Subject: [MIPS] Au1xx0 code sets incorrect mips_hpt_frequency Alchemy CPU counter ticks at the full CPU clock speed. Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/time.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 94f09194d63..7313ef234d8 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -231,7 +231,6 @@ wakeup_counter0_set(int ticks) */ unsigned long cal_r4koff(void) { - unsigned long count; unsigned long cpu_speed; unsigned long flags; unsigned long counter; @@ -258,7 +257,7 @@ unsigned long cal_r4koff(void) #if defined(CONFIG_AU1000_USE32K) { - unsigned long start, end; + unsigned long start, end, count; start = au_readl(SYS_RTCREAD); start += 2; @@ -282,7 +281,6 @@ unsigned long cal_r4koff(void) #else cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; - count = cpu_speed / 2; #endif } else { @@ -291,10 +289,9 @@ unsigned long cal_r4koff(void) * NOTE: some old silicon doesn't allow reading the PLL. */ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; - count = cpu_speed / 2; no_au1xxx_32khz = 1; } - mips_hpt_frequency = count; + mips_hpt_frequency = cpu_speed; // Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16)); spin_unlock_irqrestore(&time_lock, flags); -- cgit v1.2.3 From ea3df4ac7d4adad915e2d0431a9407b10617114c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 23 Oct 2006 23:21:21 +0100 Subject: [MIPS] Oprofile: Fix MIPSxx counter number detection. Signed-off-by: Ralf Baechle --- arch/mips/oprofile/op_model_mipsxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index ebce715f076..1fb240c57ba 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -220,7 +220,7 @@ static inline int n_counters(void) { int counters = __n_counters(); -#ifndef CONFIG_SMP +#ifdef CONFIG_MIPS_MT_SMP if (current_cpu_data.cputype == CPU_34K) return counters >> 1; #endif -- cgit v1.2.3 From 8cde4a3162fdcccaf0ecbf3c21cdb13df422936d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 26 Oct 2006 14:29:01 +0100 Subject: [MIPS] SMTC: Make 8 the default number of processors. 8 is the next larger power of two of the currently 5 supported TCs. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 14af6cce2fa..9c92b491733 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1690,6 +1690,7 @@ config NR_CPUS depends on SMP default "64" if SGI_IP27 default "2" + default "8" if MIPS_MT_SMTC help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 32 for 32-bit -- cgit v1.2.3 From f0ec69e52989986e861a352099803cbb77ca53ba Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sat, 28 Oct 2006 00:42:24 +0900 Subject: [MIPS] Fix warning about unused definition in c-sb1.c arch/mips/mm/c-sb1.c: In function `sb1_cache_init': arch/mips/mm/c-sb1.c:447: warning: unused variable `handle_vec2_sb1' Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/mm/c-sb1.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 5537558f19f..f2941b4c9f3 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -444,7 +444,6 @@ static __init void probe_cache_sizes(void) void sb1_cache_init(void) { extern char except_vec2_sb1; - extern char handle_vec2_sb1; /* Special cache error handler for SB1 */ set_uncached_handler (0x100, &except_vec2_sb1, 0x80); -- cgit v1.2.3 From 9448b8f6a014f46450ef65d81c0be2ca5a81c867 Mon Sep 17 00:00:00 2001 From: Manish Lachwani Date: Thu, 5 Oct 2006 16:30:44 -0700 Subject: [MIPS] Make SB1 cache flushes not to use on_each_cpu This fixes the start_kernel(): bug: interrupts were enabled early messages. Signed-off-by: Manish Lachwani Signed-off-by: Ralf Baechle --- arch/mips/mm/c-sb1.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index f2941b4c9f3..ea49a775bf2 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -49,6 +49,15 @@ static unsigned short dcache_sets; static unsigned int icache_range_cutoff; static unsigned int dcache_range_cutoff; +static inline void sb1_on_each_cpu(void (*func) (void *info), void *info, + int retry, int wait) +{ + preempt_disable(); + smp_call_function(func, info, retry, wait); + func(info); + preempt_enable(); +} + /* * The dcache is fully coherent to the system, with one * big caveat: the instruction stream. In other words, @@ -226,7 +235,7 @@ static void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, args.vma = vma; args.addr = addr; args.pfn = pfn; - on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); + sb1_on_each_cpu(sb1_flush_cache_page_ipi, (void *) &args, 1, 1); } #else void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn) @@ -249,7 +258,7 @@ void sb1___flush_cache_all_ipi(void *ignored) static void sb1___flush_cache_all(void) { - on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); + sb1_on_each_cpu(sb1___flush_cache_all_ipi, 0, 1, 1); } #else void sb1___flush_cache_all(void) @@ -299,7 +308,7 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; - on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); + sb1_on_each_cpu(sb1_flush_icache_range_ipi, &args, 1, 1); } #else void sb1_flush_icache_range(unsigned long start, unsigned long end) @@ -326,7 +335,7 @@ static void sb1_flush_cache_sigtramp_ipi(void *info) static void sb1_flush_cache_sigtramp(unsigned long addr) { - on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); + sb1_on_each_cpu(sb1_flush_cache_sigtramp_ipi, (void *) addr, 1, 1); } #else void sb1_flush_cache_sigtramp(unsigned long addr) -- cgit v1.2.3 From 991ea26dcbc2524a054f37911ea375e631cb8891 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 29 Oct 2006 21:07:40 +0000 Subject: [MIPS] Wire up getcpu(2) and epoll_wait(2) syscalls. Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall32-o32.S | 2 ++ arch/mips/kernel/scall64-64.S | 2 ++ arch/mips/kernel/scall64-n32.S | 2 ++ arch/mips/kernel/scall64-o32.S | 2 ++ 4 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 720fac3435d..a95f37de080 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -654,6 +654,8 @@ einval: li v0, -EINVAL sys sys_set_robust_list 2 sys sys_get_robust_list 3 /* 4310 */ sys sys_ni_syscall 0 + sys sys_getcpu 3 + sys sys_epoll_pwait 6 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3a34f62c8b1..8fb0f60f657 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -469,3 +469,5 @@ sys_call_table: PTR sys_set_robust_list PTR sys_get_robust_list PTR sys_ni_syscall /* 5270 */ + PTR sys_getcpu + PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 67b92a1d6c7..0da5ca2040f 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -395,3 +395,5 @@ EXPORT(sysn32_call_table) PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list PTR sys_ni_syscall + PTR sys_getcpu + PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 2875c4a3fa5..b9d00cae8b5 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -517,4 +517,6 @@ sys_call_table: PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ PTR sys_ni_syscall + PTR sys_getcpu + PTR sys_epoll_pwait .size sys_call_table,.-sys_call_table -- cgit v1.2.3 From a597a473b422f5a69b1f567f12e04db39fa01f39 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 29 Oct 2006 23:37:40 +0900 Subject: [MIPS] Au1000: Fix warning about unused variable. arch/mips/au1000/common/time.c: In function `mips_timer_interrupt': arch/mips/au1000/common/time.c:82: warning: unused variable `count' Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/time.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 7313ef234d8..6768638883e 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -82,7 +82,6 @@ unsigned long wtimer; void mips_timer_interrupt(void) { int irq = 63; - unsigned long count; irq_enter(); kstat_this_cpu.irqs[irq]++; -- cgit v1.2.3 From c39c30da2dad1aa3fb61862039634e9480a16fde Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sun, 29 Oct 2006 23:37:55 +0900 Subject: [MIPS] Fix return value of TXX9 SPI interrupt handler Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c index b926e6a75c2..08b20cdfd7b 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/spi_txx9.c @@ -36,14 +36,18 @@ void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on) static DECLARE_WAIT_QUEUE_HEAD(txx9_spi_wait); -static void txx9_spi_interrupt(int irq, void *dev_id) +static irqreturn_t txx9_spi_interrupt(int irq, void *dev_id) { /* disable rx intr */ tx4938_spiptr->cr0 &= ~TXx9_SPCR0_RBSIE; wake_up(&txx9_spi_wait); + + return IRQ_HANDLED; } + static struct irqaction txx9_spi_action = { - txx9_spi_interrupt, 0, 0, "spi", NULL, NULL, + .handler = txx9_spi_interrupt, + .name = "spi", }; void __init txx9_spi_irqinit(int irc_irq) -- cgit v1.2.3 From 6ceb6d3ab2d402cea326320a4143db90a66fd216 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 12:52:16 +0000 Subject: [MIPS] Ocelot G: Fix build error and numerous warnings. The cause of the build errors was a 64-bit kernel being configured in ocelot_g_defconfig without the code being 64-bit proof. Fixed for now by limiting 64-bit selection to SYS_SUPPORTS_64BIT_KERNEL if BROKEN. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- arch/mips/momentum/ocelot_g/ocelot_pld.h | 6 +++--- arch/mips/momentum/ocelot_g/setup.c | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9c92b491733..74ba7637811 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -408,7 +408,7 @@ config MOMENCO_OCELOT_C select SWAP_IO_SPACE select SYS_HAS_CPU_RM7000 select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_BIG_ENDIAN help The Ocelot is a MIPS-based Single Board Computer (SBC) made by diff --git a/arch/mips/momentum/ocelot_g/ocelot_pld.h b/arch/mips/momentum/ocelot_g/ocelot_pld.h index fcb8275e219..95e0534026d 100644 --- a/arch/mips/momentum/ocelot_g/ocelot_pld.h +++ b/arch/mips/momentum/ocelot_g/ocelot_pld.h @@ -23,8 +23,8 @@ #define OCELOT_REG_INTSET (12) #define OCELOT_REG_INTCLR (13) -#define OCELOT_PLD_WRITE(x, y) writeb(x, OCELOT_CS0_ADDR + OCELOT_REG_##y) -#define OCELOT_PLD_READ(x) readb(OCELOT_CS0_ADDR + OCELOT_REG_##x) - +#define __PLD_REG_TO_ADDR(reg) ((void *) OCELOT_CS0_ADDR + OCELOT_REG_##reg) +#define OCELOT_PLD_WRITE(x, reg) writeb(x, __PLD_REG_TO_ADDR(reg)) +#define OCELOT_PLD_READ(reg) readb(__PLD_REG_TO_ADDR(reg)) #endif /* __MOMENCO_OCELOT_PLD_H__ */ diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c index 56ec47039c1..d288f7b0184 100644 --- a/arch/mips/momentum/ocelot_g/setup.c +++ b/arch/mips/momentum/ocelot_g/setup.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -160,6 +161,10 @@ static void __init setup_l3cache(unsigned long size) printk("Done\n"); } +void __init plat_timer_setup(struct irqaction *irq) +{ +} + void __init plat_mem_setup(void) { void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache); -- cgit v1.2.3 From 408d3258f99458f2dabcb1aa33918250e4864f00 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 14:19:37 +0000 Subject: [MIPS] EMMA 2 / Markeins: Fix build wreckage due to genirq wreckage. I wonder if the original contributor still cares ... Signed-off-by: Ralf Baechle --- arch/mips/emma2rh/common/irq_emma2rh.c | 2 +- arch/mips/emma2rh/markeins/irq_markeins.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c index 7c930860c92..197ed4c2ba0 100644 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/arch/mips/emma2rh/common/irq_emma2rh.c @@ -97,7 +97,7 @@ void emma2rh_irq_init(u32 irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &emma2rh_irq_controller; + irq_desc[i].chip = &emma2rh_irq_controller; } emma2rh_irq_base = irq_base; diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c index f23ae9fcffa..0b36eb001e6 100644 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/arch/mips/emma2rh/markeins/irq_markeins.c @@ -86,7 +86,7 @@ void emma2rh_sw_irq_init(u32 irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 2; - irq_desc[i].handler = &emma2rh_sw_irq_controller; + irq_desc[i].chip = &emma2rh_sw_irq_controller; } emma2rh_sw_irq_base = irq_base; @@ -166,7 +166,7 @@ void emma2rh_gpio_irq_init(u32 irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 2; - irq_desc[i].handler = &emma2rh_gpio_irq_controller; + irq_desc[i].chip = &emma2rh_gpio_irq_controller; } emma2rh_gpio_irq_base = irq_base; -- cgit v1.2.3 From e30e66becaa237d1753d148703cf8f1301ab27f0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 14:30:07 +0000 Subject: [MIPS] EMMA 2 / Markeins: Formitting fixes split from actual address fixes. Signed-off-by: Ralf Baechle --- arch/mips/emma2rh/markeins/platform.c | 49 ++++++++++++++++------------------- 1 file changed, 23 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c index 15cc61df362..0b884a12170 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma2rh/markeins/platform.c @@ -83,32 +83,29 @@ struct platform_device i2c_emma_devices[] = { #define EMMA2RH_SERIAL_FLAGS UPF_BOOT_AUTOCONF | UPF_SKIP_TEST static struct plat_serial8250_port platform_serial_ports[] = { - [0] = { - .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR0, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, - [1] = { - .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR1, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, - [2] = { - .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), - .irq = EMMA2RH_IRQ_PFUR2, - .uartclk = EMMA2RH_SERIAL_CLOCK, - .regshift = 4, - .iotype = UPIO_MEM, - .flags = EMMA2RH_SERIAL_FLAGS, - }, - [3] = { - .flags = 0, + [0] = { + .membase= (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR0, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, [1] = { + .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR1, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, [2] = { + .membase = (void __iomem*)KSEG1ADDR(EMMA2RH_PFUR2_BASE + 3), + .irq = EMMA2RH_IRQ_PFUR2, + .uartclk = EMMA2RH_SERIAL_CLOCK, + .regshift = 4, + .iotype = UPIO_MEM, + .flags = EMMA2RH_SERIAL_FLAGS, + }, [3] = { + .flags = 0, }, }; -- cgit v1.2.3 From 4aad7b726996a2d453d210cd5691730aca087b83 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 14:47:21 +0000 Subject: [MIPS] EMMA 2 / Markeins: Convert to name struct resource initialization. This fixes the wreckage caused by shuffeling the order of struct resource members. Signed-off-by: Ralf Baechle --- arch/mips/emma2rh/markeins/platform.c | 39 +++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c index 0b884a12170..be13cecfc06 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma2rh/markeins/platform.c @@ -44,18 +44,45 @@ #define I2C_EMMA2RH "emma2rh-iic" /* must be in sync with IIC driver */ static struct resource i2c_emma_resources_0[] = { - { NULL, EMMA2RH_IRQ_PIIC0, EMMA2RH_IRQ_PIIC0, IORESOURCE_IRQ }, - { NULL, KSEG1ADDR(EMMA2RH_PIIC0_BASE), KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), 0 }, + { + .name = NULL, + .start = EMMA2RH_IRQ_PIIC0, + .end = EMMA2RH_IRQ_PIIC0, + .flags = IORESOURCE_IRQ + }, { + .name = NULL, + .start = KSEG1ADDR(EMMA2RH_PIIC0_BASE), + .end = KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), + .flags = 0 + }, }; struct resource i2c_emma_resources_1[] = { - { NULL, EMMA2RH_IRQ_PIIC1, EMMA2RH_IRQ_PIIC1, IORESOURCE_IRQ }, - { NULL, KSEG1ADDR(EMMA2RH_PIIC1_BASE), KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), 0 }, + { + .name = NULL, + .start = EMMA2RH_IRQ_PIIC1, + .end = EMMA2RH_IRQ_PIIC1, + .flags = IORESOURCE_IRQ + }, { + .name = NULL, + .start = KSEG1ADDR(EMMA2RH_PIIC1_BASE), + .end = KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), + .flags = 0 + }, }; struct resource i2c_emma_resources_2[] = { - { NULL, EMMA2RH_IRQ_PIIC2, EMMA2RH_IRQ_PIIC2, IORESOURCE_IRQ }, - { NULL, KSEG1ADDR(EMMA2RH_PIIC2_BASE), KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), 0 }, + { + .name = NULL, + .start = EMMA2RH_IRQ_PIIC2, + .end = EMMA2RH_IRQ_PIIC2, + .flags = IORESOURCE_IRQ + }, { + .name = NULL, + .start = KSEG1ADDR(EMMA2RH_PIIC2_BASE), + .end = KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), + .flags = 0 + }, }; struct platform_device i2c_emma_devices[] = { -- cgit v1.2.3 From 77aec99906367276afedf6f5583671de2ff609be Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 14:59:54 +0000 Subject: [MIPS] EMMA 2 / Markeins: struct resource takes physical addresses. Signed-off-by: Ralf Baechle --- arch/mips/emma2rh/markeins/platform.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c index be13cecfc06..11567702b15 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma2rh/markeins/platform.c @@ -51,8 +51,8 @@ static struct resource i2c_emma_resources_0[] = { .flags = IORESOURCE_IRQ }, { .name = NULL, - .start = KSEG1ADDR(EMMA2RH_PIIC0_BASE), - .end = KSEG1ADDR(EMMA2RH_PIIC0_BASE + 0x1000), + .start = EMMA2RH_PIIC0_BASE, + .end = EMMA2RH_PIIC0_BASE + 0x1000, .flags = 0 }, }; @@ -65,8 +65,8 @@ struct resource i2c_emma_resources_1[] = { .flags = IORESOURCE_IRQ }, { .name = NULL, - .start = KSEG1ADDR(EMMA2RH_PIIC1_BASE), - .end = KSEG1ADDR(EMMA2RH_PIIC1_BASE + 0x1000), + .start = EMMA2RH_PIIC1_BASE, + .end = EMMA2RH_PIIC1_BASE + 0x1000, .flags = 0 }, }; @@ -79,8 +79,8 @@ struct resource i2c_emma_resources_2[] = { .flags = IORESOURCE_IRQ }, { .name = NULL, - .start = KSEG1ADDR(EMMA2RH_PIIC2_BASE), - .end = KSEG1ADDR(EMMA2RH_PIIC2_BASE + 0x1000), + .start = EMMA2RH_PIIC2_BASE, + .end = EMMA2RH_PIIC2_BASE + 0x1000, .flags = 0 }, }; -- cgit v1.2.3 From e52331845784daeefb78ab3b13efce51af3255bc Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 15:32:27 +0000 Subject: [MIPS] JMR3927: Fixup another victim of the irq pt_regs cleanup. Signed-off-by: Ralf Baechle --- arch/mips/jmr3927/rbhma3100/irq.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 39a0243bed9..de4a238c28b 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -288,6 +288,8 @@ static void tx_branch_likely_bug_fixup(void) static void jmr3927_spurious(void) { + struct pt_regs * regs = get_irq_regs(); + #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND tx_branch_likely_bug_fixup(); #endif @@ -297,6 +299,7 @@ static void jmr3927_spurious(void) asmlinkage void plat_irq_dispatch(void) { + struct pt_regs * regs = get_irq_regs(); int irq; #ifdef CONFIG_TX_BRANCH_LIKELY_BUG_WORKAROUND -- cgit v1.2.3 From 9001f2850ff92b52d7654379e7b7feb72f78f161 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 29 Oct 2006 16:32:31 -0800 Subject: [SPARC64]: Fix Tomatillo/Schizo IRQ handling. The code in schizo_irq_trans_init() should set irq_data->sync_reg to the location of the SYNC register if this is Tomatillo, and set it to zero otherwise. But that is not what it is doing. As a result, non-Tomatillo systems were trying to access a non-existent register resulting in bus errors at the first PCI interrupt. Thanks to Roland Stigge for the bug report. Signed-off-by: David S. Miller --- arch/sparc64/kernel/prom.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c60efb3cb22..0917c24c4f0 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -793,7 +793,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, return virt_irq; } -static void schizo_irq_trans_init(struct device_node *dp) +static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) { struct linux_prom64_registers *regs; struct schizo_irq_data *irq_data; @@ -807,11 +807,24 @@ static void schizo_irq_trans_init(struct device_node *dp) dp->irq_trans->data = irq_data; irq_data->pbm_regs = regs[0].phys_addr; - irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + if (is_tomatillo) + irq_data->sync_reg = regs[3].phys_addr + 0x1a18UL; + else + irq_data->sync_reg = 0UL; irq_data->portid = of_getintprop_default(dp, "portid", 0); irq_data->chip_version = of_getintprop_default(dp, "version#", 0); } +static void schizo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 0); +} + +static void tomatillo_irq_trans_init(struct device_node *dp) +{ + __schizo_irq_trans_init(dp, 1); +} + static unsigned int pci_sun4v_irq_build(struct device_node *dp, unsigned int devino, void *_data) @@ -1050,8 +1063,8 @@ static struct irq_trans pci_irq_trans_table[] = { { "pci108e,8001", schizo_irq_trans_init }, { "SUNW,schizo+", schizo_irq_trans_init }, { "pci108e,8002", schizo_irq_trans_init }, - { "SUNW,tomatillo", schizo_irq_trans_init }, - { "pci108e,a801", schizo_irq_trans_init }, + { "SUNW,tomatillo", tomatillo_irq_trans_init }, + { "pci108e,a801", tomatillo_irq_trans_init }, { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, }; #endif -- cgit v1.2.3 From 5af47db796cb7e06e9bafb0d75ad98693b55f8b6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 30 Oct 2006 01:10:20 -0800 Subject: [SPARC64]: Add some missing print_symbol() calls. Signed-off-by: David S. Miller --- arch/sparc64/kernel/traps.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 68420e2dad0..fe1796c939c 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -87,6 +87,7 @@ static void dump_tl1_traplog(struct tl1_traplog *p) i + 1, p->trapstack[i].tstate, p->trapstack[i].tpc, p->trapstack[i].tnpc, p->trapstack[i].tt); + print_symbol("TRAPLOG: TPC<%s>\n", p->trapstack[i].tpc); } } @@ -1134,6 +1135,9 @@ static void cheetah_log_errors(struct pt_regs *regs, struct cheetah_err_info *in printk("%s" "ERROR(%d): TPC[%lx] TNPC[%lx] O7[%lx] TSTATE[%lx]\n", (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), regs->tpc, regs->tnpc, regs->u_regs[UREG_I7], regs->tstate); + printk("%s" "ERROR(%d): ", + (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id()); + print_symbol("TPC<%s>\n", regs->tpc); printk("%s" "ERROR(%d): M_SYND(%lx), E_SYND(%lx)%s%s\n", (recoverable ? KERN_WARNING : KERN_CRIT), smp_processor_id(), (afsr & CHAFSR_M_SYNDROME) >> CHAFSR_M_SYNDROME_SHIFT, @@ -1741,6 +1745,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs) smp_processor_id(), (type & 0x1) ? 'I' : 'D', regs->tpc); + print_symbol(KERN_EMERG "TPC<%s>\n", regs->tpc); panic("Irrecoverable Cheetah+ parity error."); } @@ -1748,6 +1753,7 @@ void cheetah_plus_parity_error(int type, struct pt_regs *regs) smp_processor_id(), (type & 0x1) ? 'I' : 'D', regs->tpc); + print_symbol(KERN_WARNING "TPC<%s>\n", regs->tpc); } struct sun4v_error_entry { @@ -1946,6 +1952,7 @@ void sun4v_itlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-ITLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); + print_symbol(KERN_EMERG "SUN4V-ITLB: TPC<%s>\n", regs->tpc); printk(KERN_EMERG "SUN4V-ITLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_itlb_vaddr, sun4v_err_itlb_ctx, @@ -1966,6 +1973,7 @@ void sun4v_dtlb_error_report(struct pt_regs *regs, int tl) printk(KERN_EMERG "SUN4V-DTLB: Error at TPC[%lx], tl %d\n", regs->tpc, tl); + print_symbol(KERN_EMERG "SUN4V-DTLB: TPC<%s>\n", regs->tpc); printk(KERN_EMERG "SUN4V-DTLB: vaddr[%lx] ctx[%lx] " "pte[%lx] error[%lx]\n", sun4v_err_dtlb_vaddr, sun4v_err_dtlb_ctx, -- cgit v1.2.3 From 6887d83d6a537b5002edff7efa1a7c600af0ce26 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 Oct 2006 11:44:25 +0900 Subject: sh: Wire up new syscalls. This wires up sys_move_pages, sys_getcpu, and sys_epoll_pwait. Signed-off-by: Paul Mundt --- arch/sh/kernel/syscalls.S | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index 768334e9507..ca81976e9e3 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S @@ -351,3 +351,6 @@ ENTRY(sys_call_table) .long sys_sync_file_range .long sys_tee /* 315 */ .long sys_vmsplice + .long sys_move_pages + .long sys_getcpu + .long sys_epoll_pwait -- cgit v1.2.3 From 1f6c526c409ed7ecdd02469c46ab4b4a50ebec45 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 Oct 2006 12:33:30 +0900 Subject: sh: Update r7780rp_defconfig. Small defconfig updates for R7780RP, enabling SH-RTC. Signed-off-by: Paul Mundt --- arch/sh/configs/r7780rp_defconfig | 174 +++++++++++++++++++++----------------- 1 file changed, 98 insertions(+), 76 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig index 2470364948e..34e2046c321 100644 --- a/arch/sh/configs/r7780rp_defconfig +++ b/arch/sh/configs/r7780rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 11:32:47 2006 +# Linux kernel version: 2.6.19-rc3 +# Tue Oct 31 12:32:06 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -178,7 +179,7 @@ CONFIG_MMU=y CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 -CONFIG_32BIT=y +# CONFIG_32BIT is not set CONFIG_VSYSCALL=y CONFIG_HUGETLB_PAGE_SIZE_64K=y # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set @@ -229,9 +230,7 @@ CONFIG_SH_PCLK_FREQ=32000000 # # DMA support # -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=6 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set +# CONFIG_SH_DMA is not set # # Companion Chips @@ -259,7 +258,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1" +CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/sda1" # # Bus options @@ -336,6 +335,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -440,77 +440,29 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # -CONFIG_IDE=m -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=m - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -CONFIG_BLK_DEV_IDE_SATA=y -CONFIG_BLK_DEV_IDEDISK=m -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=m -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=m -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_AEC62XX=m -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -CONFIG_BLK_DEV_PDC202XX_NEW=m -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=m -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set +# CONFIG_IDE is not set # # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m +CONFIG_SCSI=y # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set @@ -561,6 +513,7 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -570,7 +523,55 @@ CONFIG_CHR_DEV_SG=m # # Serial ATA (prod) and Parallel ATA (experimental) drivers # -# CONFIG_ATA is not set +CONFIG_ATA=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +CONFIG_SATA_SIL=y +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set # # Multi-device support (RAID and LVM) @@ -840,7 +841,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -856,6 +856,7 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -867,15 +868,10 @@ CONFIG_HWMON=y # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Misc devices -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -959,7 +955,29 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_SH=y +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set # # DMA Engine support @@ -984,6 +1002,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -991,6 +1010,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set CONFIG_FS_POSIX_ACL=y # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set CONFIG_MINIX_FS=y # CONFIG_ROMFS_FS is not set @@ -1027,7 +1047,8 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y @@ -1159,6 +1180,7 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set @@ -1178,9 +1200,9 @@ CONFIG_FORCED_INLINING=y # CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set @@ -1191,7 +1213,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_WP512 is not set # CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.2.3 From bd71ab88deab3358241f22ed6c035c427aacc4e7 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Tue, 31 Oct 2006 12:35:02 +0900 Subject: sh: Fix IPR-IRQ's for IRQ-chip change breakage. The conversion from IPR-IRQ to IRQ-chip resulted in the ipr data being allocated in a local variable in make_ipr_irq - breaking anything using IPR interrupts. This changes all of the callers of make_ipr_irq to allocate a static structure containing the IPR data which is then passed to make_ipr_irq. This removes the need for make_ipr_irq to allocate any additional space for the IPR information. Signed-off-by: Jamie Lenehan Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/hs7751rvoip/setup.c | 12 ++-- arch/sh/boards/renesas/sh7710voipgw/setup.c | 105 ++++++++++++--------------- arch/sh/boards/se/7300/irq.c | 20 +++--- arch/sh/boards/se/73180/irq.c | 47 +++++++----- arch/sh/boards/se/7343/irq.c | 90 ++++++++++++----------- arch/sh/boards/se/770x/irq.c | 80 +++++++++++---------- arch/sh/boards/se/7751/irq.c | 85 +++++++++++----------- arch/sh/boards/sh03/setup.c | 13 ++-- arch/sh/boards/snapgear/setup.c | 12 ++-- arch/sh/boards/titan/setup.c | 12 ++-- arch/sh/drivers/dma/dma-sh.c | 42 ++++++----- arch/sh/kernel/cpu/irq/ipr.c | 106 +++++++++++++--------------- arch/sh/kernel/cpu/irq/pint.c | 8 ++- 13 files changed, 331 insertions(+), 301 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/renesas/hs7751rvoip/setup.c b/arch/sh/boards/renesas/hs7751rvoip/setup.c index 1d997ffd793..f7d0e304d89 100644 --- a/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -15,12 +15,16 @@ #include #include -static void __init hs7751rvoip_init_irq(void) -{ +static struct ipr_data hs77501rvoip_ipr_map[] = { #if defined(CONFIG_HS7751RVOIP_CODEC) - make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, #endif +}; + +static void __init hs7751rvoip_init_irq(void) +{ + make_ipr_irq(hs77501rvoip_ipr_map, ARRAY_SIZE(hs77501rvoip_ipr_map)); init_hs7751rvoip_IRQ(); } diff --git a/arch/sh/boards/renesas/sh7710voipgw/setup.c b/arch/sh/boards/renesas/sh7710voipgw/setup.c index e57e7afab8c..180810b1210 100644 --- a/arch/sh/boards/renesas/sh7710voipgw/setup.c +++ b/arch/sh/boards/renesas/sh7710voipgw/setup.c @@ -13,6 +13,51 @@ #include #include +static struct ipr_data sh7710voipgw_ipr_map[] = { + { TIMER2_IRQ, TIMER2_IPR_ADDR, TIMER2_IPR_POS, TIMER2_PRIORITY }, + { WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY }, + + /* SCIF0 */ + { SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, + { SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, + { SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, + { SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, + + /* DMAC-1 */ + { DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + + /* DMAC-2 */ + { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, + { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, + + /* IPSEC */ + { IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY }, + + /* EDMAC */ + { EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, EDMAC0_PRIORITY }, + { EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, EDMAC1_PRIORITY }, + { EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, EDMAC2_PRIORITY }, + + /* SIOF0 */ + { SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + + /* SIOF1 */ + { SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, + { SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, + { SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, + { SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, SIOF1_PRIORITY }, + + /* SLIC IRQ's */ + { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, + { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, +}; + /* * Initialize IRQ setting */ @@ -37,65 +82,7 @@ static void __init sh7710voipgw_init_irq(void) */ ctrl_outw(0x2aa, INTC_ICR1); - /* Now make IPR interrupts */ - make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR, - TIMER2_IPR_POS, TIMER2_PRIORITY); - make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY); - - /* SCIF0 */ - make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - - /* DMAC-1 */ - make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - - /* DMAC-2 */ - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - - /* IPSEC */ - make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY); - - /* EDMAC */ - make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, - EDMAC0_PRIORITY); - make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, - EDMAC1_PRIORITY); - make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, - EDMAC2_PRIORITY); - - /* SIOF0 */ - make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - - /* SIOF1 */ - make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - - /* SLIC IRQ's */ - make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); - make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); + make_ipr_irq(sh7710voipgw_ipr_map, ARRAY_SIZE(sh7710voipgw_ipr_map)); } /* diff --git a/arch/sh/boards/se/7300/irq.c b/arch/sh/boards/se/7300/irq.c index ad1034f98a2..1279d776d60 100644 --- a/arch/sh/boards/se/7300/irq.c +++ b/arch/sh/boards/se/7300/irq.c @@ -13,6 +13,17 @@ #include #include +static struct ipr_data se7300_ipr_map[] = { + /* PC_IRQ[0-3] -> IRQ0 (32) */ + { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ }, + /* A_IRQ[0-3] -> IRQ1 (33) */ + { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ }, + { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, +}; + /* * Initialize IRQ setting */ @@ -23,14 +34,7 @@ init_7300se_IRQ(void) ctrl_outw(0xa000, INTC_ICR1); /* IRQ mode; IRQ0,1 enable. */ ctrl_outw(0x0000, PORT_PFCR); /* use F for IRQ[3:0] and SIU. */ - /* PC_IRQ[0-3] -> IRQ0 (32) */ - make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, 0x0f - IRQ0_IRQ); - /* A_IRQ[0-3] -> IRQ1 (33) */ - make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, 0x0f - IRQ1_IRQ); - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(se7300_ipr_map, ARRAY_SIZE(se7300_ipr_map)); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/arch/sh/boards/se/73180/irq.c b/arch/sh/boards/se/73180/irq.c index 2c62b8ea350..e7200c56bb4 100644 --- a/arch/sh/boards/se/73180/irq.c +++ b/arch/sh/boards/se/73180/irq.c @@ -87,13 +87,38 @@ shmse_irq_demux(int irq) return irq; } +static struct ipr_data se73180_siof0_ipr_map[] = { + { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, +}; +static struct ipr_data se73180_vpu_ipr_map[] = { + { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 }, +}; +static struct ipr_data se73180_other_ipr_map[] = { + { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, + { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY }, + + /* VIO interrupt */ + { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + + { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY }, +}; + /* * Initialize IRQ setting */ void __init init_73180se_IRQ(void) { - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(se73180_siof0_ipr_map, ARRAY_SIZE(se73180_siof0_ipr_map)); ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */ ctrl_outw(0x2000, 0xb07fffec); /* mrshpc irq enable */ @@ -101,27 +126,11 @@ init_73180se_IRQ(void) ctrl_outw(2 << ((7 - 5) * 2), INTC_ICR1); /* low-level irq */ make_intreq_irq(10); - make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); + make_ipr_irq(se73180_vpu_ipr_map, ARRAY_SIZE(se73180_vpu_ipr_map)); ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ - make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); - make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); - - /* VIO interrupt */ - make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + make_ipr_irq(se73180_other_ipr_map, ARRAY_SIZE(se73180_other_ipr_map)); - make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/arch/sh/boards/se/7343/irq.c b/arch/sh/boards/se/7343/irq.c index 288b62f5941..360153ecc55 100644 --- a/arch/sh/boards/se/7343/irq.c +++ b/arch/sh/boards/se/7343/irq.c @@ -102,6 +102,51 @@ shmse_irq_demux(int irq) static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade", NULL, NULL}; +static struct ipr_data se7343_irq5_ipr_map[] = { + { IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY }, +}; +static struct ipr_data se7343_siof0_vpu_ipr_map[] = { + { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + { VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8 }, +}; +static struct ipr_data se7343_other_ipr_map[] = { + { DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, + { DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY }, + + /* I2C block */ + { IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + { IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY }, + + { IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, + { IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, + { IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, + { IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY }, + + /* SIOF */ + { SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY }, + + /* SIU */ + { SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY }, + + /* VIO interrupt */ + { CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + { BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + { VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, + + /*MFI interrupt*/ + + { MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY }, + + /* LCD controller */ + { LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY }, +}; + /* * Initialize IRQ setting */ @@ -138,54 +183,17 @@ init_7343se_IRQ(void) /* Setup all external interrupts to be active low */ ctrl_outw(0xaaaa, INTC_ICR1); - make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY); + make_ipr_irq(se7343_irq5_ipr_map, ARRAY_SIZE(se7343_irq5_ipr_map)); + setup_irq(IRQ5_IRQ, &irq5); /* Set port control to use IRQ5 */ *(u16 *)0xA4050108 &= ~0xc; - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); - make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); + make_ipr_irq(se7343_siof0_vpu_ipr_map, ARRAY_SIZE(se7343_siof0_vpu_ipr_map)); ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ - make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - - /* I2C block */ - make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - - make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); - make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, - IIC1_PRIORITY); - make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, - IIC1_PRIORITY); - make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); - - /* SIOF */ - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); + make_ipr_irq(se7343_other_ipr_map, ARRAY_SIZE(se7343_other_ipr_map)); - /* SIU */ - make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); - - /* VIO interrupt */ - make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - - /*MFI interrupt*/ - - make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY); - - /* LCD controller */ - make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ } diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index cff6700bbaf..fcd7cd7fa05 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c @@ -13,6 +13,48 @@ #include #include +static struct ipr_data se770x_ipr_map[] = { +#if defined(CONFIG_CPU_SUBTYPE_SH7705) + /* This is default value */ + { 0xf-0x2, BCR_ILCRA, 2, 0x2 }, + { 0xf-0xa, BCR_ILCRA, 1, 0xa }, + { 0xf-0x5, BCR_ILCRB, 0, 0x5 }, + { 0xf-0x8, BCR_ILCRC, 1, 0x8 }, + { 0xf-0xc, BCR_ILCRC, 0, 0xc }, + { 0xf-0xe, BCR_ILCRD, 3, 0xe }, + { 0xf-0x3, BCR_ILCRD, 1, 0x3 }, /* LAN */ + { 0xf-0xd, BCR_ILCRE, 2, 0xd }, + { 0xf-0x9, BCR_ILCRE, 1, 0x9 }, + { 0xf-0x1, BCR_ILCRE, 0, 0x1 }, + { 0xf-0xf, BCR_ILCRF, 3, 0xf }, + { 0xf-0xb, BCR_ILCRF, 1, 0xb }, + { 0xf-0x7, BCR_ILCRG, 3, 0x7 }, + { 0xf-0x6, BCR_ILCRG, 2, 0x6 }, + { 0xf-0x4, BCR_ILCRG, 1, 0x4 }, +#else + { 14, BCR_ILCRA, 2, 0x0f-14 }, + { 12, BCR_ILCRA, 1, 0x0f-12 }, + { 8, BCR_ILCRB, 1, 0x0f- 8 }, + { 6, BCR_ILCRC, 3, 0x0f- 6 }, + { 5, BCR_ILCRC, 2, 0x0f- 5 }, + { 4, BCR_ILCRC, 1, 0x0f- 4 }, + { 3, BCR_ILCRC, 0, 0x0f- 3 }, + { 1, BCR_ILCRD, 3, 0x0f- 1 }, + + { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ + + { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ + { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ + { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ + { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ + + /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ + /* NOTE: #2 and #13 are not used on PC */ + { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ + { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ +#endif +}; + /* * Initialize IRQ setting */ @@ -38,42 +80,6 @@ void __init init_se_IRQ(void) ctrl_outw(0, BCR_ILCRE); ctrl_outw(0, BCR_ILCRF); ctrl_outw(0, BCR_ILCRG); - /* This is default value */ - make_ipr_irq(0xf-0x2, BCR_ILCRA, 2, 0x2); - make_ipr_irq(0xf-0xa, BCR_ILCRA, 1, 0xa); - make_ipr_irq(0xf-0x5, BCR_ILCRB, 0, 0x5); - make_ipr_irq(0xf-0x8, BCR_ILCRC, 1, 0x8); - make_ipr_irq(0xf-0xc, BCR_ILCRC, 0, 0xc); - make_ipr_irq(0xf-0xe, BCR_ILCRD, 3, 0xe); - make_ipr_irq(0xf-0x3, BCR_ILCRD, 1, 0x3); /* LAN */ - make_ipr_irq(0xf-0xd, BCR_ILCRE, 2, 0xd); - make_ipr_irq(0xf-0x9, BCR_ILCRE, 1, 0x9); - make_ipr_irq(0xf-0x1, BCR_ILCRE, 0, 0x1); - make_ipr_irq(0xf-0xf, BCR_ILCRF, 3, 0xf); - make_ipr_irq(0xf-0xb, BCR_ILCRF, 1, 0xb); - make_ipr_irq(0xf-0x7, BCR_ILCRG, 3, 0x7); - make_ipr_irq(0xf-0x6, BCR_ILCRG, 2, 0x6); - make_ipr_irq(0xf-0x4, BCR_ILCRG, 1, 0x4); -#else - make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); - make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); - make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); - make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); - make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); - make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); - make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); - make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); - - make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ - - make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ - make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ - make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ - make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ - - /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ - /* NOTE: #2 and #13 are not used on PC */ - make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ - make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ #endif + make_ipr_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); } diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c index c607b0a4847..e4c63a48296 100644 --- a/arch/sh/boards/se/7751/irq.c +++ b/arch/sh/boards/se/7751/irq.c @@ -14,53 +14,50 @@ #include #include -/* - * Initialize IRQ setting - */ -void __init init_7751se_IRQ(void) -{ - +static struct ipr_data se7751_ipr_map[] = { /* Leave old Solution Engine code in for reference. */ #if defined(CONFIG_SH_SOLUTION_ENGINE) - /* - * Super I/O (Just mimic PC): - * 1: keyboard - * 3: serial 0 - * 4: serial 1 - * 5: printer - * 6: floppy - * 8: rtc - * 12: mouse - * 14: ide0 - */ - make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-14); - make_ipr_irq(12, BCR_ILCRA, 1, 0x0f-12); - make_ipr_irq( 8, BCR_ILCRB, 1, 0x0f- 8); - make_ipr_irq( 6, BCR_ILCRC, 3, 0x0f- 6); - make_ipr_irq( 5, BCR_ILCRC, 2, 0x0f- 5); - make_ipr_irq( 4, BCR_ILCRC, 1, 0x0f- 4); - make_ipr_irq( 3, BCR_ILCRC, 0, 0x0f- 3); - make_ipr_irq( 1, BCR_ILCRD, 3, 0x0f- 1); - - make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); /* LAN */ - - make_ipr_irq( 0, BCR_ILCRE, 3, 0x0f- 0); /* PCIRQ3 */ - make_ipr_irq(11, BCR_ILCRE, 2, 0x0f-11); /* PCIRQ2 */ - make_ipr_irq( 9, BCR_ILCRE, 1, 0x0f- 9); /* PCIRQ1 */ - make_ipr_irq( 7, BCR_ILCRE, 0, 0x0f- 7); /* PCIRQ0 */ - - /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ - /* NOTE: #2 and #13 are not used on PC */ - make_ipr_irq(13, BCR_ILCRG, 1, 0x0f-13); /* SLOTIRQ2 */ - make_ipr_irq( 2, BCR_ILCRG, 0, 0x0f- 2); /* SLOTIRQ1 */ - + /* + * Super I/O (Just mimic PC): + * 1: keyboard + * 3: serial 0 + * 4: serial 1 + * 5: printer + * 6: floppy + * 8: rtc + * 12: mouse + * 14: ide0 + */ + { 14, BCR_ILCRA, 2, 0x0f-14 }, + { 12, BCR_ILCRA, 1, 0x0f-12 }, + { 8, BCR_ILCRB, 1, 0x0f- 8 }, + { 6, BCR_ILCRC, 3, 0x0f- 6 }, + { 5, BCR_ILCRC, 2, 0x0f- 5 }, + { 4, BCR_ILCRC, 1, 0x0f- 4 }, + { 3, BCR_ILCRC, 0, 0x0f- 3 }, + { 1, BCR_ILCRD, 3, 0x0f- 1 }, + + { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ + + { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ + { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ + { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ + { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ + + /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ + /* NOTE: #2 and #13 are not used on PC */ + { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ + { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ #elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) - - make_ipr_irq(13, BCR_ILCRD, 3, 2); - - /* Add additional calls to make_ipr_irq() as drivers are added - * and tested. - */ + { 13, BCR_ILCRD, 3, 2 }, + /* Add additional entries here as drivers are added and tested. */ #endif +}; +/* + * Initialize IRQ setting + */ +void __init init_7751se_IRQ(void) +{ + make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map)); } diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index 137e2ba9243..5ad1e19771b 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c @@ -14,14 +14,17 @@ #include #include +static struct ipr_data sh03_ipr_map[] = { + { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, + { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, + { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, + { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, +}; + static void __init init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - - make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); - make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); - make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); - make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); + make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map)); } extern void *cf_io_base; diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index 540d0bf1644..650fb364594 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c @@ -68,6 +68,13 @@ module_init(eraseconfig_init); * IRL3 = crypto */ +static struct ipr_data snapgear_ipr_map[] = { + make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); + make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); + make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); + make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); +}; + static void __init init_snapgear_IRQ(void) { /* enable individual interrupt mode for externals */ @@ -75,10 +82,7 @@ static void __init init_snapgear_IRQ(void) printk("Setup SnapGear IRQ/IPR ...\n"); - make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); - make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); - make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); - make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); + make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map)); } /* diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 52b66d8b8d2..a6046d93758 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -9,15 +9,19 @@ extern void __init pcibios_init_platform(void); +static struct ipr_data titan_ipr_map[] = { + { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, + { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, + { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, + { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, +}; + static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - make_ipr_irq( TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */ - make_ipr_irq( TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */ - make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */ - make_ipr_irq( TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */ + make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); } struct sh_machine_vector mv_titan __initmv = { diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index d8ece20bb2c..66078601335 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -19,23 +19,34 @@ #include #include "dma-sh.h" -static inline unsigned int get_dmte_irq(unsigned int chan) -{ - unsigned int irq = 0; + +#ifdef CONFIG_CPU_SH4 +static struct ipr_data dmae_ipr_map[] = { + { DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, +}; +#endif +static struct ipr_data dmte_ipr_map[] = { /* * Normally we could just do DMTE0_IRQ + chan outright, though in the * case of the 7751R, the DMTE IRQs for channels > 4 start right above * the SCIF */ - if (chan < 4) { - irq = DMTE0_IRQ + chan; - } else { -#ifdef DMTE4_IRQ - irq = DMTE4_IRQ + chan - 4; -#endif - } + { DMTE0_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE0_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE0_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE0_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE4_IRQ + 0, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE4_IRQ + 1, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE4_IRQ + 2, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, + { DMTE4_IRQ + 3, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY }, +}; +static inline unsigned int get_dmte_irq(unsigned int chan) +{ + unsigned int irq = 0; + if (chan < ARRAY_SIZE(dmte_ipr_map)) + irq = dmte_ipr_map[chan].irq; return irq; } @@ -258,17 +269,16 @@ static int __init sh_dmac_init(void) int i; #ifdef CONFIG_CPU_SH4 - make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); + make_ipr_irq(dmae_ipr_map, ARRAY_SIZE(dmae_ipr_map)); i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); if (unlikely(i < 0)) return i; #endif - for (i = 0; i < info->nr_channels; i++) { - int irq = get_dmte_irq(i); - - make_ipr_irq(irq, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - } + i = info->nr_channels; + if (i > ARRAY_SIZE(dmte_ipr_map)) + i = ARRAY_SIZE(dmte_ipr_map); + make_ipr_irq(dmte_ipr_map, i); /* * Initialize DMAOR, and clean up any error flags that may have diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index f7997312ef9..a0089563cbf 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -23,24 +23,21 @@ #include #include -struct ipr_data { - unsigned int addr; /* Address of Interrupt Priority Register */ - int shift; /* Shifts of the 16-bit data */ - int priority; /* The priority */ -}; static void disable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + int shift = p->shift*4; /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); + ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr); } static void enable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); + int shift = p->shift*4; /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); + ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr); } static struct irq_chip ipr_irq_chip = { @@ -50,67 +47,57 @@ static struct irq_chip ipr_irq_chip = { .mask_ack = disable_ipr_irq, }; -void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) +void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) { - struct ipr_data ipr_data; - - disable_irq_nosync(irq); - - ipr_data.addr = addr; - ipr_data.shift = pos*4; /* POSition (0-3) x 4 means shift */ - ipr_data.priority = priority; + int i; - set_irq_chip_and_handler_name(irq, &ipr_irq_chip, + for (i = 0; i < nr_irqs; i++) { + unsigned int irq = table[i].irq; + disable_irq_nosync(irq); + set_irq_chip_and_handler_name(irq, &ipr_irq_chip, handle_level_irq, "level"); - set_irq_chip_data(irq, &ipr_data); - - enable_ipr_irq(irq); + set_irq_chip_data(irq, &table[i]); + enable_ipr_irq(irq); + } } +EXPORT_SYMBOL(make_ipr_irq); -/* XXX: This needs to die a horrible death.. */ -void __init init_IRQ(void) -{ +static struct ipr_data sys_ipr_map[] = { #ifndef CONFIG_CPU_SUBTYPE_SH7780 - make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); - make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); + { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, + { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY }, #ifdef RTC_IRQ - make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); + { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY }, #endif - #ifdef SCI_ERI_IRQ - make_ipr_irq(SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); - make_ipr_irq(SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); - make_ipr_irq(SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY); + { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, + { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, + { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, #endif - #ifdef SCIF1_ERI_IRQ - make_ipr_irq(SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); - make_ipr_irq(SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); - make_ipr_irq(SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); - make_ipr_irq(SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY); + { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, + { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, #endif - #if defined(CONFIG_CPU_SUBTYPE_SH7300) - make_ipr_irq(SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); + { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, + { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, + { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, #endif - #ifdef SCIF_ERI_IRQ - make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); - make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); - make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); - make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY); + { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, + { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, #endif - #ifdef IRDA_ERI_IRQ - make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); - make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); - make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); - make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY); + { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, + { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, #endif - #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) @@ -124,14 +111,19 @@ void __init init_IRQ(void) * You should set corresponding bits of PFC to "00" * to enable these interrupts. */ - make_ipr_irq(IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY); - make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); - make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); - make_ipr_irq(IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY); - make_ipr_irq(IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY); - make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY); + { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY }, + { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, + { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, + { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY }, + { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY }, + { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY }, #endif #endif +}; + +void __init init_IRQ(void) +{ + make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map)); #ifdef CONFIG_CPU_HAS_PINT_IRQ init_IRQ_pint(); @@ -153,5 +145,3 @@ int ipr_irq_demux(int irq) return irq; } #endif - -EXPORT_SYMBOL(make_ipr_irq); diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c index 17f47b373d6..f60007783a2 100644 --- a/arch/sh/kernel/cpu/irq/pint.c +++ b/arch/sh/kernel/cpu/irq/pint.c @@ -84,12 +84,16 @@ void make_pint_irq(unsigned int irq) disable_pint_irq(irq); } +static struct ipr_data pint_ipr_map[] = { + { PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY }, + { PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY }, +}; + void __init init_IRQ_pint(void) { int i; - make_ipr_irq(PINT0_IRQ, PINT0_IPR_ADDR, PINT0_IPR_POS, PINT0_PRIORITY); - make_ipr_irq(PINT8_IRQ, PINT8_IPR_ADDR, PINT8_IPR_POS, PINT8_PRIORITY); + make_ipr_irq(pint_ipr_map, ARRAY_SIZE(pint_ipr_map)); enable_irq(PINT0_IRQ); enable_irq(PINT8_IRQ); -- cgit v1.2.3 From 4731f2dfd5049b7a2b3b5a7131525f6151855f0d Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Tue, 31 Oct 2006 12:36:35 +0900 Subject: sh: Titan defconfig update. Small defconfig update for titan for 2.6.19-rc3, adding SH-RTC. Signed-off-by: Jamie Lenehan Signed-off-by: Paul Mundt --- arch/sh/configs/titan_defconfig | 101 ++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index 5e817546113..41049cf14b7 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 12:59:14 2006 +# Linux kernel version: 2.6.19-rc3 +# Mon Oct 30 18:04:49 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,6 +10,7 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -23,7 +24,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set @@ -236,8 +237,8 @@ CONFIG_HZ_250=y CONFIG_HZ=250 # CONFIG_KEXEC is not set # CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set # @@ -247,7 +248,7 @@ CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x009e0000 # CONFIG_UBC_WAKEUP is not set CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf" +CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf rw" # # Bus options @@ -334,6 +335,7 @@ CONFIG_INET_XFRM_TUNNEL=y CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m # CONFIG_TCP_CONG_ADVANCED is not set @@ -355,9 +357,10 @@ CONFIG_INET6_XFRM_TUNNEL=y CONFIG_INET6_TUNNEL=y CONFIG_INET6_XFRM_MODE_TRANSPORT=y CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=y -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y @@ -713,6 +716,12 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -778,9 +787,9 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set @@ -1095,7 +1104,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -1123,15 +1131,10 @@ CONFIG_HWMON=y # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Misc devices -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -1177,9 +1180,9 @@ CONFIG_USB_DEVICEFS=y # USB Host Controller Drivers # CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_SPLIT_ISO=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y # CONFIG_USB_OHCI_BIG_ENDIAN is not set @@ -1235,7 +1238,6 @@ CONFIG_USB_STORAGE=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1246,11 +1248,20 @@ CONFIG_USB_STORAGE=y # # USB Network Adapters # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=m +CONFIG_USB_NET_PLUSB=m +# CONFIG_USB_NET_MCS7830 is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +CONFIG_USB_NET_ZAURUS=m CONFIG_USB_MON=y # @@ -1285,6 +1296,7 @@ CONFIG_USB_SERIAL_ARK3116=m # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set # CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m @@ -1316,6 +1328,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1357,7 +1370,26 @@ CONFIG_USB_SERIAL_PL2303=m # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +CONFIG_RTC_DRV_SH=m +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set # # DMA Engine support @@ -1380,8 +1412,12 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set +CONFIG_EXT4DEV_FS=m +# CONFIG_EXT4DEV_FS_XATTR is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=m +# CONFIG_JBD2_DEBUG is not set CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set @@ -1393,9 +1429,10 @@ CONFIG_XFS_FS=m # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set +CONFIG_ROMFS_FS=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set @@ -1480,7 +1517,12 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_WEAK_PW_HASH=y +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1583,9 +1625,10 @@ CONFIG_LOG_BUF_SHIFT=16 # CONFIG_DEBUG_LIST is not set # CONFIG_FRAME_POINTER is not set # CONFIG_FORCED_INLINING is not set +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y +# CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_EARLY_PRINTK is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set @@ -1605,7 +1648,7 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=m @@ -1615,7 +1658,7 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m -- cgit v1.2.3 From 97d88ac83540f9ba9536326c30db4815c5b9169b Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:03 -0800 Subject: [PATCH] uml ubd driver: allow using up to 16 UBD devices With 256 minors and 16 minors used per each UBD device, we can allow the use of up to 16 UBD devices per UML. Also chnage parse_unit and leave to the caller (which already do it) the check for excess numbers, since this is just supposed to do raw parsing. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index bc458f57921..54d24738280 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -117,7 +117,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); -#define MAX_DEV (8) +#define MAX_DEV (16) static struct block_device_operations ubd_blops = { .owner = THIS_MODULE, @@ -277,7 +277,7 @@ static int parse_unit(char **ptr) return(-1); *ptr = end; } - else if (('a' <= *str) && (*str <= 'h')) { + else if (('a' <= *str) && (*str <= 'z')) { n = *str - 'a'; str++; *ptr = str; -- cgit v1.2.3 From 2a9d32f682b2b4928dcd4680bc99e98a3d096816 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:04 -0800 Subject: [PATCH] uml ubd driver: document some struct fields Add documentation about some fields in struct ubd, whose meaning is non-obvious due to struct names (should change names altogether, I agree). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 54d24738280..e104f59ec51 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -150,8 +150,9 @@ static struct gendisk *fake_gendisk[MAX_DEV]; static struct openflags global_openflags = OPEN_FLAGS; struct cow { - /* This is the backing file, actually */ + /* backing file name */ char *file; + /* backing file fd */ int fd; unsigned long *bitmap; unsigned long bitmap_len; @@ -160,6 +161,8 @@ struct cow { }; struct ubd { + /* name (and fd, below) of the file opened for writing, either the + * backing or the cow file. */ char *file; int count; int fd; -- cgit v1.2.3 From 7d314e346d6081e8013a96206e601a48528d8f60 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:05 -0800 Subject: [PATCH] uml ubd driver: var renames Rename the ubd_dev array to ubd_devs and then call any "struct ubd" ubd_dev instead of dev, which doesn't make clear what we're treating (and no, it's not hungarian notation - not any more than calling all vm_area_struct vma or all inodes inode). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 196 ++++++++++++++++++++++----------------------- 1 file changed, 98 insertions(+), 98 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index e104f59ec51..761e3f9cac2 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -195,14 +195,14 @@ struct ubd { .cow = DEFAULT_COW, \ } -struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; +struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; static int ubd0_init(void) { - struct ubd *dev = &ubd_dev[0]; + struct ubd *ubd_dev = &ubd_devs[0]; - if(dev->file == NULL) - dev->file = "root_fs"; + if(ubd_dev->file == NULL) + ubd_dev->file = "root_fs"; return(0); } @@ -290,7 +290,7 @@ static int parse_unit(char **ptr) static int ubd_setup_common(char *str, int *index_out) { - struct ubd *dev; + struct ubd *ubd_dev; struct openflags flags = global_openflags; char *backing_file; int n, err, i; @@ -345,8 +345,8 @@ static int ubd_setup_common(char *str, int *index_out) err = 1; spin_lock(&ubd_lock); - dev = &ubd_dev[n]; - if(dev->file != NULL){ + ubd_dev = &ubd_devs[n]; + if(ubd_dev->file != NULL){ printk(KERN_ERR "ubd_setup : device already configured\n"); goto out; } @@ -363,10 +363,10 @@ static int ubd_setup_common(char *str, int *index_out) flags.s = 1; break; case 'd': - dev->no_cow = 1; + ubd_dev->no_cow = 1; break; case 'c': - dev->shared = 1; + ubd_dev->shared = 1; break; case '=': str++; @@ -393,7 +393,7 @@ break_loop: } if(backing_file){ - if(dev->no_cow) + if(ubd_dev->no_cow) printk(KERN_ERR "Can't specify both 'd' and a " "cow file\n"); else { @@ -401,9 +401,9 @@ break_loop: backing_file++; } } - dev->file = str; - dev->cow.file = backing_file; - dev->boot_openflags = flags; + ubd_dev->file = str; + ubd_dev->cow.file = backing_file; + ubd_dev->boot_openflags = flags; out: spin_unlock(&ubd_lock); return(err); @@ -544,83 +544,83 @@ void kill_io_thread(void) __uml_exitcall(kill_io_thread); -static int ubd_file_size(struct ubd *dev, __u64 *size_out) +static int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; - file = dev->cow.file ? dev->cow.file : dev->file; + file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; return(os_file_size(file, size_out)); } -static void ubd_close(struct ubd *dev) +static void ubd_close(struct ubd *ubd_dev) { - os_close_file(dev->fd); - if(dev->cow.file == NULL) + os_close_file(ubd_dev->fd); + if(ubd_dev->cow.file == NULL) return; - os_close_file(dev->cow.fd); - vfree(dev->cow.bitmap); - dev->cow.bitmap = NULL; + os_close_file(ubd_dev->cow.fd); + vfree(ubd_dev->cow.bitmap); + ubd_dev->cow.bitmap = NULL; } -static int ubd_open_dev(struct ubd *dev) +static int ubd_open_dev(struct ubd *ubd_dev) { struct openflags flags; char **back_ptr; int err, create_cow, *create_ptr; - dev->openflags = dev->boot_openflags; + ubd_dev->openflags = ubd_dev->boot_openflags; create_cow = 0; - create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; - back_ptr = dev->no_cow ? NULL : &dev->cow.file; - dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared, - back_ptr, &dev->cow.bitmap_offset, - &dev->cow.bitmap_len, &dev->cow.data_offset, + create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL; + back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file; + ubd_dev->fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared, + back_ptr, &ubd_dev->cow.bitmap_offset, + &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset, create_ptr); - if((dev->fd == -ENOENT) && create_cow){ - dev->fd = create_cow_file(dev->file, dev->cow.file, - dev->openflags, 1 << 9, PAGE_SIZE, - &dev->cow.bitmap_offset, - &dev->cow.bitmap_len, - &dev->cow.data_offset); - if(dev->fd >= 0){ + if((ubd_dev->fd == -ENOENT) && create_cow){ + ubd_dev->fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file, + ubd_dev->openflags, 1 << 9, PAGE_SIZE, + &ubd_dev->cow.bitmap_offset, + &ubd_dev->cow.bitmap_len, + &ubd_dev->cow.data_offset); + if(ubd_dev->fd >= 0){ printk(KERN_INFO "Creating \"%s\" as COW file for " - "\"%s\"\n", dev->file, dev->cow.file); + "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file); } } - if(dev->fd < 0){ - printk("Failed to open '%s', errno = %d\n", dev->file, - -dev->fd); - return(dev->fd); + if(ubd_dev->fd < 0){ + printk("Failed to open '%s', errno = %d\n", ubd_dev->file, + -ubd_dev->fd); + return(ubd_dev->fd); } - if(dev->cow.file != NULL){ + if(ubd_dev->cow.file != NULL){ err = -ENOMEM; - dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); - if(dev->cow.bitmap == NULL){ + ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); + if(ubd_dev->cow.bitmap == NULL){ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); goto error; } flush_tlb_kernel_vm(); - err = read_cow_bitmap(dev->fd, dev->cow.bitmap, - dev->cow.bitmap_offset, - dev->cow.bitmap_len); + err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap, + ubd_dev->cow.bitmap_offset, + ubd_dev->cow.bitmap_len); if(err < 0) goto error; - flags = dev->openflags; + flags = ubd_dev->openflags; flags.w = 0; - err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL, + err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL, NULL, NULL, NULL, NULL); if(err < 0) goto error; - dev->cow.fd = err; + ubd_dev->cow.fd = err; } return(0); error: - os_close_file(dev->fd); + os_close_file(ubd_dev->fd); return(err); } @@ -645,13 +645,13 @@ static int ubd_new_disk(int major, u64 size, int unit, /* sysfs register (not for ide fake devices) */ if (major == MAJOR_NR) { - ubd_dev[unit].pdev.id = unit; - ubd_dev[unit].pdev.name = DRIVER_NAME; - platform_device_register(&ubd_dev[unit].pdev); - disk->driverfs_dev = &ubd_dev[unit].pdev.dev; + ubd_devs[unit].pdev.id = unit; + ubd_devs[unit].pdev.name = DRIVER_NAME; + platform_device_register(&ubd_devs[unit].pdev); + disk->driverfs_dev = &ubd_devs[unit].pdev.dev; } - disk->private_data = &ubd_dev[unit]; + disk->private_data = &ubd_devs[unit]; disk->queue = ubd_queue; add_disk(disk); @@ -663,25 +663,25 @@ static int ubd_new_disk(int major, u64 size, int unit, static int ubd_add(int n) { - struct ubd *dev = &ubd_dev[n]; + struct ubd *ubd_dev = &ubd_devs[n]; int err; err = -ENODEV; - if(dev->file == NULL) + if(ubd_dev->file == NULL) goto out; - err = ubd_file_size(dev, &dev->size); + err = ubd_file_size(ubd_dev, &ubd_dev->size); if(err < 0) goto out; - dev->size = ROUND_BLOCK(dev->size); + ubd_dev->size = ROUND_BLOCK(ubd_dev->size); - err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); + err = ubd_new_disk(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err) goto out; if(fake_major != MAJOR_NR) - ubd_new_disk(fake_major, dev->size, n, + ubd_new_disk(fake_major, ubd_dev->size, n, &fake_gendisk[n]); /* perhaps this should also be under the "if (fake_major)" above */ @@ -713,7 +713,7 @@ static int ubd_config(char *str) spin_lock(&ubd_lock); err = ubd_add(n); if(err) - ubd_dev[n].file = NULL; + ubd_devs[n].file = NULL; spin_unlock(&ubd_lock); return(err); @@ -721,7 +721,7 @@ static int ubd_config(char *str) static int ubd_get_config(char *name, char *str, int size, char **error_out) { - struct ubd *dev; + struct ubd *ubd_dev; int n, len = 0; n = parse_unit(&name); @@ -730,19 +730,19 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) return(-1); } - dev = &ubd_dev[n]; + ubd_dev = &ubd_devs[n]; spin_lock(&ubd_lock); - if(dev->file == NULL){ + if(ubd_dev->file == NULL){ CONFIG_CHUNK(str, size, len, "", 1); goto out; } - CONFIG_CHUNK(str, size, len, dev->file, 0); + CONFIG_CHUNK(str, size, len, ubd_dev->file, 0); - if(dev->cow.file != NULL){ + if(ubd_dev->cow.file != NULL){ CONFIG_CHUNK(str, size, len, ",", 0); - CONFIG_CHUNK(str, size, len, dev->cow.file, 1); + CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1); } else CONFIG_CHUNK(str, size, len, "", 1); @@ -763,7 +763,7 @@ static int ubd_id(char **str, int *start_out, int *end_out) static int ubd_remove(int n) { - struct ubd *dev; + struct ubd *ubd_dev; int err = -ENODEV; spin_lock(&ubd_lock); @@ -771,14 +771,14 @@ static int ubd_remove(int n) if(ubd_gendisk[n] == NULL) goto out; - dev = &ubd_dev[n]; + ubd_dev = &ubd_devs[n]; - if(dev->file == NULL) + if(ubd_dev->file == NULL) goto out; /* you cannot remove a open disk */ err = -EBUSY; - if(dev->count > 0) + if(ubd_dev->count > 0) goto out; del_gendisk(ubd_gendisk[n]); @@ -791,8 +791,8 @@ static int ubd_remove(int n) fake_gendisk[n] = NULL; } - platform_device_unregister(&dev->pdev); - *dev = ((struct ubd) DEFAULT_UBD); + platform_device_unregister(&ubd_dev->pdev); + *ubd_dev = ((struct ubd) DEFAULT_UBD); err = 0; out: spin_unlock(&ubd_lock); @@ -870,7 +870,7 @@ int ubd_driver_init(void){ return(0); } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, - IRQF_DISABLED, "ubd", ubd_dev); + IRQF_DISABLED, "ubd", ubd_devs); if(err != 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; @@ -881,24 +881,24 @@ device_initcall(ubd_driver_init); static int ubd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ubd *dev = disk->private_data; + struct ubd *ubd_dev = disk->private_data; int err = 0; - if(dev->count == 0){ - err = ubd_open_dev(dev); + if(ubd_dev->count == 0){ + err = ubd_open_dev(ubd_dev); if(err){ printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", - disk->disk_name, dev->file, -err); + disk->disk_name, ubd_dev->file, -err); goto out; } } - dev->count++; - set_disk_ro(disk, !dev->openflags.w); + ubd_dev->count++; + set_disk_ro(disk, !ubd_dev->openflags.w); /* This should no more be needed. And it didn't work anyway to exclude * read-write remounting of filesystems.*/ - /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ - if(--dev->count == 0) ubd_close(dev); + /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){ + if(--ubd_dev->count == 0) ubd_close(ubd_dev); err = -EROFS; }*/ out: @@ -908,10 +908,10 @@ static int ubd_open(struct inode *inode, struct file *filp) static int ubd_release(struct inode * inode, struct file * file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ubd *dev = disk->private_data; + struct ubd *ubd_dev = disk->private_data; - if(--dev->count == 0) - ubd_close(dev); + if(--ubd_dev->count == 0) + ubd_close(ubd_dev); return(0); } @@ -979,12 +979,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, static int prepare_request(struct request *req, struct io_thread_req *io_req) { struct gendisk *disk = req->rq_disk; - struct ubd *dev = disk->private_data; + struct ubd *ubd_dev = disk->private_data; __u64 offset; int len; /* This should be impossible now */ - if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ + if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ printk("Write attempted on readonly ubd device %s\n", disk->disk_name); end_request(req, 0); @@ -994,8 +994,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) offset = ((__u64) req->sector) << 9; len = req->current_nr_sectors << 9; - io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; - io_req->fds[1] = dev->fd; + io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; + io_req->fds[1] = ubd_dev->fd; io_req->cow_offset = -1; io_req->offset = offset; io_req->length = len; @@ -1004,13 +1004,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; io_req->offsets[0] = 0; - io_req->offsets[1] = dev->cow.data_offset; + io_req->offsets[1] = ubd_dev->cow.data_offset; io_req->buffer = req->buffer; io_req->sectorsize = 1 << 9; - if(dev->cow.file != NULL) - cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, - dev->cow.bitmap_len); + if(ubd_dev->cow.file != NULL) + cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, + ubd_dev->cow.bitmap_len); return(0); } @@ -1048,18 +1048,18 @@ static void do_ubd_request(request_queue_t *q) static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) { - struct ubd *dev = bdev->bd_disk->private_data; + struct ubd *ubd_dev = bdev->bd_disk->private_data; geo->heads = 128; geo->sectors = 32; - geo->cylinders = dev->size / (128 * 32 * 512); + geo->cylinders = ubd_dev->size / (128 * 32 * 512); return 0; } static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { - struct ubd *dev = inode->i_bdev->bd_disk->private_data; + struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data; struct hd_driveid ubd_id = { .cyls = 0, .heads = 128, @@ -1069,7 +1069,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, switch (cmd) { struct cdrom_volctrl volume; case HDIO_GET_IDENTITY: - ubd_id.cyls = dev->size / (128 * 32 * 512); + ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, sizeof(ubd_id))) return(-EFAULT); -- cgit v1.2.3 From 5f75a4f887a35b99878fc07ed749a90375194b63 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:06 -0800 Subject: [PATCH] uml ubd driver: give better names to some functions. To rethink locking, I needed to understand well what each function does. While doing this I renamed some: * ubd_close -> ubd_close_dev (since it pairs with ubd_open_dev) * ubd_new_disk -> ubd_disk_register (it handles registration with the block layer - one hopes this makes clearer the difference with ubd_add()) Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 761e3f9cac2..cdd82e89618 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -552,7 +552,7 @@ static int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) return(os_file_size(file, size_out)); } -static void ubd_close(struct ubd *ubd_dev) +static void ubd_close_dev(struct ubd *ubd_dev) { os_close_file(ubd_dev->fd); if(ubd_dev->cow.file == NULL) @@ -624,7 +624,7 @@ static int ubd_open_dev(struct ubd *ubd_dev) return(err); } -static int ubd_new_disk(int major, u64 size, int unit, +static int ubd_disk_register(int major, u64 size, int unit, struct gendisk **disk_out) { @@ -676,12 +676,12 @@ static int ubd_add(int n) ubd_dev->size = ROUND_BLOCK(ubd_dev->size); - err = ubd_new_disk(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); + err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err) goto out; if(fake_major != MAJOR_NR) - ubd_new_disk(fake_major, ubd_dev->size, n, + ubd_disk_register(fake_major, ubd_dev->size, n, &fake_gendisk[n]); /* perhaps this should also be under the "if (fake_major)" above */ @@ -898,7 +898,7 @@ static int ubd_open(struct inode *inode, struct file *filp) /* This should no more be needed. And it didn't work anyway to exclude * read-write remounting of filesystems.*/ /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){ - if(--ubd_dev->count == 0) ubd_close(ubd_dev); + if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); err = -EROFS; }*/ out: @@ -911,7 +911,7 @@ static int ubd_release(struct inode * inode, struct file * file) struct ubd *ubd_dev = disk->private_data; if(--ubd_dev->count == 0) - ubd_close(ubd_dev); + ubd_close_dev(ubd_dev); return(0); } -- cgit v1.2.3 From d7fb2c3865ca0f95d92e2864c3dc9220789d83f5 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:07 -0800 Subject: [PATCH] uml ubd driver: change ubd_lock to be a mutex This lock protects ubd setup and teardown, so is only used in process context; beyond that, during such setup memory allocations must be performed and some generic functions which can sleep must be called (such as add_disk()). So the only correct solution is to make it a mutex instead of a spin_lock. No other change is done - this lock must be acquired in different places but it's done afterwards. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index cdd82e89618..a3061ae39b3 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -107,7 +107,8 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) #define DRIVER_NAME "uml-blkdev" static DEFINE_SPINLOCK(ubd_io_lock); -static DEFINE_SPINLOCK(ubd_lock); + +static DEFINE_MUTEX(ubd_lock); static void (*do_ubd)(void); @@ -314,7 +315,7 @@ static int ubd_setup_common(char *str, int *index_out) } err = 1; - spin_lock(&ubd_lock); + mutex_lock(&ubd_lock); if(fake_major != MAJOR_NR){ printk(KERN_ERR "Can't assign a fake major twice\n"); goto out1; @@ -326,7 +327,7 @@ static int ubd_setup_common(char *str, int *index_out) major); err = 0; out1: - spin_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return(err); } @@ -343,7 +344,7 @@ static int ubd_setup_common(char *str, int *index_out) } err = 1; - spin_lock(&ubd_lock); + mutex_lock(&ubd_lock); ubd_dev = &ubd_devs[n]; if(ubd_dev->file != NULL){ @@ -405,7 +406,7 @@ break_loop: ubd_dev->cow.file = backing_file; ubd_dev->boot_openflags = flags; out: - spin_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return(err); } @@ -710,11 +711,11 @@ static int ubd_config(char *str) } if(n == -1) return(0); - spin_lock(&ubd_lock); + mutex_lock(&ubd_lock); err = ubd_add(n); if(err) ubd_devs[n].file = NULL; - spin_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return(err); } @@ -731,7 +732,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) } ubd_dev = &ubd_devs[n]; - spin_lock(&ubd_lock); + mutex_lock(&ubd_lock); if(ubd_dev->file == NULL){ CONFIG_CHUNK(str, size, len, "", 1); @@ -747,7 +748,7 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) else CONFIG_CHUNK(str, size, len, "", 1); out: - spin_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return(len); } @@ -766,7 +767,7 @@ static int ubd_remove(int n) struct ubd *ubd_dev; int err = -ENODEV; - spin_lock(&ubd_lock); + mutex_lock(&ubd_lock); if(ubd_gendisk[n] == NULL) goto out; @@ -795,7 +796,7 @@ static int ubd_remove(int n) *ubd_dev = ((struct ubd) DEFAULT_UBD); err = 0; out: - spin_unlock(&ubd_lock); + mutex_unlock(&ubd_lock); return err; } -- cgit v1.2.3 From 33f775eea185e8df7701c4afc2c8fcee85c83282 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:08 -0800 Subject: [PATCH] uml ubd driver: ubd_io_lock usage fixup Add some comments about requirements for ubd_io_lock and expand its use. When an irq signals that the "controller" (i.e. another thread on the host, which does the actual requests and is the only one blocked on I/O on the host) has done some work, we call again the request function ourselves (do_ubd_request). We now do that with ubd_io_lock held - that's useful to protect against concurrent calls to elv_next_request and so on. XXX: Maybe we shouldn't call at all the request function. Input needed on this. Are we supposed to plug and unplug the queue? That code "indirectly" does that by setting a flag, called do_ubd, which makes the request function return (it's a residual of 2.4 block layer interface). Meanwhile, however, merge this patch, which improves things. Cc: Jens Axboe Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index a3061ae39b3..6cd8988e8fd 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -106,6 +106,8 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) #define DRIVER_NAME "uml-blkdev" +/* Can be taken in interrupt context, and is passed to the block layer to lock + * the request queue. Kernel side code knows that. */ static DEFINE_SPINLOCK(ubd_io_lock); static DEFINE_MUTEX(ubd_lock); @@ -497,6 +499,8 @@ static void __ubd_finish(struct request *req, int error) end_request(req, 1); } +/* Callable only from interrupt context - otherwise you need to do + * spin_lock_irq()/spin_lock_irqsave() */ static inline void ubd_finish(struct request *req, int error) { spin_lock(&ubd_io_lock); @@ -504,7 +508,7 @@ static inline void ubd_finish(struct request *req, int error) spin_unlock(&ubd_io_lock); } -/* Called without ubd_io_lock held */ +/* Called without ubd_io_lock held, and only in interrupt context. */ static void ubd_handler(void) { struct io_thread_req req; @@ -525,7 +529,9 @@ static void ubd_handler(void) ubd_finish(rq, req.error); reactivate_fd(thread_fd, UBD_IRQ); + spin_lock(&ubd_io_lock); do_ubd_request(ubd_queue); + spin_unlock(&ubd_io_lock); } static irqreturn_t ubd_intr(int irq, void *dev) -- cgit v1.2.3 From 2fe30a34a141c2188ff2cdd670d031088d9c5d20 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:09 -0800 Subject: [PATCH] uml ubd driver: convert do_ubd to a boolean variable do_ubd is actually just a boolean variable - the way it is used currently is a leftover from the old 2.4 block layer, but it is still used; its use is suspicious, but removing it would be too intrusive for now and needs more thinking. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 6cd8988e8fd..460d669b477 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -112,7 +112,9 @@ static DEFINE_SPINLOCK(ubd_io_lock); static DEFINE_MUTEX(ubd_lock); -static void (*do_ubd)(void); +/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and + * probably it doesn't make sense even for that. */ +static int do_ubd; static int ubd_open(struct inode * inode, struct file * filp); static int ubd_release(struct inode * inode, struct file * file); @@ -508,6 +510,7 @@ static inline void ubd_finish(struct request *req, int error) spin_unlock(&ubd_io_lock); } +/* XXX - move this inside ubd_intr. */ /* Called without ubd_io_lock held, and only in interrupt context. */ static void ubd_handler(void) { @@ -515,7 +518,7 @@ static void ubd_handler(void) struct request *rq = elv_next_request(ubd_queue); int n; - do_ubd = NULL; + do_ubd = 0; intr_count++; n = os_read_file(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ @@ -1043,7 +1046,7 @@ static void do_ubd_request(request_queue_t *q) return; err = prepare_request(req, &io_req); if(!err){ - do_ubd = ubd_handler; + do_ubd = 1; n = os_write_file(thread_fd, (char *) &io_req, sizeof(io_req)); if(n != sizeof(io_req)) -- cgit v1.2.3 From e7f6552f237498c805af9f01aba168b731e0a4ce Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:09 -0800 Subject: [PATCH] uml ubd driver: reformat ubd_config Pure whitespace and style fixes split out from subsequent patch. Some changes (err -> ret) don't make sense now, only later, but I split them out anyway since they cluttered the patch. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 460d669b477..eed95dc356e 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -706,27 +706,36 @@ out: static int ubd_config(char *str) { - int n, err; + int n, ret; str = kstrdup(str, GFP_KERNEL); - if(str == NULL){ + if (str == NULL) { printk(KERN_ERR "ubd_config failed to strdup string\n"); - return(1); + ret = 1; + goto out; } - err = ubd_setup_common(str, &n); - if(err){ - kfree(str); - return(-1); + ret = ubd_setup_common(str, &n); + if (ret) { + ret = -1; + goto err_free; + } + if (n == -1) { + ret = 0; + goto out; } - if(n == -1) return(0); mutex_lock(&ubd_lock); - err = ubd_add(n); - if(err) + ret = ubd_add(n); + if (ret) ubd_devs[n].file = NULL; mutex_unlock(&ubd_lock); - return(err); +out: + return ret; + +err_free: + kfree(str); + goto out; } static int ubd_get_config(char *name, char *str, int size, char **error_out) -- cgit v1.2.3 From 84e945e399ce9710a34035ea81eaf5719aa709af Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:10 -0800 Subject: [PATCH] uml ubd driver: use bitfields where possible Use bitfields for boolean fields in ubd data structure. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index eed95dc356e..3e3bb22c3ce 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -174,8 +174,8 @@ struct ubd { __u64 size; struct openflags boot_openflags; struct openflags openflags; - int shared; - int no_cow; + unsigned shared:1; + unsigned no_cow:1; struct cow cow; struct platform_device pdev; }; -- cgit v1.2.3 From 0bf16bffeef65622603af22151156807323d7dc7 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:11 -0800 Subject: [PATCH] uml ubd driver: do not store error codes as ->fd To simplify error handling, make sure fd is saved into ubd_dev->fd only when we are sure it is an fd and not an error code. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 3e3bb22c3ce..125a63fd3a4 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -578,33 +578,36 @@ static int ubd_open_dev(struct ubd *ubd_dev) struct openflags flags; char **back_ptr; int err, create_cow, *create_ptr; + int fd; ubd_dev->openflags = ubd_dev->boot_openflags; create_cow = 0; create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL; back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file; - ubd_dev->fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared, + + fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared, back_ptr, &ubd_dev->cow.bitmap_offset, &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset, create_ptr); - if((ubd_dev->fd == -ENOENT) && create_cow){ - ubd_dev->fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file, + if((fd == -ENOENT) && create_cow){ + fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file, ubd_dev->openflags, 1 << 9, PAGE_SIZE, &ubd_dev->cow.bitmap_offset, &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset); - if(ubd_dev->fd >= 0){ + if(fd >= 0){ printk(KERN_INFO "Creating \"%s\" as COW file for " "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file); } } - if(ubd_dev->fd < 0){ + if(fd < 0){ printk("Failed to open '%s', errno = %d\n", ubd_dev->file, - -ubd_dev->fd); - return(ubd_dev->fd); + -fd); + return fd; } + ubd_dev->fd = fd; if(ubd_dev->cow.file != NULL){ err = -ENOMEM; -- cgit v1.2.3 From d8d7c28ec0b50ac57ddc909ae6eca1519473f300 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Mon, 30 Oct 2006 22:07:12 -0800 Subject: [PATCH] uml ubd driver: various little changes Fix a small memory leak in ubd_config, and clearify the confusion which lead to it. Then, some little changes not affecting operations - * move init functions together, * add a comment about a potential problem in case of some evolution in the block layer, * mark all initcalls as static __init functions * mark an used once little function as inline * document that mconsole methods are all called in process context (was triggered when checking ubd mconsole methods). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/ubd_kern.c | 44 +++++++++++++++++++++++------------------ arch/um/include/mconsole_kern.h | 1 + arch/um/kernel/tt/tracer.c | 1 - 3 files changed, 26 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 125a63fd3a4..49c047b75cc 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -202,17 +202,6 @@ struct ubd { struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; -static int ubd0_init(void) -{ - struct ubd *ubd_dev = &ubd_devs[0]; - - if(ubd_dev->file == NULL) - ubd_dev->file = "root_fs"; - return(0); -} - -__initcall(ubd0_init); - /* Only changed by fake_ide_setup which is a setup */ static int fake_ide = 0; static struct proc_dir_entry *proc_ide_root = NULL; @@ -293,6 +282,10 @@ static int parse_unit(char **ptr) return(n); } +/* If *index_out == -1 at exit, the passed option was a general one; + * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it + * should not be freed on exit. + */ static int ubd_setup_common(char *str, int *index_out) { struct ubd *ubd_dev; @@ -480,8 +473,9 @@ int thread_fd = -1; /* Changed by ubd_handler, which is serialized because interrupts only * happen on CPU 0. + * XXX: currently unused. */ -int intr_count = 0; +static int intr_count = 0; /* call ubd_finish if you need to serialize */ static void __ubd_finish(struct request *req, int error) @@ -554,7 +548,7 @@ void kill_io_thread(void) __uml_exitcall(kill_io_thread); -static int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) +static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) { char *file; @@ -724,7 +718,7 @@ static int ubd_config(char *str) } if (n == -1) { ret = 0; - goto out; + goto err_free; } mutex_lock(&ubd_lock); @@ -821,6 +815,7 @@ out: return err; } +/* All these are called by mconsole in process context and without ubd-specific locks. */ static struct mc_device ubd_mc = { .name = "ubd", .config = ubd_config, @@ -829,7 +824,7 @@ static struct mc_device ubd_mc = { .remove = ubd_remove, }; -static int ubd_mc_init(void) +static int __init ubd_mc_init(void) { mconsole_register_dev(&ubd_mc); return 0; @@ -837,13 +832,24 @@ static int ubd_mc_init(void) __initcall(ubd_mc_init); +static int __init ubd0_init(void) +{ + struct ubd *ubd_dev = &ubd_devs[0]; + + if(ubd_dev->file == NULL) + ubd_dev->file = "root_fs"; + return(0); +} + +__initcall(ubd0_init); + static struct platform_driver ubd_driver = { .driver = { .name = DRIVER_NAME, }, }; -int ubd_init(void) +static int __init ubd_init(void) { int i; @@ -871,7 +877,7 @@ int ubd_init(void) late_initcall(ubd_init); -int ubd_driver_init(void){ +static int __init ubd_driver_init(void){ unsigned long stack; int err; @@ -1378,8 +1384,8 @@ void do_io(struct io_thread_req *req) */ int kernel_fd = -1; -/* Only changed by the io thread */ -int io_count = 0; +/* Only changed by the io thread. XXX: currently unused. */ +static int io_count = 0; int io_thread(void *arg) { diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h index d0b690197fd..1ea6d928e1c 100644 --- a/arch/um/include/mconsole_kern.h +++ b/arch/um/include/mconsole_kern.h @@ -14,6 +14,7 @@ struct mconsole_entry { struct mc_request request; }; +/* All these methods are called in process context. */ struct mc_device { struct list_head list; char *name; diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 9882342206e..b9195355075 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -176,7 +176,6 @@ struct { int signal_index[32]; int nsignals = 0; int debug_trace = 0; -extern int io_nsignals, io_count, intr_count; extern void signal_usr1(int sig); -- cgit v1.2.3 From d1480c56feb2a894fd47fb399999a5b320c3e103 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Mon, 30 Oct 2006 22:07:13 -0800 Subject: [PATCH] uml: add _text definition to linker scripts kallsyms now refers to addresses as '_text + 0xADDRESS', rather than just '0xADDRESS', so we need to define _text. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/dyn.lds.S | 1 + arch/um/kernel/uml.lds.S | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 68ed24df5c8..e36f92b463c 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -14,6 +14,7 @@ SECTIONS * is remapped.*/ __binary_start = .; . = ALIGN(4096); /* Init code and data */ + _text = .; _stext = .; __init_begin = .; .init.text : { diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 8eca47a6ff0..f6301274cf3 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -25,6 +25,7 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ #endif + _text = .; _stext = .; __init_begin = .; .init.text : { -- cgit v1.2.3 From 0887fa5158fe7da4a46ae526d313ae636440deae Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 11:52:03 +0000 Subject: [MIPS] TX4927: Remove indent error message that somehow ended in the code. Signed-off-by: Ralf Baechle --- arch/mips/tx4927/common/tx4927_setup.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c index 4658b2ae483..941c441729b 100644 --- a/arch/mips/tx4927/common/tx4927_setup.c +++ b/arch/mips/tx4927/common/tx4927_setup.c @@ -112,8 +112,6 @@ void print_cp0(char *key, int num, char *name, u32 val) return; } -indent: Standard input:25: Error:Unexpected end of file - void dump_cp0(char *key) { -- cgit v1.2.3 From e8f05de54055e90e6d58e45866f84ecdb0b48acd Mon Sep 17 00:00:00 2001 From: Manish Lachwani Date: Sat, 22 Jan 2005 09:23:38 -0800 Subject: [MIPS] Add missing file for support of backplane on TX4927 based board Signed-off-by: Manish Lachwani Signed-off-by: Ralf Baechle --- arch/mips/tx4927/common/smsc_fdc37m81x.c | 172 +++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 arch/mips/tx4927/common/smsc_fdc37m81x.c (limited to 'arch') diff --git a/arch/mips/tx4927/common/smsc_fdc37m81x.c b/arch/mips/tx4927/common/smsc_fdc37m81x.c new file mode 100644 index 00000000000..33f517bc9a0 --- /dev/null +++ b/arch/mips/tx4927/common/smsc_fdc37m81x.c @@ -0,0 +1,172 @@ +/* + * Interface for smsc fdc48m81x Super IO chip + * + * Author: MontaVista Software, Inc. source@mvista.com + * + * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + * + * Copyright 2004 (c) MontaVista Software, Inc. + */ +#include +#include +#include +#include + +#define DEBUG + +/* Common Registers */ +#define SMSC_FDC37M81X_CONFIG_INDEX 0x00 +#define SMSC_FDC37M81X_CONFIG_DATA 0x01 +#define SMSC_FDC37M81X_CONF 0x02 +#define SMSC_FDC37M81X_INDEX 0x03 +#define SMSC_FDC37M81X_DNUM 0x07 +#define SMSC_FDC37M81X_DID 0x20 +#define SMSC_FDC37M81X_DREV 0x21 +#define SMSC_FDC37M81X_PCNT 0x22 +#define SMSC_FDC37M81X_PMGT 0x23 +#define SMSC_FDC37M81X_OSC 0x24 +#define SMSC_FDC37M81X_CONFPA0 0x26 +#define SMSC_FDC37M81X_CONFPA1 0x27 +#define SMSC_FDC37M81X_TEST4 0x2B +#define SMSC_FDC37M81X_TEST5 0x2C +#define SMSC_FDC37M81X_TEST1 0x2D +#define SMSC_FDC37M81X_TEST2 0x2E +#define SMSC_FDC37M81X_TEST3 0x2F + +/* Logical device numbers */ +#define SMSC_FDC37M81X_FDD 0x00 +#define SMSC_FDC37M81X_SERIAL1 0x04 +#define SMSC_FDC37M81X_SERIAL2 0x05 +#define SMSC_FDC37M81X_KBD 0x07 + +/* Logical device Config Registers */ +#define SMSC_FDC37M81X_ACTIVE 0x30 +#define SMSC_FDC37M81X_BASEADDR0 0x60 +#define SMSC_FDC37M81X_BASEADDR1 0x61 +#define SMSC_FDC37M81X_INT 0x70 +#define SMSC_FDC37M81X_INT2 0x72 +#define SMSC_FDC37M81X_MODE 0xF0 + +/* Chip Config Values */ +#define SMSC_FDC37M81X_CONFIG_ENTER 0x55 +#define SMSC_FDC37M81X_CONFIG_EXIT 0xaa +#define SMSC_FDC37M81X_CHIP_ID 0x4d + +static unsigned long g_smsc_fdc37m81x_base = 0; + +static inline unsigned char smsc_fdc37m81x_rd(unsigned char index) +{ + outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + + return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); +} + +static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data) +{ + outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA); +} + +void smsc_fdc37m81x_config_beg(void) +{ + if (g_smsc_fdc37m81x_base) { + outb(SMSC_FDC37M81X_CONFIG_ENTER, + g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); + } +} + +void smsc_fdc37m81x_config_end(void) +{ + if (g_smsc_fdc37m81x_base) + outb(SMSC_FDC37M81X_CONFIG_EXIT, + g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX); +} + +u8 smsc_fdc37m81x_config_get(u8 reg) +{ + u8 val = 0; + + if (g_smsc_fdc37m81x_base) + val = smsc_fdc37m81x_rd(reg); + + return val; +} + +void smsc_fdc37m81x_config_set(u8 reg, u8 val) +{ + if (g_smsc_fdc37m81x_base) + smsc_dc37m81x_wr(reg, val); +} + +unsigned long __init smsc_fdc37m81x_init(unsigned long port) +{ + const int field = sizeof(unsigned long) * 2; + u8 chip_id; + + if (g_smsc_fdc37m81x_base) + printk("smsc_fdc37m81x_init() stepping on old base=0x%0*lx\n", + field, g_smsc_fdc37m81x_base); + + g_smsc_fdc37m81x_base = port; + + smsc_fdc37m81x_config_beg(); + + chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); + if (chip_id == SMSC_FDC37M81X_CHIP_ID) + smsc_fdc37m81x_config_end(); + else { + printk("smsc_fdc37m81x_init() unknow chip id 0x%02x\n", + chip_id); + g_smsc_fdc37m81x_base = 0; + } + + return g_smsc_fdc37m81x_base; +} + +#ifdef DEBUG +void smsc_fdc37m81x_config_dump_one(char *key, u8 dev, u8 reg) +{ + printk("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg, + smsc_fdc37m81x_rd(reg)); +} + +void smsc_fdc37m81x_config_dump(void) +{ + u8 orig; + char *fname = "smsc_fdc37m81x_config_dump()"; + + smsc_fdc37m81x_config_beg(); + + orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); + + printk("%s: common\n", fname); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DNUM); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DID); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_DREV); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_PCNT); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, + SMSC_FDC37M81X_PMGT); + + printk("%s: keyboard\n", fname); + smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_ACTIVE); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_INT); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_INT2); + smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, + SMSC_FDC37M81X_LDCR_F0); + + smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); + + smsc_fdc37m81x_config_end(); +} +#endif -- cgit v1.2.3 From c21e6d65f70d64b359a37545592f39e28074864e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 13:41:59 +0000 Subject: [MIPS] Sort out missuse of __init for prom_getcmdline() Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/prom.c | 2 +- arch/mips/au1000/common/setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index b4b010a2fe3..6fce60af005 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c @@ -47,7 +47,7 @@ extern int prom_argc; extern char **prom_argv, **prom_envp; -char * prom_getcmdline(void) +char * __init_or_module prom_getcmdline(void) { return &(arcs_cmdline[0]); } diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 377ae0d8ff0..919172db560 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c @@ -43,7 +43,7 @@ #include #include -extern char * __init prom_getcmdline(void); +extern char * prom_getcmdline(void); extern void __init board_setup(void); extern void au1000_restart(char *); extern void au1000_halt(void); -- cgit v1.2.3 From 38384c8bd82474bf74ea68e4e44aaa14504deb07 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 31 Oct 2006 13:38:44 +0900 Subject: [MIPS] Yosemite: fix uninitialized variable in titan_i2c_xfer() Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/pmc-sierra/yosemite/i2c-yosemite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c index 416da22b3bf..85b14c73c22 100644 --- a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c +++ b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c @@ -74,7 +74,7 @@ static int titan_i2c_poll(void) int titan_i2c_xfer(unsigned int slave_addr, titan_i2c_command * cmd, int size, unsigned int *addr) { - int loop = 0, bytes, i; + int loop, bytes = 0, i; unsigned int *write_data, data, *read_data; unsigned long reg_val, val; -- cgit v1.2.3 From 3ab0f40f333007eb31dc1e08f578ec224c7d71c2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Tue, 31 Oct 2006 13:44:38 +0900 Subject: [MIPS] Fix warning of printk format in mips_srs_init() arch/mips/kernel/traps.c:1115: warning: int format, long unsigned int arg (arg 2) Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cce8313ec27..9fda1b8be3a 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1111,7 +1111,7 @@ static struct shadow_registers { static void mips_srs_init(void) { shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; - printk(KERN_INFO "%d MIPSR2 register sets available\n", + printk(KERN_INFO "%ld MIPSR2 register sets available\n", shadow_registers.sr_supported); shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ } -- cgit v1.2.3 From 781b0f8d4f9c90137ea32771346ab49f0e5319b3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 18:25:10 +0000 Subject: [MIPS] VSMP: Fix initialization ordering bug. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 152 +++++++++++++++++++++++++--------------------- 1 file changed, 83 insertions(+), 69 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 3b5f3b63262..06b29fa73f5 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -140,15 +140,88 @@ static struct irqaction irq_call = { .name = "IPI_call" }; +static void __init smp_copy_vpe_config(void) +{ + write_vpe_c0_status( + (read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); + + /* set config to be the same as vpe0, particularly kseg0 coherency alg */ + write_vpe_c0_config( read_c0_config()); + + /* make sure there are no software interrupts pending */ + write_vpe_c0_cause(0); + + /* Propagate Config7 */ + write_vpe_c0_config7(read_c0_config7()); +} + +static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, + unsigned int ncpu) +{ + if (tc > ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) + return ncpu; + + /* Deactivate all but VPE 0 */ + if (tc != 0) { + unsigned long tmp = read_vpe_c0_vpeconf0(); + + tmp &= ~VPECONF0_VPA; + + /* master VPE */ + tmp |= VPECONF0_MVP; + write_vpe_c0_vpeconf0(tmp); + + /* Record this as available CPU */ + cpu_set(tc, phys_cpu_present_map); + __cpu_number_map[tc] = ++ncpu; + __cpu_logical_map[ncpu] = tc; + } + + /* Disable multi-threading with TC's */ + write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); + + if (tc != 0) + smp_copy_vpe_config(); + + return ncpu; +} + +static void __init smp_tc_init(unsigned int tc, unsigned int mvpconf0) +{ + unsigned long tmp; + + if (!tc) + return; + + /* bind a TC to each VPE, May as well put all excess TC's + on the last VPE */ + if (tc >= (((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1)) + write_tc_c0_tcbind(read_tc_c0_tcbind() | ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); + else { + write_tc_c0_tcbind(read_tc_c0_tcbind() | tc); + + /* and set XTC */ + write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (tc << VPECONF0_XTC_SHIFT)); + } + + tmp = read_tc_c0_tcstatus(); + + /* mark not allocated and not dynamically allocatable */ + tmp &= ~(TCSTATUS_A | TCSTATUS_DA); + tmp |= TCSTATUS_IXMT; /* interrupt exempt */ + write_tc_c0_tcstatus(tmp); + + write_tc_c0_tchalt(TCHALT_H); +} + /* * Common setup before any secondaries are started * Make sure all CPU's are in a sensible state before we boot any of the * secondarys */ -void plat_smp_setup(void) +void __init plat_smp_setup(void) { - unsigned long val; - int i, num; + unsigned int mvpconf0, ntc, tc, ncpu = 0; #ifdef CONFIG_MIPS_MT_FPAFF /* If we have an FPU, enroll ourselves in the FPU-full mask */ @@ -167,75 +240,16 @@ void plat_smp_setup(void) /* Put MVPE's into 'configuration state' */ set_c0_mvpcontrol(MVPCONTROL_VPC); - val = read_c0_mvpconf0(); + mvpconf0 = read_c0_mvpconf0(); + ntc = (mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT; /* we'll always have more TC's than VPE's, so loop setting everything to a sensible state */ - for (i = 0, num = 0; i <= ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT); i++) { - settc(i); - - /* VPE's */ - if (i <= ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)) { - - /* deactivate all but vpe0 */ - if (i != 0) { - unsigned long tmp = read_vpe_c0_vpeconf0(); - - tmp &= ~VPECONF0_VPA; - - /* master VPE */ - tmp |= VPECONF0_MVP; - write_vpe_c0_vpeconf0(tmp); - - /* Record this as available CPU */ - cpu_set(i, phys_cpu_present_map); - __cpu_number_map[i] = ++num; - __cpu_logical_map[num] = i; - } - - /* disable multi-threading with TC's */ - write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); - - if (i != 0) { - write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); + for (tc = 0; tc <= ntc; tc++) { + settc(tc); - /* set config to be the same as vpe0, particularly kseg0 coherency alg */ - write_vpe_c0_config( read_c0_config()); - - /* make sure there are no software interrupts pending */ - write_vpe_c0_cause(0); - - /* Propagate Config7 */ - write_vpe_c0_config7(read_c0_config7()); - } - - } - - /* TC's */ - - if (i != 0) { - unsigned long tmp; - - /* bind a TC to each VPE, May as well put all excess TC's - on the last VPE */ - if ( i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)+1) ) - write_tc_c0_tcbind(read_tc_c0_tcbind() | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) ); - else { - write_tc_c0_tcbind( read_tc_c0_tcbind() | i); - - /* and set XTC */ - write_vpe_c0_vpeconf0( read_vpe_c0_vpeconf0() | (i << VPECONF0_XTC_SHIFT)); - } - - tmp = read_tc_c0_tcstatus(); - - /* mark not allocated and not dynamically allocatable */ - tmp &= ~(TCSTATUS_A | TCSTATUS_DA); - tmp |= TCSTATUS_IXMT; /* interrupt exempt */ - write_tc_c0_tcstatus(tmp); - - write_tc_c0_tchalt(TCHALT_H); - } + smp_tc_init(tc, mvpconf0); + ncpu = smp_vpe_init(tc, mvpconf0, ncpu); } /* Release config state */ @@ -243,7 +257,7 @@ void plat_smp_setup(void) /* We'll wait until starting the secondaries before starting MVPE */ - printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); + printk(KERN_INFO "Detected %i available secondary CPU(s)\n", ncpu); } void __init plat_prepare_cpus(unsigned int max_cpus) -- cgit v1.2.3 From e79f55a8c7aaae5a33e8c2b29682ec8e603b5434 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 19:53:15 +0000 Subject: [MIPS] Flags must be unsigned long. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/generic/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index c079e2ae02a..65970670500 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -208,7 +208,7 @@ static unsigned int __init estimate_cpu_frequency(void) count = 6000000; #endif #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) - unsigned int flags; + unsigned long flags; local_irq_save(flags); -- cgit v1.2.3 From 70e46f48cb5933119712ee27945309a4bfc98282 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 18:33:09 +0000 Subject: [MIPS] VSMP: Synchronize cp0 counters on bootup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp-mt.c | 2 ++ arch/mips/mips-boards/generic/time.c | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 06b29fa73f5..2ac19a6cbf6 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -153,6 +153,8 @@ static void __init smp_copy_vpe_config(void) /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); + + write_vpe_c0_count(read_c0_count()); } static unsigned int __init smp_vpe_init(unsigned int tc, unsigned int mvpconf0, diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 65970670500..d817c60c5ca 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -209,6 +209,7 @@ static unsigned int __init estimate_cpu_frequency(void) #endif #if defined(CONFIG_MIPS_ATLAS) || defined(CONFIG_MIPS_MALTA) unsigned long flags; + unsigned int start; local_irq_save(flags); @@ -217,13 +218,13 @@ static unsigned int __init estimate_cpu_frequency(void) while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); /* Start r4k counter. */ - write_c0_count(0); + start = read_c0_count(); /* Read counter exactly on falling edge of update flag */ while (CMOS_READ(RTC_REG_A) & RTC_UIP); while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); - count = read_c0_count(); + count = read_c0_count() - start; /* restore interrupts */ local_irq_restore(flags); -- cgit v1.2.3 From 16b7b2ac0148e839da86af8747b6fa4aad43a9b7 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 24 Oct 2006 00:21:27 +0900 Subject: [MIPS] Fixup migration to GENERIC_TIME Since we already moved to GENERIC_TIME, we should implement alternatives of old do_gettimeoffset routines to get sub-jiffies resolution from gettimeofday(). This patch includes: * MIPS clocksource support (based on works by Manish Lachwani). * remove unused gettimeoffset routines and related codes. * remove unised 64bit do_div64_32(). * simplify mips_hpt_init. (no argument needed, __init tag) * simplify c0_hpt_timer_init. (no need to write to c0_count) * remove some hpt_init routines. * mips_hpt_mask variable to specify bitmask of hpt value. * convert jmr3927_do_gettimeoffset to jmr3927_hpt_read. * convert ip27_do_gettimeoffset to ip27_hpt_read. * convert bcm1480_do_gettimeoffset to bcm1480_hpt_read. * simplify sb1250 hpt functions. (no need to subtract and shift) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/time.c | 98 ---------- arch/mips/dec/time.c | 9 +- arch/mips/jmr3927/rbhma3100/setup.c | 40 +--- arch/mips/kernel/time.c | 319 ++++++-------------------------- arch/mips/philips/pnx8550/common/time.c | 4 +- arch/mips/pmc-sierra/yosemite/smp.c | 6 +- arch/mips/sgi-ip27/ip27-timer.c | 16 +- arch/mips/sibyte/bcm1480/time.c | 33 ++-- arch/mips/sibyte/sb1250/time.c | 28 +-- 9 files changed, 92 insertions(+), 461 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c index 6768638883e..fa1c62f0551 100644 --- a/arch/mips/au1000/common/time.c +++ b/arch/mips/au1000/common/time.c @@ -53,9 +53,6 @@ static unsigned long r4k_cur; /* What counter should be at next timer irq */ int no_au1xxx_32khz; extern int allow_au1k_wait; /* default off for CP0 Counter */ -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi = 0, timerlo = 0; - #ifdef CONFIG_PM #if HZ < 100 || HZ > 1000 #error "unsupported HZ value! Must be in [100,1000]" @@ -90,10 +87,6 @@ void mips_timer_interrupt(void) goto null; do { - count = read_c0_count(); - timerhi += (count < timerlo); /* Wrap around */ - timerlo = count; - kstat_this_cpu.irqs[irq]++; do_timer(1); #ifndef CONFIG_SMP @@ -297,88 +290,6 @@ unsigned long cal_r4koff(void) return (cpu_speed / HZ); } -/* This is for machines which generate the exact clock. */ -#define USECS_PER_JIFFY (1000000/HZ) -#define USECS_PER_JIFFY_FRAC (0x100000000LL*1000000/HZ&0xffffffff) - -static unsigned long -div64_32(unsigned long v1, unsigned long v2, unsigned long v3) -{ - unsigned long r0; - do_div64_32(r0, v1, v2, v3); - return r0; -} - -static unsigned long do_fast_cp0_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long r0; - - /* Last jiffy when do_fast_gettimeoffset() was called. */ - static unsigned long last_jiffies=0; - unsigned long quotient; - - /* - * Cached "1/(clocks per usec)*2^32" value. - * It has to be recalculated once each jiffy. - */ - static unsigned long cached_quotient=0; - - tmp = jiffies; - - quotient = cached_quotient; - - if (tmp && last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - r0 = div64_32(timerhi, timerlo, tmp); - quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = read_c0_count(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu\t%1,%2\n\t" - "mfhi\t%0" - : "=r" (res) - : "r" (count), "r" (quotient) - : "hi", "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - - return res; -} - -#ifdef CONFIG_PM -static unsigned long do_fast_pm_gettimeoffset(void) -{ - unsigned long pc0; - unsigned long offset; - - pc0 = au_readl(SYS_TOYREAD); - au_sync(); - offset = pc0 - last_pc0; - if (offset > 2*MATCH20_INC) { - printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n", - (unsigned)offset, (unsigned)last_pc0, - (unsigned)last_match20, (unsigned)pc0); - } - offset = (unsigned long)((offset * 305) / 10); - return offset; -} -#endif - void __init plat_timer_setup(struct irqaction *irq) { unsigned int est_freq; @@ -416,7 +327,6 @@ void __init plat_timer_setup(struct irqaction *irq) unsigned int c0_status; printk("WARNING: no 32KHz clock found.\n"); - do_gettimeoffset = do_fast_cp0_gettimeoffset; /* Ensure we get CPO_COUNTER interrupts. */ @@ -441,19 +351,11 @@ void __init plat_timer_setup(struct irqaction *irq) while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); startup_match20_interrupt(counter0_irq); - do_gettimeoffset = do_fast_pm_gettimeoffset; - /* We can use the real 'wait' instruction. */ allow_au1k_wait = 1; } -#else - /* We have to do this here instead of in timer_init because - * the generic code in arch/mips/kernel/time.c will write - * over our function pointer. - */ - do_gettimeoffset = do_fast_cp0_gettimeoffset; #endif } diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 4cf0c06e241..69e424e9ab6 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -160,11 +160,6 @@ static unsigned int dec_ioasic_hpt_read(void) return ioasic_read(IO_REG_FCTR); } -static void dec_ioasic_hpt_init(unsigned int count) -{ - ioasic_write(IO_REG_FCTR, ioasic_read(IO_REG_FCTR) - count); -} - void __init dec_time_init(void) { @@ -174,11 +169,9 @@ void __init dec_time_init(void) mips_timer_state = dec_timer_state; mips_timer_ack = dec_timer_ack; - if (!cpu_has_counter && IOASIC) { + if (!cpu_has_counter && IOASIC) /* For pre-R4k systems we use the I/O ASIC's counter. */ mips_hpt_read = dec_ioasic_hpt_read; - mips_hpt_init = dec_ioasic_hpt_init; - } /* Set up the rate of periodic DS1287 interrupts. */ CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 025434054ed..16e5dfe7aa8 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -170,12 +170,20 @@ static void jmr3927_machine_power_off(void) while (1); } +static unsigned int jmr3927_hpt_read(void) +{ + /* We assume this function is called xtime_lock held. */ + return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; +} + #define USE_RTC_DS1742 #ifdef USE_RTC_DS1742 extern void rtc_ds1742_init(unsigned long base); #endif static void __init jmr3927_time_init(void) { + mips_hpt_read = jmr3927_hpt_read; + mips_hpt_frequency = JMR3927_TIMER_CLK; #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { rtc_ds1742_init(JMR3927_IOC_NVRAMB_ADDR); @@ -183,12 +191,8 @@ static void __init jmr3927_time_init(void) #endif } -unsigned long jmr3927_do_gettimeoffset(void); - void __init plat_timer_setup(struct irqaction *irq) { - do_gettimeoffset = jmr3927_do_gettimeoffset; - jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; @@ -200,34 +204,6 @@ void __init plat_timer_setup(struct irqaction *irq) #define USECS_PER_JIFFY (1000000/HZ) -unsigned long jmr3927_do_gettimeoffset(void) -{ - unsigned long count; - unsigned long res = 0; - - /* MUST read TRR before TISR. */ - count = jmr3927_tmrptr->trr; - - if (jmr3927_tmrptr->tisr & TXx927_TMTISR_TIIS) { - /* timer interrupt is pending. use Max value. */ - res = USECS_PER_JIFFY - 1; - } else { - /* convert to usec */ - /* res = count / (JMR3927_TIMER_CLK / 1000000); */ - res = (count << 7) / ((JMR3927_TIMER_CLK << 7) / 1000000); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY-1; - } - - return res; -} - - //#undef DO_WRITE_THROUGH #define DO_WRITE_THROUGH #define DO_ENABLE_CACHE diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index debe86c2f69..e535f86efa2 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,6 +11,7 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ +#include #include #include #include @@ -67,15 +68,9 @@ int (*rtc_mips_set_time)(unsigned long) = null_rtc_set_time; int (*rtc_mips_set_mmss)(unsigned long); -/* usecs per counter cycle, shifted to left by 32 bits */ -static unsigned int sll32_usecs_per_cycle; - /* how many counter cycles in a jiffy */ static unsigned long cycles_per_jiffy __read_mostly; -/* Cycle counter value at the previous timer interrupt.. */ -static unsigned int timerhi, timerlo; - /* expirelo is the count value for next CPU timer interrupt */ static unsigned int expirelo; @@ -93,7 +88,7 @@ static unsigned int null_hpt_read(void) return 0; } -static void null_hpt_init(unsigned int count) +static void __init null_hpt_init(void) { /* nothing */ } @@ -128,186 +123,18 @@ static unsigned int c0_hpt_read(void) return read_c0_count(); } -/* For use solely as a high precision timer. */ -static void c0_hpt_init(unsigned int count) -{ - write_c0_count(read_c0_count() - count); -} - /* For use both as a high precision timer and an interrupt source. */ -static void c0_hpt_timer_init(unsigned int count) +static void __init c0_hpt_timer_init(void) { - count = read_c0_count() - count; - expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; - write_c0_count(expirelo - cycles_per_jiffy); + expirelo = read_c0_count() + cycles_per_jiffy; write_c0_compare(expirelo); - write_c0_count(count); } int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); -void (*mips_hpt_init)(unsigned int); - -/* - * Gettimeoffset routines. These routines returns the time duration - * since last timer interrupt in usecs. - * - * If the exact CPU counter frequency is known, use fixed_rate_gettimeoffset. - * Otherwise use calibrate_gettimeoffset() - * - * If the CPU does not have the counter register, you can either supply - * your own gettimeoffset() routine, or use null_gettimeoffset(), which - * gives the same resolution as HZ. - */ - -static unsigned long null_gettimeoffset(void) -{ - return 0; -} - - -/* The function pointer to one of the gettimeoffset funcs. */ -unsigned long (*do_gettimeoffset)(void) = null_gettimeoffset; - - -static unsigned long fixed_rate_gettimeoffset(void) -{ - u32 count; - unsigned long res; - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (sll32_usecs_per_cycle) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - - -/* - * Cached "1/(clocks per usec) * 2^32" value. - * It has to be recalculated once each jiffy. - */ -static unsigned long cached_quotient; - -/* Last jiffy when calibrate_divXX_gettimeoffset() was called. */ -static unsigned long last_jiffies; - -/* - * This is moved from dec/time.c:do_ioasic_gettimeoffset() by Maciej. - */ -static unsigned long calibrate_div32_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies != 0) { - unsigned long r0; - do_div64_32(r0, timerhi, timerlo, tmp); - do_div64_32(quotient, USECS_PER_JIFFY, - USECS_PER_JIFFY_FRAC, r0); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (quotient) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - -static unsigned long calibrate_div64_gettimeoffset(void) -{ - u32 count; - unsigned long res, tmp; - unsigned long quotient; - - tmp = jiffies; - - quotient = cached_quotient; - - if (last_jiffies != tmp) { - last_jiffies = tmp; - if (last_jiffies) { - unsigned long r0; - __asm__(".set push\n\t" - ".set mips3\n\t" - "lwu %0,%3\n\t" - "dsll32 %1,%2,0\n\t" - "or %1,%1,%0\n\t" - "ddivu $0,%1,%4\n\t" - "mflo %1\n\t" - "dsll32 %0,%5,0\n\t" - "or %0,%0,%6\n\t" - "ddivu $0,%0,%1\n\t" - "mflo %0\n\t" - ".set pop" - : "=&r" (quotient), "=&r" (r0) - : "r" (timerhi), "m" (timerlo), - "r" (tmp), "r" (USECS_PER_JIFFY), - "r" (USECS_PER_JIFFY_FRAC) - : "hi", "lo", GCC_REG_ACCUM); - cached_quotient = quotient; - } - } - - /* Get last timer tick in absolute kernel time */ - count = mips_hpt_read(); - - /* .. relative to previous jiffy (32 bits is enough) */ - count -= timerlo; - - __asm__("multu %1,%2" - : "=h" (res) - : "r" (count), "r" (quotient) - : "lo", GCC_REG_ACCUM); - - /* - * Due to possible jiffies inconsistencies, we need to check - * the result so that we'll get a timer that is monotonic. - */ - if (res >= USECS_PER_JIFFY) - res = USECS_PER_JIFFY - 1; - - return res; -} - +void (*mips_hpt_init)(void) __initdata = null_hpt_init; +unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -334,18 +161,10 @@ void local_timer_interrupt(int irq, void *dev_id) */ irqreturn_t timer_interrupt(int irq, void *dev_id) { - unsigned long j; - unsigned int count; - write_seqlock(&xtime_lock); - count = mips_hpt_read(); mips_timer_ack(); - /* Update timerhi/timerlo for intra-jiffy calibration. */ - timerhi += count < timerlo; /* Wrap around */ - timerlo = count; - /* * call the generic timer interrupt handling */ @@ -368,47 +187,6 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) } } - /* - * If jiffies has overflown in this timer_interrupt, we must - * update the timer[hi]/[lo] to make fast gettimeoffset funcs - * quotient calc still valid. -arca - * - * The first timer interrupt comes late as interrupts are - * enabled long after timers are initialized. Therefore the - * high precision timer is fast, leading to wrong gettimeoffset() - * calculations. We deal with it by setting it based on the - * number of its ticks between the second and the third interrupt. - * That is still somewhat imprecise, but it's a good estimate. - * --macro - */ - j = jiffies; - if (j < 4) { - static unsigned int prev_count; - static int hpt_initialized; - - switch (j) { - case 0: - timerhi = timerlo = 0; - mips_hpt_init(count); - break; - case 2: - prev_count = count; - break; - case 3: - if (!hpt_initialized) { - unsigned int c3 = 3 * (count - prev_count); - - timerhi = 0; - timerlo = c3; - mips_hpt_init(count - c3); - hpt_initialized = 1; - } - break; - default: - break; - } - } - write_sequnlock(&xtime_lock); /* @@ -476,12 +254,11 @@ asmlinkage void ll_local_timer_interrupt(int irq) * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use fixed_rate_gettimeoffset - * or use cpu counter as timer interrupt source) + * (only needed if you intended to use cpu counter as timer interrupt + * source) * 2) setup xtime based on rtc_mips_get_time(). - * 3) choose a appropriate gettimeoffset routine. - * 4) calculate a couple of cached variables for later usage - * 5) plat_timer_setup() - + * 3) calculate a couple of cached variables for later usage + * 4) plat_timer_setup() - * a) (optional) over-write any choices made above by time_init(). * b) machine specific code should setup the timer irqaction. * c) enable the timer interrupt @@ -533,13 +310,48 @@ static unsigned int __init calibrate_hpt(void) } while (--i); hpt_end = mips_hpt_read(); - hpt_count = hpt_end - hpt_start; + hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; hz = HZ; frequency = (u64)hpt_count * (u64)hz; return frequency >> log_2_loops; } +static cycle_t read_mips_hpt(void) +{ + return (cycle_t)mips_hpt_read(); +} + +static struct clocksource clocksource_mips = { + .name = "MIPS", + .read = read_mips_hpt, + .is_continuous = 1, +}; + +static void __init init_mips_clocksource(void) +{ + u64 temp; + u32 shift; + + if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) + return; + + /* Calclate a somewhat reasonable rating value */ + clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; + /* Find a shift value */ + for (shift = 32; shift > 0; shift--) { + temp = (u64) NSEC_PER_SEC << shift; + do_div(temp, mips_hpt_frequency); + if ((temp >> 32) == 0) + break; + } + clocksource_mips.shift = shift; + clocksource_mips.mult = (u32)temp; + clocksource_mips.mask = mips_hpt_mask; + + clocksource_register(&clocksource_mips); +} + void __init time_init(void) { if (board_time_init) @@ -555,41 +367,21 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !mips_hpt_read) { + if (!cpu_has_counter && !mips_hpt_read) /* No high precision timer -- sorry. */ mips_hpt_read = null_hpt_read; - mips_hpt_init = null_hpt_init; - } else if (!mips_hpt_frequency && !mips_timer_state) { + else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ - if (!mips_hpt_read) { + if (!mips_hpt_read) /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - mips_hpt_init = c0_hpt_init; - } - - if (cpu_has_mips32r1 || cpu_has_mips32r2 || - (current_cpu_data.isa_level == MIPS_CPU_ISA_I) || - (current_cpu_data.isa_level == MIPS_CPU_ISA_II)) - /* - * We need to calibrate the counter but we don't have - * 64-bit division. - */ - do_gettimeoffset = calibrate_div32_gettimeoffset; - else - /* - * We need to calibrate the counter but we *do* have - * 64-bit division. - */ - do_gettimeoffset = calibrate_div64_gettimeoffset; } else { /* We know counter frequency. Or we can get it. */ if (!mips_hpt_read) { /* No external high precision timer -- use R4k. */ mips_hpt_read = c0_hpt_read; - if (mips_timer_state) - mips_hpt_init = c0_hpt_init; - else { + if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ mips_hpt_init = c0_hpt_timer_init; mips_timer_ack = c0_timer_ack; @@ -598,16 +390,9 @@ void __init time_init(void) if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); - do_gettimeoffset = fixed_rate_gettimeoffset; - /* Calculate cache parameters. */ cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; - /* sll32_usecs_per_cycle = 10^6 * 2^32 / mips_counter_freq */ - do_div64_32(sll32_usecs_per_cycle, - 1000000, mips_hpt_frequency / 2, - mips_hpt_frequency); - /* Report the high precision timer rate for a reference. */ printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, @@ -619,7 +404,7 @@ void __init time_init(void) mips_timer_ack = null_timer_ack; /* This sets up the high precision timer for the first interrupt. */ - mips_hpt_init(mips_hpt_read()); + mips_hpt_init(); /* * Call board specific timer interrupt setup. @@ -633,6 +418,8 @@ void __init time_init(void) * is not invoked accidentally. */ plat_timer_setup(&timer_irqaction); + + init_mips_clocksource(); } #define FEBRUARY 2 diff --git a/arch/mips/philips/pnx8550/common/time.c b/arch/mips/philips/pnx8550/common/time.c index 0af655b1f33..65c440e8480 100644 --- a/arch/mips/philips/pnx8550/common/time.c +++ b/arch/mips/philips/pnx8550/common/time.c @@ -41,8 +41,8 @@ extern unsigned int mips_hpt_frequency; * 1) board_time_init() - * a) (optional) set up RTC routines, * b) (optional) calibrate and set the mips_hpt_frequency - * (only needed if you intended to use fixed_rate_gettimeoffset - * or use cpu counter as timer interrupt source) + * (only needed if you intended to use cpu counter as timer interrupt + * source) */ void pnx8550_time_init(void) diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 65fa3a23ea5..3cc0436db6c 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -3,9 +3,7 @@ #include #include - -extern unsigned int (*mips_hpt_read)(void); -extern void (*mips_hpt_init)(unsigned int); +#include #define LAUNCHSTACK_SIZE 256 @@ -101,7 +99,7 @@ void prom_cpus_done(void) */ void prom_init_secondary(void) { - mips_hpt_init(mips_hpt_read()); + mips_hpt_init(); set_c0_status(ST0_CO | ST0_IE | ST0_IM); } diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 4e870fc4469..c965705f342 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -134,13 +134,6 @@ again: irq_exit(); } -unsigned long ip27_do_gettimeoffset(void) -{ - unsigned long ct_cur1; - ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY; - return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000; -} - /* Includes for ioc3_init(). */ #include #include @@ -248,12 +241,17 @@ void __init plat_timer_setup(struct irqaction *irq) setup_irq(irqno, &rt_irqaction); } +static unsigned int ip27_hpt_read(void) +{ + return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); +} + void __init ip27_time_init(void) { + mips_hpt_read = ip27_hpt_read; + mips_hpt_frequency = CYCLES_PER_SEC; xtime.tv_sec = get_m48t35_time(); xtime.tv_nsec = 0; - - do_gettimeoffset = ip27_do_gettimeoffset; } void __init cpu_time_init(void) diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index bf12af46132..e136bde5248 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -47,6 +47,12 @@ #define IMR_IP3_VAL K_BCM1480_INT_MAP_I1 #define IMR_IP4_VAL K_BCM1480_INT_MAP_I2 +#ifdef CONFIG_SIMULATION +#define BCM1480_HPT_VALUE 50000 +#else +#define BCM1480_HPT_VALUE 1000000 +#endif + extern int bcm1480_steal_irq(int irq); void bcm1480_time_init(void) @@ -59,11 +65,6 @@ void bcm1480_time_init(void) BUG(); } - if (!cpu) { - /* Use our own gettimeoffset() routine */ - do_gettimeoffset = bcm1480_gettimeoffset; - } - bcm1480_mask_irq(cpu, irq); /* Map the timer interrupt to ip[4] of this cpu */ @@ -74,11 +75,7 @@ void bcm1480_time_init(void) /* Disable the timer and set up the count */ __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); __raw_writeq( -#ifndef CONFIG_SIMULATION - 1000000/HZ -#else - 50000/HZ -#endif + BCM1480_HPT_VALUE/HZ , IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT))); /* Set the timer running */ @@ -122,16 +119,16 @@ void bcm1480_timer_interrupt(void) } } -/* - * We use our own do_gettimeoffset() instead of the generic one, - * because the generic one does not work for SMP case. - * In addition, since we use general timer 0 for system time, - * we can get accurate intra-jiffy offset without calibration. - */ -unsigned long bcm1480_gettimeoffset(void) +static unsigned int bcm1480_hpt_read(void) { + /* We assume this function is called xtime_lock held. */ unsigned long count = __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT))); + return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; +} - return 1000000/HZ - count; +void __init bcm1480_hpt_setup(void) +{ + mips_hpt_read = bcm1480_hpt_read; + mips_hpt_frequency = BCM1480_HPT_VALUE; } diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index 0ccf1796dd7..bcb74f2c194 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -47,15 +47,11 @@ #define SB1250_HPT_NUM 3 #define SB1250_HPT_VALUE M_SCD_TIMER_CNT /* max value */ -#define SB1250_HPT_SHIFT ((sizeof(unsigned int)*8)-V_SCD_TIMER_WIDTH) extern int sb1250_steal_irq(int irq); static unsigned int sb1250_hpt_read(void); -static void sb1250_hpt_init(unsigned int); - -static unsigned int hpt_offset; void __init sb1250_hpt_setup(void) { @@ -69,13 +65,9 @@ void __init sb1250_hpt_setup(void) __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); - /* - * we need to fill 32 bits, so just use the upper 23 bits and pretend - * the timer is going 512Mhz instead of 1Mhz - */ - mips_hpt_frequency = V_SCD_TIMER_FREQ << SB1250_HPT_SHIFT; - mips_hpt_init = sb1250_hpt_init; + mips_hpt_frequency = V_SCD_TIMER_FREQ; mips_hpt_read = sb1250_hpt_read; + mips_hpt_mask = M_SCD_TIMER_INIT; } } @@ -149,11 +141,7 @@ void sb1250_timer_interrupt(void) /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over - * again. There's no easy way to set to a specific value so store init value - * in hpt_offset and subtract each time. - * - * Note: Timer isn't full 32bits so shift it into the upper part making - * it appear to run at a higher frequency. + * again. */ static unsigned int sb1250_hpt_read(void) { @@ -161,13 +149,5 @@ static unsigned int sb1250_hpt_read(void) count = G_SCD_TIMER_CNT(__raw_readq(IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CNT)))); - count = (SB1250_HPT_VALUE - count) << SB1250_HPT_SHIFT; - - return count - hpt_offset; -} - -static void sb1250_hpt_init(unsigned int count) -{ - hpt_offset = count; - return; + return SB1250_HPT_VALUE - count; } -- cgit v1.2.3 From 5ee7737379b1d7f0c977c0f1661fbaf01a8d4721 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Fri, 27 Oct 2006 19:49:53 +0900 Subject: [IA64] cpu-hotplug: Fixing confliction between CPU hot-add and IPI Signed-off-by: Kenji Kaneshige Acked-by: Satoru Takeuchi Acked-by: KAMEZAWA Hiroyuki Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 657ac99a451..2763e791778 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -328,10 +328,14 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wait) { struct call_data_struct data; - int cpus = num_online_cpus()-1; + int cpus; - if (!cpus) + spin_lock(&call_lock); + cpus = num_online_cpus() - 1; + if (!cpus) { + spin_unlock(&call_lock); return 0; + } /* Can deadlock when called with interrupts disabled */ WARN_ON(irqs_disabled()); @@ -343,8 +347,6 @@ smp_call_function (void (*func) (void *info), void *info, int nonatomic, int wai if (wait) atomic_set(&data.finished, 0); - spin_lock(&call_lock); - call_data = &data; mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC */ send_IPI_allbutself(IPI_CALL_FUNC); -- cgit v1.2.3 From 264b0f99308436deaee38bab99e586612d012fc1 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Wed, 25 Oct 2006 17:59:47 -0500 Subject: [IA64] MCA recovery: Montecito support The information in MCA records is filled in slightly differently on Montecito than on Madison/McKinley. Usually, the cache check and bus check target identifiers have the same address. On Montecito the cache check and bus check target identifiers can be different if a corrected error (ie SBE or unconsumed poison data) was encountered and then an uncorrected error (ie DBE) was consumed. In that case, the cache check target identifier is the physical address of the DBE (that caused the MCA to surface) while the bus check target identifier is the physical address of the SBE. This patch correctly finds the target identifier that triggered the MCA. If there are multiple valid cache target identifiers in the same error record then use the one with the lowest cache level. Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/kernel/mca_drv.c | 95 +++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index a45009d2bc9..afc1403799c 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c @@ -434,6 +434,50 @@ is_mca_global(peidx_table_t *peidx, pal_bus_check_info_t *pbci, return MCA_IS_GLOBAL; } +/** + * get_target_identifier - Get the valid Cache or Bus check target identifier. + * @peidx: pointer of index of processor error section + * + * Return value: + * target address on Success / 0 on Failue + */ +static u64 +get_target_identifier(peidx_table_t *peidx) +{ + u64 target_address = 0; + sal_log_mod_error_info_t *smei; + pal_cache_check_info_t *pcci; + int i, level = 9; + + /* + * Look through the cache checks for a valid target identifier + * If more than one valid target identifier, return the one + * with the lowest cache level. + */ + for (i = 0; i < peidx_cache_check_num(peidx); i++) { + smei = (sal_log_mod_error_info_t *)peidx_cache_check(peidx, i); + if (smei->valid.target_identifier && smei->target_identifier) { + pcci = (pal_cache_check_info_t *)&(smei->check_info); + if (!target_address || (pcci->level < level)) { + target_address = smei->target_identifier; + level = pcci->level; + continue; + } + } + } + if (target_address) + return target_address; + + /* + * Look at the bus check for a valid target identifier + */ + smei = peidx_bus_check(peidx, 0); + if (smei && smei->valid.target_identifier) + return smei->target_identifier; + + return 0; +} + /** * recover_from_read_error - Try to recover the errors which type are "read"s. * @slidx: pointer of index of SAL error record @@ -450,13 +494,14 @@ recover_from_read_error(slidx_table_t *slidx, peidx_table_t *peidx, pal_bus_check_info_t *pbci, struct ia64_sal_os_state *sos) { - sal_log_mod_error_info_t *smei; + u64 target_identifier; pal_min_state_area_t *pmsa; struct ia64_psr *psr1, *psr2; ia64_fptr_t *mca_hdlr_bh = (ia64_fptr_t*)mca_handler_bhhook; /* Is target address valid? */ - if (!pbci->tv) + target_identifier = get_target_identifier(peidx); + if (!target_identifier) return fatal_mca("target address not valid"); /* @@ -487,32 +532,28 @@ recover_from_read_error(slidx_table_t *slidx, pmsa = sos->pal_min_state; if (psr1->cpl != 0 || ((psr2->cpl != 0) && mca_recover_range(pmsa->pmsa_iip))) { - smei = peidx_bus_check(peidx, 0); - if (smei->valid.target_identifier) { - /* - * setup for resume to bottom half of MCA, - * "mca_handler_bhhook" - */ - /* pass to bhhook as argument (gr8, ...) */ - pmsa->pmsa_gr[8-1] = smei->target_identifier; - pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip; - pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr; - /* set interrupted return address (but no use) */ - pmsa->pmsa_br0 = pmsa->pmsa_iip; - /* change resume address to bottom half */ - pmsa->pmsa_iip = mca_hdlr_bh->fp; - pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp; - /* set cpl with kernel mode */ - psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; - psr2->cpl = 0; - psr2->ri = 0; - psr2->bn = 1; - psr2->i = 0; - - return mca_recovered("user memory corruption. " + /* + * setup for resume to bottom half of MCA, + * "mca_handler_bhhook" + */ + /* pass to bhhook as argument (gr8, ...) */ + pmsa->pmsa_gr[8-1] = target_identifier; + pmsa->pmsa_gr[9-1] = pmsa->pmsa_iip; + pmsa->pmsa_gr[10-1] = pmsa->pmsa_ipsr; + /* set interrupted return address (but no use) */ + pmsa->pmsa_br0 = pmsa->pmsa_iip; + /* change resume address to bottom half */ + pmsa->pmsa_iip = mca_hdlr_bh->fp; + pmsa->pmsa_gr[1-1] = mca_hdlr_bh->gp; + /* set cpl with kernel mode */ + psr2 = (struct ia64_psr *)&pmsa->pmsa_ipsr; + psr2->cpl = 0; + psr2->ri = 0; + psr2->bn = 1; + psr2->i = 0; + + return mca_recovered("user memory corruption. " "kill affected process - recovered."); - } - } return fatal_mca("kernel context not recovered, iip 0x%lx\n", -- cgit v1.2.3 From fa1d19e5d9a94120f31e5783ab44758f46892d94 Mon Sep 17 00:00:00 2001 From: Troy Heber Date: Wed, 25 Oct 2006 14:46:15 -0600 Subject: [IA64] move SAL_CACHE_FLUSH check later in boot The check to see if the firmware drops interrupts during a SAL_CACHE_FLUSH is done to early in the boot. SAL_CACHE_FLUSH expects to be able to make PAL calls in virtual mode, on some cell based machines a fault occurs causing a MCA. This patch moves the check after mmu_context_init so the TLB and VHPT are properly setup. Signed-off-by Troy Heber Signed-off-by: Tony Luck --- arch/ia64/kernel/sal.c | 11 +++++++---- arch/ia64/kernel/setup.c | 2 ++ 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index 642fdc7b969..20bad78b507 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c @@ -223,12 +223,13 @@ static void __init sal_desc_ap_wakeup(void *p) { } */ static int sal_cache_flush_drops_interrupts; -static void __init +void __init check_sal_cache_flush (void) { unsigned long flags; int cpu; - u64 vector; + u64 vector, cache_type = 3; + struct ia64_sal_retval isrv; cpu = get_cpu(); local_irq_save(flags); @@ -243,7 +244,10 @@ check_sal_cache_flush (void) while (!ia64_get_irr(IA64_TIMER_VECTOR)) cpu_relax(); - ia64_sal_cache_flush(3); + SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); + + if (isrv.status) + printk(KERN_ERR "SAL_CAL_FLUSH failed with %ld\n", isrv.status); if (ia64_get_irr(IA64_TIMER_VECTOR)) { vector = ia64_get_ivr(); @@ -331,7 +335,6 @@ ia64_sal_init (struct ia64_sal_systab *systab) p += SAL_DESC_SIZE(*p); } - check_sal_cache_flush(); } int diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c4caa800349..d10404a4175 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -457,6 +457,8 @@ setup_arch (char **cmdline_p) cpu_init(); /* initialize the bootstrap CPU */ mmu_context_init(); /* initialize context_id bitmap */ + check_sal_cache_flush(); + #ifdef CONFIG_ACPI acpi_boot_init(); #endif -- cgit v1.2.3 From 024e4f2c5175a482c234cf67ed22368d770bf78f Mon Sep 17 00:00:00 2001 From: Keith Owens Date: Wed, 18 Oct 2006 15:36:49 +1000 Subject: [IA64] Correct definition of handle_IPI The declaration of handle_IPI in arch/ia64/kernel/smp.c was changed but not the definition of this function. Remove struct pt_regs from handle_IPI(). Signed-off-by: Keith Owens Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 2763e791778..6ab95ceaf9d 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -108,7 +108,7 @@ cpu_die(void) } irqreturn_t -handle_IPI (int irq, void *dev_id, struct pt_regs *regs) +handle_IPI (int irq, void *dev_id) { int this_cpu = get_cpu(); unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation); -- cgit v1.2.3 From 441cbd8dace80545db2ac43175ac1c097d96f75c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 26 Oct 2006 15:38:10 +1000 Subject: [POWERPC] Fix various offb issues This patch fixes a few issues in offb: - A test was inverted causing the palette hack to never work (no device node was passed down to the init function) - Some cards seem to have their assigned-addresses property in a random order, thus we need to try using of_get_pci_address() first, which will fail if it's not a PCI device, and fallback to of_get_address() in that case. of_get_pci_address() properly parsees assigned-addresses to test the BAR number and thus will get it right whatever the order is. - Some cards (like GXT4500) provide a linebytes of 0xffffffff in the device-tree which does no good. This patch handles that by using the screen width when that happens. (Also fixes btext.c while at it). - Add detection of the GXT4500 in addition to the GXT2000 for the palette hacks (we use the same hack, palette is linear in register space at offset 0x6000). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/btext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c index 995fcef156f..93f21aaf7c8 100644 --- a/arch/powerpc/kernel/btext.c +++ b/arch/powerpc/kernel/btext.c @@ -182,7 +182,7 @@ int btext_initialize(struct device_node *np) prop = get_property(np, "linux,bootx-linebytes", NULL); if (prop == NULL) prop = get_property(np, "linebytes", NULL); - if (prop) + if (prop && *prop != 0xffffffffu) pitch = *prop; if (pitch == 1) pitch = 0x1000; -- cgit v1.2.3 From dd6c89f686bdb2a5de72fab636fc839e5a0add6d Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Fri, 27 Oct 2006 15:06:32 -0500 Subject: [POWERPC] Fix oprofile support for e500 in arch/powerpc Fixed a compile error in building the 85xx support with oprofile, and in the process cleaned up some issues with the fsl_booke performance monitor code. * Reorganized FSL Book-E performance monitoring code so that the 7450 wouldn't be built if the e500 was, and cleaned it up so it was more self-contained. * Added a cpu_setup function for FSL Book-E. The original cpu_setup function prototype had no arguments, assuming that the reg_setup function would copy the required information into variables which represented the registers. This was silly for e500, since it has 1 register per counter (rather than 3 for all counters), so the code has been restructured to have cpu_setup take the current counter config array as an argument, with op_powerpc_setup() invoking op_powerpc_cpu_setup() through on_each_cpu(), and op_powerpc_cpu_setup() invoking the model-specific cpu_setup function with an argument. The argument is ignored on all other platforms at present. * Fixed a confusing line where a trinary operator only had two arguments Signed-off-by: Andrew Fleming Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 1 - arch/powerpc/kernel/perfmon_fsl_booke.c | 221 ----------------------------- arch/powerpc/kernel/pmc.c | 2 +- arch/powerpc/oprofile/Makefile | 2 +- arch/powerpc/oprofile/common.c | 10 +- arch/powerpc/oprofile/op_model_7450.c | 2 +- arch/powerpc/oprofile/op_model_fsl_booke.c | 170 +++++++++++++++++----- arch/powerpc/oprofile/op_model_power4.c | 2 +- arch/powerpc/oprofile/op_model_rs64.c | 2 +- 9 files changed, 149 insertions(+), 263 deletions(-) delete mode 100644 arch/powerpc/kernel/perfmon_fsl_booke.c (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 8b133afbdc2..7af23c43fd4 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -38,7 +38,6 @@ obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o obj32-$(CONFIG_MODULES) += module_32.o -obj-$(CONFIG_E500) += perfmon_fsl_booke.o ifeq ($(CONFIG_PPC_MERGE),y) diff --git a/arch/powerpc/kernel/perfmon_fsl_booke.c b/arch/powerpc/kernel/perfmon_fsl_booke.c deleted file mode 100644 index e0dcf2b41fb..00000000000 --- a/arch/powerpc/kernel/perfmon_fsl_booke.c +++ /dev/null @@ -1,221 +0,0 @@ -/* arch/powerpc/kernel/perfmon_fsl_booke.c - * Freescale Book-E Performance Monitor code - * - * Author: Andy Fleming - * Copyright (c) 2004 Freescale Semiconductor, Inc - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -static inline u32 get_pmlca(int ctr); -static inline void set_pmlca(int ctr, u32 pmlca); - -static inline u32 get_pmlca(int ctr) -{ - u32 pmlca; - - switch (ctr) { - case 0: - pmlca = mfpmr(PMRN_PMLCA0); - break; - case 1: - pmlca = mfpmr(PMRN_PMLCA1); - break; - case 2: - pmlca = mfpmr(PMRN_PMLCA2); - break; - case 3: - pmlca = mfpmr(PMRN_PMLCA3); - break; - default: - panic("Bad ctr number\n"); - } - - return pmlca; -} - -static inline void set_pmlca(int ctr, u32 pmlca) -{ - switch (ctr) { - case 0: - mtpmr(PMRN_PMLCA0, pmlca); - break; - case 1: - mtpmr(PMRN_PMLCA1, pmlca); - break; - case 2: - mtpmr(PMRN_PMLCA2, pmlca); - break; - case 3: - mtpmr(PMRN_PMLCA3, pmlca); - break; - default: - panic("Bad ctr number\n"); - } -} - -void init_pmc_stop(int ctr) -{ - u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | - PMLCA_FCM1 | PMLCA_FCM0); - u32 pmlcb = 0; - - switch (ctr) { - case 0: - mtpmr(PMRN_PMLCA0, pmlca); - mtpmr(PMRN_PMLCB0, pmlcb); - break; - case 1: - mtpmr(PMRN_PMLCA1, pmlca); - mtpmr(PMRN_PMLCB1, pmlcb); - break; - case 2: - mtpmr(PMRN_PMLCA2, pmlca); - mtpmr(PMRN_PMLCB2, pmlcb); - break; - case 3: - mtpmr(PMRN_PMLCA3, pmlca); - mtpmr(PMRN_PMLCB3, pmlcb); - break; - default: - panic("Bad ctr number!\n"); - } -} - -void set_pmc_event(int ctr, int event) -{ - u32 pmlca; - - pmlca = get_pmlca(ctr); - - pmlca = (pmlca & ~PMLCA_EVENT_MASK) | - ((event << PMLCA_EVENT_SHIFT) & - PMLCA_EVENT_MASK); - - set_pmlca(ctr, pmlca); -} - -void set_pmc_user_kernel(int ctr, int user, int kernel) -{ - u32 pmlca; - - pmlca = get_pmlca(ctr); - - if(user) - pmlca &= ~PMLCA_FCU; - else - pmlca |= PMLCA_FCU; - - if(kernel) - pmlca &= ~PMLCA_FCS; - else - pmlca |= PMLCA_FCS; - - set_pmlca(ctr, pmlca); -} - -void set_pmc_marked(int ctr, int mark0, int mark1) -{ - u32 pmlca = get_pmlca(ctr); - - if(mark0) - pmlca &= ~PMLCA_FCM0; - else - pmlca |= PMLCA_FCM0; - - if(mark1) - pmlca &= ~PMLCA_FCM1; - else - pmlca |= PMLCA_FCM1; - - set_pmlca(ctr, pmlca); -} - -void pmc_start_ctr(int ctr, int enable) -{ - u32 pmlca = get_pmlca(ctr); - - pmlca &= ~PMLCA_FC; - - if (enable) - pmlca |= PMLCA_CE; - else - pmlca &= ~PMLCA_CE; - - set_pmlca(ctr, pmlca); -} - -void pmc_start_ctrs(int enable) -{ - u32 pmgc0 = mfpmr(PMRN_PMGC0); - - pmgc0 &= ~PMGC0_FAC; - pmgc0 |= PMGC0_FCECE; - - if (enable) - pmgc0 |= PMGC0_PMIE; - else - pmgc0 &= ~PMGC0_PMIE; - - mtpmr(PMRN_PMGC0, pmgc0); -} - -void pmc_stop_ctrs(void) -{ - u32 pmgc0 = mfpmr(PMRN_PMGC0); - - pmgc0 |= PMGC0_FAC; - - pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); - - mtpmr(PMRN_PMGC0, pmgc0); -} - -void dump_pmcs(void) -{ - printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); - printk("pmc\t\tpmlca\t\tpmlcb\n"); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), - mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), - mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), - mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); - printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), - mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); -} - -EXPORT_SYMBOL(init_pmc_stop); -EXPORT_SYMBOL(set_pmc_event); -EXPORT_SYMBOL(set_pmc_user_kernel); -EXPORT_SYMBOL(set_pmc_marked); -EXPORT_SYMBOL(pmc_start_ctr); -EXPORT_SYMBOL(pmc_start_ctrs); -EXPORT_SYMBOL(pmc_stop_ctrs); -EXPORT_SYMBOL(dump_pmcs); diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index a0a2efadeab..3d8f6f44641 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c @@ -71,7 +71,7 @@ int reserve_pmc_hardware(perf_irq_t new_perf_irq) } pmc_owner_caller = __builtin_return_address(0); - perf_irq = new_perf_irq ? : dummy_perf; + perf_irq = new_perf_irq ? new_perf_irq : dummy_perf; out: spin_unlock(&pmc_owner_lock); diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 3145d610b5b..0b5df9c96ae 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile @@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ oprofile-y := $(DRIVER_OBJS) common.o backtrace.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o -oprofile-$(CONFIG_PPC32) += op_model_7450.o +oprofile-$(CONFIG_6xx) += op_model_7450.o diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index fd0bbbe7a4d..63bbef3b63f 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -34,6 +34,11 @@ static void op_handle_interrupt(struct pt_regs *regs) model->handle_interrupt(regs, ctr); } +static void op_powerpc_cpu_setup(void *dummy) +{ + model->cpu_setup(ctr); +} + static int op_powerpc_setup(void) { int err; @@ -47,7 +52,7 @@ static int op_powerpc_setup(void) model->reg_setup(ctr, &sys, model->num_counters); /* Configure the registers on all cpus. */ - on_each_cpu(model->cpu_setup, NULL, 0, 1); + on_each_cpu(op_powerpc_cpu_setup, NULL, 0, 1); return 0; } @@ -142,7 +147,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case PPC_OPROFILE_POWER4: model = &op_model_power4; break; -#else +#endif +#ifdef CONFIG_6xx case PPC_OPROFILE_G4: model = &op_model_7450; break; diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c index d8ee3aea83f..f481c0ed5e6 100644 --- a/arch/powerpc/oprofile/op_model_7450.c +++ b/arch/powerpc/oprofile/op_model_7450.c @@ -81,7 +81,7 @@ static void pmc_stop_ctrs(void) /* Configures the counters on this CPU based on the global * settings */ -static void fsl7450_cpu_setup(void *unused) +static void fsl7450_cpu_setup(struct op_counter_config *ctr) { /* freeze all counters */ pmc_stop_ctrs(); diff --git a/arch/powerpc/oprofile/op_model_fsl_booke.c b/arch/powerpc/oprofile/op_model_fsl_booke.c index e29dede3142..0b3c31f5209 100644 --- a/arch/powerpc/oprofile/op_model_fsl_booke.c +++ b/arch/powerpc/oprofile/op_model_fsl_booke.c @@ -32,42 +32,152 @@ static unsigned long reset_value[OP_MAX_COUNTER]; static int num_counters; static int oprofile_running; -static inline unsigned int ctr_read(unsigned int i) +static void init_pmc_stop(int ctr) { - switch(i) { - case 0: - return mfpmr(PMRN_PMC0); - case 1: - return mfpmr(PMRN_PMC1); - case 2: - return mfpmr(PMRN_PMC2); - case 3: - return mfpmr(PMRN_PMC3); - default: - return 0; - } -} + u32 pmlca = (PMLCA_FC | PMLCA_FCS | PMLCA_FCU | + PMLCA_FCM1 | PMLCA_FCM0); + u32 pmlcb = 0; -static inline void ctr_write(unsigned int i, unsigned int val) -{ - switch(i) { + switch (ctr) { case 0: - mtpmr(PMRN_PMC0, val); + mtpmr(PMRN_PMLCA0, pmlca); + mtpmr(PMRN_PMLCB0, pmlcb); break; case 1: - mtpmr(PMRN_PMC1, val); + mtpmr(PMRN_PMLCA1, pmlca); + mtpmr(PMRN_PMLCB1, pmlcb); break; case 2: - mtpmr(PMRN_PMC2, val); + mtpmr(PMRN_PMLCA2, pmlca); + mtpmr(PMRN_PMLCB2, pmlcb); break; case 3: - mtpmr(PMRN_PMC3, val); + mtpmr(PMRN_PMLCA3, pmlca); + mtpmr(PMRN_PMLCB3, pmlcb); break; default: - break; + panic("Bad ctr number!\n"); } } +static void set_pmc_event(int ctr, int event) +{ + u32 pmlca; + + pmlca = get_pmlca(ctr); + + pmlca = (pmlca & ~PMLCA_EVENT_MASK) | + ((event << PMLCA_EVENT_SHIFT) & + PMLCA_EVENT_MASK); + + set_pmlca(ctr, pmlca); +} + +static void set_pmc_user_kernel(int ctr, int user, int kernel) +{ + u32 pmlca; + + pmlca = get_pmlca(ctr); + + if(user) + pmlca &= ~PMLCA_FCU; + else + pmlca |= PMLCA_FCU; + + if(kernel) + pmlca &= ~PMLCA_FCS; + else + pmlca |= PMLCA_FCS; + + set_pmlca(ctr, pmlca); +} + +static void set_pmc_marked(int ctr, int mark0, int mark1) +{ + u32 pmlca = get_pmlca(ctr); + + if(mark0) + pmlca &= ~PMLCA_FCM0; + else + pmlca |= PMLCA_FCM0; + + if(mark1) + pmlca &= ~PMLCA_FCM1; + else + pmlca |= PMLCA_FCM1; + + set_pmlca(ctr, pmlca); +} + +static void pmc_start_ctr(int ctr, int enable) +{ + u32 pmlca = get_pmlca(ctr); + + pmlca &= ~PMLCA_FC; + + if (enable) + pmlca |= PMLCA_CE; + else + pmlca &= ~PMLCA_CE; + + set_pmlca(ctr, pmlca); +} + +static void pmc_start_ctrs(int enable) +{ + u32 pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 &= ~PMGC0_FAC; + pmgc0 |= PMGC0_FCECE; + + if (enable) + pmgc0 |= PMGC0_PMIE; + else + pmgc0 &= ~PMGC0_PMIE; + + mtpmr(PMRN_PMGC0, pmgc0); +} + +static void pmc_stop_ctrs(void) +{ + u32 pmgc0 = mfpmr(PMRN_PMGC0); + + pmgc0 |= PMGC0_FAC; + + pmgc0 &= ~(PMGC0_PMIE | PMGC0_FCECE); + + mtpmr(PMRN_PMGC0, pmgc0); +} + +static void dump_pmcs(void) +{ + printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0)); + printk("pmc\t\tpmlca\t\tpmlcb\n"); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0), + mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1), + mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2), + mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2)); + printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3), + mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3)); +} + +static void fsl_booke_cpu_setup(struct op_counter_config *ctr) +{ + int i; + + /* freeze all counters */ + pmc_stop_ctrs(); + + for (i = 0;i < num_counters;i++) { + init_pmc_stop(i); + + set_pmc_event(i, ctr[i].event); + + set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); + } +} static void fsl_booke_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -77,23 +187,14 @@ static void fsl_booke_reg_setup(struct op_counter_config *ctr, num_counters = num_ctrs; - /* freeze all counters */ - pmc_stop_ctrs(); - /* Our counters count up, and "count" refers to * how much before the next interrupt, and we interrupt * on overflow. So we calculate the starting value * which will give us "count" until overflow. * Then we set the events on the enabled counters */ - for (i = 0; i < num_counters; ++i) { + for (i = 0; i < num_counters; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; - init_pmc_stop(i); - - set_pmc_event(i, ctr[i].event); - - set_pmc_user_kernel(i, ctr[i].user, ctr[i].kernel); - } } static void fsl_booke_start(struct op_counter_config *ctr) @@ -105,8 +206,8 @@ static void fsl_booke_start(struct op_counter_config *ctr) for (i = 0; i < num_counters; ++i) { if (ctr[i].enabled) { ctr_write(i, reset_value[i]); - /* Set Each enabled counterd to only - * count when the Mark bit is not set */ + /* Set each enabled counter to only + * count when the Mark bit is *not* set */ set_pmc_marked(i, 1, 0); pmc_start_ctr(i, 1); } else { @@ -177,6 +278,7 @@ static void fsl_booke_handle_interrupt(struct pt_regs *regs, struct op_powerpc_model op_model_fsl_booke = { .reg_setup = fsl_booke_reg_setup, + .cpu_setup = fsl_booke_cpu_setup, .start = fsl_booke_start, .stop = fsl_booke_stop, .handle_interrupt = fsl_booke_handle_interrupt, diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index 6a927effcc7..356709d515b 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c @@ -82,7 +82,7 @@ static inline int mmcra_must_set_sample(void) return 0; } -static void power4_cpu_setup(void *unused) +static void power4_cpu_setup(struct op_counter_config *ctr) { unsigned int mmcr0 = mmcr0_val; unsigned long mmcra = mmcra_val; diff --git a/arch/powerpc/oprofile/op_model_rs64.c b/arch/powerpc/oprofile/op_model_rs64.c index 042f8f4867a..19c5ee089bc 100644 --- a/arch/powerpc/oprofile/op_model_rs64.c +++ b/arch/powerpc/oprofile/op_model_rs64.c @@ -102,7 +102,7 @@ static void rs64_reg_setup(struct op_counter_config *ctr, /* XXX setup user and kernel profiling */ } -static void rs64_cpu_setup(void *unused) +static void rs64_cpu_setup(struct op_counter_config *ctr) { unsigned int mmcr0; -- cgit v1.2.3 From 5d2efba64b231a1733c4048d1708d77e07f26426 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Mon, 30 Oct 2006 16:15:59 +1100 Subject: [POWERPC] Use 4kB iommu pages even on 64kB-page systems The 10Gigabit ethernet device drivers appear to be able to chew up all 256MB of TCE mappings on pSeries systems, as evidenced by numerous error messages: iommu_alloc failed, tbl c0000000010d5c48 vaddr c0000000d875eff0 npages 1 Some experimentation indicates that this is essentially because one 1500 byte ethernet MTU gets mapped as a 64K DMA region when the large 64K pages are enabled. Thus, it doesn't take much to exhaust all of the available DMA mappings for a high-speed card. This patch changes the iommu allocator to work with its own unique, distinct page size. Although the patch is long, its actually quite simple: it just #defines a distinct IOMMU_PAGE_SIZE and then uses this in all the places that matter. As a side effect, it also dramatically improves network performance on platforms with H-calls on iommu translation inserts/removes (since we no longer call it 16 times for a 1500 bytes packet when the iommu HW is still 4k). In the future, we might want to make the IOMMU_PAGE_SIZE a variable in the iommu_table instance, thus allowing support for different HW page sizes in the iommu itself. Signed-off-by: Linas Vepstas Signed-off-by: Benjamin Herrenschmidt Acked-by: Olof Johansson Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/iommu.c | 77 ++++++++++++++++++++-------------- arch/powerpc/kernel/vio.c | 4 +- arch/powerpc/platforms/iseries/iommu.c | 11 +---- arch/powerpc/platforms/pseries/iommu.c | 35 ++++------------ arch/powerpc/sysdev/dart.h | 1 - arch/powerpc/sysdev/dart_iommu.c | 8 +--- 6 files changed, 58 insertions(+), 78 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index f88a2a675d9..ba6b7256084 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -47,6 +47,17 @@ static int novmerge = 0; static int novmerge = 1; #endif +static inline unsigned long iommu_num_pages(unsigned long vaddr, + unsigned long slen) +{ + unsigned long npages; + + npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK); + npages >>= IOMMU_PAGE_SHIFT; + + return npages; +} + static int __init setup_iommu(char *str) { if (!strcmp(str, "novmerge")) @@ -178,10 +189,10 @@ static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, } entry += tbl->it_offset; /* Offset into real TCE table */ - ret = entry << PAGE_SHIFT; /* Set the return dma address */ + ret = entry << IOMMU_PAGE_SHIFT; /* Set the return dma address */ /* Put the TCEs in the HW table */ - ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & PAGE_MASK, + ppc_md.tce_build(tbl, entry, npages, (unsigned long)page & IOMMU_PAGE_MASK, direction); @@ -203,7 +214,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, unsigned long entry, free_entry; unsigned long i; - entry = dma_addr >> PAGE_SHIFT; + entry = dma_addr >> IOMMU_PAGE_SHIFT; free_entry = entry - tbl->it_offset; if (((free_entry + npages) > tbl->it_size) || @@ -270,7 +281,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Init first segment length for backout at failure */ outs->dma_length = 0; - DBG("mapping %d elements:\n", nelems); + DBG("sg mapping %d elements:\n", nelems); spin_lock_irqsave(&(tbl->it_lock), flags); @@ -285,9 +296,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, } /* Allocate iommu entries for that segment */ vaddr = (unsigned long)page_address(s->page) + s->offset; - npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); - npages >>= PAGE_SHIFT; - entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0); + npages = iommu_num_pages(vaddr, slen); + entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); @@ -301,14 +311,14 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Convert entry to a dma_addr_t */ entry += tbl->it_offset; - dma_addr = entry << PAGE_SHIFT; - dma_addr |= s->offset; + dma_addr = entry << IOMMU_PAGE_SHIFT; + dma_addr |= (s->offset & ~IOMMU_PAGE_MASK); - DBG(" - %lx pages, entry: %lx, dma_addr: %lx\n", + DBG(" - %lu pages, entry: %lx, dma_addr: %lx\n", npages, entry, dma_addr); /* Insert into HW table */ - ppc_md.tce_build(tbl, entry, npages, vaddr & PAGE_MASK, direction); + ppc_md.tce_build(tbl, entry, npages, vaddr & IOMMU_PAGE_MASK, direction); /* If we are in an open segment, try merging */ if (segstart != s) { @@ -323,7 +333,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, DBG(" can't merge, new segment.\n"); } else { outs->dma_length += s->length; - DBG(" merged, new len: %lx\n", outs->dma_length); + DBG(" merged, new len: %ux\n", outs->dma_length); } } @@ -367,9 +377,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, if (s->dma_length != 0) { unsigned long vaddr, npages; - vaddr = s->dma_address & PAGE_MASK; - npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) - >> PAGE_SHIFT; + vaddr = s->dma_address & IOMMU_PAGE_MASK; + npages = iommu_num_pages(s->dma_address, s->dma_length); __iommu_free(tbl, vaddr, npages); s->dma_address = DMA_ERROR_CODE; s->dma_length = 0; @@ -398,8 +407,7 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, if (sglist->dma_length == 0) break; - npages = (PAGE_ALIGN(dma_handle + sglist->dma_length) - - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT; + npages = iommu_num_pages(dma_handle,sglist->dma_length); __iommu_free(tbl, dma_handle, npages); sglist++; } @@ -532,12 +540,11 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, BUG_ON(direction == DMA_NONE); uaddr = (unsigned long)vaddr; - npages = PAGE_ALIGN(uaddr + size) - (uaddr & PAGE_MASK); - npages >>= PAGE_SHIFT; + npages = iommu_num_pages(uaddr, size); if (tbl) { dma_handle = iommu_alloc(tbl, vaddr, npages, direction, - mask >> PAGE_SHIFT, 0); + mask >> IOMMU_PAGE_SHIFT, 0); if (dma_handle == DMA_ERROR_CODE) { if (printk_ratelimit()) { printk(KERN_INFO "iommu_alloc failed, " @@ -545,7 +552,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, tbl, vaddr, npages); } } else - dma_handle |= (uaddr & ~PAGE_MASK); + dma_handle |= (uaddr & ~IOMMU_PAGE_MASK); } return dma_handle; @@ -554,11 +561,14 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) { + unsigned int npages; + BUG_ON(direction == DMA_NONE); - if (tbl) - iommu_free(tbl, dma_handle, (PAGE_ALIGN(dma_handle + size) - - (dma_handle & PAGE_MASK)) >> PAGE_SHIFT); + if (tbl) { + npages = iommu_num_pages(dma_handle, size); + iommu_free(tbl, dma_handle, npages); + } } /* Allocates a contiguous real buffer and creates mappings over it. @@ -570,11 +580,11 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, { void *ret = NULL; dma_addr_t mapping; - unsigned int npages, order; + unsigned int order; + unsigned int nio_pages, io_order; struct page *page; size = PAGE_ALIGN(size); - npages = size >> PAGE_SHIFT; order = get_order(size); /* @@ -598,8 +608,10 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, memset(ret, 0, size); /* Set up tces to cover the allocated range */ - mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, - mask >> PAGE_SHIFT, order); + nio_pages = size >> IOMMU_PAGE_SHIFT; + io_order = get_iommu_order(size); + mapping = iommu_alloc(tbl, ret, nio_pages, DMA_BIDIRECTIONAL, + mask >> IOMMU_PAGE_SHIFT, io_order); if (mapping == DMA_ERROR_CODE) { free_pages((unsigned long)ret, order); return NULL; @@ -611,12 +623,13 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, void iommu_free_coherent(struct iommu_table *tbl, size_t size, void *vaddr, dma_addr_t dma_handle) { - unsigned int npages; - if (tbl) { + unsigned int nio_pages; + + size = PAGE_ALIGN(size); + nio_pages = size >> IOMMU_PAGE_SHIFT; + iommu_free(tbl, dma_handle, nio_pages); size = PAGE_ALIGN(size); - npages = size >> PAGE_SHIFT; - iommu_free(tbl, dma_handle, npages); free_pages((unsigned long)vaddr, get_order(size)); } } diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index cb87e71eec6..ed007878d1b 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -92,9 +92,9 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) &tbl->it_index, &offset, &size); /* TCE table size - measured in tce entries */ - tbl->it_size = size >> PAGE_SHIFT; + tbl->it_size = size >> IOMMU_PAGE_SHIFT; /* offset for VIO should always be 0 */ - tbl->it_offset = offset >> PAGE_SHIFT; + tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; tbl->it_busno = 0; tbl->it_type = TCE_VB; diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index f4cbbcf8773..218817d13c5 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -43,9 +43,6 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, u64 rc; u64 tce, rpn; - index <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - while (npages--) { rpn = virt_to_abs(uaddr) >> TCE_SHIFT; tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; @@ -75,9 +72,6 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) { u64 rc; - npages <<= TCE_PAGE_FACTOR; - index <<= TCE_PAGE_FACTOR; - while (npages--) { rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) @@ -136,10 +130,9 @@ void iommu_table_getparms_iSeries(unsigned long busno, panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); /* itc_size is in pages worth of table, it_size is in # of entries */ - tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / - TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; + tbl->it_size = (parms->itc_size * TCE_PAGE_SIZE) / TCE_ENTRY_SIZE; tbl->it_busno = parms->itc_busno; - tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; + tbl->it_offset = parms->itc_offset; tbl->it_index = parms->itc_index; tbl->it_blocksize = 1; tbl->it_type = virtbus ? TCE_VB : TCE_PCI; diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index d24ba547e53..556c279a789 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -57,9 +57,6 @@ static void tce_build_pSeries(struct iommu_table *tbl, long index, u64 *tcep; u64 rpn; - index <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - proto_tce = TCE_PCI_READ; // Read allowed if (direction != DMA_TO_DEVICE) @@ -82,9 +79,6 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) { u64 *tcep; - npages <<= TCE_PAGE_FACTOR; - index <<= TCE_PAGE_FACTOR; - tcep = ((u64 *)tbl->it_base) + index; while (npages--) @@ -95,7 +89,6 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) { u64 *tcep; - index <<= TCE_PAGE_FACTOR; tcep = ((u64 *)tbl->it_base) + index; return *tcep; @@ -109,9 +102,6 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, u64 proto_tce, tce; u64 rpn; - tcenum <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) @@ -146,7 +136,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, u64 rpn; long l, limit; - if (TCE_PAGE_FACTOR == 0 && npages == 1) + if (npages == 1) return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr, direction); @@ -164,9 +154,6 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, __get_cpu_var(tce_page) = tcep; } - tcenum <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) @@ -207,9 +194,6 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages { u64 rc; - tcenum <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - while (npages--) { rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); @@ -229,9 +213,6 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n { u64 rc; - tcenum <<= TCE_PAGE_FACTOR; - npages <<= TCE_PAGE_FACTOR; - rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); if (rc && printk_ratelimit()) { @@ -248,7 +229,6 @@ static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) u64 rc; unsigned long tce_ret; - tcenum <<= TCE_PAGE_FACTOR; rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); if (rc && printk_ratelimit()) { @@ -289,7 +269,7 @@ static void iommu_table_setparms(struct pci_controller *phb, tbl->it_busno = phb->bus->number; /* Units of tce entries */ - tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; + tbl->it_offset = phb->dma_window_base_cur >> IOMMU_PAGE_SHIFT; /* Test if we are going over 2GB of DMA space */ if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { @@ -300,7 +280,7 @@ static void iommu_table_setparms(struct pci_controller *phb, phb->dma_window_base_cur += phb->dma_window_size; /* Set the tce table size - measured in entries */ - tbl->it_size = phb->dma_window_size >> PAGE_SHIFT; + tbl->it_size = phb->dma_window_size >> IOMMU_PAGE_SHIFT; tbl->it_index = 0; tbl->it_blocksize = 16; @@ -325,8 +305,8 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, tbl->it_base = 0; tbl->it_blocksize = 16; tbl->it_type = TCE_PCI; - tbl->it_offset = offset >> PAGE_SHIFT; - tbl->it_size = size >> PAGE_SHIFT; + tbl->it_offset = offset >> IOMMU_PAGE_SHIFT; + tbl->it_size = size >> IOMMU_PAGE_SHIFT; } static void iommu_bus_setup_pSeries(struct pci_bus *bus) @@ -522,8 +502,6 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) const void *dma_window = NULL; struct pci_dn *pci; - DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); - /* dev setup for LPAR is a little tricky, since the device tree might * contain the dma-window properties per-device and not neccesarily * for the bus. So we need to search upwards in the tree until we @@ -532,6 +510,9 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); + DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n", + dev, pci_name(dev), dn->full_name); + for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { dma_window = get_property(pdn, "ibm,dma-window", NULL); diff --git a/arch/powerpc/sysdev/dart.h b/arch/powerpc/sysdev/dart.h index 1c8817c4835..ff202edb059 100644 --- a/arch/powerpc/sysdev/dart.h +++ b/arch/powerpc/sysdev/dart.h @@ -72,7 +72,6 @@ #define DART_PAGE_SHIFT 12 #define DART_PAGE_SIZE (1 << DART_PAGE_SHIFT) -#define DART_PAGE_FACTOR (PAGE_SHIFT - DART_PAGE_SHIFT) #endif /* _POWERPC_SYSDEV_DART_H */ diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 03b4477dd7f..572b7846cc7 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -156,9 +156,6 @@ static void dart_build(struct iommu_table *tbl, long index, DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); - index <<= DART_PAGE_FACTOR; - npages <<= DART_PAGE_FACTOR; - dp = ((unsigned int*)tbl->it_base) + index; /* On U3, all memory is contigous, so we can move this @@ -199,9 +196,6 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) DBG("dart: free at: %lx, %lx\n", index, npages); - index <<= DART_PAGE_FACTOR; - npages <<= DART_PAGE_FACTOR; - dp = ((unsigned int *)tbl->it_base) + index; while (npages--) @@ -281,7 +275,7 @@ static void iommu_table_dart_setup(void) iommu_table_dart.it_busno = 0; iommu_table_dart.it_offset = 0; /* it_size is in number of entries */ - iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; + iommu_table_dart.it_size = dart_tablesize / sizeof(u32); /* Initialize the common IOMMU code */ iommu_table_dart.it_base = (unsigned long)dart_vbase; -- cgit v1.2.3 From 302439d2167e0f1e01a6480ac40c06063f4e16a1 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Tue, 31 Oct 2006 17:53:42 +0800 Subject: [POWERPC] qe_lib: qe_issue_cmd writes wrong value to CECDR Changed qe_issue_cmd() to write cmd_input to the CECDR unmodified. It was treating cmd_input as a virtual address and tried to convert it to a physical address. Signed-off-by: Timur Tabi Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/qe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 2bae632d3ad..e4223226a7a 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -122,8 +122,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) mcn_shift = QE_CR_MCN_NORMAL_SHIFT; } - out_be32(&qe_immr->cp.cecdr, - immrbar_virt_to_phys((void *)cmd_input)); + out_be32(&qe_immr->cp.cecdr, cmd_input); out_be32(&qe_immr->cp.cecr, (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32) mcn_protocol << mcn_shift)); -- cgit v1.2.3 From 96268889ee369b36203b7a06e8aabb197270216e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 31 Oct 2006 18:40:39 +0000 Subject: [POWERPC] Make high hugepage areas preempt safe Checking source for other get_paca()->field preemption dangers found that open_high_hpage_areas does a structure copy into its paca while preemption is enabled: unsafe however gcc accomplishes it. Just remove that copy: it's done safely afterwards by on_each_cpu, as in open_low_hpage_areas. Signed-off-by: Hugh Dickins Acked-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/mm/hugetlbpage.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 5615acc2952..fd68b74c07c 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -480,9 +480,6 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) mm->context.high_htlb_areas |= newareas; - /* update the paca copy of the context struct */ - get_paca()->context = mm->context; - /* the context change must make it to memory before the flush, * so that further SLB misses do the right thing. */ mb(); -- cgit v1.2.3 From 0d69a052d4d7c4085706b9ac0d1bd28ff90c9fca Mon Sep 17 00:00:00 2001 From: "Gui,Jian" Date: Wed, 1 Nov 2006 10:50:15 +0800 Subject: [POWERPC] Disallow kprobes on emulate_step and branch_taken On powerpc, probing on emulate_step function will crash 2.6.18.1 when it is triggered. When kprobe is triggered, emulate_step() is on its kernel path and will cause recursive kprobe fault. And branch_taken() is called in emulate_step(). This disallows kprobes on both of them. Signed-off-by: Paul Mackerras --- arch/powerpc/lib/sstep.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 9590ba780b9..7e8ded051b5 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -9,6 +9,7 @@ * 2 of the License, or (at your option) any later version. */ #include +#include #include #include #include @@ -25,7 +26,7 @@ extern char system_call_common[]; /* * Determine whether a conditional branch instruction would branch. */ -static int branch_taken(unsigned int instr, struct pt_regs *regs) +static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs) { unsigned int bo = (instr >> 21) & 0x1f; unsigned int bi; @@ -51,7 +52,7 @@ static int branch_taken(unsigned int instr, struct pt_regs *regs) * or -1 if the instruction is one that should not be stepped, * such as an rfid, or a mtmsrd that would clear MSR_RI. */ -int emulate_step(struct pt_regs *regs, unsigned int instr) +int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) { unsigned int opcode, rd; unsigned long int imm; -- cgit v1.2.3 From 4393c4f6788cee65095dd838cfeca6edefbfeb52 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 1 Nov 2006 15:11:39 +1100 Subject: [POWERPC] Make alignment exception always check exception table The alignment exception used to only check the exception table for -EFAULT, not for other errors. That opens an oops window if we can coerce the kernel into getting an alignment exception for other reasons in what would normally be a user-protected accessor, which can be done via some of the futex ops. This fixes it by always checking the exception tables. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/traps.c | 18 ++++++++++-------- arch/ppc/kernel/traps.c | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 5ed4c2ceb5c..c66b4771ef4 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -843,7 +843,7 @@ void __kprobes program_check_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs) { - int fixed = 0; + int sig, code, fixed = 0; /* we don't implement logging of alignment exceptions */ if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS)) @@ -857,14 +857,16 @@ void alignment_exception(struct pt_regs *regs) /* Operand address was bad */ if (fixed == -EFAULT) { - if (user_mode(regs)) - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); - else - /* Search exception table */ - bad_page_fault(regs, regs->dar, SIGSEGV); - return; + sig = SIGSEGV; + code = SEGV_ACCERR; + } else { + sig = SIGBUS; + code = BUS_ADRALN; } - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); + if (user_mode(regs)) + _exception(sig, regs, code, regs->dar); + else + bad_page_fault(regs, regs->dar, sig); } void StackOverflow(struct pt_regs *regs) diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index aafc8e8893d..9661a91183b 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -708,7 +708,7 @@ void single_step_exception(struct pt_regs *regs) void alignment_exception(struct pt_regs *regs) { - int fixed; + int sig, code, fixed = 0; fixed = fix_alignment(regs); if (fixed == 1) { @@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs *regs) return; } if (fixed == -EFAULT) { - /* fixed == -EFAULT means the operand address was bad */ - if (user_mode(regs)) - _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar); - else - bad_page_fault(regs, regs->dar, SIGSEGV); - return; + sig = SIGSEGV; + code = SEGV_ACCERR; + } else { + sig = SIGBUS; + code = BUS_ADRALN; } - _exception(SIGBUS, regs, BUS_ADRALN, regs->dar); + if (user_mode(regs)) + _exception(sig, regs, code, regs->dar); + else + bad_page_fault(regs, regs->dar, sig); } void StackOverflow(struct pt_regs *regs) -- cgit v1.2.3 From 130fe05dbc0114609cfef9815c0c5580b42decfa Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 1 Nov 2006 09:11:00 -0800 Subject: i386: clean up io-apic accesses This is preparation for fixing the ordering of the accesses that got broken by the commit cf4c6a2f27f5db810b69dcb1da7f194489e8ff88 when factoring out the "common" io apic routing entry accesses. Move the accessor function (that were only used by io_apic.c) out of a header file, and use proper memory-mapped accesses rather than making up our own "volatile" pointers. Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 350192d6ab9..eb10bd5da64 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -91,6 +91,46 @@ static struct irq_pin_list { int apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +struct io_apic { + unsigned int index; + unsigned int unused[3]; + unsigned int data; +}; + +static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) +{ + return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); +} + +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + return readl(&io_apic->data); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + * + * Older SiS APIC requires we rewrite the index register + */ +static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) +{ + volatile struct io_apic *io_apic = io_apic_base(apic); + if (sis_apic_bug) + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + union entry_union { struct { u32 w1, w2; }; struct IO_APIC_route_entry entry; -- cgit v1.2.3 From 242954b5aa8e5ec84f46a84637daf08ee4247c6e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 24 Oct 2006 02:29:01 +0100 Subject: [MIPS] 16K & 64K page size fixes Derived from Peter Watkins 's work. Signed-off-by: Ralf Baechle --- arch/mips/kernel/asm-offsets.c | 2 +- arch/mips/kernel/head.S | 3 ++- arch/mips/kernel/r4k_switch.S | 5 +++++ arch/mips/kernel/vmlinux.lds.S | 10 ++++++++++ arch/mips/lib-64/dump_tlb.c | 6 +++--- arch/mips/mips-boards/generic/memory.c | 2 +- arch/mips/mm/pg-r4k.c | 30 ++++++++++++++++++++++++++++-- arch/mips/mm/tlbex.c | 13 ++++++++++--- 8 files changed, 60 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index e9ce5b3721a..ff88b06f89d 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c @@ -22,7 +22,7 @@ #define offset(string, ptr, member) \ __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member))) #define constant(string, member) \ - __asm__("\n@@@" string "%x0" : : "ri" (member)) + __asm__("\n@@@" string "%X0" : : "ri" (member)) #define size(string, size) \ __asm__("\n@@@" string "%0" : : "i" (sizeof(size))) #define linefeed text("") diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 8c6db0fc72f..ddc1b71c937 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -189,7 +189,8 @@ NESTED(kernel_entry, 16, sp) # kernel entry point MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_ADDIU sp, $28, _THREAD_SIZE - 32 + PTR_LI sp, _THREAD_SIZE - 32 + PTR_ADDU sp, $28 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d5c8b82fed7..cc566cf1224 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -85,7 +85,12 @@ move $28, a2 cpu_restore_nonscratch a1 +#if (_THREAD_SIZE - 32) < 0x10000 PTR_ADDIU t0, $28, _THREAD_SIZE - 32 +#else + PTR_LI t0, _THREAD_SIZE - 32 + PTR_ADDU t0, $28 +#endif set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */ diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 25ed3337ce3..79f0317d84a 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -50,6 +50,16 @@ SECTIONS /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + /* + * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which + * limits the maximum alignment to at most 32kB and results in the following + * warning: + * + * CC arch/mips/kernel/init_task.o + * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’ + * is greater than maximum object file alignment. Using 32768 + */ + . = ALIGN(_PAGE_SIZE); *(.data.init_task) *(.data) diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c index be8261be679..594df1a05ec 100644 --- a/arch/mips/lib-64/dump_tlb.c +++ b/arch/mips/lib-64/dump_tlb.c @@ -149,7 +149,7 @@ void dump_list_process(struct task_struct *t, void *address) printk("Addr == %08lx\n", addr); printk("tasks->mm.pgd == %08lx\n", (unsigned long) t->mm->pgd); - page_dir = pgd_offset(t->mm, 0); + page_dir = pgd_offset(t->mm, 0UL); printk("page_dir == %016lx\n", (unsigned long) page_dir); pgd = pgd_offset(t->mm, addr); @@ -184,13 +184,13 @@ void dump_list_current(void *address) dump_list_process(current, address); } -unsigned int vtop(void *address) +unsigned long vtop(void *address) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; - unsigned int addr, paddr; + unsigned long addr, paddr; addr = (unsigned long) address; pgd = pgd_offset(current->mm, addr); diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index be80c5dd4a0..eeed944e0f8 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c @@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memory(void) if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; - addr = boot_mem_map.map[i].addr; + addr = PAGE_ALIGN(boot_mem_map.map[i].addr); while (addr < boot_mem_map.map[i].addr + boot_mem_map.map[i].size) { ClearPageReserved(virt_to_page(__va(addr))); diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c index b7c749232ff..d41fc5885e8 100644 --- a/arch/mips/mm/pg-r4k.c +++ b/arch/mips/mm/pg-r4k.c @@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsigned long offset) emit_instruction(mi); } +static inline void build_addiu_a2(unsigned long offset) +{ + union mips_instruction mi; + + BUG_ON(offset > 0x7fff); + + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; + mi.i_format.rs = 6; /* $a2 */ + mi.i_format.rt = 6; /* $a2 */ + mi.i_format.simmediate = offset; + + emit_instruction(mi); +} + static inline void build_addiu_a1(unsigned long offset) { union mips_instruction mi; @@ -333,6 +347,7 @@ static inline void build_jr_ra(void) void __init build_clear_page(void) { unsigned int loop_start; + unsigned long off; epc = (unsigned int *) &clear_page_array; instruction_pending = 0; @@ -369,7 +384,12 @@ void __init build_clear_page(void) } } - build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0)); + off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear : 0); + if (off > 0x7fff) { + build_addiu_a2_a0(off >> 1); + build_addiu_a2(off >> 1); + } else + build_addiu_a2_a0(off); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ @@ -420,12 +440,18 @@ dest = label(); void __init build_copy_page(void) { unsigned int loop_start; + unsigned long off; epc = (unsigned int *) ©_page_array; store_offset = load_offset = 0; instruction_pending = 0; - build_addiu_a2_a0(PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0)); + off = PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy : 0); + if (off > 0x7fff) { + build_addiu_a2_a0(off >> 1); + build_addiu_a2(off >> 1); + } else + build_addiu_a2_a0(off); if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) build_insn_word(0x3c01a000); /* lui $at, 0xa000 */ diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 6f8b25cfa6f..fec318a1c8c 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -102,7 +102,7 @@ enum opcode { insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, - insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, + insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, @@ -145,6 +145,7 @@ static __initdata struct insn insn_table[] = { { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, + { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE }, { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, { insn_j, M(j_op,0,0,0,0,0), JIMM }, @@ -385,6 +386,7 @@ I_u2u1u3(_dsll); I_u2u1u3(_dsll32); I_u2u1u3(_dsra); I_u2u1u3(_dsrl); +I_u2u1u3(_dsrl32); I_u3u1u2(_dsubu); I_0(_eret); I_u1(_j); @@ -996,7 +998,12 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, #endif l_vmalloc_done(l, *p); - i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); /* get pgd offset in bytes */ + + if (PGDIR_SHIFT - 3 < 32) /* get pgd offset in bytes */ + i_dsrl(p, tmp, tmp, PGDIR_SHIFT-3); + else + i_dsrl32(p, tmp, tmp, PGDIR_SHIFT - 3 - 32); + i_andi(p, tmp, tmp, (PTRS_PER_PGD - 1)<<3); i_daddu(p, ptr, ptr, tmp); /* add in pgd offset */ i_dmfc0(p, tmp, C0_BADVADDR); /* get faulting address */ @@ -1073,7 +1080,7 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) static __init void build_adjust_context(u32 **p, unsigned int ctx) { - unsigned int shift = 4 - (PTE_T_LOG2 + 1); + unsigned int shift = 4 - (PTE_T_LOG2 + 1) + PAGE_SHIFT - 12; unsigned int mask = (PTRS_PER_PTE / 2 - 1) << (PTE_T_LOG2 + 1); switch (current_cpu_data.cputype) { -- cgit v1.2.3 From cb56837ea5f15fa5279fd490f292134c3a92e5de Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 22:49:04 +0000 Subject: [MIPS] SMTC: Fix crash if # of TC's > # of VPE's after pt_regs irq cleanup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/entry.S | 3 +++ arch/mips/kernel/smtc-asm.S | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 417c08ac76e..f10b6a19f8b 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -83,7 +83,10 @@ FEXPORT(syscall_exit) FEXPORT(restore_all) # restore full frame #ifdef CONFIG_MIPS_MT_SMTC /* Detect and execute deferred IPI "interrupts" */ + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) jal deferred_smtc_ipi + LONG_S s0, TI_REGS($28) /* Re-arm any temporarily masked interrupts not explicitly "acked" */ mfc0 v0, CP0_TCSTATUS ori v1, v0, TCSTATUS_IXMT diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 1cb9441f147..921207c4a83 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/arch/mips/kernel/smtc-asm.S @@ -101,7 +101,9 @@ FEXPORT(__smtc_ipi_vector) lw t0,PT_PADSLOT5(sp) /* Argument from sender passed in stack pad slot 4 */ lw a0,PT_PADSLOT4(sp) - PTR_LA ra, _ret_from_irq + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) + PTR_LA ra, ret_from_irq jr t0 /* @@ -119,7 +121,10 @@ LEAF(self_ipi) subu t1,sp,PT_SIZE sw ra,PT_EPC(t1) sw a0,PT_PADSLOT4(t1) + LONG_L s0, TI_REGS($28) + LONG_S sp, TI_REGS($28) la t2,ipi_decode + LONG_S s0, TI_REGS($28) sw t2,PT_PADSLOT5(t1) /* Save pre-disable value of TCStatus */ sw t0,PT_TCSTATUS(t1) -- cgit v1.2.3 From 64c590b7a62ae1272fe4afd7b915de314591f35e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 1 Nov 2006 00:22:00 +0000 Subject: [MIPS] SMTC: Synchronize cp0 counters on bootup. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index cc1f7474f7d..3b78caf112f 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -476,6 +476,7 @@ void mipsmt_prepare_cpus(void) write_vpe_c0_compare(0); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); + write_vpe_c0_count(read_c0_count()); } /* enable multi-threading within VPE */ write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); -- cgit v1.2.3 From 67cac1eba7eee92e2b25c1e8e4737968dc7c8522 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 1 Nov 2006 18:55:22 +0900 Subject: [MIPS] Fix warning in mips-boards generic PCI arch/mips/mips-boards/generic/pci.c: In function `mips_pcibios_init': arch/mips/mips-boards/generic/pci.c:227: warning: comparison of distinct pointer types lacks a cast arch/mips/mips-boards/generic/pci.c:228: warning: comparison of distinct pointer types lacks a cast Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/generic/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/generic/pci.c b/arch/mips/mips-boards/generic/pci.c index 9337f6c8873..3192a14698c 100644 --- a/arch/mips/mips-boards/generic/pci.c +++ b/arch/mips/mips-boards/generic/pci.c @@ -90,7 +90,7 @@ static struct pci_controller msc_controller = { void __init mips_pcibios_init(void) { struct pci_controller *controller; - unsigned long start, end, map, start1, end1, map1, map2, map3, mask; + resource_size_t start, end, map, start1, end1, map1, map2, map3, mask; switch (mips_revision_corid) { case MIPS_REVISION_CORID_QED_RM5261: -- cgit v1.2.3 From f9dadfa71bc594df09044da61d1c72701121d802 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 1 Nov 2006 10:05:35 -0800 Subject: i386: write IO APIC irq routing entries in correct order Since the "mask" bit is in the low word, when we write a new entry, we need to write the high word first, before we potentially unmask it. The exception is when we actually want to mask the interrupt, in which case we want to write the low word first to make sure that the high word doesn't change while the interrupt routing is still active. Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index eb10bd5da64..507983c513c 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -147,11 +147,33 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) return eu.entry; } +/* + * When we write a new IO APIC routing entry, we need to write the high + * word first! If the mask bit in the low word is clear, we will enable + * the interrupt, and we need to make sure the entry is fully populated + * before that happens. + */ static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { unsigned long flags; union entry_union eu; eu.entry = e; + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2*pin, eu.w2); + io_apic_write(apic, 0x10 + 2*pin, eu.w1); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +/* + * When we mask an IO APIC routing entry, we need to write the low + * word first, in order to set the mask bit before we change the + * high bits! + */ +static void ioapic_mask_entry(int apic, int pin) +{ + unsigned long flags; + union entry_union eu = { .entry.mask = 1 }; + spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x10 + 2*pin, eu.w1); io_apic_write(apic, 0x11 + 2*pin, eu.w2); @@ -274,9 +296,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) /* * Disable it in the IO-APIC irq-routing table: */ - memset(&entry, 0, sizeof(entry)); - entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + ioapic_mask_entry(apic, pin); } static void clear_IO_APIC (void) -- cgit v1.2.3 From 3ccfc65c5004e5fe5cfbffe43b8acc686680b53e Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 2 Nov 2006 09:44:37 +1100 Subject: [PATCH] powerpc: Eliminate "exceeds stub group size" linker warning It turns out that the linker warnings on 64-bit powerpc about "section blah exceeds stub group size" were being triggered by conditional branches in head_64.S branching to global symbols, whether in head_64.S or in other files. This eliminates the warnings by making some global symbols in head_64.S no longer global, and by rearranging some branches. Signed-off-by: Paul Mackerras [ Yee-haa. Maybe I'll notice newly introduced real warnings now - Linus ] Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/head_64.S | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 291e3629b50..e720729f3e5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -487,7 +487,7 @@ BEGIN_FTR_SECTION rlwimi r13,r12,16,0x20 mfcr r12 cmpwi r13,0x2c - beq .do_stab_bolted_pSeries + beq do_stab_bolted_pSeries mtcrf 0x80,r12 mfspr r12,SPRN_SPRG2 END_FTR_SECTION_IFCLR(CPU_FTR_SLB) @@ -600,7 +600,7 @@ system_call_pSeries: STD_EXCEPTION_PSERIES(., performance_monitor) .align 7 -_GLOBAL(do_stab_bolted_pSeries) +do_stab_bolted_pSeries: mtcrf 0x80,r12 mfspr r12,SPRN_SPRG2 EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted) @@ -1046,7 +1046,7 @@ slb_miss_fault: li r5,0 std r4,_DAR(r1) std r5,_DSISR(r1) - b .handle_page_fault + b handle_page_fault unrecov_user_slb: EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN) @@ -1174,12 +1174,13 @@ program_check_common: .globl fp_unavailable_common fp_unavailable_common: EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) - bne .load_up_fpu /* if from user, just load it up */ + bne 1f /* if from user, just load it up */ bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD ENABLE_INTS bl .kernel_fp_unavailable_exception BUG_OPCODE +1: b .load_up_fpu .align 7 .globl altivec_unavailable_common @@ -1279,10 +1280,10 @@ _GLOBAL(do_hash_page) std r4,_DSISR(r1) andis. r0,r4,0xa450 /* weird error? */ - bne- .handle_page_fault /* if not, try to insert a HPTE */ + bne- handle_page_fault /* if not, try to insert a HPTE */ BEGIN_FTR_SECTION andis. r0,r4,0x0020 /* Is it a segment table fault? */ - bne- .do_ste_alloc /* If so handle it */ + bne- do_ste_alloc /* If so handle it */ END_FTR_SECTION_IFCLR(CPU_FTR_SLB) /* @@ -1324,7 +1325,7 @@ BEGIN_FW_FTR_SECTION * because ret_from_except_lite will check for and handle pending * interrupts if necessary. */ - beq .ret_from_except_lite + beq 13f /* For a hash failure, we don't bother re-enabling interrupts */ ble- 12f @@ -1346,14 +1347,14 @@ BEGIN_FW_FTR_SECTION END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES) /* Here we have a page fault that hash_page can't handle. */ -_GLOBAL(handle_page_fault) +handle_page_fault: ENABLE_INTS 11: ld r4,_DAR(r1) ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl .do_page_fault cmpdi r3,0 - beq+ .ret_from_except_lite + beq+ 13f bl .save_nvgprs mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD @@ -1370,12 +1371,14 @@ _GLOBAL(handle_page_fault) bl .low_hash_fault b .ret_from_except +13: b .ret_from_except_lite + /* here we have a segment miss */ -_GLOBAL(do_ste_alloc) +do_ste_alloc: bl .ste_allocate /* try to insert stab entry */ cmpdi r3,0 - beq+ fast_exception_return - b .handle_page_fault + bne- handle_page_fault + b fast_exception_return /* * r13 points to the PACA, r9 contains the saved CR, -- cgit v1.2.3 From 8427829711b35e0e62668618cec577f65c102935 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 2 Nov 2006 02:00:02 +0000 Subject: Revert "[MIPS] Make SPARSEMEM selectable on QEMU." This reverts commit 31473747bd441719f9f6a07385684dce547533e0. Another amazing example of patch(1) messing up - lmo changeset 66e8560d11d02bcadc261498471831a6375ad046 was merged twice to kernel.org and ended up doing this rubbish job. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 74ba7637811..76f1cea6ddc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -427,7 +427,6 @@ config MOMENCO_OCELOT_G select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN - select ARCH_SPARSEMEM_ENABLE help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -1631,9 +1630,6 @@ config ARCH_DISCONTIGMEM_ENABLE or have huge holes in the physical address space for other reasons. See for more. -config ARCH_SPARSEMEM_ENABLE - bool - config ARCH_SPARSEMEM_ENABLE bool select SPARSEMEM_STATIC -- cgit v1.2.3 From 8a88ca8f7fd15d06e53a848c6b3558ed9973327c Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 2 Nov 2006 17:23:33 +0000 Subject: [MIPS] Fix merge screwup by patch(1) Patch happily applied an Ocelot G patch to Ocelot C when merging linux-mips.org changeset 91ee9a801e65d2981dfe327d2519c7fc6ab02e6b into kernel.org as 6ceb6d3ab2d402cea326320a4143db90a66fd216. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 76f1cea6ddc..848089ecb64 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -408,7 +408,7 @@ config MOMENCO_OCELOT_C select SWAP_IO_SPACE select SYS_HAS_CPU_RM7000 select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if BROKEN + select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN help The Ocelot is a MIPS-based Single Board Computer (SBC) made by @@ -425,7 +425,7 @@ config MOMENCO_OCELOT_G select SWAP_IO_SPACE select SYS_HAS_CPU_RM7000 select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_BIG_ENDIAN help The Ocelot is a MIPS-based Single Board Computer (SBC) made by -- cgit v1.2.3 From 1a5c5de1b64ec510a6ab6994702c295db00b9acc Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 2 Nov 2006 17:23:33 +0000 Subject: [MIPS] IP27: Allow SMP ;-) Another changeset messed up by patch. When lmo commit 4ef893e0515e8bf336dfbd200884f244869fbb43 was merged to kernel.org as e73ea273ef87a04ff59fc368fa33333dca275dde patch happily applied the IP27 segment to IP22. f63f36c18b11e166d0f362ac04dbcd7e6ea23f9e did fix the effects partially - and with a wrong log message. Now fixed for real (tm). Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 848089ecb64..1443024b1c7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -559,6 +559,7 @@ config SGI_IP27 select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA + select SYS_SUPPORTS_SMP help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y -- cgit v1.2.3 From 9ba126cfbf505f4d5b39ed294cedd241321c7a91 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 13 Oct 2006 11:22:52 +0100 Subject: [MIPS] Fix warning about init_initrd() call if !CONFIG_BLK_DEV_INITRD. Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index fdbb508661c..8f6e89697cc 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -223,7 +223,11 @@ disable: #else /* !CONFIG_BLK_DEV_INITRD */ -#define init_initrd() 0 +static unsigned long __init init_initrd(void) +{ + return 0; +} + #define finalize_initrd() do {} while (0) #endif -- cgit v1.2.3 From 8b922a851731037b2f1e1669e9b1a0baff3ab5dc Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 30 Oct 2006 12:48:04 +0000 Subject: [MIPS] Ocelot G: Fix : "CURRENTLY_UNUSED" is not defined warning. CC arch/mips/momentum/ocelot_g/gt-irq.o arch/mips/momentum/ocelot_g/gt-irq.c:30:5: warning: "CURRENTLY_UNUSED" is not defined arch/mips/momentum/ocelot_g/gt-irq.c:199:5: warning: "CURRENTLY_UNUSED" is not defined Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_g/gt-irq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_g/gt-irq.c b/arch/mips/momentum/ocelot_g/gt-irq.c index 7b5cc6648f7..e5576bd50fa 100644 --- a/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/arch/mips/momentum/ocelot_g/gt-irq.c @@ -27,7 +27,7 @@ unsigned long bus_clock; * be handled and ack'ed differently than other MIPS interrupts. */ -#if CURRENTLY_UNUSED +#if 0 struct tq_struct irq_handlers[MAX_CAUSE_REGS][MAX_CAUSE_REG_WIDTH]; void hook_irq_handler(int int_cause, int bit_num, void *isr_ptr); @@ -95,7 +95,7 @@ int disable_galileo_irq(int int_cause, int bit_num) return 0; return 1; } -#endif /* UNUSED */ +#endif /* 0 */ /* * Interrupt handler for interrupts coming from the Galileo chip via P0_INT#. @@ -196,7 +196,7 @@ void gt64240_time_init(void) void gt64240_irq_init(void) { -#if CURRENTLY_UNUSED +#if 0 int i, j; /* Reset irq handlers pointers to NULL */ @@ -208,5 +208,5 @@ void gt64240_irq_init(void) irq_handlers[i][j].data = NULL; } } -#endif +#endif /* 0 */ } -- cgit v1.2.3 From 236d333c3c05c179e31f461285c09271256a1381 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 10 Oct 2006 22:13:55 +0900 Subject: [MIPS] Do not use -msym32 option for modules. On 64-bit kernel, modules are loaded into XKSEG for now. While XKSEG address is not a sign-extended 32-bit address, we can not use -msym32 option. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 641aa30b363..d580d46f967 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -63,7 +63,9 @@ cflags-y += -mabi=64 ifdef CONFIG_BUILD_ELF64 cflags-y += $(call cc-option,-mno-explicit-relocs) else -cflags-y += $(call cc-option,-msym32) +# -msym32 can not be used for modules since they are loaded into XKSEG +CFLAGS_MODULE += $(call cc-option,-mno-explicit-relocs) +CFLAGS_KERNEL += $(call cc-option,-msym32) endif endif -- cgit v1.2.3 From 73218187e8650c08d4e4735dbeeeb860f438da7c Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Thu, 2 Nov 2006 23:44:24 +0100 Subject: [ARM] 3917/1: Fix dmabounce symbol exports dma_sync_single is no more (and to be removed in 2.7) so this export should be dma_sync_single_for_cpu. Also export dma_sync_single_for_device. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/common/dmabounce.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 028bdc9228f..2e635b814c1 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c @@ -662,7 +662,8 @@ EXPORT_SYMBOL(dma_map_single); EXPORT_SYMBOL(dma_unmap_single); EXPORT_SYMBOL(dma_map_sg); EXPORT_SYMBOL(dma_unmap_sg); -EXPORT_SYMBOL(dma_sync_single); +EXPORT_SYMBOL(dma_sync_single_for_cpu); +EXPORT_SYMBOL(dma_sync_single_for_device); EXPORT_SYMBOL(dma_sync_sg); EXPORT_SYMBOL(dmabounce_register_dev); EXPORT_SYMBOL(dmabounce_unregister_dev); -- cgit v1.2.3 From 94c52fde553260e86f263448034930abe364faec Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 30 Oct 2006 02:27:45 +0100 Subject: [ARM] 3915/1: S3C2412: Add s3c2410_gpio_getirq() to general gpio.c s3c2410_gpio_getirq() holds for the S3C2412 build, so ensure that it gets built for all the current S3C24XX architectures Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/gpio.c | 21 ++++++++++++++++++++- arch/arm/mach-s3c2410/s3c2410-gpio.c | 19 ------------------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c index db6393c9986..ba346546150 100644 --- a/arch/arm/mach-s3c2410/gpio.c +++ b/arch/arm/mach-s3c2410/gpio.c @@ -3,7 +3,7 @@ * Copyright (c) 2004-2005 Simtec Electronics * Ben Dooks * - * S3C2410 GPIO support + * S3C24XX GPIO support * * 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 @@ -163,3 +163,22 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) } EXPORT_SYMBOL(s3c2410_modify_misccr); + +int s3c2410_gpio_getirq(unsigned int pin) +{ + if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15) + return -1; /* not valid interrupts */ + + if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) + return -1; /* not valid pin */ + + if (pin < S3C2410_GPF4) + return (pin - S3C2410_GPF0) + IRQ_EINT0; + + if (pin < S3C2410_GPG0) + return (pin - S3C2410_GPF4) + IRQ_EINT4; + + return (pin - S3C2410_GPG0) + IRQ_EINT8; +} + +EXPORT_SYMBOL(s3c2410_gpio_getirq); diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c index a2098f692d8..ec3a276cc3c 100644 --- a/arch/arm/mach-s3c2410/s3c2410-gpio.c +++ b/arch/arm/mach-s3c2410/s3c2410-gpio.c @@ -69,22 +69,3 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, } EXPORT_SYMBOL(s3c2410_gpio_irqfilter); - -int s3c2410_gpio_getirq(unsigned int pin) -{ - if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15) - return -1; /* not valid interrupts */ - - if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) - return -1; /* not valid pin */ - - if (pin < S3C2410_GPF4) - return (pin - S3C2410_GPF0) + IRQ_EINT0; - - if (pin < S3C2410_GPG0) - return (pin - S3C2410_GPF4) + IRQ_EINT4; - - return (pin - S3C2410_GPG0) + IRQ_EINT8; -} - -EXPORT_SYMBOL(s3c2410_gpio_getirq); -- cgit v1.2.3 From 8f7f9435e6df0985c877d10259393bdfaac3655f Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 Oct 2006 05:13:19 +0100 Subject: [ARM] 3912/1: Make PXA270 advertise HWCAP_IWMMXT capability ARM patch 3756/1 added HWCAP_IWMMXT. This patch adds support for broadcasting that info via /proc/cpuinfo and sets it for the CPU features of the PXA270. I've booted 19rc3 on a pxa270 and confirmed that the /proc/cpuinfo shows "iwmmxt" in the Features. Signed-off-by: Paul Gortmaker Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 4 ++++ arch/arm/mm/proc-xscale.S | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 6bbd93dd186..29efc9f8205 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -357,6 +357,9 @@ static void __init setup_processor(void) #ifndef CONFIG_VFP elf_hwcap &= ~HWCAP_VFP; #endif +#ifndef CONFIG_IWMMXT + elf_hwcap &= ~HWCAP_IWMMXT; +#endif cpu_proc_init(); } @@ -854,6 +857,7 @@ static const char *hwcap_str[] = { "vfp", "edsp", "java", + "iwmmxt", NULL }; diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index e8b377d637f..2749c1f88d7 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -909,7 +909,7 @@ __pxa270_proc_info: b __xscale_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_IWMMXT .long cpu_pxa270_name .long xscale_processor_functions .long v4wbi_tlb_fns -- cgit v1.2.3 From 6851ecc6e2fa4a01449a0fec9f4abd9aec43afde Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Nov 2006 23:02:24 -0800 Subject: PCI: Revert "PCI: i386/x86_84: disable PCI resource decode on device disable" This reverts commit 53e4d30dd666d7f83598957ee4a415eefb47c9a6. It was found that it caused unneeded problems (see http://bugzilla.kernel.org/show_bug.cgi?id=7082 for details of one such issue. Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 1 - arch/i386/pci/i386.c | 9 --------- arch/i386/pci/pci.h | 1 - 3 files changed, 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 6d5ace845e4..cdfcf971098 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -343,7 +343,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - pcibios_disable_resources(dev); if (pcibios_disable_irq) pcibios_disable_irq(dev); } diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 10154a2cac6..98580292f0d 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -242,15 +242,6 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) return 0; } -void pcibios_disable_resources(struct pci_dev *dev) -{ - u16 cmd; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY); - pci_write_config_word(dev, PCI_COMMAND, cmd); -} - /* * If we set up a device for bus mastering, we need to check the latency * timer as certain crappy BIOSes forget to set it properly. diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index ad065cebd7b..a0a25180b61 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -43,7 +43,6 @@ extern unsigned int pcibios_max_latency; void pcibios_resource_survey(void); int pcibios_enable_resources(struct pci_dev *, int); -void pcibios_disable_resources(struct pci_dev *); /* pci-pc.c */ -- cgit v1.2.3 From 984d115bbf2d731ed2264031fe49c1378d730db0 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Fri, 3 Nov 2006 01:47:20 +0100 Subject: [ARM] 3918/1: ixp4xx irq-chip rework This is a rework of the ixp4xx irq_chip implementation. The use of two irq_chip structures and potentially switching between them is a violation of the intended use of the IRQ framework. The current implementation does not work with current in-kernel spinlock debugging or lockdep due to lock recursion problems caused by calling set_irq_chip/handler from within the chip's set_irq_type(). This patch goes back to using one irq_chip structure and handling the differences between edge/level, normal/GPIO interrupts inside the ack/mask/unmask routines themselves. Signed-off-by: Kevin Hilman Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common.c | 60 ++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index c7513f6eb50..fbe288a8da6 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -86,7 +86,8 @@ enum ixp4xx_irq_type { IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE }; -static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); +/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */ +static unsigned long long ixp4xx_irq_edge = 0; /* * IRQ -> GPIO mapping table @@ -135,7 +136,11 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) default: return -EINVAL; } - ixp4xx_config_irq(irq, irq_type); + + if (irq_type == IXP4XX_IRQ_EDGE) + ixp4xx_irq_edge |= (1 << irq); + else + ixp4xx_irq_edge &= ~(1 << irq); if (line >= 8) { /* pins 8-15 */ line -= 8; @@ -167,14 +172,6 @@ static void ixp4xx_irq_mask(unsigned int irq) *IXP4XX_ICMR &= ~(1 << irq); } -static void ixp4xx_irq_unmask(unsigned int irq) -{ - if (cpu_is_ixp46x() && irq >= 32) - *IXP4XX_ICMR2 |= (1 << (irq - 32)); - else - *IXP4XX_ICMR |= (1 << irq); -} - static void ixp4xx_irq_ack(unsigned int irq) { int line = (irq < 32) ? irq2gpio[irq] : -1; @@ -187,41 +184,25 @@ static void ixp4xx_irq_ack(unsigned int irq) * Level triggered interrupts on GPIO lines can only be cleared when the * interrupt condition disappears. */ -static void ixp4xx_irq_level_unmask(unsigned int irq) +static void ixp4xx_irq_unmask(unsigned int irq) { - ixp4xx_irq_ack(irq); - ixp4xx_irq_unmask(irq); -} + if (!(ixp4xx_irq_edge & (1 << irq))) + ixp4xx_irq_ack(irq); -static struct irqchip ixp4xx_irq_level_chip = { - .ack = ixp4xx_irq_mask, - .mask = ixp4xx_irq_mask, - .unmask = ixp4xx_irq_level_unmask, - .set_type = ixp4xx_set_irq_type, -}; + if (cpu_is_ixp46x() && irq >= 32) + *IXP4XX_ICMR2 |= (1 << (irq - 32)); + else + *IXP4XX_ICMR |= (1 << irq); +} -static struct irqchip ixp4xx_irq_edge_chip = { +static struct irqchip ixp4xx_irq_chip = { + .name = "IXP4xx", .ack = ixp4xx_irq_ack, .mask = ixp4xx_irq_mask, .unmask = ixp4xx_irq_unmask, .set_type = ixp4xx_set_irq_type, }; -static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type) -{ - switch (type) { - case IXP4XX_IRQ_LEVEL: - set_irq_chip(irq, &ixp4xx_irq_level_chip); - set_irq_handler(irq, do_level_IRQ); - break; - case IXP4XX_IRQ_EDGE: - set_irq_chip(irq, &ixp4xx_irq_edge_chip); - set_irq_handler(irq, do_edge_IRQ); - break; - } - set_irq_flags(irq, IRQF_VALID); -} - void __init ixp4xx_init_irq(void) { int i = 0; @@ -241,8 +222,11 @@ void __init ixp4xx_init_irq(void) } /* Default to all level triggered */ - for(i = 0; i < NR_IRQS; i++) - ixp4xx_config_irq(i, IXP4XX_IRQ_LEVEL); + for(i = 0; i < NR_IRQS; i++) { + set_irq_chip(i, &ixp4xx_irq_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID); + } } -- cgit v1.2.3 From d91f75fb761e1e691796287889774cc8690034c1 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 3 Nov 2006 18:30:12 +0100 Subject: [ARM] 3920/1: S3C24XX: Remove smdk2410_defconfig Remove the smdk2410_defconifg as it is out of data and has not been touched since 2.6.11. Use the s3c2410_defconfig instead. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/smdk2410_defconfig | 735 ------------------------------------ 1 file changed, 735 deletions(-) delete mode 100644 arch/arm/configs/smdk2410_defconfig (limited to 'arch') diff --git a/arch/arm/configs/smdk2410_defconfig b/arch/arm/configs/smdk2410_defconfig deleted file mode 100644 index 4d123d33c7d..00000000000 --- a/arch/arm/configs/smdk2410_defconfig +++ /dev/null @@ -1,735 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 22:42:40 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -CONFIG_ARCH_S3C2410=y -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# S3C24XX Implementations -# -# CONFIG_ARCH_BAST is not set -# CONFIG_ARCH_H1940 is not set -# CONFIG_MACH_N30 is not set -CONFIG_ARCH_SMDK2410=y -# CONFIG_ARCH_S3C2440 is not set -# CONFIG_MACH_VR1000 is not set -# CONFIG_MACH_RX3715 is not set -# CONFIG_MACH_OTOM is not set -# CONFIG_MACH_NEXCODER_2440 is not set -CONFIG_CPU_S3C2410=y - -# -# S3C2410 Boot -# - -# -# S3C2410 Setup -# -# CONFIG_S3C2410_DMA is not set -CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=1f04 mem=32M" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_PARTITIONS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_SMC91X is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_S3C2410=y -CONFIG_SERIAL_S3C2410_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_S3C2410_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_VIRTUAL=y - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set -CONFIG_DEBUG_S3C2410_PORT=y -CONFIG_DEBUG_S3C2410_UART=0 - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -CONFIG_LIBCRC32C=y -- cgit v1.2.3 From 73d15da44f34626b4ad18eb4d56e1c2c4aaed578 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 3 Nov 2006 18:33:43 +0100 Subject: [ARM] 3921/1: S3C24XX: remove bast_defconfig Remove the bast_defconfig, as it has not been updated since 2.6.13. The s3c2410_defconfig should be a good replacement. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/bast_defconfig | 947 ---------------------------------------- 1 file changed, 947 deletions(-) delete mode 100644 arch/arm/configs/bast_defconfig (limited to 'arch') diff --git a/arch/arm/configs/bast_defconfig b/arch/arm/configs/bast_defconfig deleted file mode 100644 index 4a8564f386a..00000000000 --- a/arch/arm/configs/bast_defconfig +++ /dev/null @@ -1,947 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 02:24:16 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -CONFIG_ARCH_S3C2410=y -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# S3C24XX Implementations -# -CONFIG_ARCH_BAST=y -# CONFIG_ARCH_H1940 is not set -# CONFIG_MACH_N30 is not set -# CONFIG_ARCH_SMDK2410 is not set -# CONFIG_ARCH_S3C2440 is not set -CONFIG_MACH_VR1000=y -# CONFIG_MACH_RX3715 is not set -# CONFIG_MACH_OTOM is not set -# CONFIG_MACH_NEXCODER_2440 is not set -CONFIG_CPU_S3C2410=y - -# -# S3C2410 Boot -# -# CONFIG_S3C2410_BOOT_WATCHDOG is not set - -# -# S3C2410 Setup -# -CONFIG_S3C2410_DMA=y -# CONFIG_S3C2410_DMA_DEBUG is not set -# CONFIG_S3C2410_PM_DEBUG is not set -# CONFIG_S3C2410_PM_CHECK is not set -CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_ARM920T=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="root=/dev/hda1 ro init=/bin/bash console=ttySAC0" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -CONFIG_PM=y -CONFIG_APM=y - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -CONFIG_MTD_CMDLINE_PARTS=y -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -CONFIG_MTD_MAP_BANK_WIDTH_16=y -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -# CONFIG_MTD_CFI_AMDSTD is not set -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_XIP is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set -# CONFIG_MTD_IMPA7 is not set -CONFIG_MTD_BAST=y -CONFIG_MTD_BAST_MAXSIZE=4 - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -CONFIG_MTD_NAND=y -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_S3C2410=y -# CONFIG_MTD_NAND_S3C2410_DEBUG is not set -# CONFIG_MTD_NAND_S3C2410_HWECC is not set -# CONFIG_MTD_NAND_DISKONCHIP is not set -# CONFIG_MTD_NAND_NANDSIM is not set - -# -# Parallel port support -# -CONFIG_PARPORT=y -# CONFIG_PARPORT_PC is not set -# CONFIG_PARPORT_ARC is not set -# CONFIG_PARPORT_GSC is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECD=y -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=m -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDE_BAST=y -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_SMC91X is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_PARKBD is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_SERIAL_NONSTANDARD=y -# CONFIG_COMPUTONE is not set -# CONFIG_ROCKETPORT is not set -# CONFIG_CYCLADES is not set -# CONFIG_DIGIEPCA is not set -# CONFIG_MOXA_INTELLIO is not set -# CONFIG_MOXA_SMARTIO is not set -# CONFIG_ISI is not set -# CONFIG_SYNCLINKMP is not set -# CONFIG_N_HDLC is not set -# CONFIG_RISCOM8 is not set -# CONFIG_SPECIALIX is not set -# CONFIG_SX is not set -# CONFIG_RIO is not set -# CONFIG_STALDRV is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 -CONFIG_SERIAL_8250_EXTENDED=y -CONFIG_SERIAL_8250_MANY_PORTS=y -CONFIG_SERIAL_8250_SHARE_IRQ=y -# CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set -# CONFIG_SERIAL_8250_RSA is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_S3C2410=y -CONFIG_SERIAL_S3C2410_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 -CONFIG_PRINTER=y -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=y -# CONFIG_TIPAR is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set - -# -# Watchdog Device Drivers -# -# CONFIG_SOFT_WATCHDOG is not set -CONFIG_S3C2410_WATCHDOG=y -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -CONFIG_S3C2410_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ISA is not set -# CONFIG_I2C_PARPORT is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -CONFIG_I2C_S3C2410=y -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Hardware Sensors Chip support -# -CONFIG_I2C_SENSOR=m -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -CONFIG_SENSORS_LM75=m -# CONFIG_SENSORS_LM77 is not set -CONFIG_SENSORS_LM78=m -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -CONFIG_SENSORS_LM85=m -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set - -# -# Other I2C Chip support -# -CONFIG_SENSORS_EEPROM=m -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_SOFT_CURSOR is not set -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -CONFIG_JFFS_FS=y -CONFIG_JFFS_FS_VERBOSE=0 -# CONFIG_JFFS_PROC_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -# CONFIG_MINIX_SUBPARTITION is not set -CONFIG_SOLARIS_X86_PARTITION=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_LOG_BUF_SHIFT=16 -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_FS is not set -CONFIG_FRAME_POINTER=y -CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set -CONFIG_DEBUG_S3C2410_PORT=y -CONFIG_DEBUG_S3C2410_UART=0 - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -- cgit v1.2.3 From da86341856befac4e2f4b16965d6f78379dc960a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 3 Nov 2006 18:38:02 +0100 Subject: [ARM] 3922/1: S3C24XX: update s3c2410_defconfig to 2.6.19-rc4 Update the s3c2410_defconfig to 2.6.19-rc4 Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/s3c2410_defconfig | 49 ++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index a8322264104..c773380fed3 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,9 +1,10 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Wed Sep 20 20:27:31 2006 +# Linux kernel version: 2.6.19-rc4 +# Fri Nov 3 17:34:07 2006 # CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set CONFIG_MMU=y CONFIG_GENERIC_HARDIRQS=y CONFIG_TRACE_IRQFLAGS_SUPPORT=y @@ -29,17 +30,20 @@ CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -CONFIG_SYSCTL=y +# CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -70,6 +74,7 @@ CONFIG_KMOD=y # # Block layer # +CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set # @@ -120,6 +125,7 @@ CONFIG_ARCH_S3C2410=y # # S3C24XX Implementations # +# CONFIG_MACH_AML_M5900 is not set CONFIG_MACH_ANUBIS=y CONFIG_MACH_OSIRIS=y CONFIG_ARCH_BAST=y @@ -178,6 +184,8 @@ CONFIG_CPU_CACHE_V4WT=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_COPY_V4WB=y CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y # # Processor Features @@ -251,6 +259,7 @@ CONFIG_BINFMT_AOUT=y CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_APM=y # @@ -266,6 +275,7 @@ CONFIG_NET=y CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -286,10 +296,12 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -377,6 +389,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_NFTL is not set # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set # # RAM/ROM/Flash chip drivers @@ -512,6 +525,7 @@ CONFIG_BLK_DEV_IDE_BAST=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set # # Multi-device support (RAID and LVM) @@ -606,6 +620,7 @@ CONFIG_DM9000=y # Input device support # CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set # # Userland interfaces @@ -628,6 +643,7 @@ CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_XTKBD is not set # CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_STOWAWAY is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y # CONFIG_MOUSE_SERIAL is not set @@ -734,7 +750,6 @@ CONFIG_S3C2410_WATCHDOG=y # CONFIG_USBPCWATCHDOG is not set CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set -CONFIG_S3C2410_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -747,7 +762,6 @@ CONFIG_S3C2410_RTC=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -798,6 +812,7 @@ CONFIG_SENSORS_EEPROM=m # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -834,6 +849,7 @@ CONFIG_SENSORS_LM85=m # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set @@ -845,6 +861,7 @@ CONFIG_SENSORS_LM85=m # # Misc devices # +# CONFIG_TIFM_CORE is not set # # LED devices @@ -863,7 +880,6 @@ CONFIG_SENSORS_LM85=m # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -876,6 +892,7 @@ CONFIG_VIDEO_V4L2=y # CONFIG_FIRMWARE_EDID=y CONFIG_FB=y +# CONFIG_FB_DDC is not set CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y @@ -951,7 +968,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # # may also be needed; see USB_STORAGE Help for more information # -# CONFIG_USB_STORAGE is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1007,6 +1023,7 @@ CONFIG_USB_MON=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1014,11 +1031,12 @@ CONFIG_USB_MON=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1051,6 +1069,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1058,6 +1077,7 @@ CONFIG_FS_MBCACHE=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y @@ -1089,6 +1109,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # Pseudo filesystems # CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set @@ -1219,6 +1240,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # Kernel hacking # # CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y @@ -1238,9 +1260,10 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y # CONFIG_DEBUG_WAITQ is not set @@ -1261,10 +1284,6 @@ CONFIG_DEBUG_S3C2410_UART=0 # # CONFIG_CRYPTO is not set -# -# Hardware crypto devices -# - # # Library routines # -- cgit v1.2.3 From 3f84ada6c173d856b5e06b239931866ed7dd7a16 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 3 Nov 2006 18:47:10 +0100 Subject: [ARM] 3923/1: S3C24XX: update s3c2410_defconfig with new drivers Add the new drivers, such as SPI, LED and RTC core, to the s3c2410_defconfig. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/s3c2410_defconfig | 65 ++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index c773380fed3..0563c14395e 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.19-rc4 -# Fri Nov 3 17:34:07 2006 +# Fri Nov 3 17:41:31 2006 # CONFIG_ARM=y # CONFIG_GENERIC_TIME is not set @@ -66,7 +66,8 @@ CONFIG_BASE_SMALL=0 # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -431,6 +432,8 @@ CONFIG_MTD_BAST_MAXSIZE=4 # # Self-contained MTD device drivers # +# CONFIG_MTD_DATAFLASH is not set +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -806,8 +809,21 @@ CONFIG_SENSORS_EEPROM=m # # SPI support # -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_BITBANG=m +# CONFIG_SPI_BUTTERFLY is not set +CONFIG_SPI_S3C24XX_GPIO=m +CONFIG_SPI_S3C24XX=m + +# +# SPI Protocol Masters +# # # Dallas's 1-wire bus @@ -835,6 +851,7 @@ CONFIG_HWMON_VID=m # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM70 is not set CONFIG_SENSORS_LM75=m # CONFIG_SENSORS_LM77 is not set CONFIG_SENSORS_LM78=m @@ -866,15 +883,21 @@ CONFIG_SENSORS_LM85=m # # LED devices # -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m # # LED drivers # +CONFIG_LEDS_S3C24XX=m # # LED Triggers # +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +# CONFIG_LEDS_TRIGGER_IDE_DISK is not set +CONFIG_LEDS_TRIGGER_HEARTBEAT=m # # Multimedia devices @@ -1057,7 +1080,37 @@ CONFIG_USB_MON=y # Real Time Clock # CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +CONFIG_RTC_DRV_S3C=y +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_V3020 is not set # # File systems -- cgit v1.2.3 From 90d53909443b3986569b38ef145f09ea2359af75 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 2 Nov 2006 22:07:18 -0800 Subject: [PATCH] acpi_noirq section fix WARNING: vmlinux - Section mismatch: reference to .init.data:acpi_noirq from .text between 'pcibios_penalize_isa_irq' (at offset 0xc026ffa1) and 'pirq_serverworks_get' Acked-by: "Brown, Len" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index ab974ff9707..22e4c466e5a 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -70,7 +70,7 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return #define PREFIX "ACPI: " -int acpi_noirq __initdata; /* skip ACPI IRQ initialization */ +int acpi_noirq; /* skip ACPI IRQ initialization */ int acpi_pci_disabled __initdata; /* skip ACPI PCI scan and IRQ initialization */ int acpi_ht __initdata = 1; /* enable HT */ -- cgit v1.2.3 From 53b173327d283b9bdbfb0c3b6de6f0eb197819d6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 2 Nov 2006 22:07:22 -0800 Subject: [PATCH] uml: fix I/O hang Fix a UML hang in which everything would just stop until some I/O happened - a ping, someone whacking the keyboard - at which point everything would start up again as though nothing had happened. The cause was gcc reordering some code which absolutely needed to be executed in the order in the source. When unblock_signals switches signals from off to on, it needs to see if any interrupts had happened in the critical section. The interrupt handlers check signals_enabled - if it is zero, then the handler adds a bit to the "pending" bitmask and returns. unblock_signals checks this mask to see if any signals need to be delivered. The crucial part is this: signals_enabled = 1; save_pending = pending; if(save_pending == 0) return; pending = 0; In order to avoid an interrupt arriving between reading pending and setting it to zero, in which case, the record of the interrupt would be erased, signals are enabled. What happened was that gcc reordered this so that 'save_pending = pending' came before 'signals_enabled = 1', creating a one-instruction window within which an interrupt could arrive, set its bit in pending, and have it be immediately erased. When the I/O workload is purely disk-based, the loss of a block device interrupt stops the entire I/O system because the next block request will wait for the current one to finish. Thus the system hangs until something else causes some I/O to arrive, such as a network packet or console input. The fix to this particular problem is a memory barrier between enabling signals and reading the pending signal mask. An xchg would also probably work. Looking over this code for similar problems led me to do a few more things: - make signals_enabled and pending volatile so that they don't get cached in registers - add an mb() to the return paths of block_signals and unblock_signals so that the modification of signals_enabled doesn't get shuffled into the caller in the event that these are inlined in the future. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/barrier.h | 9 +++++++++ arch/um/include/sysdep-x86_64/barrier.h | 7 +++++++ arch/um/os-Linux/signal.c | 31 ++++++++++++++++++++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 arch/um/include/sysdep-i386/barrier.h create mode 100644 arch/um/include/sysdep-x86_64/barrier.h (limited to 'arch') diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h new file mode 100644 index 00000000000..b58d52c5b2f --- /dev/null +++ b/arch/um/include/sysdep-i386/barrier.h @@ -0,0 +1,9 @@ +#ifndef __SYSDEP_I386_BARRIER_H +#define __SYSDEP_I386_BARRIER_H + +/* Copied from include/asm-i386 for use by userspace. i386 has the option + * of using mfence, but I'm just using this, which works everywhere, for now. + */ +#define mb() asm volatile("lock; addl $0,0(%esp)") + +#endif diff --git a/arch/um/include/sysdep-x86_64/barrier.h b/arch/um/include/sysdep-x86_64/barrier.h new file mode 100644 index 00000000000..7b610befdc8 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/barrier.h @@ -0,0 +1,7 @@ +#ifndef __SYSDEP_X86_64_BARRIER_H +#define __SYSDEP_X86_64_BARRIER_H + +/* Copied from include/asm-x86_64 for use by userspace. */ +#define mb() asm volatile("mfence":::"memory") + +#endif diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6b81739279d..b897e8592d7 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -15,6 +15,7 @@ #include "user.h" #include "signal_kern.h" #include "sysdep/sigcontext.h" +#include "sysdep/barrier.h" #include "sigcontext.h" #include "mode.h" #include "os.h" @@ -34,8 +35,12 @@ #define SIGALRM_BIT 2 #define SIGALRM_MASK (1 << SIGALRM_BIT) -static int signals_enabled = 1; -static int pending = 0; +/* These are used by both the signal handlers and + * block/unblock_signals. I don't want modifications cached in a + * register - they must go straight to memory. + */ +static volatile int signals_enabled = 1; +static volatile int pending = 0; void sig_handler(int sig, struct sigcontext *sc) { @@ -152,6 +157,12 @@ int change_sig(int signal, int on) void block_signals(void) { signals_enabled = 0; + /* This must return with signals disabled, so this barrier + * ensures that writes are flushed out before the return. + * This might matter if gcc figures out how to inline this and + * decides to shuffle this code into the caller. + */ + mb(); } void unblock_signals(void) @@ -171,9 +182,23 @@ void unblock_signals(void) */ signals_enabled = 1; + /* Setting signals_enabled and reading pending must + * happen in this order. + */ + mb(); + save_pending = pending; - if(save_pending == 0) + if(save_pending == 0){ + /* This must return with signals enabled, so + * this barrier ensures that writes are + * flushed out before the return. This might + * matter if gcc figures out how to inline + * this (unlikely, given its size) and decides + * to shuffle this code into the caller. + */ + mb(); return; + } pending = 0; -- cgit v1.2.3 From 1f6f61649d8c64d7a3a4d143405df9a7bdd4af10 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Thu, 2 Nov 2006 22:07:23 -0800 Subject: [PATCH] uml: include tidying In order to get the __NR_* constants, we need sys/syscall.h. linux/unistd.h works as well since it includes syscall.h, however syscall.h is more parsimonious. We were inconsistent in this, and this patch adds syscall.h includes where necessary and removes linux/unistd.h includes where they are not needed. asm/unistd.h also includes the __NR_* constants, but these are not the glibc-sanctioned ones, so this also removes one such inclusion. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/process.c | 1 - arch/um/os-Linux/skas/process.c | 2 +- arch/um/os-Linux/tls.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 51f0893640a..c692a192957 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index cb9ab54146c..9b34fe65949 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include "user.h" #include "sysdep/ptrace.h" diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c index 9f7999f27c7..16215b99080 100644 --- a/arch/um/os-Linux/tls.c +++ b/arch/um/os-Linux/tls.c @@ -1,7 +1,7 @@ #include +#include #include #include -#include #include #include "sysdep/tls.h" #include "uml-config.h" -- cgit v1.2.3 From 59359ff87700f5e742c96a55da9cf0819984c128 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 5 Nov 2006 16:51:03 -0800 Subject: [SPARC]: Fix robust futex syscalls and wire up migrate_pages. When I added the entries for the robust futex syscall entries, I forgot to bump NR_SYSCALLS. The current situation is error-prone because NR_SYSCALLS lives in entry.S where the system call limit checks are enforced. Move the definition to asm/unistd.h in order to make this mistake much more difficult to make. And wire up sys_migrate_pages since the powerpc folks implemented the compat wrapper for us. Signed-off-by: David S. Miller --- arch/sparc/kernel/entry.S | 3 +-- arch/sparc/kernel/systbls.S | 5 +++-- arch/sparc64/kernel/entry.S | 3 +-- arch/sparc64/kernel/systbls.S | 8 +++++--- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index a4edff4c3be..831f540251f 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -32,13 +32,12 @@ #include #include #include +#include #include #define curptr g6 -#define NR_SYSCALLS 300 /* Each OS is different... */ - /* These are just handy. */ #define _SV save %sp, -STACKFRAME_SZ, %sp #define _RS restore diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 10df38eeae0..ea75ca56905 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -78,7 +78,7 @@ sys_call_table: /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .long sys_set_robust_list, sys_get_robust_list +/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -190,6 +190,7 @@ sunos_sys_table: /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys, sunos_nosys, sunos_nosys - .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys +/*300*/ .long sunos_nosys, sunos_nosys, sunos_nosys #endif diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 0aaa35fc5a9..6f28bec0a9b 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -22,11 +22,10 @@ #include #include #include +#include #define curptr g6 -#define NR_SYSCALLS 300 /* Each OS is different... */ - .text .align 32 diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 419a63fca17..9a8026797ac 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -79,7 +79,7 @@ sys_call_table32: .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare -/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list +/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages #endif /* CONFIG_COMPAT */ @@ -149,7 +149,7 @@ sys_call_table: .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .word sys_set_robust_list, sys_get_robust_list +/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -262,5 +262,7 @@ sunos_sys_table: /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys +/*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys + #endif -- cgit v1.2.3 From e9a43850e6a99e335c8120579749389b376bc204 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 30 Oct 2006 09:31:27 +0100 Subject: AVR32: Get rid of board_early_init board_early_init() is left over from some early prototyping work where we had to initialize the SDRAM controller ourselves. This depends on the kernel being loaded into static RAM, which just isn't possible on any commercially available products today. In order to run without a boot loader, we need to create a zImage stub or have the debugger initialize the SDRAM for us (for really low-level debugging) Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/atstk1000/setup.c | 9 --------- arch/avr32/kernel/head.S | 3 --- 2 files changed, 12 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boards/atstk1000/setup.c b/arch/avr32/boards/atstk1000/setup.c index 191ab85de9a..272c011802a 100644 --- a/arch/avr32/boards/atstk1000/setup.c +++ b/arch/avr32/boards/atstk1000/setup.c @@ -21,15 +21,6 @@ struct tag *bootloader_tags __initdata; struct lcdc_platform_data __initdata atstk1000_fb0_data; -asmlinkage void __init board_early_init(void) -{ - extern void sdram_init(void); - -#ifdef CONFIG_LOADER_STANDALONE - sdram_init(); -#endif -} - void __init board_setup_fbmem(unsigned long fbmem_start, unsigned long fbmem_size) { diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S index 773b7ad87be..6163bd0acb9 100644 --- a/arch/avr32/kernel/head.S +++ b/arch/avr32/kernel/head.S @@ -30,9 +30,6 @@ kernel_entry: mov r7, 0 #endif - /* Set up the PIO, SDRAM controller, early printk, etc. */ - rcall board_early_init - /* Start the show */ lddpc pc, kernel_start_addr -- cgit v1.2.3 From 168c8fa32ff40d6caf7226a5abf2a0096f3393bf Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Tue, 31 Oct 2006 20:01:11 +0100 Subject: AVR32: Fix thinko in generic_find_next_zero_le_bit() The existing implementation of this function seems to be looking for a one although it should be looking for a zero. This causes trouble for the ext2 filesystem, which tends to report -ENOSPC without this patch. Fix this by complementing each word before scanning. Signed-off-by: Haavard Skinnemoen --- arch/avr32/lib/findbit.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/avr32/lib/findbit.S b/arch/avr32/lib/findbit.S index 2b4856f4bf7..c6b91dee857 100644 --- a/arch/avr32/lib/findbit.S +++ b/arch/avr32/lib/findbit.S @@ -136,6 +136,7 @@ ENTRY(generic_find_next_zero_le_bit) /* offset is not word-aligned. Handle the first (32 - r10) bits */ ldswp.w r8, r12[0] sub r12, -4 + com r8 lsr r8, r8, r10 brne .L_found @@ -146,7 +147,7 @@ ENTRY(generic_find_next_zero_le_bit) /* Main loop. offset must be word-aligned */ 1: ldswp.w r8, r12[0] - cp.w r8, 0 + com r8 brne .L_found sub r12, -4 sub r9, 32 -- cgit v1.2.3 From bcc8bcb1f0cc51c0042497d5de2d79743050e3bb Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 6 Nov 2006 10:49:00 +0100 Subject: [S390] revert add_active_range() usage patch. Commit 7676bef9c183fd573822cac9992927ef596d584c breaks DCSS support on s390. DCSS needs initialized struct pages to work. With the usage of add_active_range() only the struct pages for physically present pages are initialized. This could be fixed if the DCSS driver would initiliaze the struct pages itself, but this doesn't work too. This is because the mem_map array does not include holes after the last present memory area and therefore there is nothing that could be initialized. To fix this and to avoid some dirty hacks revert this patch for now. Will be added later when we move to a virtual mem_map. Cc: Carsten Otte Cc: Adrian Bunk Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 --- arch/s390/defconfig | 1 - arch/s390/kernel/setup.c | 53 +++++++++++++++++++++++++++++++++++++----------- arch/s390/mm/init.c | 32 ++++++++++++++++++++--------- 4 files changed, 63 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 608193cfe43..245b81bc715 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -236,9 +236,6 @@ config WARN_STACK_SIZE This allows you to specify the maximum frame size a function may have without the compiler complaining about it. -config ARCH_POPULATES_NODE_MAP - def_bool y - source "mm/Kconfig" comment "I/O subsystem configuration" diff --git a/arch/s390/defconfig b/arch/s390/defconfig index c313e9a9304..7cd51e73e27 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -119,7 +119,6 @@ CONFIG_PACK_STACK=y CONFIG_CHECK_STACK=y CONFIG_STACK_GUARD=256 # CONFIG_WARN_STACK is not set -CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 49f2b68e32b..a31abddf115 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -70,6 +70,7 @@ struct { #define CHUNK_READ_WRITE 0 #define CHUNK_READ_ONLY 1 volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ +unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; /* @@ -357,6 +358,21 @@ void machine_power_off(void) */ void (*pm_power_off)(void) = machine_power_off; +static void __init +add_memory_hole(unsigned long start, unsigned long end) +{ + unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; + + if (end <= dma_pfn) + zholes_size[ZONE_DMA] += end - start + 1; + else if (start > dma_pfn) + zholes_size[ZONE_NORMAL] += end - start + 1; + else { + zholes_size[ZONE_DMA] += dma_pfn - start + 1; + zholes_size[ZONE_NORMAL] += end - dma_pfn; + } +} + static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); @@ -478,6 +494,7 @@ setup_memory(void) { unsigned long bootmap_size; unsigned long start_pfn, end_pfn, init_pfn; + unsigned long last_rw_end; int i; /* @@ -533,27 +550,39 @@ setup_memory(void) /* * Register RAM areas with the bootmem allocator. */ + last_rw_end = start_pfn; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - unsigned long start_chunk, end_chunk, pfn; + unsigned long start_chunk, end_chunk; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; - start_chunk = PFN_DOWN(memory_chunk[i].addr); - end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; - end_chunk = min(end_chunk, end_pfn); - if (start_chunk >= end_chunk) - continue; - add_active_range(0, start_chunk, end_chunk); - pfn = max(start_chunk, start_pfn); - for (; pfn <= end_chunk; pfn++) - page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); + start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); + start_chunk >>= PAGE_SHIFT; + end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); + end_chunk >>= PAGE_SHIFT; + if (start_chunk < start_pfn) + start_chunk = start_pfn; + if (end_chunk > end_pfn) + end_chunk = end_pfn; + if (start_chunk < end_chunk) { + /* Initialize storage key for RAM pages */ + for (init_pfn = start_chunk ; init_pfn < end_chunk; + init_pfn++) + page_set_storage_key(init_pfn << PAGE_SHIFT, + PAGE_DEFAULT_KEY); + free_bootmem(start_chunk << PAGE_SHIFT, + (end_chunk - start_chunk) << PAGE_SHIFT); + if (last_rw_end < start_chunk) + add_memory_hole(last_rw_end, start_chunk - 1); + last_rw_end = end_chunk; + } } psw_set_key(PAGE_DEFAULT_KEY); - free_bootmem_with_active_regions(0, max_pfn); - reserve_bootmem(0, PFN_PHYS(start_pfn)); + if (last_rw_end < end_pfn - 1) + add_memory_hole(last_rw_end, end_pfn - 1); /* * Reserve the bootmem bitmap itself as well. We do this in two diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index d9989171870..e1881c31b1c 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -84,6 +84,7 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +extern unsigned long __initdata zholes_size[]; /* * paging_init() sets up the page tables */ @@ -100,15 +101,16 @@ void __init paging_init(void) unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; static const int ssm_mask = 0x04000000L; unsigned long ro_start_pfn, ro_end_pfn; - unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long zones_size[MAX_NR_ZONES]; ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = max_low_pfn; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + memset(zones_size, 0, sizeof(zones_size)); + zones_size[ZONE_DMA] = max_low_pfn; + free_area_init_node(0, &contig_page_data, zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, + zholes_size); /* unmap whole virtual address space */ @@ -168,16 +170,26 @@ void __init paging_init(void) unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; static const int ssm_mask = 0x04000000L; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long dma_pfn, high_pfn; unsigned long ro_start_pfn, ro_end_pfn; - unsigned long max_zone_pfns[MAX_NR_ZONES]; + memset(zones_size, 0, sizeof(zones_size)); + dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; + high_pfn = max_low_pfn; ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); - memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); - max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(max_zone_pfns); + if (dma_pfn > high_pfn) + zones_size[ZONE_DMA] = high_pfn; + else { + zones_size[ZONE_DMA] = dma_pfn; + zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; + } + + /* Initialize mem_map[]. */ + free_area_init_node(0, &contig_page_data, zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); /* * map whole physical memory to virtual memory (identity mapping) -- cgit v1.2.3 From c4972f33169e3e1ce06ad00917ddaf2c3b49b36a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 6 Nov 2006 10:49:02 +0100 Subject: [S390] IRQs too early enabled. setup_lowcore() calls ctl_set_bit() which returns withs interrupts enabled. The setup arch code is not supposed to enable interrupts that early. Therefore use the __ctl_set_bit() variant. This fixes the not working lock dependency validator on non 64 bit systems. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index a31abddf115..2aa13e8e000 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -450,7 +450,7 @@ setup_lowcore(void) lc->extended_save_area_addr = (__u32) __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0); /* enable extended save area */ - ctl_set_bit(14, 29); + __ctl_set_bit(14, 29); } #endif set_prefix((u32)(unsigned long) lc); -- cgit v1.2.3 From bbfd2bf9028a55cb85ff51eb34dc663b7e49ed55 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 6 Nov 2006 14:02:44 +0100 Subject: AVR32: Wire up sys_epoll_pwait Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/syscall-stubs.S | 9 +++++++++ arch/avr32/kernel/syscall_table.S | 1 + 2 files changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S index 7589a9b426c..890286a1e62 100644 --- a/arch/avr32/kernel/syscall-stubs.S +++ b/arch/avr32/kernel/syscall-stubs.S @@ -100,3 +100,12 @@ __sys_splice: rcall sys_splice sub sp, -4 popm pc + + .global __sys_epoll_pwait + .type __sys_epoll_pwait,@function +__sys_epoll_pwait: + pushm lr + st.w --sp, ARG6 + rcall sys_epoll_pwait + sub sp, -4 + popm pc diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index 63b206965d0..db8f8b55ffd 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S @@ -286,4 +286,5 @@ sys_call_table: .long sys_sync_file_range .long sys_tee .long sys_vmsplice + .long __sys_epoll_pwait /* 265 */ .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ -- cgit v1.2.3 From 6af0f5f83169ef215b4579834ddfb2691e8a7bff Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 6 Nov 2006 14:06:45 +0100 Subject: AVR32: Add missing return instruction in __raw_writesb __raw_writesb ends with a conditional branch, which is obviously wrong. It should return after the last loop terminates. Signed-off-by: Haavard Skinnemoen --- arch/avr32/lib/io-readsb.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/avr32/lib/io-readsb.S b/arch/avr32/lib/io-readsb.S index b319d5e7174..2be5da7ed26 100644 --- a/arch/avr32/lib/io-readsb.S +++ b/arch/avr32/lib/io-readsb.S @@ -45,3 +45,5 @@ __raw_readsb: sub r10, 1 st.b r11++, r8 brne 3b + + retal r12 -- cgit v1.2.3 From cca72333e71e348995859b88628c1abcb58b759e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Nov 2006 17:42:47 +0000 Subject: [MIPS] Ocelot C: Fix large number of warnings. Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_c/ocelot_c_fpga.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h index 7228cd19e5e..f0f5581dcb5 100644 --- a/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h +++ b/arch/mips/momentum/ocelot_c/ocelot_c_fpga.h @@ -53,7 +53,9 @@ #define OCELOT_C_REG_INTSET 0xe #define OCELOT_C_REG_INTCLR 0xf -#define OCELOT_FPGA_WRITE(x, y) writeb(x, OCELOT_C_CS0_ADDR + OCELOT_C_REG_##y) -#define OCELOT_FPGA_READ(x) readb(OCELOT_C_CS0_ADDR + OCELOT_C_REG_##x) +#define __FPGA_REG_TO_ADDR(reg) \ + ((void *) OCELOT_C_CS0_ADDR + OCELOT_C_REG_##reg) +#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) +#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) #endif -- cgit v1.2.3 From 9c422e2ad6a1d8bd03e2e9d49e5c63b82165d596 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Nov 2006 17:45:25 +0000 Subject: [MIPS] Ocelot C: fix eth registration after conversion to platform_device Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_c/setup.c | 124 +++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 9c0c462af65..0a3ffa33771 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -69,7 +70,6 @@ #include "ocelot_c_fpga.h" unsigned long marvell_base; -extern unsigned long mv64340_sram_base; unsigned long cpu_clock; /* These functions are used for rebooting or halting the machine*/ @@ -119,7 +119,6 @@ void PMON_v2_setup(void) add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfffffffffe000000, PM_16M); marvell_base = 0xfffffffff4000000; - mv64340_sram_base = 0xfffffffffe000000; #else /* marvell and extra space */ add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000), 0xf4000000, PM_64K); @@ -129,7 +128,6 @@ void PMON_v2_setup(void) add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); marvell_base = 0xf4000000; - mv64340_sram_base = 0xfe000000; #endif } @@ -365,3 +363,123 @@ static int io_base_ioremap(void) module_init(io_base_ioremap); #endif + +#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +#define MV_SRAM_BASE 0xfe000000UL +#define MV_SRAM_SIZE (256 * 1024) + +#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) +#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) + +#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE +#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) + +#define MV64x60_IRQ_ETH_0 48 +#define MV64x60_IRQ_ETH_1 49 + +#ifdef CONFIG_MV643XX_ETH_0 + +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth0_pd = { + .tx_sram_addr = MV_SRAM_BASE_ETH0, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_0 */ + +#ifdef CONFIG_MV643XX_ETH_1 + +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct mv643xx_eth_platform_data eth1_pd = { + .tx_sram_addr = MV_SRAM_BASE_ETH1, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_1 */ + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif + /* The third port is not wired up on the Ocelot C */ +}; + +int mv643xx_eth_add_pds(void) +{ + int ret; + + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); + +#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ -- cgit v1.2.3 From 2002d2bde1a9ad10e2521b8b117c11abfbc2ee93 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Nov 2006 17:48:17 +0000 Subject: [MIPS] Ocelot C: Fix warning about missmatching format string. CC arch/mips/momentum/ocelot_c/setup.o arch/mips/momentum/ocelot_c/setup.c: In function 'momenco_time_init': arch/mips/momentum/ocelot_c/setup.c:223: warning: format '%d' expects type 'int', but argument 2 has type 'long unsigned int' Change data type to match format string; a 32-bit type better suits our needs. Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_c/prom.c | 2 +- arch/mips/momentum/ocelot_c/setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 4c50a147f42..1f67728d6a4 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -29,7 +29,7 @@ struct callvectors* debug_vectors; extern unsigned long marvell_base; -extern unsigned long cpu_clock; +extern unsigned int cpu_clock; #ifdef CONFIG_MV643XX_ETH extern unsigned char prom_mac_addr_base[6]; diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 0a3ffa33771..7832d4e04c3 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -70,7 +70,7 @@ #include "ocelot_c_fpga.h" unsigned long marvell_base; -unsigned long cpu_clock; +unsigned int cpu_clock; /* These functions are used for rebooting or halting the machine*/ extern void momenco_ocelot_restart(char *command); -- cgit v1.2.3 From ad0b365573718a4a83266f98c9a49305c8eaf0b8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 3 Nov 2006 18:06:33 +0000 Subject: [MIPS] Ocelot C: Fix mapping of ioport address range. o Fix warnings o 768MB worth of I/O ports were insane o 64-bit kernels don't need special handling because ioremap does the magic Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_c/setup.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 7832d4e04c3..b0e82a097f7 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -344,25 +344,23 @@ void __init plat_mem_setup(void) } } -#ifndef CONFIG_64BIT -/* This needs to be one of the first initcalls, because no I/O port access - can work before this */ +/* + * This needs to be one of the first initcalls, because no I/O port access + * can work before this + */ static int io_base_ioremap(void) { - /* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */ - void *io_remap_range = ioremap(0xc0000000, 0x30000000); + void __iomem * io_remap_range = ioremap(0xc0000000UL, 0x10000); - if (!io_remap_range) { + if (!io_remap_range) panic("Could not ioremap I/O port range"); - } - printk("io_remap_range set at 0x%08x\n", (uint32_t)io_remap_range); - set_io_port_base(io_remap_range - 0xc0000000); + + set_io_port_base((unsigned long) io_remap_range); return 0; } module_init(io_base_ioremap); -#endif #if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) -- cgit v1.2.3 From d19f7befe929d400df89699eb51b8d7f4ef1b2d8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 4 Nov 2006 13:02:46 +0000 Subject: [MIPS] Ocelot 3: Fix large number of warnings. Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_3/ocelot_3_fpga.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h index 227e429fe72..5710a9029f1 100644 --- a/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h +++ b/arch/mips/momentum/ocelot_3/ocelot_3_fpga.h @@ -51,7 +51,9 @@ extern unsigned long ocelot_fpga_base; -#define OCELOT_FPGA_WRITE(x, y) writeb(x, ocelot_fpga_base + OCELOT_3_REG_##y) -#define OCELOT_FPGA_READ(x) readb(ocelot_fpga_base + OCELOT_3_REG_##x) +#define __FPGA_REG_TO_ADDR(reg) \ + ((void *) ocelot_fpga_base + OCELOT_3_REG_##reg) +#define OCELOT_FPGA_WRITE(x, reg) writeb(x, __FPGA_REG_TO_ADDR(reg)) +#define OCELOT_FPGA_READ(reg) readb(__FPGA_REG_TO_ADDR(reg)) #endif -- cgit v1.2.3 From d6b861c6402307e30c7df24dcda911df64a5f9d6 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 4 Nov 2006 23:26:27 +0000 Subject: [MIPS] SB1: On bootup only flush cache on local CPU. This fixes a warning on bootup warning in smp_call_function. Signed-off-by: Ralf Baechle --- arch/mips/mm/c-sb1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index ea49a775bf2..d0ddb4a768a 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -505,5 +505,5 @@ void sb1_cache_init(void) : : "memory"); - flush_cache_all(); + local_sb1___flush_cache_all(); } -- cgit v1.2.3 From 907c51b2d1705b022c3fb65b66cb4e5e09346433 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 5 Nov 2006 01:18:11 +0000 Subject: [MIPS] Ocelot C: Fix MAC address detection after platform_device conversion. Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_c/Makefile | 2 +- arch/mips/momentum/ocelot_c/platform.c | 201 +++++++++++++++++++++++++++++++++ arch/mips/momentum/ocelot_c/prom.c | 58 ---------- arch/mips/momentum/ocelot_c/setup.c | 121 -------------------- 4 files changed, 202 insertions(+), 180 deletions(-) create mode 100644 arch/mips/momentum/ocelot_c/platform.c (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 94802b4db47..d69161aa167 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile @@ -2,7 +2,7 @@ # Makefile for Momentum Computer's Ocelot-C and -CS boards. # -obj-y += cpci-irq.o irq.o prom.o reset.o \ +obj-y += cpci-irq.o irq.o platform.o prom.o reset.o \ setup.o uart-irq.o obj-$(CONFIG_KGDB) += dbg_io.o diff --git a/arch/mips/momentum/ocelot_c/platform.c b/arch/mips/momentum/ocelot_c/platform.c new file mode 100644 index 00000000000..6c495b2f156 --- /dev/null +++ b/arch/mips/momentum/ocelot_c/platform.c @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#include + +#include "ocelot_c_fpga.h" + +#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +#define MV_SRAM_BASE 0xfe000000UL +#define MV_SRAM_SIZE (256 * 1024) + +#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) +#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) + +#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE +#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) + +#define MV64x60_IRQ_ETH_0 48 +#define MV64x60_IRQ_ETH_1 49 + +#ifdef CONFIG_MV643XX_ETH_0 + +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth0_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth0_pd = { + .mac_addr = eth0_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH0, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_0 */ + +#ifdef CONFIG_MV643XX_ETH_1 + +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth1_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth1_pd = { + .mac_addr = eth1_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH1, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_1 */ + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif + /* The third port is not wired up on the Ocelot C */ +}; + +static u8 __init exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + udelay(1); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + udelay(1); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; +} + +static void __init get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} + +/* + * Copy and increment ethernet MAC address by a small value. + * + * This is useful for systems where the only one MAC address is stored in + * non-volatile memory for multiple ports. + */ +static inline void eth_mac_add(unsigned char *dst, unsigned char *src, + unsigned int add) +{ + int i; + + BUG_ON(add >= 256); + + for (i = ETH_ALEN; i >= 0; i--) { + dst[i] = src[i] + add; + add = dst[i] < src[i]; /* compute carry */ + } + + WARN_ON(add); +} + +static int __init mv643xx_eth_add_pds(void) +{ + unsigned char mac[ETH_ALEN]; + int ret; + + get_mac(mac); +#ifdef CONFIG_MV643XX_ETH_0 + eth_mac_add(eth1_mac_addr, mac, 0); +#endif +#ifdef CONFIG_MV643XX_ETH_1 + eth_mac_add(eth1_mac_addr, mac, 1); +#endif + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); + +#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff --git a/arch/mips/momentum/ocelot_c/prom.c b/arch/mips/momentum/ocelot_c/prom.c index 1f67728d6a4..d0b77e101d7 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -31,10 +31,6 @@ struct callvectors* debug_vectors; extern unsigned long marvell_base; extern unsigned int cpu_clock; -#ifdef CONFIG_MV643XX_ETH -extern unsigned char prom_mac_addr_base[6]; -#endif - const char *get_system_type(void) { #ifdef CONFIG_CPU_SR71000 @@ -44,55 +40,6 @@ const char *get_system_type(void) #endif } -#ifdef CONFIG_MV643XX_ETH -static void burn_clocks(void) -{ - int i; - - /* this loop should burn at least 1us -- this should be plenty */ - for (i = 0; i < 0x10000; i++) - ; -} - -static u8 exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - burn_clocks(); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - burn_clocks(); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); -} - -void get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} -#endif - - #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -226,11 +173,6 @@ void __init prom_init(void) mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_C; -#ifdef CONFIG_MV643XX_ETH - /* get the base MAC address for on-board ethernet ports */ - get_mac(prom_mac_addr_base); -#endif - #ifndef CONFIG_64BIT debug_vectors->printf("Booting Linux kernel...\n"); #endif diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index b0e82a097f7..0b6b2338cfb 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -361,123 +360,3 @@ static int io_base_ioremap(void) } module_init(io_base_ioremap); - -#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) - -static struct resource mv643xx_eth_shared_resources[] = { - [0] = { - .name = "ethernet shared base", - .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, - .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + - MV643XX_ETH_SHARED_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, -}; - -static struct platform_device mv643xx_eth_shared_device = { - .name = MV643XX_ETH_SHARED_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), - .resource = mv643xx_eth_shared_resources, -}; - -#define MV_SRAM_BASE 0xfe000000UL -#define MV_SRAM_SIZE (256 * 1024) - -#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) -#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) - -#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE -#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) - -#define MV64x60_IRQ_ETH_0 48 -#define MV64x60_IRQ_ETH_1 49 - -#ifdef CONFIG_MV643XX_ETH_0 - -static struct resource mv64x60_eth0_resources[] = { - [0] = { - .name = "eth0 irq", - .start = MV64x60_IRQ_ETH_0, - .end = MV64x60_IRQ_ETH_0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth0_pd = { - .tx_sram_addr = MV_SRAM_BASE_ETH0, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth0_device = { - .name = MV643XX_ETH_NAME, - .id = 0, - .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), - .resource = mv64x60_eth0_resources, - .dev = { - .platform_data = ð0_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_0 */ - -#ifdef CONFIG_MV643XX_ETH_1 - -static struct resource mv64x60_eth1_resources[] = { - [0] = { - .name = "eth1 irq", - .start = MV64x60_IRQ_ETH_1, - .end = MV64x60_IRQ_ETH_1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct mv643xx_eth_platform_data eth1_pd = { - .tx_sram_addr = MV_SRAM_BASE_ETH1, - .tx_sram_size = MV_SRAM_TXRING_SIZE, - .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, - - .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, - .rx_sram_size = MV_SRAM_RXRING_SIZE, - .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, -}; - -static struct platform_device eth1_device = { - .name = MV643XX_ETH_NAME, - .id = 1, - .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), - .resource = mv64x60_eth1_resources, - .dev = { - .platform_data = ð1_pd, - }, -}; -#endif /* CONFIG_MV643XX_ETH_1 */ - -static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { - &mv643xx_eth_shared_device, -#ifdef CONFIG_MV643XX_ETH_0 - ð0_device, -#endif -#ifdef CONFIG_MV643XX_ETH_1 - ð1_device, -#endif - /* The third port is not wired up on the Ocelot C */ -}; - -int mv643xx_eth_add_pds(void) -{ - int ret; - - ret = platform_add_devices(mv643xx_eth_pd_devs, - ARRAY_SIZE(mv643xx_eth_pd_devs)); - - return ret; -} - -device_initcall(mv643xx_eth_add_pds); - -#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ -- cgit v1.2.3 From ff28cbd2804105b144a7054e0302615e1da6749f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 5 Nov 2006 01:18:43 +0000 Subject: [MIPS] Ocelot 3: Fix MAC address detection after platform_device conversion. Signed-off-by: Ralf Baechle --- arch/mips/momentum/ocelot_3/Makefile | 2 +- arch/mips/momentum/ocelot_3/platform.c | 235 +++++++++++++++++++++++++++++++++ arch/mips/momentum/ocelot_3/prom.c | 58 -------- arch/mips/momentum/ocelot_3/setup.c | 2 +- 4 files changed, 237 insertions(+), 60 deletions(-) create mode 100644 arch/mips/momentum/ocelot_3/platform.c (limited to 'arch') diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile index 8bcea64dd27..d5a090a85a1 100644 --- a/arch/mips/momentum/ocelot_3/Makefile +++ b/arch/mips/momentum/ocelot_3/Makefile @@ -5,4 +5,4 @@ # removes any old dependencies. DON'T put your own dependencies here # unless it's something special (ie not a .c file). # -obj-y += irq.o prom.o reset.o setup.o +obj-y += irq.o platform.o prom.o reset.o setup.o diff --git a/arch/mips/momentum/ocelot_3/platform.c b/arch/mips/momentum/ocelot_3/platform.c new file mode 100644 index 00000000000..eefe5841fbb --- /dev/null +++ b/arch/mips/momentum/ocelot_3/platform.c @@ -0,0 +1,235 @@ +#include +#include +#include +#include +#include + +#include "ocelot_3_fpga.h" + +#if defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) + +static struct resource mv643xx_eth_shared_resources[] = { + [0] = { + .name = "ethernet shared base", + .start = 0xf1000000 + MV643XX_ETH_SHARED_REGS, + .end = 0xf1000000 + MV643XX_ETH_SHARED_REGS + + MV643XX_ETH_SHARED_REGS_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device mv643xx_eth_shared_device = { + .name = MV643XX_ETH_SHARED_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv643xx_eth_shared_resources), + .resource = mv643xx_eth_shared_resources, +}; + +#define MV_SRAM_BASE 0xfe000000UL +#define MV_SRAM_SIZE (256 * 1024) + +#define MV_SRAM_RXRING_SIZE (MV_SRAM_SIZE / 4) +#define MV_SRAM_TXRING_SIZE (MV_SRAM_SIZE / 4) + +#define MV_SRAM_BASE_ETH0 MV_SRAM_BASE +#define MV_SRAM_BASE_ETH1 (MV_SRAM_BASE + (MV_SRAM_SIZE / 2)) + +#define MV64x60_IRQ_ETH_0 48 +#define MV64x60_IRQ_ETH_1 49 +#define MV64x60_IRQ_ETH_2 50 + +#ifdef CONFIG_MV643XX_ETH_0 + +static struct resource mv64x60_eth0_resources[] = { + [0] = { + .name = "eth0 irq", + .start = MV64x60_IRQ_ETH_0, + .end = MV64x60_IRQ_ETH_0, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth0_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth0_pd = { + .mac_addr = eth0_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH0, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH0 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth0_device = { + .name = MV643XX_ETH_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(mv64x60_eth0_resources), + .resource = mv64x60_eth0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_0 */ + +#ifdef CONFIG_MV643XX_ETH_1 + +static struct resource mv64x60_eth1_resources[] = { + [0] = { + .name = "eth1 irq", + .start = MV64x60_IRQ_ETH_1, + .end = MV64x60_IRQ_ETH_1, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth1_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth1_pd = { + .mac_addr = eth1_mac_addr, + + .tx_sram_addr = MV_SRAM_BASE_ETH1, + .tx_sram_size = MV_SRAM_TXRING_SIZE, + .tx_queue_size = MV_SRAM_TXRING_SIZE / 16, + + .rx_sram_addr = MV_SRAM_BASE_ETH1 + MV_SRAM_TXRING_SIZE, + .rx_sram_size = MV_SRAM_RXRING_SIZE, + .rx_queue_size = MV_SRAM_RXRING_SIZE / 16, +}; + +static struct platform_device eth1_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth1_resources), + .resource = mv64x60_eth1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_1 */ + +#ifdef CONFIG_MV643XX_ETH_2 + +static struct resource mv64x60_eth2_resources[] = { + [0] = { + .name = "eth2 irq", + .start = MV64x60_IRQ_ETH_2, + .end = MV64x60_IRQ_ETH_2, + .flags = IORESOURCE_IRQ, + }, +}; + +static char eth2_mac_addr[ETH_ALEN]; + +static struct mv643xx_eth_platform_data eth2_pd = { + .mac_addr = eth2_mac_addr, +}; + +static struct platform_device eth2_device = { + .name = MV643XX_ETH_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(mv64x60_eth2_resources), + .resource = mv64x60_eth2_resources, + .dev = { + .platform_data = ð2_pd, + }, +}; +#endif /* CONFIG_MV643XX_ETH_2 */ + +static struct platform_device *mv643xx_eth_pd_devs[] __initdata = { + &mv643xx_eth_shared_device, +#ifdef CONFIG_MV643XX_ETH_0 + ð0_device, +#endif +#ifdef CONFIG_MV643XX_ETH_1 + ð1_device, +#endif +#ifdef CONFIG_MV643XX_ETH_2 + ð2_device, +#endif +}; + +static u8 __init exchange_bit(u8 val, u8 cs) +{ + /* place the data */ + OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); + udelay(1); + + /* turn the clock on */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); + udelay(1); + + /* turn the clock off and read-strobe */ + OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); + + /* return the data */ + return (OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1; +} + +static void __init get_mac(char dest[6]) +{ + u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int i,j; + + for (i = 0; i < 12; i++) + exchange_bit(read_opcode[i], 1); + + for (j = 0; j < 6; j++) { + dest[j] = 0; + for (i = 0; i < 8; i++) { + dest[j] <<= 1; + dest[j] |= exchange_bit(0, 1); + } + } + + /* turn off CS */ + exchange_bit(0,0); +} + +/* + * Copy and increment ethernet MAC address by a small value. + * + * This is useful for systems where the only one MAC address is stored in + * non-volatile memory for multiple ports. + */ +static inline void eth_mac_add(unsigned char *dst, unsigned char *src, + unsigned int add) +{ + int i; + + BUG_ON(add >= 256); + + for (i = ETH_ALEN; i >= 0; i--) { + dst[i] = src[i] + add; + add = dst[i] < src[i]; /* compute carry */ + } + + WARN_ON(add); +} + +static int __init mv643xx_eth_add_pds(void) +{ + unsigned char mac[ETH_ALEN]; + int ret; + + get_mac(mac); +#ifdef CONFIG_MV643XX_ETH_0 + eth_mac_add(eth1_mac_addr, mac, 0); +#endif +#ifdef CONFIG_MV643XX_ETH_1 + eth_mac_add(eth1_mac_addr, mac, 1); +#endif +#ifdef CONFIG_MV643XX_ETH_2 + eth_mac_add(eth2_mac_addr, mac, 2); +#endif + ret = platform_add_devices(mv643xx_eth_pd_devs, + ARRAY_SIZE(mv643xx_eth_pd_devs)); + + return ret; +} + +device_initcall(mv643xx_eth_add_pds); + +#endif /* defined(CONFIG_MV643XX_ETH) || defined(CONFIG_MV643XX_ETH_MODULE) */ diff --git a/arch/mips/momentum/ocelot_3/prom.c b/arch/mips/momentum/ocelot_3/prom.c index 296d945bc24..6ce9b7fdb82 100644 --- a/arch/mips/momentum/ocelot_3/prom.c +++ b/arch/mips/momentum/ocelot_3/prom.c @@ -34,64 +34,11 @@ struct callvectors* debug_vectors; extern unsigned long marvell_base; extern unsigned long cpu_clock; -#ifdef CONFIG_MV643XX_ETH -extern unsigned char prom_mac_addr_base[6]; -#endif - const char *get_system_type(void) { return "Momentum Ocelot-3"; } -#ifdef CONFIG_MV643XX_ETH -void burn_clocks(void) -{ - int i; - - /* this loop should burn at least 1us -- this should be plenty */ - for (i = 0; i < 0x10000; i++) - ; -} - -u8 exchange_bit(u8 val, u8 cs) -{ - /* place the data */ - OCELOT_FPGA_WRITE((val << 2) | cs, EEPROM_MODE); - burn_clocks(); - - /* turn the clock on */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x2, EEPROM_MODE); - burn_clocks(); - - /* turn the clock off and read-strobe */ - OCELOT_FPGA_WRITE((val << 2) | cs | 0x10, EEPROM_MODE); - - /* return the data */ - return ((OCELOT_FPGA_READ(EEPROM_MODE) >> 3) & 0x1); -} - -void get_mac(char dest[6]) -{ - u8 read_opcode[12] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int i,j; - - for (i = 0; i < 12; i++) - exchange_bit(read_opcode[i], 1); - - for (j = 0; j < 6; j++) { - dest[j] = 0; - for (i = 0; i < 8; i++) { - dest[j] <<= 1; - dest[j] |= exchange_bit(0, 1); - } - } - - /* turn off CS */ - exchange_bit(0,0); -} -#endif - - #ifdef CONFIG_64BIT unsigned long signext(unsigned long addr) @@ -228,11 +175,6 @@ void __init prom_init(void) mips_machgroup = MACH_GROUP_MOMENCO; mips_machtype = MACH_MOMENCO_OCELOT_3; -#ifdef CONFIG_MV643XX_ETH - /* get the base MAC address for on-board ethernet ports */ - get_mac(prom_mac_addr_base); -#endif - #ifndef CONFIG_64BIT debug_vectors->printf("Booting Linux kernel...\n"); #endif diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index 7d74f8c5412..ff0829f8111 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c @@ -4,7 +4,7 @@ * BRIEF MODULE DESCRIPTION * Momentum Computer Ocelot-3 board dependent boot routines * - * Copyright (C) 1996, 1997, 01, 05 Ralf Baechle + * Copyright (C) 1996, 1997, 01, 05 - 06 Ralf Baechle * Copyright (C) 2000 RidgeRun, Inc. * Copyright (C) 2001 Red Hat, Inc. * Copyright (C) 2002 Momentum Computer -- cgit v1.2.3 From 325d08d1a44b601fbf70c259fb61c38d2af7d309 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 6 Nov 2006 13:32:39 +0000 Subject: [MIPS] EV64120: Fix timer initialization for HZ != 100. Signed-off-by: Ralf Baechle --- arch/mips/gt64120/common/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index c83ae6acd60..e6e48323e75 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c @@ -71,7 +71,7 @@ void gt64120_time_init(void) /* Disable timer first */ GT_WRITE(GT_TC_CONTROL_OFS, 0); /* Load timer value for 100 Hz */ - GT_WRITE(GT_TC3_OFS, Sys_clock / 100); + GT_WRITE(GT_TC3_OFS, Sys_clock / HZ); /* * Create the IRQ structure entry for the timer. Since we're too early -- cgit v1.2.3 From 4a4cf77923eeb3cec40a302656d6ab5ced04ba48 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 6 Nov 2006 17:41:06 +0000 Subject: [MIPS] Make irq number allocator generally available for fixing EV64120. Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq.c | 42 +++++++++++++++++++++++++++++++++++++++++ arch/mips/sgi-ip27/ip27-irq.c | 23 ---------------------- arch/mips/sgi-ip27/ip27-timer.c | 2 -- 3 files changed, 42 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index dd24434392b..9b0e49d63d7 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -26,6 +26,48 @@ #include #include +static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; + +int __devinit allocate_irqno(void) +{ + int irq; + +again: + irq = find_first_zero_bit(irq_map, NR_IRQS); + + if (irq >= NR_IRQS) + return -ENOSPC; + + if (test_and_set_bit(irq, irq_map)) + goto again; + + return irq; +} + +EXPORT_SYMBOL_GPL(allocate_irqno); + +/* + * Allocate the 16 legacy interrupts for i8259 devices. This happens early + * in the kernel initialization so treating allocation failure as BUG() is + * ok. + */ +void __init alloc_legacy_irqno(void) +{ + int i; + + for (i = 0; i <= 16; i++) + BUG_ON(test_and_set_bit(i, irq_map)); +} + +void __devinit free_irqno(unsigned int irq) +{ + smp_mb__before_clear_bit(); + clear_bit(irq, irq_map); + smp_mb__after_clear_bit(); +} + +EXPORT_SYMBOL_GPL(free_irqno); + /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index f01ba1f9077..270ecd3e6b4 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -354,29 +354,6 @@ static struct irq_chip bridge_irq_type = { .end = end_bridge_irq, }; -static unsigned long irq_map[NR_IRQS / BITS_PER_LONG]; - -int allocate_irqno(void) -{ - int irq; - -again: - irq = find_first_zero_bit(irq_map, NR_IRQS); - - if (irq >= NR_IRQS) - return -ENOSPC; - - if (test_and_set_bit(irq, irq_map)) - goto again; - - return irq; -} - -void free_irqno(unsigned int irq) -{ - clear_bit(irq, irq_map); -} - void __devinit register_bridge_irq(unsigned int irq) { irq_desc[irq].status = IRQ_DISABLED; diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index c965705f342..5e82a268e3c 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -214,8 +214,6 @@ static struct irqaction rt_irqaction = { .name = "timer" }; -extern int allocate_irqno(void); - void __init plat_timer_setup(struct irqaction *irq) { int irqno = allocate_irqno(); -- cgit v1.2.3 From 4e5852f31a22094a19bbc305e42651b6c92f3008 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 6 Nov 2006 18:05:08 +0000 Subject: [MIPS] EV64120: Fix PCI interrupt allocation. Signed-off-by: Ralf Baechle --- arch/mips/pci/Makefile | 2 +- arch/mips/pci/fixup-ev64120.c | 34 ---------------------------------- arch/mips/pci/pci-ev64120.c | 21 +++++++++++++++++++++ 3 files changed, 22 insertions(+), 35 deletions(-) delete mode 100644 arch/mips/pci/fixup-ev64120.c create mode 100644 arch/mips/pci/pci-ev64120.c (limited to 'arch') diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 3cf0dd4ba54..70cb55b89df 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -26,7 +26,7 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o -obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o +obj-$(CONFIG_MIPS_EV64120) += pci-ev64120.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o diff --git a/arch/mips/pci/fixup-ev64120.c b/arch/mips/pci/fixup-ev64120.c deleted file mode 100644 index 8dbb90d63f0..00000000000 --- a/arch/mips/pci/fixup-ev64120.c +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include - -int pci_range_ck(unsigned char bus, unsigned char dev) -{ - if (((bus == 0) || (bus == 1)) && (dev >= 6) && (dev <= 8)) - return 0; - - return -1; -} - -/* - * After detecting all agents over the PCI , this function is called - * in order to give an interrupt number for each PCI device starting - * from IRQ 20. It does also enables master for each device. - */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) -{ - unsigned int irq = 20; - struct pci_bus *current_bus = bus; - struct pci_dev *dev; - struct list_head *devices_link; - - list_for_each(devices_link, &(current_bus->devices)) { - dev = pci_dev_b(devices_link); - if (dev != NULL) { - dev->irq = irq++; - - /* Assign an interrupt number for the device */ - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); - pcibios_set_master(dev); - } - } -} diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c new file mode 100644 index 00000000000..9cd859ef184 --- /dev/null +++ b/arch/mips/pci/pci-ev64120.c @@ -0,0 +1,21 @@ +#include + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + if (!pin) + return 0; + + irq = allocate_irqno(); + if (irq < 0) + return 0; + + return irq; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} -- cgit v1.2.3 From 73f4388aedade209650ed629ab767d3e2b636f7b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 6 Nov 2006 18:17:35 +0000 Subject: [MIPS] Fix EV64120 and Ocelot builds by providing a plat_timer_setup(). Signed-off-by: Ralf Baechle --- arch/mips/gt64120/common/time.c | 2 +- arch/mips/gt64120/ev64120/setup.c | 2 -- arch/mips/gt64120/momenco_ocelot/setup.c | 3 --- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index e6e48323e75..c47eeb76819 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c @@ -64,7 +64,7 @@ static irqreturn_t gt64120_irq(int irq, void *dev_id) * as *irq (=irq0 in ../kernel/time.c). We will do our own timer interrupt * handling. */ -void gt64120_time_init(void) +void __init plat_timer_setup(struct irqaction *irq) { static struct irqaction timer; diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c index 91c2d3f4161..99c8d42212e 100644 --- a/arch/mips/gt64120/ev64120/setup.c +++ b/arch/mips/gt64120/ev64120/setup.c @@ -68,7 +68,6 @@ unsigned long __init prom_free_prom_memory(void) * Initializes basic routines and structures pointers, memory size (as * given by the bios and saves the command line. */ -extern void gt64120_time_init(void); void __init plat_mem_setup(void) { @@ -76,7 +75,6 @@ void __init plat_mem_setup(void) _machine_halt = galileo_machine_halt; pm_power_off = galileo_machine_power_off; - board_time_init = gt64120_time_init; set_io_port_base(KSEG1); } diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c index 0e5bbee2d5b..94f94ebbda6 100644 --- a/arch/mips/gt64120/momenco_ocelot/setup.c +++ b/arch/mips/gt64120/momenco_ocelot/setup.c @@ -70,7 +70,6 @@ extern void momenco_ocelot_restart(char *command); extern void momenco_ocelot_halt(void); extern void momenco_ocelot_power_off(void); -extern void gt64120_time_init(void); extern void momenco_ocelot_irq_setup(void); static char reset_reason; @@ -156,8 +155,6 @@ void __init plat_mem_setup(void) void (*l3func)(unsigned long)=KSEG1ADDR(&setup_l3cache); unsigned int tmpword; - board_time_init = gt64120_time_init; - _machine_restart = momenco_ocelot_restart; _machine_halt = momenco_ocelot_halt; pm_power_off = momenco_ocelot_power_off; -- cgit v1.2.3 From 6d15cb42fe4f8c07c80c9d49db721fcfe2da0e90 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 6 Nov 2006 19:29:16 +0100 Subject: [ARM] 3926/1: make timer led handle HZ != 100 The timer LED is unusable at HZ=large, since it's got a hard-wired value of 100 ticks per cycle; when HZ=1024 (for example) it's essentially always-on. This patch just makes that be HZ ticks per cycle. Signed-off-by: David Brownell Signed-off-by: Russell King --- arch/arm/kernel/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 0c5a6091a93..6ff5e3ff6cb 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -220,10 +220,10 @@ EXPORT_SYMBOL(leds_event); #ifdef CONFIG_LEDS_TIMER static inline void do_leds(void) { - static unsigned int count = 50; + static unsigned int count = HZ/2; if (--count == 0) { - count = 50; + count = HZ/2; leds_event(led_timer); } } -- cgit v1.2.3 From 5e7098275094ec405f2b19285ec0c38aead42d53 Mon Sep 17 00:00:00 2001 From: Ray Lehtiniemi Date: Tue, 7 Nov 2006 03:19:15 +0100 Subject: [ARM] 3927/1: Allow show_mem() to work with holes in memory map. show_mem() was not correctly handling holes in the memory map. It was treating the freed sections of the map as though they contained valid struct page entries. This could cause incorrect debugging output or even a kernel panic. This patch keeps the struct meminfo around after system initialization so that show_mem() can use it when scanning memory. show_mem() now walks over each bank of each online node, rather than assuming that each node contains a single contiguous bank. Signed-off-by: Ray Lehtiniemi Signed-off-by: Russell King --- arch/arm/mm/init.c | 61 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 27 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 22217fe2650..b5814b4b6f3 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -32,40 +32,51 @@ extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; /* - * The sole use of this is to pass memory configuration - * data from paging_init to mem_init. + * This is used to pass memory configuration data from paging_init + * to mem_init, and by show_mem() to skip holes in the memory map. */ -static struct meminfo meminfo __initdata = { 0, }; +static struct meminfo meminfo = { 0, }; + +#define for_each_nodebank(iter,mi,no) \ + for (iter = 0; iter < mi->nr_banks; iter++) \ + if (mi->bank[iter].node == no) void show_mem(void) { int free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0, slab = 0, node; + int shared = 0, cached = 0, slab = 0, node, i; + struct meminfo * mi = &meminfo; printk("Mem-info:\n"); show_free_areas(); printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_online_node(node) { - struct page *page, *end; - - page = NODE_MEM_MAP(node); - end = page + NODE_DATA(node)->node_spanned_pages; - - do { - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (PageSlab(page)) - slab++; - else if (!page_count(page)) - free++; - else - shared += page_count(page) - 1; - page++; - } while (page < end); + for_each_nodebank (i,mi,node) { + unsigned int pfn1, pfn2; + struct page *page, *end; + + pfn1 = mi->bank[i].start >> PAGE_SHIFT; + pfn2 = (mi->bank[i].size + mi->bank[i].start) >> PAGE_SHIFT; + + page = NODE_MEM_MAP(node) + pfn1; + end = NODE_MEM_MAP(node) + pfn2; + + do { + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (PageSlab(page)) + slab++; + else if (!page_count(page)) + free++; + else + shared += page_count(page) - 1; + page++; + } while (page < end); + } } printk("%d pages of RAM\n", total); @@ -76,10 +87,6 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } -#define for_each_nodebank(iter,mi,no) \ - for (iter = 0; iter < mi->nr_banks; iter++) \ - if (mi->bank[iter].node == no) - /* * FIXME: We really want to avoid allocating the bootmap bitmap * over the top of the initrd. Hopefully, this is located towards -- cgit v1.2.3 From 16b7f4dcd340875625714438a812ea06400f9666 Mon Sep 17 00:00:00 2001 From: Jan-Benedict Glaw Date: Tue, 7 Nov 2006 23:50:37 +0100 Subject: Update for the srm_env driver. This patch contains a fix for a bug introduced more than a year ago (not setting *eof) and updates whitespace a bit. Signed-off-by: Jan-Benedict Glaw --- arch/alpha/kernel/srm_env.c | 84 +++++++++++++++------------------------------ 1 file changed, 27 insertions(+), 57 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 990ac61028f..f7dd081d57f 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c @@ -2,7 +2,7 @@ * srm_env.c - Access to SRM environment * variables through linux' procfs * - * Copyright (C) 2001-2002 Jan-Benedict Glaw + * (C) 2001,2002,2006 by Jan-Benedict Glaw * * This driver is at all a modified version of Erik Mouw's * Documentation/DocBook/procfs_example.c, so: thank @@ -21,7 +21,7 @@ * 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, @@ -29,33 +29,6 @@ * */ -/* - * Changelog - * ~~~~~~~~~ - * - * Thu, 22 Aug 2002 15:10:43 +0200 - * - Update Config.help entry. I got a number of emails asking - * me to tell their senders if they could make use of this - * piece of code... So: "SRM is something like BIOS for your - * Alpha" - * - Update code formatting a bit to better conform CodingStyle - * rules. - * - So this is v0.0.5, with no changes (except formatting) - * - * Wed, 22 May 2002 00:11:21 +0200 - * - Fix typo on comment (SRC -> SRM) - * - Call this "Version 0.0.4" - * - * Tue, 9 Apr 2002 18:44:40 +0200 - * - Implement access by variable name and additionally - * by number. This is done by creating two subdirectories - * where one holds all names (like the old directory - * did) and the other holding 256 files named like "0", - * "1" and so on. - * - Call this "Version 0.0.3" - * - */ - #include #include #include @@ -67,7 +40,7 @@ #define BASE_DIR "srm_environment" /* Subdir in /proc/ */ #define NAMED_DIR "named_variables" /* Subdir for known variables */ #define NUMBERED_DIR "numbered_variables" /* Subdir for all variables */ -#define VERSION "0.0.5" /* Module version */ +#define VERSION "0.0.6" /* Module version */ #define NAME "srm_env" /* Module name */ MODULE_AUTHOR("Jan-Benedict Glaw "); @@ -106,7 +79,6 @@ static srm_env_t srm_named_entries[] = { static srm_env_t srm_numbered_entries[256]; - static int srm_env_read(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -115,21 +87,23 @@ srm_env_read(char *page, char **start, off_t off, int count, int *eof, unsigned long ret; srm_env_t *entry; - if(off != 0) - return -EFAULT; + if (off != 0) { + *eof = 1; + return 0; + } entry = (srm_env_t *) data; ret = callback_getenv(entry->id, page, count); - if((ret >> 61) == 0) + if ((ret >> 61) == 0) { nbytes = (int) ret; - else + *eof = 1; + } else nbytes = -EFAULT; return nbytes; } - static int srm_env_write(struct file *file, const char __user *buffer, unsigned long count, void *data) @@ -155,7 +129,7 @@ srm_env_write(struct file *file, const char __user *buffer, unsigned long count, ret1 = callback_setenv(entry->id, buf, count); if ((ret1 >> 61) == 0) { - do + do ret2 = callback_save_env(); while((ret2 >> 61) == 1); res = (int) ret1; @@ -172,14 +146,14 @@ srm_env_cleanup(void) srm_env_t *entry; unsigned long var_num; - if(base_dir) { + if (base_dir) { /* * Remove named entries */ - if(named_dir) { + if (named_dir) { entry = srm_named_entries; - while(entry->name != NULL && entry->id != 0) { - if(entry->proc_entry) { + while (entry->name != NULL && entry->id != 0) { + if (entry->proc_entry) { remove_proc_entry(entry->name, named_dir); entry->proc_entry = NULL; @@ -192,11 +166,11 @@ srm_env_cleanup(void) /* * Remove numbered entries */ - if(numbered_dir) { - for(var_num = 0; var_num <= 255; var_num++) { + if (numbered_dir) { + for (var_num = 0; var_num <= 255; var_num++) { entry = &srm_numbered_entries[var_num]; - if(entry->proc_entry) { + if (entry->proc_entry) { remove_proc_entry(entry->name, numbered_dir); entry->proc_entry = NULL; @@ -212,7 +186,6 @@ srm_env_cleanup(void) return; } - static int __init srm_env_init(void) { @@ -222,7 +195,7 @@ srm_env_init(void) /* * Check system */ - if(!alpha_using_srm) { + if (!alpha_using_srm) { printk(KERN_INFO "%s: This Alpha system doesn't " "know about SRM (or you've booted " "SRM->MILO->Linux, which gets " @@ -233,14 +206,14 @@ srm_env_init(void) /* * Init numbers */ - for(var_num = 0; var_num <= 255; var_num++) + for (var_num = 0; var_num <= 255; var_num++) sprintf(number[var_num], "%ld", var_num); /* * Create base directory */ base_dir = proc_mkdir(BASE_DIR, NULL); - if(base_dir == NULL) { + if (!base_dir) { printk(KERN_ERR "Couldn't create base dir /proc/%s\n", BASE_DIR); goto cleanup; @@ -251,7 +224,7 @@ srm_env_init(void) * Create per-name subdirectory */ named_dir = proc_mkdir(NAMED_DIR, base_dir); - if(named_dir == NULL) { + if (!named_dir) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NAMED_DIR); goto cleanup; @@ -262,7 +235,7 @@ srm_env_init(void) * Create per-number subdirectory */ numbered_dir = proc_mkdir(NUMBERED_DIR, base_dir); - if(numbered_dir == NULL) { + if (!numbered_dir) { printk(KERN_ERR "Couldn't create dir /proc/%s/%s\n", BASE_DIR, NUMBERED_DIR); goto cleanup; @@ -274,10 +247,10 @@ srm_env_init(void) * Create all named nodes */ entry = srm_named_entries; - while(entry->name != NULL && entry->id != 0) { + while (entry->name && entry->id) { entry->proc_entry = create_proc_entry(entry->name, 0644, named_dir); - if(entry->proc_entry == NULL) + if (!entry->proc_entry) goto cleanup; entry->proc_entry->data = (void *) entry; @@ -291,13 +264,13 @@ srm_env_init(void) /* * Create all numbered nodes */ - for(var_num = 0; var_num <= 255; var_num++) { + for (var_num = 0; var_num <= 255; var_num++) { entry = &srm_numbered_entries[var_num]; entry->name = number[var_num]; entry->proc_entry = create_proc_entry(entry->name, 0644, numbered_dir); - if(entry->proc_entry == NULL) + if (!entry->proc_entry) goto cleanup; entry->id = var_num; @@ -318,7 +291,6 @@ cleanup: return -ENOMEM; } - static void __exit srm_env_exit(void) { @@ -328,7 +300,5 @@ srm_env_exit(void) return; } - module_init(srm_env_init); module_exit(srm_env_exit); - -- cgit v1.2.3 From de8e7c12430a73654ae3cedbc45428d56c6b777b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Nov 2006 10:09:28 -0800 Subject: Revert "[PATCH] i386: Add MMCFG resources to i386 too" This reverts commit de09bddb9d6f96785be470c832b881e6d72d589f. It tried to reserve the MMCONFIG mmio memory ranges, but since the MMCONFIG information is broken and often bogus (which is why we don't dare use it most of the time _anyway_), it does more harm than good. Cc: Jeff Chua Cc: Adrian Bunk Cc: Andi Kleen Signed-off-by: Linus Torvalds --- arch/i386/pci/mmconfig.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index d0c3da3aa2a..c6b6d9bbc45 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -154,38 +154,6 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; - -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - /* K8 systems have some devices (typically in the builtin northbridge) that are only accessible using type1 Normally this can be expressed in the MCFG by not listing them @@ -222,8 +190,6 @@ static __init void unreachable_devices(void) } } - - void __init pci_mmcfg_init(int type) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) @@ -251,5 +217,4 @@ void __init pci_mmcfg_init(int type) pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; unreachable_devices(); - pci_mmcfg_insert_resources(); } -- cgit v1.2.3 From 6c0ffb9d2fd987c79c6cbb81c3f3011c63749b1a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Nov 2006 10:23:03 -0800 Subject: x86-64: clean up io-apic accesses This is just commit 130fe05dbc0114609cfef9815c0c5580b42decfa ported to x86-64, for all the same reasons. It cleans up the IO-APIC accesses in order to then fix the ordering issues. We move the accessor functions (that were only used by io_apic.c) out of a header file, and use proper memory-mapped accesses rather than making up our own "volatile" pointers. Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/io_apic.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index fe429e5d6b2..96e02d84571 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -88,6 +88,52 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +struct io_apic { + unsigned int index; + unsigned int unused[3]; + unsigned int data; +}; + +static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) +{ + return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); +} + +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + return readl(&io_apic->data); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + */ +static inline void io_apic_modify(unsigned int apic, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(value, &io_apic->data); +} + +/* + * Synchronize the IO-APIC and the CPU by doing + * a dummy read from the IO-APIC + */ +static inline void io_apic_sync(unsigned int apic) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + readl(&io_apic->data); +} + #define __DO_ACTION(R, ACTION, FINAL) \ \ { \ -- cgit v1.2.3 From 48797ebd9e8b16fddcd4ef062f792314a6b9219a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Nov 2006 10:27:54 -0800 Subject: x86-64: write IO APIC irq routing entries in correct order This is the x86-64 version of f9dadfa71bc594df09044da61d1c72701121d802 that did the same thing on i386. Since the "mask" bit is in the low word, when we write a new entry, we need to write the high word first, before we potentially unmask it. The exception is when we actually want to mask the interrupt, in which case we want to write the low word first to make sure that the high word doesn't change while the interrupt routing is still active. Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/io_apic.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 96e02d84571..3b8f9c68ad3 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -172,11 +172,33 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) return eu.entry; } +/* + * When we write a new IO APIC routing entry, we need to write the high + * word first! If the mask bit in the low word is clear, we will enable + * the interrupt, and we need to make sure the entry is fully populated + * before that happens. + */ static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { unsigned long flags; union entry_union eu; eu.entry = e; + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2*pin, eu.w2); + io_apic_write(apic, 0x10 + 2*pin, eu.w1); + spin_unlock_irqrestore(&ioapic_lock, flags); +} + +/* + * When we mask an IO APIC routing entry, we need to write the low + * word first, in order to set the mask bit before we change the + * high bits! + */ +static void ioapic_mask_entry(int apic, int pin) +{ + unsigned long flags; + union entry_union eu = { .entry.mask = 1 }; + spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x10 + 2*pin, eu.w1); io_apic_write(apic, 0x11 + 2*pin, eu.w2); @@ -302,9 +324,7 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) /* * Disable it in the IO-APIC irq-routing table: */ - memset(&entry, 0, sizeof(entry)); - entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + ioapic_mask_entry(apic, pin); } static void clear_IO_APIC (void) -- cgit v1.2.3 From d654c673d6394bc26e159b1057b357371b4ce1dc Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 8 Nov 2006 17:44:37 -0800 Subject: [PATCH] Regression in 2.6.19-rc microcode driver If the microcode driver is built in (rather than module) there are some, ehm, interesting effects happening due to the new "call out to userspace" behavior that is introduced.. and which runs too early. The result is a boot hang; which is really nasty. The patch below is a minimally safe patch to fix this regression for 2.6.19 by just not requesting actual microcode updates during early boot. (That is a good idea in general anyway) The "real" fix is a lot more complex given the entire cpu hotplug scenario (during cpu hotplug you normally need to load the microcode as well); but the interactions for that are just really messy at this point; this fix at least makes it work and avoids a full detangle of hotplug. Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/microcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index c4d0291b519..23f5984d065 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -577,7 +577,7 @@ static void microcode_init_cpu(int cpu) set_cpus_allowed(current, cpumask_of_cpu(cpu)); mutex_lock(µcode_mutex); collect_cpu_info(cpu); - if (uci->valid) + if (uci->valid && system_state == SYSTEM_RUNNING) cpu_request_microcode(cpu); mutex_unlock(µcode_mutex); set_cpus_allowed(current, old); -- cgit v1.2.3 From c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 8 Nov 2006 17:44:41 -0800 Subject: [PATCH] i386: Force data segment to be 4K aligned o Currently there is no specific alignment restriction in linker script and in some cases it can be placed non 4K aligned addresses. This fails kexec which checks that segment to be loaded is page aligned. o I guess, it does not harm data segment to be 4K aligned. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index adc1f232afe..c6f84a0322b 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -51,6 +51,7 @@ SECTIONS __tracedata_end = .; /* writeable */ + . = ALIGN(4096); .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ *(.data) CONSTRUCTORS -- cgit v1.2.3 From 8bdc052eccdc7893d075d3f1f7103594a458c8c4 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 8 Nov 2006 17:44:49 -0800 Subject: [PATCH] kretprobe: fix kretprobe-booster to save regs and set status There are two bugs in the kretprobe-booster. 1) It doesn't make room for gs registers. 2) It doesn't change status of the current kprobe. This status will effect the fault handling. This patch fixes these bugs and, additionally, saves skipped registers for compatibility with the original kretprobe. Signed-off-by: Masami Hiramatsu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index d98e44b16fe..fc79e1e859c 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -361,8 +361,11 @@ no_kprobe: asm volatile ( ".global kretprobe_trampoline\n" "kretprobe_trampoline: \n" " pushf\n" - /* skip cs, eip, orig_eax, es, ds */ - " subl $20, %esp\n" + /* skip cs, eip, orig_eax */ + " subl $12, %esp\n" + " pushl %gs\n" + " pushl %ds\n" + " pushl %es\n" " pushl %eax\n" " pushl %ebp\n" " pushl %edi\n" @@ -373,10 +376,10 @@ no_kprobe: " movl %esp, %eax\n" " call trampoline_handler\n" /* move eflags to cs */ - " movl 48(%esp), %edx\n" - " movl %edx, 44(%esp)\n" + " movl 52(%esp), %edx\n" + " movl %edx, 48(%esp)\n" /* save true return address on eflags */ - " movl %eax, 48(%esp)\n" + " movl %eax, 52(%esp)\n" " popl %ebx\n" " popl %ecx\n" " popl %edx\n" @@ -384,8 +387,8 @@ no_kprobe: " popl %edi\n" " popl %ebp\n" " popl %eax\n" - /* skip eip, orig_eax, es, ds */ - " addl $16, %esp\n" + /* skip eip, orig_eax, es, ds, gs */ + " addl $20, %esp\n" " popf\n" " ret\n"); } @@ -404,6 +407,10 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); + /* fixup registers */ + regs->xcs = __KERNEL_CS; + regs->eip = trampoline_address; + regs->orig_eax = 0xffffffff; /* * It is possible to have multiple instances associated with a given @@ -425,6 +432,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) if (ri->rp && ri->rp->handler){ __get_cpu_var(current_kprobe) = &ri->rp->kp; + get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; ri->rp->handler(ri, regs); __get_cpu_var(current_kprobe) = NULL; } -- cgit v1.2.3 From 6c33eb39976b67628452ebc791834c7d590e545e Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Wed, 8 Nov 2006 17:44:50 -0800 Subject: [PATCH] ia64: select ACPI_NUMA if ACPI When ACPI && NUMA, pxm_to_node is used and it exists in drivers/acpi/numa.c Tony said: The patch makes sense ... if you pick both of "ACPI" and "NUMA", then you need (and should automatically be given) ACPI_NUMA too. The only open question is whether there is a better way of getting there. Perhaps with less configuration options in the first place? We are heading towards a future where so many systems will be NUMA that there would seem to be little benefit in keeping ACPI_NUMA separate from ACPI ... but perhaps we aren't quite there yet. Signed-off-by: KAMEZAWA Hiroyuki Cc: Len Brown Acked-by: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 70f7eb9fed3..14682396f7f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -341,6 +341,7 @@ config NUMA bool "NUMA support" depends on !IA64_HP_SIM && !FLATMEM default y if IA64_SGI_SN2 + select ACPI_NUMA if ACPI help Say Y to compile the kernel to support NUMA (Non-Uniform Memory Access). This option is for configuring high-end multiprocessor -- cgit v1.2.3 From ec68307cc5a8dc499e48693843bb42f6b6028458 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 8 Nov 2006 17:44:57 -0800 Subject: [PATCH] htirq: refactor so we only have one function that writes to the chip This refactoring actually optimizes the code a little by caching the value that we think the device is programmed with instead of reading it back from the hardware. Which simplifies the code a little and should speed things up a bit. This patch introduces the concept of a ht_irq_msg and modifies the architecture read/write routines to update this code. There is a minor consistency fix here as well as x86_64 forgot to initialize the htirq as masked. Signed-off-by: Eric W. Biederman Cc: Andi Kleen Acked-by: Bryan O'Sullivan Cc: Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 26 ++++++++++++-------------- arch/x86_64/kernel/io_apic.c | 31 +++++++++++++++---------------- 2 files changed, 27 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 507983c513c..ad84bc2802a 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2624,18 +2624,16 @@ void arch_teardown_msi_irq(unsigned int irq) static void target_ht_irq(unsigned int irq, unsigned int dest) { - u32 low, high; - low = read_ht_irq_low(irq); - high = read_ht_irq_high(irq); + struct ht_irq_msg msg; + fetch_ht_irq_msg(irq, &msg); - low &= ~(HT_IRQ_LOW_DEST_ID_MASK); - high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); + msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK); + msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); - low |= HT_IRQ_LOW_DEST_ID(dest); - high |= HT_IRQ_HIGH_DEST_ID(dest); + msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest); + msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); - write_ht_irq_low(irq, low); - write_ht_irq_high(irq, high); + write_ht_irq_msg(irq, &msg); } static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) @@ -2673,7 +2671,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) vector = assign_irq_vector(irq); if (vector >= 0) { - u32 low, high; + struct ht_irq_msg msg; unsigned dest; cpumask_t tmp; @@ -2681,9 +2679,10 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) cpu_set(vector >> 8, tmp); dest = cpu_mask_to_apicid(tmp); - high = HT_IRQ_HIGH_DEST_ID(dest); + msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); - low = HT_IRQ_LOW_BASE | + msg.address_lo = + HT_IRQ_LOW_BASE | HT_IRQ_LOW_DEST_ID(dest) | HT_IRQ_LOW_VECTOR(vector) | ((INT_DEST_MODE == 0) ? @@ -2695,8 +2694,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) HT_IRQ_LOW_MT_ARBITRATED) | HT_IRQ_LOW_IRQ_MASKED; - write_ht_irq_low(irq, low); - write_ht_irq_high(irq, high); + write_ht_irq_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &ht_irq_chip, handle_edge_irq, "edge"); diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 3b8f9c68ad3..41bfc49301a 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1955,18 +1955,16 @@ void arch_teardown_msi_irq(unsigned int irq) static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector) { - u32 low, high; - low = read_ht_irq_low(irq); - high = read_ht_irq_high(irq); + struct ht_irq_msg msg; + fetch_ht_irq_msg(irq, &msg); - low &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); - high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); + msg.address_lo &= ~(HT_IRQ_LOW_VECTOR_MASK | HT_IRQ_LOW_DEST_ID_MASK); + msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK); - low |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); - high |= HT_IRQ_HIGH_DEST_ID(dest); + msg.address_lo |= HT_IRQ_LOW_VECTOR(vector) | HT_IRQ_LOW_DEST_ID(dest); + msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest); - write_ht_irq_low(irq, low); - write_ht_irq_high(irq, high); + write_ht_irq_msg(irq, &msg); } static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) @@ -1987,7 +1985,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) dest = cpu_mask_to_apicid(tmp); - target_ht_irq(irq, dest, vector & 0xff); + target_ht_irq(irq, dest, vector); set_native_irq_info(irq, mask); } #endif @@ -2010,14 +2008,15 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) vector = assign_irq_vector(irq, TARGET_CPUS, &tmp); if (vector >= 0) { - u32 low, high; + struct ht_irq_msg msg; unsigned dest; dest = cpu_mask_to_apicid(tmp); - high = HT_IRQ_HIGH_DEST_ID(dest); + msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest); - low = HT_IRQ_LOW_BASE | + msg.address_lo = + HT_IRQ_LOW_BASE | HT_IRQ_LOW_DEST_ID(dest) | HT_IRQ_LOW_VECTOR(vector) | ((INT_DEST_MODE == 0) ? @@ -2026,10 +2025,10 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) HT_IRQ_LOW_RQEOI_EDGE | ((INT_DELIVERY_MODE != dest_LowestPrio) ? HT_IRQ_LOW_MT_FIXED : - HT_IRQ_LOW_MT_ARBITRATED); + HT_IRQ_LOW_MT_ARBITRATED) | + HT_IRQ_LOW_IRQ_MASKED; - write_ht_irq_low(irq, low); - write_ht_irq_high(irq, high); + write_ht_irq_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &ht_irq_chip, handle_edge_irq, "edge"); -- cgit v1.2.3 From 621da0f8af228525e4b40390e36fbdc44a587cf1 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 9 Nov 2006 16:00:06 +1100 Subject: [POWERPC] Make sure initrd and dtb sections get into zImage correctly The "wrapper" script was using the wrong names for the initrd and dtb (device-tree blob) sections. This fixes it, and also ensures the symbols for the start and end of the dtb get defined correctly. Signed-off-by: Paul Mackerras --- arch/powerpc/boot/wrapper | 4 ++-- arch/powerpc/boot/zImage.lds.S | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index eab7318729e..b5fb1fee76f 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -179,11 +179,11 @@ if [ -z "$cacheit" ]; then fi if [ -n "$initrd" ]; then - addsec $tmp "$initrd" initrd + addsec $tmp "$initrd" $isection fi if [ -n "$dtb" ]; then - addsec $tmp "$dtb" dtb + addsec $tmp "$dtb" .kernel:dtb fi if [ "$platform" != "miboot" ]; then diff --git a/arch/powerpc/boot/zImage.lds.S b/arch/powerpc/boot/zImage.lds.S index 4b6bb3ffe3d..4be3c6414b0 100644 --- a/arch/powerpc/boot/zImage.lds.S +++ b/arch/powerpc/boot/zImage.lds.S @@ -21,6 +21,11 @@ SECTIONS __got2_end = .; } + . = ALIGN(8); + _dtb_start = .; + .kernel:dtb : { *(.kernel:dtb) } + _dtb_end = .; + . = ALIGN(4096); _vmlinux_start = .; .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) } -- cgit v1.2.3 From 8cc05f79d2a4e33d5cb621f36a448d5157f46893 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Tue, 17 Oct 2006 11:16:22 +0100 Subject: [ARM] 3857/2: pnx4008: add devices' registration This patch adds platform devices' registration for the devices which drivers either have been added to the mainline or on the way to. arch/arm/mach-pnx4008/core.c | 69 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) Signed-off-by: Vitaly Wool Signed-off-by: Russell King --- arch/arm/mach-pnx4008/core.c | 69 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pnx4008/core.c b/arch/arm/mach-pnx4008/core.c index 3d73c1e9375..429c796938b 100644 --- a/arch/arm/mach-pnx4008/core.c +++ b/arch/arm/mach-pnx4008/core.c @@ -133,10 +133,79 @@ static struct platform_device serial_device = { }, }; +static struct platform_device nand_flash_device = { + .name = "pnx4008-flash", + .id = -1, + .dev = { + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +/* The dmamask must be set for OHCI to work */ +static u64 ohci_dmamask = ~(u32) 0; + +static struct resource ohci_resources[] = { + { + .start = IO_ADDRESS(PNX4008_USB_CONFIG_BASE), + .end = IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x100), + .flags = IORESOURCE_MEM, + }, { + .start = USB_HOST_INT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device ohci_device = { + .name = "pnx4008-usb-ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(ohci_resources), + .resource = ohci_resources, +}; + +static struct platform_device sdum_device = { + .name = "pnx4008-sdum", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + }, +}; + +static struct platform_device rgbfb_device = { + .name = "pnx4008-rgbfb", + .id = 0, + .dev = { + .coherent_dma_mask = 0xffffffff, + } +}; + +struct resource watchdog_resources[] = { + { + .start = PNX4008_WDOG_BASE, + .end = PNX4008_WDOG_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device watchdog_device = { + .name = "pnx4008-watchdog", + .id = -1, + .num_resources = ARRAY_SIZE(watchdog_resources), + .resource = watchdog_resources, +}; + static struct platform_device *devices[] __initdata = { &spipnx_1, &spipnx_2, &serial_device, + &ohci_device, + &nand_flash_device, + &sdum_device, + &rgbfb_device, + &watchdog_device, }; -- cgit v1.2.3 From ae883cab9457aad0fb3342249e1207873d3b64de Mon Sep 17 00:00:00 2001 From: John Rose Date: Wed, 8 Nov 2006 10:07:30 -0600 Subject: [POWERPC] pseries: Force 4k update_flash block and list sizes The enablement of 64k pages on pseries platforms exposed a bug in the RTAS mechanism for updating firmware. RTAS assumes 4k for flash block and list sizes, and use of any other sizes results in a failure, even though PAPR does not specify any such requirement. This patch changes the rtas_flash module to force the use of 4k memory block and list sizes when preparing and sending a firmware image to RTAS. The rtas_flash function now uses a slab cache of 4k blocks with 4k alignment, rather than get_zeroed_page(), to allocate the memory for the flash blocks and lists. The 4k alignment requirement is specified in PAPR. Signed-off-by: John Rose Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/rtas_flash.c | 47 +++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 1442b63a75d..6f6fc977cb3 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -72,6 +72,10 @@ #define VALIDATE_BUF_SIZE 4096 #define RTAS_MSG_MAXLEN 64 +/* Quirk - RTAS requires 4k list length and block size */ +#define RTAS_BLKLIST_LENGTH 4096 +#define RTAS_BLK_SIZE 4096 + struct flash_block { char *data; unsigned long length; @@ -83,7 +87,7 @@ struct flash_block { * into a version/length and translate the pointers * to absolute. */ -#define FLASH_BLOCKS_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct flash_block)) +#define FLASH_BLOCKS_PER_NODE ((RTAS_BLKLIST_LENGTH - 16) / sizeof(struct flash_block)) struct flash_block_list { unsigned long num_blocks; struct flash_block_list *next; @@ -96,6 +100,9 @@ struct flash_block_list_header { /* just the header of flash_block_list */ static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; +/* Use slab cache to guarantee 4k alignment */ +static kmem_cache_t *flash_block_cache = NULL; + #define FLASH_BLOCK_LIST_VERSION (1UL) /* Local copy of the flash block list. @@ -153,7 +160,7 @@ static int flash_list_valid(struct flash_block_list *flist) return FLASH_IMG_NULL_DATA; } block_size = f->blocks[i].length; - if (block_size <= 0 || block_size > PAGE_SIZE) { + if (block_size <= 0 || block_size > RTAS_BLK_SIZE) { return FLASH_IMG_BAD_LEN; } image_size += block_size; @@ -177,9 +184,9 @@ static void free_flash_list(struct flash_block_list *f) while (f) { for (i = 0; i < f->num_blocks; i++) - free_page((unsigned long)(f->blocks[i].data)); + kmem_cache_free(flash_block_cache, f->blocks[i].data); next = f->next; - free_page((unsigned long)f); + kmem_cache_free(flash_block_cache, f); f = next; } } @@ -278,6 +285,12 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, return msglen; } +/* constructor for flash_block_cache */ +void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags) +{ + memset(ptr, 0, RTAS_BLK_SIZE); +} + /* We could be much more efficient here. But to keep this function * simple we allocate a page to the block list no matter how small the * count is. If the system is low on memory it will be just as well @@ -302,7 +315,7 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, * proc file */ if (uf->flist == NULL) { - uf->flist = (struct flash_block_list *) get_zeroed_page(GFP_KERNEL); + uf->flist = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!uf->flist) return -ENOMEM; } @@ -313,21 +326,21 @@ static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, next_free = fl->num_blocks; if (next_free == FLASH_BLOCKS_PER_NODE) { /* Need to allocate another block_list */ - fl->next = (struct flash_block_list *)get_zeroed_page(GFP_KERNEL); + fl->next = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!fl->next) return -ENOMEM; fl = fl->next; next_free = 0; } - if (count > PAGE_SIZE) - count = PAGE_SIZE; - p = (char *)get_zeroed_page(GFP_KERNEL); + if (count > RTAS_BLK_SIZE) + count = RTAS_BLK_SIZE; + p = kmem_cache_alloc(flash_block_cache, GFP_KERNEL); if (!p) return -ENOMEM; if(copy_from_user(p, buffer, count)) { - free_page((unsigned long)p); + kmem_cache_free(flash_block_cache, p); return -EFAULT; } fl->blocks[next_free].data = p; @@ -791,6 +804,16 @@ int __init rtas_flash_init(void) goto cleanup; rtas_flash_term_hook = rtas_flash_firmware; + + flash_block_cache = kmem_cache_create("rtas_flash_cache", + RTAS_BLK_SIZE, RTAS_BLK_SIZE, 0, + rtas_block_ctor, NULL); + if (!flash_block_cache) { + printk(KERN_ERR "%s: failed to create block cache\n", + __FUNCTION__); + rc = -ENOMEM; + goto cleanup; + } return 0; cleanup: @@ -805,6 +828,10 @@ cleanup: void __exit rtas_flash_cleanup(void) { rtas_flash_term_hook = NULL; + + if (flash_block_cache) + kmem_cache_destroy(flash_block_cache); + remove_flash_pde(firmware_flash_pde); remove_flash_pde(firmware_update_pde); remove_flash_pde(validate_pde); -- cgit v1.2.3 From ab56dbddc8a23ff3f4602855aaf0fcb3c814118b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 10 Nov 2006 15:11:20 +1100 Subject: [POWERPC] Fix cell "new style" mapping and add debug This fixes a typo in the "new style" code for mapping SPE resources, which causes it to try to map the same resource 4 times. It also adds some pr_debug's that are useful to track down issues with the firmware when bringinh up new machines. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 41 +++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d0fb959e3ef..7aa809d5a24 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -655,14 +655,19 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) for (i=0; i < 3; i++) { ret = of_irq_map_one(np, i, &oirq); - if (ret) + if (ret) { + pr_debug("spu_new: failed to get irq %d\n", i); goto err; - + } ret = -EINVAL; + pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], + oirq.controller->full_name); spu->irqs[i] = irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size); - if (spu->irqs[i] == NO_IRQ) + if (spu->irqs[i] == NO_IRQ) { + pr_debug("spu_new: failed to map it !\n"); goto err; + } } return 0; @@ -681,7 +686,7 @@ static int spu_map_resource(struct device_node *node, int nr, struct resource resource = { }; int ret; - ret = of_address_to_resource(node, 0, &resource); + ret = of_address_to_resource(node, nr, &resource); if (ret) goto out; @@ -704,22 +709,42 @@ static int __init spu_map_device(struct spu *spu, struct device_node *node) ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, &spu->local_store_phys); - if (ret) + if (ret) { + pr_debug("spu_new: failed to map %s resource 0\n", + node->full_name); goto out; + } ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, &spu->problem_phys); - if (ret) + if (ret) { + pr_debug("spu_new: failed to map %s resource 1\n", + node->full_name); goto out_unmap; + } ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, NULL); - if (ret) + if (ret) { + pr_debug("spu_new: failed to map %s resource 2\n", + node->full_name); goto out_unmap; + } if (!firmware_has_feature(FW_FEATURE_LPAR)) ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, NULL); - if (ret) + if (ret) { + pr_debug("spu_new: failed to map %s resource 3\n", + node->full_name); goto out_unmap; + } + pr_debug("spu_new: %s maps:\n", node->full_name); + pr_debug(" local store : 0x%016lx -> 0x%p\n", + spu->local_store_phys, spu->local_store); + pr_debug(" problem state : 0x%016lx -> 0x%p\n", + spu->problem_phys, spu->problem); + pr_debug(" priv2 : 0x%p\n", spu->priv2); + pr_debug(" priv1 : 0x%p\n", spu->priv1); + return 0; out_unmap: -- cgit v1.2.3 From 36b600f2649e3be49039efe31edeeb64277dbd99 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 2 Nov 2006 21:08:45 -0800 Subject: [POWERPC] cell: set ARCH_SPARSEMEM_DEFAULT in Kconfig The current cell processor support needs sparsemem, so set it as the default memory model. Signed-off-by: Geoff Levand Acked-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 2bd9b7fb0f6..0673dbedb24 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -740,7 +740,7 @@ config ARCH_SPARSEMEM_ENABLE config ARCH_SPARSEMEM_DEFAULT def_bool y - depends on SMP && PPC_PSERIES + depends on (SMP && PPC_PSERIES) || PPC_CELL config ARCH_POPULATES_NODE_MAP def_bool y -- cgit v1.2.3 From 6751718932be7325c898e5908daec2ee917afd09 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 11 Nov 2006 22:54:07 +0000 Subject: [ARM] Remove PM_LEGACY=y from selected ARM defconfigs Most ARM defconfigs don't actually need to have PM_LEGACY enabled. Disable it for ATEB9200, Collie, IXP4xx, OMAP H2, S3C2410 and Versatile. Signed-off-by: Russell King --- arch/arm/configs/ateb9200_defconfig | 2 +- arch/arm/configs/collie_defconfig | 2 +- arch/arm/configs/ixp4xx_defconfig | 6 ++---- arch/arm/configs/omap_h2_1610_defconfig | 2 +- arch/arm/configs/s3c2410_defconfig | 2 +- arch/arm/configs/versatile_defconfig | 2 +- 6 files changed, 7 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig index 15e6b0bbbde..3de5c643848 100644 --- a/arch/arm/configs/ateb9200_defconfig +++ b/arch/arm/configs/ateb9200_defconfig @@ -217,7 +217,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index 074c47a4fb2..a3758913c0b 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -219,7 +219,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set CONFIG_APM=y diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index 4975b914f92..fac7c3b240c 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -206,10 +206,8 @@ CONFIG_BINFMT_ELF=y # # Power management options # -CONFIG_PM=y -CONFIG_PM_LEGACY=y -# CONFIG_PM_DEBUG is not set -CONFIG_APM=y +# CONFIG_PM is not set +# CONFIG_APM is not set # # Networking diff --git a/arch/arm/configs/omap_h2_1610_defconfig b/arch/arm/configs/omap_h2_1610_defconfig index 05adb0b34e7..b0efd4ca993 100644 --- a/arch/arm/configs/omap_h2_1610_defconfig +++ b/arch/arm/configs/omap_h2_1610_defconfig @@ -257,7 +257,7 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 0563c14395e..c0152393e49 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -258,7 +258,7 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_APM=y diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 96b7a776242..f7bf6ef27d1 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -200,7 +200,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set # CONFIG_APM is not set -- cgit v1.2.3 From a7a1ed305043961ed06e0ee5e7a4a2cc1250f4b5 Mon Sep 17 00:00:00 2001 From: "s.hauer@pengutronix.de" Date: Thu, 2 Nov 2006 13:56:04 +0100 Subject: [PATCH] Remove occurences of PPC_MULTIPLATFORM in head_64.S Since iSeries is merged to MULTIPLATFORM, there is no way to build a 64bit kernel without MULTIPLATFORM, so PPC_MULTIPLATFORM can be removed in 64bit-only files. Signed-off-by: Sascha Hauer Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/entry_64.S | 4 ---- arch/powerpc/kernel/head_64.S | 11 ----------- 2 files changed, 15 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 86e2bdd5afd..ec754c92ba9 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -736,8 +736,6 @@ _STATIC(rtas_restore_regs) #endif /* CONFIG_PPC_RTAS */ -#ifdef CONFIG_PPC_MULTIPLATFORM - _GLOBAL(enter_prom) mflr r0 std r0,16(r1) @@ -822,5 +820,3 @@ _GLOBAL(enter_prom) ld r0,16(r1) mtlr r0 blr - -#endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index d2890050b7e..76d1c81afe5 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -72,13 +72,11 @@ .text .globl _stext _stext: -#ifdef CONFIG_PPC_MULTIPLATFORM _GLOBAL(__start) /* NOP this out unconditionally */ BEGIN_FTR_SECTION b .__start_initialization_multiplatform END_FTR_SECTION(0, 1) -#endif /* CONFIG_PPC_MULTIPLATFORM */ /* Catch branch to 0 in real mode */ trap @@ -1643,7 +1641,6 @@ _STATIC(__start_initialization_iSeries) b .start_here_common #endif /* CONFIG_PPC_ISERIES */ -#ifdef CONFIG_PPC_MULTIPLATFORM _STATIC(__mmu_off) mfmsr r3 @@ -1669,13 +1666,11 @@ _STATIC(__mmu_off) * */ _GLOBAL(__start_initialization_multiplatform) -#ifdef CONFIG_PPC_MULTIPLATFORM /* * Are we booted from a PROM Of-type client-interface ? */ cmpldi cr0,r5,0 bne .__boot_from_prom /* yes -> prom */ -#endif /* Save parameters */ mr r31,r3 @@ -1702,7 +1697,6 @@ _GLOBAL(__start_initialization_multiplatform) bl .__mmu_off b .__after_prom_start -#ifdef CONFIG_PPC_MULTIPLATFORM _STATIC(__boot_from_prom) /* Save parameters */ mr r31,r3 @@ -1742,7 +1736,6 @@ _STATIC(__boot_from_prom) bl .prom_init /* We never return */ trap -#endif /* * At this point, r3 contains the physical address we are running at, @@ -1798,8 +1791,6 @@ _STATIC(__after_prom_start) bl .copy_and_flush /* copy the rest */ b .start_here_multiplatform -#endif /* CONFIG_PPC_MULTIPLATFORM */ - /* * Copy routine used to copy the kernel to start at physical address 0 * and flush and invalidate the caches as needed. @@ -1964,7 +1955,6 @@ _GLOBAL(enable_64b_mode) isync blr -#ifdef CONFIG_PPC_MULTIPLATFORM /* * This is where the main kernel code starts. */ @@ -2035,7 +2025,6 @@ _STATIC(start_here_multiplatform) mtspr SPRN_SRR1,r4 rfid b . /* prevent speculative execution */ -#endif /* CONFIG_PPC_MULTIPLATFORM */ /* This is where all platforms converge execution */ _STATIC(start_here_common) -- cgit v1.2.3 From 99a565bab1a41819b9f85c8c069a2f3fc6e27d55 Mon Sep 17 00:00:00 2001 From: "s.hauer@pengutronix.de" Date: Thu, 2 Nov 2006 13:56:06 +0100 Subject: [PATCH] Remove occurences of PPC_MULTIPLATFORM in pci_64.c Since iSeries is merged to MULTIPLATFORM, there is no way to build a 64bit kernel without MULTIPLATFORM, so PPC_MULTIPLATFORM can be removed in 64bit-only files. Signed-off-by: Sascha Hauer Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_64.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 9bae8a5bf67..80ae9ea15cd 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -42,11 +42,9 @@ unsigned long pci_probe_only = 1; int pci_assign_all_buses = 0; -#ifdef CONFIG_PPC_MULTIPLATFORM static void fixup_resource(struct resource *res, struct pci_dev *dev); static void do_bus_setup(struct pci_bus *bus); static void phbs_remap_io(void); -#endif /* pci_io_base -- the base address from which io bars are offsets. * This is the lowest I/O base address (so bar values are always positive), @@ -251,7 +249,6 @@ static void __init pcibios_claim_of_setup(void) pcibios_claim_one_bus(b); } -#ifdef CONFIG_PPC_MULTIPLATFORM static u32 get_int_prop(struct device_node *np, const char *name, u32 def) { const u32 *prop; @@ -506,7 +503,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node, pci_scan_child_bus(bus); } EXPORT_SYMBOL(of_scan_pci_bridge); -#endif /* CONFIG_PPC_MULTIPLATFORM */ void __devinit scan_phb(struct pci_controller *hose) { @@ -540,7 +536,7 @@ void __devinit scan_phb(struct pci_controller *hose) } mode = PCI_PROBE_NORMAL; -#ifdef CONFIG_PPC_MULTIPLATFORM + if (node && ppc_md.pci_probe_mode) mode = ppc_md.pci_probe_mode(bus); DBG(" probe mode: %d\n", mode); @@ -548,7 +544,7 @@ void __devinit scan_phb(struct pci_controller *hose) bus->subordinate = hose->last_busno; of_scan_bus(node, bus); } -#endif /* CONFIG_PPC_MULTIPLATFORM */ + if (mode == PCI_PROBE_NORMAL) hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); } @@ -592,11 +588,9 @@ static int __init pcibios_init(void) if (ppc64_isabridge_dev != NULL) printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); -#ifdef CONFIG_PPC_MULTIPLATFORM if (!firmware_has_feature(FW_FEATURE_ISERIES)) /* map in PCI I/O space */ phbs_remap_io(); -#endif printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); @@ -873,8 +867,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev) device_create_file(&pdev->dev, &dev_attr_devspec); } -#ifdef CONFIG_PPC_MULTIPLATFORM - #define ISA_SPACE_MASK 0x1 #define ISA_SPACE_IO 0x1 @@ -1343,8 +1335,6 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) return NULL; } -#endif /* CONFIG_PPC_MULTIPLATFORM */ - unsigned long pci_address_to_pio(phys_addr_t address) { struct pci_controller *hose, *tmp; -- cgit v1.2.3 From fd6e7d2d6a0231ebfa08e1f9a323497ea548da7d Mon Sep 17 00:00:00 2001 From: "s.hauer@pengutronix.de" Date: Thu, 2 Nov 2006 13:56:10 +0100 Subject: [PATCH] Clean up usage of boot_dev dev_t boot_dev is declared in arch/powerpc/kernel/setup_32.c and in arch/powerpc/kernel/setup_64.c but not used in these files. It is only used in arch/powerpc/platforms/powermac/setup.c, so make it static in this file. Signed-off-by: Sascha Hauer Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_32.c | 4 ---- arch/powerpc/kernel/setup_64.c | 1 - arch/powerpc/platforms/powermac/setup.c | 2 +- 3 files changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 191d0ab0922..517ed1b1b16 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -63,10 +63,6 @@ unsigned int DMA_MODE_WRITE; int have_of = 1; -#ifdef CONFIG_PPC_MULTIPLATFORM -dev_t boot_dev; -#endif /* CONFIG_PPC_MULTIPLATFORM */ - #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; #endif diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index b1b0cda3f74..ae6b67ce54e 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -71,7 +71,6 @@ int have_of = 1; int boot_cpuid = 0; -dev_t boot_dev; u64 ppc64_pft_size; /* Pick defaults since we might want to patch instructions diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 824a618396a..cb1c342061e 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -361,7 +361,7 @@ char *bootdevice; void *boot_host; int boot_target; int boot_part; -extern dev_t boot_dev; +static dev_t boot_dev; #ifdef CONFIG_SCSI void __init note_scsi_host(struct device_node *node, void *host) -- cgit v1.2.3 From 2fcd34291b650723091a06e4b51b546961f308a3 Mon Sep 17 00:00:00 2001 From: "s.hauer@pengutronix.de" Date: Thu, 2 Nov 2006 13:56:11 +0100 Subject: [PATCH] Make nvram_64.o a 64bit-only object Make nvram_64.o dependent on 64bit, not on MULTIPLATFORM. Signed-off-by: Sascha Hauer Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 8b133afbdc2..82c223852e6 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -17,7 +17,7 @@ obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o cpu_setup_ppc970.o \ - firmware.o sysfs.o + firmware.o sysfs.o nvram_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_PPC_970_NAP) += idle_power4.o @@ -32,7 +32,6 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o -obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o obj-$(CONFIG_TAU) += tau_6xx.o -- cgit v1.2.3 From 0f6c95dcabdaa8fdc95b125582bd12625adfbde6 Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Wed, 8 Nov 2006 17:14:43 +0100 Subject: [PATCH] Add MPC5200 Interrupt Controller support. This adds support for the MPC52xx Interrupt controller for ARCH=powerpc. It includes the main code in arch/powerpc/sysdev/ as well as a header file in include/asm-powerpc. Signed-off-by: Nicolas DET Acked-by: Sylvain Munaut Acked-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/mpc52xx_pic.c | 538 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 539 insertions(+) create mode 100644 arch/powerpc/sysdev/mpc52xx_pic.c (limited to 'arch') diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index f15af0e82f1..5b87f7b42a1 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ +obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_pic.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o diff --git a/arch/powerpc/sysdev/mpc52xx_pic.c b/arch/powerpc/sysdev/mpc52xx_pic.c new file mode 100644 index 00000000000..6df51f04b8f --- /dev/null +++ b/arch/powerpc/sysdev/mpc52xx_pic.c @@ -0,0 +1,538 @@ +/* + * + * Programmable Interrupt Controller functions for the Freescale MPC52xx. + * + * Copyright (C) 2006 bplan GmbH + * + * Based on the code from the 2.4 kernel by + * Dale Farnsworth and Kent Borg. + * + * Copyright (C) 2004 Sylvain Munaut + * Copyright (C) 2003 Montavista Software, Inc + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * +*/ + +static struct mpc52xx_intr __iomem *intr; +static struct mpc52xx_sdma __iomem *sdma; +static struct irq_host *mpc52xx_irqhost = NULL; + +static unsigned char mpc52xx_map_senses[4] = { + IRQ_TYPE_LEVEL_HIGH, + IRQ_TYPE_EDGE_RISING, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_LEVEL_LOW, +}; + +/* + * +*/ + +static inline void io_be_setbit(u32 __iomem * addr, int bitno) +{ + out_be32(addr, in_be32(addr) | (1 << bitno)); +} + +static inline void io_be_clrbit(u32 __iomem * addr, int bitno) +{ + out_be32(addr, in_be32(addr) & ~(1 << bitno)); +} + +/* + * IRQ[0-3] interrupt irq_chip +*/ + +static void mpc52xx_extirq_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->ctrl, 11 - l2irq); +} + +static void mpc52xx_extirq_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->ctrl, 11 - l2irq); +} + +static void mpc52xx_extirq_ack(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->ctrl, 27 - l2irq); +} + +static struct irq_chip mpc52xx_extirq_irqchip = { + .typename = " MPC52xx IRQ[0-3] ", + .mask = mpc52xx_extirq_mask, + .unmask = mpc52xx_extirq_unmask, + .ack = mpc52xx_extirq_ack, +}; + +/* + * Main interrupt irq_chip +*/ + +static void mpc52xx_main_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->main_mask, 15 - l2irq); +} + +static void mpc52xx_main_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->main_mask, 15 - l2irq); +} + +static struct irq_chip mpc52xx_main_irqchip = { + .typename = "MPC52xx Main", + .mask = mpc52xx_main_mask, + .mask_ack = mpc52xx_main_mask, + .unmask = mpc52xx_main_unmask, +}; + +/* + * Peripherals interrupt irq_chip +*/ + +static void mpc52xx_periph_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->per_mask, 31 - l2irq); +} + +static void mpc52xx_periph_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->per_mask, 31 - l2irq); +} + +static struct irq_chip mpc52xx_periph_irqchip = { + .typename = "MPC52xx Peripherals", + .mask = mpc52xx_periph_mask, + .mask_ack = mpc52xx_periph_mask, + .unmask = mpc52xx_periph_unmask, +}; + +/* + * SDMA interrupt irq_chip +*/ + +static void mpc52xx_sdma_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&sdma->IntMask, l2irq); +} + +static void mpc52xx_sdma_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&sdma->IntMask, l2irq); +} + +static void mpc52xx_sdma_ack(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + out_be32(&sdma->IntPend, 1 << l2irq); +} + +static struct irq_chip mpc52xx_sdma_irqchip = { + .typename = "MPC52xx SDMA", + .mask = mpc52xx_sdma_mask, + .unmask = mpc52xx_sdma_unmask, + .ack = mpc52xx_sdma_ack, +}; + +/* + * irq_host +*/ + +static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node) +{ + pr_debug("%s: node=%p\n", __func__, node); + return mpc52xx_irqhost->host_data == node; +} + +static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, + u32 * intspec, unsigned int intsize, + irq_hw_number_t * out_hwirq, + unsigned int *out_flags) +{ + int intrvect_l1; + int intrvect_l2; + int intrvect_type; + int intrvect_linux; + + if (intsize != 3) + return -1; + + intrvect_l1 = (int)intspec[0]; + intrvect_l2 = (int)intspec[1]; + intrvect_type = (int)intspec[2]; + + intrvect_linux = + (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; + intrvect_linux |= + (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK; + + pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1, + intrvect_l2); + + *out_hwirq = intrvect_linux; + *out_flags = mpc52xx_map_senses[intrvect_type]; + + return 0; +} + +/* + * this function retrieves the correct IRQ type out + * of the MPC regs + * Only externals IRQs needs this +*/ +static int mpc52xx_irqx_gettype(int irq) +{ + int type; + u32 ctrl_reg; + + ctrl_reg = in_be32(&intr->ctrl); + type = (ctrl_reg >> (22 - irq * 2)) & 0x3; + + return mpc52xx_map_senses[type]; +} + +static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t irq) +{ + int l1irq; + int l2irq; + struct irq_chip *good_irqchip; + void *good_handle; + int type; + + l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + /* + * Most of ours IRQs will be level low + * Only external IRQs on some platform may be others + */ + type = IRQ_TYPE_LEVEL_LOW; + + switch (l1irq) { + case MPC52xx_IRQ_L1_CRIT: + pr_debug("%s: Critical. l2=%x\n", __func__, l2irq); + + BUG_ON(l2irq != 0); + + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + break; + + case MPC52xx_IRQ_L1_MAIN: + pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq); + + if ((l2irq >= 1) && (l2irq <= 3)) { + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + } else { + good_irqchip = &mpc52xx_main_irqchip; + } + break; + + case MPC52xx_IRQ_L1_PERP: + pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_periph_irqchip; + break; + + case MPC52xx_IRQ_L1_SDMA: + pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_sdma_irqchip; + break; + + default: + pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq); + printk(KERN_ERR "Unknow IRQ!\n"); + return -EINVAL; + } + + switch (type) { + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_RISING: + good_handle = handle_edge_irq; + break; + default: + good_handle = handle_level_irq; + } + + set_irq_chip_and_handler(virq, good_irqchip, good_handle); + + pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq, + (int)irq, type); + + return 0; +} + +static struct irq_host_ops mpc52xx_irqhost_ops = { + .match = mpc52xx_irqhost_match, + .xlate = mpc52xx_irqhost_xlate, + .map = mpc52xx_irqhost_map, +}; + +/* + * init (public) +*/ + +void __init mpc52xx_init_irq(void) +{ + struct device_node *picnode = NULL; + int picnode_regsize; + u32 picnode_regoffset; + + struct device_node *sdmanode = NULL; + int sdmanode_regsize; + u32 sdmanode_regoffset; + + u64 size64; + int flags; + + u32 intr_ctrl; + + picnode = of_find_compatible_node(NULL, "interrupt-controller", + "mpc5200-pic"); + if (picnode == NULL) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to find the interrupt controller " + "in the OpenFirmware device tree\n"); + goto end; + } + + sdmanode = of_find_compatible_node(NULL, "dma-controller", + "mpc5200-bestcomm"); + if (sdmanode == NULL) { + printk(KERN_ERR "MPC52xx PIC" + "Unable to find the Bestcomm DMA controller device " + "in the OpenFirmware device tree\n"); + goto end; + } + + /* Retrieve PIC ressources */ + picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags); + if (picnode_regoffset == 0) { + printk(KERN_ERR "MPC52xx PIC" + "Unable to get the interrupt controller address\n"); + goto end; + } + + picnode_regoffset = + of_translate_address(picnode, (u32 *) picnode_regoffset); + picnode_regsize = (int)size64; + + /* Retrieve SDMA ressources */ + sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags); + if (sdmanode_regoffset == 0) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to get the Bestcomm DMA controller address\n"); + goto end; + } + + sdmanode_regoffset = + of_translate_address(sdmanode, (u32 *) sdmanode_regoffset); + sdmanode_regsize = (int)size64; + + /* Remap the necessary zones */ + intr = ioremap(picnode_regoffset, picnode_regsize); + if (intr == NULL) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to ioremap interrupt controller registers!\n"); + goto end; + } + + sdma = ioremap(sdmanode_regoffset, sdmanode_regsize); + if (sdma == NULL) { + iounmap(intr); + printk(KERN_ERR "MPC52xx PIC: " + "Unable to ioremap Bestcomm DMA registers!\n"); + goto end; + } + + printk(KERN_INFO "MPC52xx PIC: MPC52xx PIC Remapped at 0x%8.8x\n", + picnode_regoffset); + printk(KERN_INFO "MPC52xx PIC: MPC52xx SDMA Remapped at 0x%8.8x\n", + sdmanode_regoffset); + + /* Disable all interrupt sources. */ + out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ + out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ + out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */ + out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */ + intr_ctrl = in_be32(&intr->ctrl); + intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */ + intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */ + 0x00001000 | /* MEE master external enable */ + 0x00000000 | /* 0 means disable IRQ 0-3 */ + 0x00000001; /* CEb route critical normally */ + out_be32(&intr->ctrl, intr_ctrl); + + /* Zero a bunch of the priority settings. */ + out_be32(&intr->per_pri1, 0); + out_be32(&intr->per_pri2, 0); + out_be32(&intr->per_pri3, 0); + out_be32(&intr->main_pri1, 0); + out_be32(&intr->main_pri2, 0); + + /* + * As last step, add an irq host to translate the real + * hw irq information provided by the ofw to linux virq + */ + + mpc52xx_irqhost = + irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTHWIRQ, + &mpc52xx_irqhost_ops, -1); + + if (mpc52xx_irqhost) { + mpc52xx_irqhost->host_data = picnode; + printk(KERN_INFO "MPC52xx PIC is up and running!\n"); + } else { + printk(KERN_ERR + "MPC52xx PIC: Unable to allocate the IRQ host\n"); + } + +end: + of_node_put(picnode); + of_node_put(sdmanode); +} + +/* + * get_irq (public) +*/ +unsigned int mpc52xx_get_irq(void) +{ + u32 status; + int irq = NO_IRQ_IGNORE; + + status = in_be32(&intr->enc_status); + if (status & 0x00000400) { /* critical */ + irq = (status >> 8) & 0x3; + if (irq == 2) /* high priority peripheral */ + goto peripheral; + irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else if (status & 0x00200000) { /* main */ + irq = (status >> 16) & 0x1f; + if (irq == 4) /* low priority peripheral */ + goto peripheral; + irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else if (status & 0x20000000) { /* peripheral */ + peripheral: + irq = (status >> 24) & 0x1f; + if (irq == 0) { /* bestcomm */ + status = in_be32(&sdma->IntPend); + irq = ffs(status) - 1; + irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else + irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } + + pr_debug("%s: irq=%x. virq=%d\n", __func__, irq, + irq_linear_revmap(mpc52xx_irqhost, irq)); + + return irq_linear_revmap(mpc52xx_irqhost, irq); +} + -- cgit v1.2.3 From c37858d333a50815c74349396e31a535f4128e0b Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Sun, 5 Nov 2006 12:57:16 +0100 Subject: [PATCH] Add Efika platform support Add Efika (http://www.bplan-gmbh.de/efika_spec_en.html) platform support for arch/powerpc. Signed-off-by: Nicolas DET Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 8 ++ arch/powerpc/platforms/Makefile | 1 + arch/powerpc/platforms/efika/Makefile | 1 + arch/powerpc/platforms/efika/efika.h | 19 +++++ arch/powerpc/platforms/efika/pci.c | 119 +++++++++++++++++++++++++++ arch/powerpc/platforms/efika/setup.c | 149 ++++++++++++++++++++++++++++++++++ 6 files changed, 297 insertions(+) create mode 100644 arch/powerpc/platforms/efika/Makefile create mode 100644 arch/powerpc/platforms/efika/efika.h create mode 100644 arch/powerpc/platforms/efika/pci.c create mode 100644 arch/powerpc/platforms/efika/setup.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7107d472413..a41d191bf1b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -386,6 +386,14 @@ config PPC_CHRP select PPC_UDBG_16550 default y +config PPC_EFIKA + bool "bPlan Efika 5k2. MPC5200B based computer" + depends on PPC_MULTIPLATFORM && PPC32 + select PPC_RTAS + select RTAS_PROC + select PPC_MPC52xx + default y + config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_MULTIPLATFORM diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index e58fa953a50..7ad2673d0aa 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -5,6 +5,7 @@ ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif endif +obj-$(CONFIG_PPC_EFIKA) += efika/ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_83xx) += 83xx/ diff --git a/arch/powerpc/platforms/efika/Makefile b/arch/powerpc/platforms/efika/Makefile new file mode 100644 index 00000000000..17b2a781fba --- /dev/null +++ b/arch/powerpc/platforms/efika/Makefile @@ -0,0 +1 @@ +obj-y += setup.o mpc52xx.o pci.o diff --git a/arch/powerpc/platforms/efika/efika.h b/arch/powerpc/platforms/efika/efika.h new file mode 100644 index 00000000000..2f060fd097d --- /dev/null +++ b/arch/powerpc/platforms/efika/efika.h @@ -0,0 +1,19 @@ +/* + * Efika 5K2 platform setup - Header file + * + * Copyright (C) 2006 bplan GmbH + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#ifndef __ARCH_POWERPC_EFIKA__ +#define __ARCH_POWERPC_EFIKA__ + +#define EFIKA_PLATFORM_NAME "Efika" + +extern void __init efika_pcisetup(void); + +#endif diff --git a/arch/powerpc/platforms/efika/pci.c b/arch/powerpc/platforms/efika/pci.c new file mode 100644 index 00000000000..62e05b2a922 --- /dev/null +++ b/arch/powerpc/platforms/efika/pci.c @@ -0,0 +1,119 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "efika.h" + +#ifdef CONFIG_PCI +/* + * Access functions for PCI config space using RTAS calls. + */ +static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 * val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int ret = -1; + int rval; + + rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); + *val = ret; + return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static int rtas_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int rval; + + rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, + addr, len, val); + return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rtas_pci_ops = { + rtas_read_config, + rtas_write_config +}; + +void __init efika_pcisetup(void) +{ + const int *bus_range; + int len; + struct pci_controller *hose; + struct device_node *root; + struct device_node *pcictrl; + + root = of_find_node_by_path("/"); + if (root == NULL) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Unable to find the root node\n"); + return; + } + + for (pcictrl = NULL;;) { + pcictrl = of_get_next_child(root, pcictrl); + if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) + break; + } + + of_node_put(root); + + if (pcictrl == NULL) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Unable to find the PCI bridge node\n"); + return; + } + + bus_range = get_property(pcictrl, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Can't get bus-range for %s\n", pcictrl->full_name); + return; + } + + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", + bus_range[0]); + else + printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s\n", pcictrl->full_name); + printk("\n"); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Can't allocate PCI controller structure for %s\n", + pcictrl->full_name); + return; + } + + hose->arch_data = of_node_get(pcictrl); + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + hose->ops = &rtas_pci_ops; + + pci_process_bridge_OF_ranges(hose, pcictrl, 0); +} + +#else +void __init efika_pcisetup(void) +{} +#endif diff --git a/arch/powerpc/platforms/efika/setup.c b/arch/powerpc/platforms/efika/setup.c new file mode 100644 index 00000000000..3bc1b5fe0ce --- /dev/null +++ b/arch/powerpc/platforms/efika/setup.c @@ -0,0 +1,149 @@ +/* + * + * Efika 5K2 platform setup + * Some code really inspired from the lite5200b platform. + * + * Copyright (C) 2006 bplan GmbH + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "efika.h" + +static void efika_show_cpuinfo(struct seq_file *m) +{ + struct device_node *root; + const char *revision = NULL; + const char *codegendescription = NULL; + const char *codegenvendor = NULL; + + root = of_find_node_by_path("/"); + if (root) { + revision = get_property(root, "revision", NULL); + codegendescription = + get_property(root, "CODEGEN,description", NULL); + codegenvendor = get_property(root, "CODEGEN,vendor", NULL); + + of_node_put(root); + } + + if (codegendescription) + seq_printf(m, "machine\t\t: %s\n", codegendescription); + else + seq_printf(m, "machine\t\t: Efika\n"); + + if (revision) + seq_printf(m, "revision\t: %s\n", revision); + + if (codegenvendor) + seq_printf(m, "vendor\t\t: %s\n", codegenvendor); + + of_node_put(root); +} + +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(); + + if (ppc_md.progress) + ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0); +} + +static void __init efika_init(void) +{ + struct device_node *np; + struct device_node *cnp = NULL; + const u32 *base; + + /* Find every child of the SOC node and add it to of_platform */ + np = of_find_node_by_name(NULL, "builtin"); + if (np) { + char name[BUS_ID_SIZE]; + while ((cnp = of_get_next_child(np, cnp))) { + strcpy(name, cnp->name); + + base = get_property(cnp, "reg", NULL); + if (base == NULL) + continue; + + snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base); + of_platform_device_create(cnp, name, NULL); + + printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name); + } + } + + if (ppc_md.progress) + ppc_md.progress(" Have fun with your Efika! ", 0x7777); +} + +static int __init efika_probe(void) +{ + char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), + "model", NULL); + + if (model == NULL) + return 0; + if (strcmp(model, "EFIKA5K2")) + return 0; + + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + return 1; +} + +define_machine(efika) +{ + .name = EFIKA_PLATFORM_NAME, + .probe = efika_probe, + .setup_arch = efika_setup_arch, + .init = efika_init, + .show_cpuinfo = efika_show_cpuinfo, + .init_IRQ = mpc52xx_init_irq, + .get_irq = mpc52xx_get_irq, + .restart = rtas_restart, + .power_off = rtas_power_off, + .halt = rtas_halt, + .set_rtc_time = rtas_set_rtc_time, + .get_rtc_time = rtas_get_rtc_time, + .progress = rtas_progress, + .get_boot_time = rtas_get_boot_time, + .calibrate_decr = generic_calibrate_decr, + .phys_mem_access_prot = pci_phys_mem_access_prot, +}; -- cgit v1.2.3 From a9b14973a8c42b2aecc968851372203c6567e196 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Thu, 19 Oct 2006 19:52:26 -0500 Subject: [PATCH] Slight refactor of interrupt mapping for FSL parts * Cleaned up interrupt mapping a little by adding a helper function which parses the irq out of the device-tree, and puts it into a resource. * Changed the arch/ppc platform files to specify PHY_POLL, instead of -1 * Changed the fixed phy to use PHY_IGNORE_INTERRUPT * Added ethtool.h and mii.h to phy.h includes Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/fsl_soc.c | 28 +++++++++++----------------- arch/ppc/platforms/83xx/mpc834x_sys.c | 4 ++-- arch/ppc/platforms/85xx/mpc8540_ads.c | 4 ++-- arch/ppc/platforms/85xx/mpc8560_ads.c | 4 ++-- arch/ppc/platforms/85xx/mpc85xx_cds_common.c | 6 +++--- arch/ppc/platforms/85xx/sbc8560.c | 2 +- arch/ppc/platforms/85xx/stx_gp3.c | 2 +- arch/ppc/platforms/85xx/tqm85xx.c | 4 ++-- arch/ppc/platforms/mpc8272ads_setup.c | 6 +++--- arch/ppc/platforms/mpc866ads_setup.c | 4 ++-- 10 files changed, 29 insertions(+), 35 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index dbe92ae2033..ad31e56e892 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -146,7 +147,7 @@ static int __init gfar_mdio_of_init(void) } for (k = 0; k < 32; k++) - mdio_data.irq[k] = -1; + mdio_data.irq[k] = PHY_POLL; while ((child = of_get_next_child(np, child)) != NULL) { int irq = irq_of_parse_and_map(child, 0); @@ -177,6 +178,7 @@ static const char *gfar_tx_intr = "tx"; static const char *gfar_rx_intr = "rx"; static const char *gfar_err_intr = "error"; + static int __init gfar_of_init(void) { struct device_node *np; @@ -204,8 +206,7 @@ static int __init gfar_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[1]); model = get_property(np, "model", NULL); @@ -214,12 +215,10 @@ static int __init gfar_of_init(void) r[1].name = gfar_tx_intr; r[2].name = gfar_rx_intr; - r[2].start = r[2].end = irq_of_parse_and_map(np, 1); - r[2].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 1, &r[2]); r[3].name = gfar_err_intr; - r[3].start = r[3].end = irq_of_parse_and_map(np, 2); - r[3].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 2, &r[3]); n_res += 2; } @@ -323,8 +322,7 @@ static int __init fsl_i2c_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[1]); i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); if (IS_ERR(i2c_dev)) { @@ -459,8 +457,7 @@ static int __init fsl_usb_of_init(void) if (ret) goto err; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[1]); usb_dev_mph = platform_device_register_simple("fsl-ehci", i, r, 2); @@ -507,8 +504,7 @@ static int __init fsl_usb_of_init(void) if (ret) goto unreg_mph; - r[1].start = r[1].end = irq_of_parse_and_map(np, 0); - r[1].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[1]); usb_dev_dr = platform_device_register_simple("fsl-ehci", i, r, 2); @@ -591,8 +587,7 @@ static int __init fs_enet_of_init(void) r[2].name = fcc_regs_c; fs_enet_data.fcc_regs_c = r[2].start; - r[3].start = r[3].end = irq_of_parse_and_map(np, 0); - r[3].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[3]); fs_enet_dev = platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); @@ -754,8 +749,7 @@ static int __init cpm_uart_of_init(void) goto err; r[1].name = scc_pram; - r[2].start = r[2].end = irq_of_parse_and_map(np, 0); - r[2].flags = IORESOURCE_IRQ; + of_irq_to_resource(np, 0, &r[2]); cpm_uart_dev = platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 3397f0de159..b84f8df325c 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c @@ -121,8 +121,8 @@ mpc834x_sys_setup_arch(void) mdata->irq[0] = MPC83xx_IRQ_EXT1; mdata->irq[1] = MPC83xx_IRQ_EXT2; - mdata->irq[2] = -1; - mdata->irq[31] = -1; + mdata->irq[2] = PHY_POLL; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 4f839da6782..00a3ba57063 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -92,9 +92,9 @@ mpc8540ads_setup_arch(void) mdata->irq[0] = MPC85xx_IRQ_EXT5; mdata->irq[1] = MPC85xx_IRQ_EXT5; - mdata->irq[2] = -1; + mdata->irq[2] = PHY_POLL; mdata->irq[3] = MPC85xx_IRQ_EXT5; - mdata->irq[31] = -1; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c index 14ecec7bbed..3a060468dd9 100644 --- a/arch/ppc/platforms/85xx/mpc8560_ads.c +++ b/arch/ppc/platforms/85xx/mpc8560_ads.c @@ -156,9 +156,9 @@ mpc8560ads_setup_arch(void) mdata->irq[0] = MPC85xx_IRQ_EXT5; mdata->irq[1] = MPC85xx_IRQ_EXT5; - mdata->irq[2] = -1; + mdata->irq[2] = PHY_POLL; mdata->irq[3] = MPC85xx_IRQ_EXT5; - mdata->irq[31] = -1; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index 5ce0f69c1db..2d59eb776c9 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c @@ -451,9 +451,9 @@ mpc85xx_cds_setup_arch(void) mdata->irq[0] = MPC85xx_IRQ_EXT5; mdata->irq[1] = MPC85xx_IRQ_EXT5; - mdata->irq[2] = -1; - mdata->irq[3] = -1; - mdata->irq[31] = -1; + mdata->irq[2] = PHY_POLL; + mdata->irq[3] = PHY_POLL; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index 764d580ff53..1d10ab98f66 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c @@ -129,7 +129,7 @@ sbc8560_setup_arch(void) mdata->irq[25] = MPC85xx_IRQ_EXT6; mdata->irq[26] = MPC85xx_IRQ_EXT7; - mdata->irq[31] = -1; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c index 4bb18ab2767..b1f5b737c70 100644 --- a/arch/ppc/platforms/85xx/stx_gp3.c +++ b/arch/ppc/platforms/85xx/stx_gp3.c @@ -123,7 +123,7 @@ gp3_setup_arch(void) mdata->irq[2] = MPC85xx_IRQ_EXT5; mdata->irq[4] = MPC85xx_IRQ_EXT5; - mdata->irq[31] = -1; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c index dd45f2e1844..4ee2bd156dc 100644 --- a/arch/ppc/platforms/85xx/tqm85xx.c +++ b/arch/ppc/platforms/85xx/tqm85xx.c @@ -137,9 +137,9 @@ tqm85xx_setup_arch(void) mdata->irq[0] = MPC85xx_IRQ_EXT8; mdata->irq[1] = MPC85xx_IRQ_EXT8; - mdata->irq[2] = -1; + mdata->irq[2] = PHY_POLL; mdata->irq[3] = MPC85xx_IRQ_EXT8; - mdata->irq[31] = -1; + mdata->irq[31] = PHY_POLL; /* setup the board related information for the enet controllers */ pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c index 1f9ea36837b..0bc06768cf2 100644 --- a/arch/ppc/platforms/mpc8272ads_setup.c +++ b/arch/ppc/platforms/mpc8272ads_setup.c @@ -266,10 +266,10 @@ static void __init mpc8272ads_fixup_mdio_pdata(struct platform_device *pdev, int idx) { m82xx_mii_bb_pdata.irq[0] = PHY_INTERRUPT; - m82xx_mii_bb_pdata.irq[1] = -1; - m82xx_mii_bb_pdata.irq[2] = -1; + m82xx_mii_bb_pdata.irq[1] = PHY_POLL; + m82xx_mii_bb_pdata.irq[2] = PHY_POLL; m82xx_mii_bb_pdata.irq[3] = PHY_INTERRUPT; - m82xx_mii_bb_pdata.irq[31] = -1; + m82xx_mii_bb_pdata.irq[31] = PHY_POLL; m82xx_mii_bb_pdata.mdio_dat.offset = diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c index e95d2c11174..8a0c07eb444 100644 --- a/arch/ppc/platforms/mpc866ads_setup.c +++ b/arch/ppc/platforms/mpc866ads_setup.c @@ -361,7 +361,7 @@ int __init mpc866ads_init(void) fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; /* No PHY interrupt line here */ - fmpi->irq[0xf] = -1; + fmpi->irq[0xf] = PHY_POLL; /* Since either of the uarts could be used as console, they need to ready */ #ifdef CONFIG_SERIAL_CPM_SMC1 @@ -380,7 +380,7 @@ int __init mpc866ads_init(void) fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; /* No PHY interrupt line here */ - fmpi->irq[0xf] = -1; + fmpi->irq[0xf] = PHY_POLL; return 0; } -- cgit v1.2.3 From a416dd8d9cd3a3fa77b9839e0e6fc3c54927d8c3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 8 Nov 2006 10:22:59 +1100 Subject: [PATCH] Do a single one-line printk in bad_page_fault() bad_page_fault() prints a message telling the user what type of bad fault we took. The first line of this message is currently implemented as two separate printks. This has the unfortunate effect that if several cpus simultaneously take a bad fault, the first and second parts of the printk get jumbled up, which looks dodge and is hard to read. So do a single one-line printk for each fault type. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/mm/fault.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index e8fa50624b7..03aeb3a4607 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -426,18 +426,21 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) /* kernel has accessed a bad area */ - printk(KERN_ALERT "Unable to handle kernel paging request for "); switch (regs->trap) { - case 0x300: - case 0x380: - printk("data at address 0x%08lx\n", regs->dar); - break; - case 0x400: - case 0x480: - printk("instruction fetch\n"); - break; - default: - printk("unknown fault\n"); + case 0x300: + case 0x380: + printk(KERN_ALERT "Unable to handle kernel paging request for " + "data at address 0x%08lx\n", regs->dar); + break; + case 0x400: + case 0x480: + printk(KERN_ALERT "Unable to handle kernel paging request for " + "instruction fetch\n"); + break; + default: + printk(KERN_ALERT "Unable to handle kernel paging request for " + "unknown fault\n"); + break; } printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n", regs->nip); -- cgit v1.2.3 From e9c4b4bd56a7dfdc8879a5876e498991c9194321 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 8 Nov 2006 17:50:44 -0700 Subject: [PATCH] Remove dtb file created by wrapper script When the wrapper script is passed a dts file, it runs 'dtc' to create a dtb file. This patch deletes that dtb file once its no longer needed. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/wrapper | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index b5fb1fee76f..024e4d425c5 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -184,6 +184,9 @@ fi if [ -n "$dtb" ]; then addsec $tmp "$dtb" .kernel:dtb + if [ -n "$dts" ]; then + rm $dtb + fi fi if [ "$platform" != "miboot" ]; then -- cgit v1.2.3 From 25787afa5c16d35cdfb191f63a3a406b3206744e Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Wed, 8 Nov 2006 17:52:25 -0700 Subject: [PATCH] Remove arch/powerpc/boot/zImage file. The bootwrapper Makefile does not clean up the 'zImage' file that may be left laying around. This patch removes it when cleaning that directory. Signed-off-by: Mark A. Greer Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 789def38af4..042bac319be 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -75,7 +75,7 @@ $(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S @cp $< $@ clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ - empty.c zImage.coff.lds zImage.lds zImage.sandpoint + empty.c zImage zImage.coff.lds zImage.lds zImage.sandpoint quiet_cmd_bootcc = BOOTCC $@ cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< -- cgit v1.2.3 From 0613ffbf53625ccecb96500b1cc7b0ef70cc8f04 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 9 Nov 2006 18:53:52 +0100 Subject: [PATCH] Fix compile warnings with CONFIG_PM=n Fix compile warnings with CONFIG_PM=n arch/powerpc/platforms/powermac/feature.c:489: warning: 'save_gpio_levels' defined but not used arch/powerpc/platforms/powermac/feature.c:490: warning: 'save_gpio_extint' defined but not used arch/powerpc/platforms/powermac/feature.c:491: warning: 'save_gpio_normal' defined but not used arch/powerpc/platforms/powermac/feature.c:492: warning: 'save_unin_clock_ctl' defined but not used Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/powermac/feature.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index e49621be664..c29a6a064d2 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c @@ -486,10 +486,6 @@ static long heathrow_sound_enable(struct device_node *node, long param, static u32 save_fcr[6]; static u32 save_mbcr; -static u32 save_gpio_levels[2]; -static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; -static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; -static u32 save_unin_clock_ctl; static struct dbdma_regs save_dbdma[13]; static struct dbdma_regs save_alt_dbdma[13]; @@ -1548,6 +1544,10 @@ void g5_phy_disable_cpu1(void) #ifdef CONFIG_PM +static u32 save_gpio_levels[2]; +static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT]; +static u8 save_gpio_normal[KEYLARGO_GPIO_CNT]; +static u32 save_unin_clock_ctl; static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode) { -- cgit v1.2.3 From fc9e8b4e275b6882cb537154c8fc7cde3692eea0 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 9 Nov 2006 15:42:44 -0600 Subject: [PATCH] Optimize qe_brg struct to use an array The qe_brg structure manually defined each of the 16 BRG registers, which made any code that used them cumbersome. This patch replaces the fields with a single 16-element array. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/qe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index 2bae632d3ad..812c87c73bb 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c @@ -175,8 +175,7 @@ void qe_setbrg(u32 brg, u32 rate) u32 divisor, tempval; int div16 = 0; - bp = &qe_immr->brg.brgc1; - bp += brg; + bp = &qe_immr->brg.brgc[brg]; divisor = (get_brg_clk() / rate); if (divisor > QE_BRGC_DIVISOR_MAX + 1) { -- cgit v1.2.3 From 57744ea95edd340d7140852ce86c743df2cd588c Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Fri, 10 Nov 2006 12:01:02 -0800 Subject: [PATCH] Check for null init_early routine Add a check for a null ppc_md.init_early to allow platforms that don't require an init_early routine to just set this member to null. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/setup_64.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index ae6b67ce54e..2fef772edfc 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -380,7 +380,8 @@ void __init setup_system(void) * setting up the hash table pointers. It also sets up some interrupt-mapping * related options that will be used by finish_device_tree() */ - ppc_md.init_early(); + if (ppc_md.init_early) + ppc_md.init_early(); /* * We can discover serial ports now since the above did setup the -- cgit v1.2.3 From b61c5509fe8f6c665c146ab14f960000d4a5d1a9 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 10 Nov 2006 18:08:30 -0600 Subject: [PATCH] Make git ignore new wrapper generated files The new 'wrapper' code generates files that git should ignore; add them to .gitignore. Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/boot/.gitignore | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore index 45c9ad23526..590e72f06d5 100644 --- a/arch/powerpc/boot/.gitignore +++ b/arch/powerpc/boot/.gitignore @@ -1,20 +1,27 @@ addnote +empty.c +hack-coff infblock.c infblock.h infcodes.c infcodes.h inffast.c inffast.h +inffixed.h inflate.c +inflate.h inftrees.c inftrees.h infutil.c infutil.h kernel-vmlinux.strip.c kernel-vmlinux.strip.gz +mktree uImage zImage zImage.vmode +zImage.coff.lds +zImage.lds zconf.h zlib.h zutil.h -- cgit v1.2.3 From 1a4b0fc503ff4149f5915be4aeb179b9453cf485 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Fri, 10 Nov 2006 12:27:49 -0800 Subject: [PATCH] mspec driver build fix Fix MSPEC driver to build for non SN2 enabled configs as the driver should work in cached and uncached modes (no fetchop) on these systems. In addition make MSPEC select IA64_UNCACHED_ALLOCATOR, which is required for it and move it to arch/ia64/Kconfig to avoid warnings on non ia64 architectures running allmodconfig. Once the Kconfig code is fixed, we can move it back. Signed-off-by: Jes Sorensen Cc: Fernando Luis Vzquez Cao Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 14682396f7f..683b12c6f76 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -484,6 +484,15 @@ source "net/Kconfig" source "drivers/Kconfig" +config MSPEC + tristate "Memory special operations driver" + depends on IA64 + select IA64_UNCACHED_ALLOCATOR + help + If you have an ia64 and you want to enable memory special + operations support (formerly known as fetchop), say Y here, + otherwise say N. + source "fs/Kconfig" source "lib/Kconfig" -- cgit v1.2.3 From aa8d18731508bb0a16f69b77e5f4541f0d6fb553 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 14 Nov 2006 15:15:40 +0000 Subject: [ARM] Remove OP_MAX_COUNTER OP_MAX_COUNTER never referenced, and is a reminant of an earlier oprofile implementation. Remove it. Signed-off-by: Russell King --- arch/arm/oprofile/op_counter.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/oprofile/op_counter.h b/arch/arm/oprofile/op_counter.h index 8c5351d751c..ca942a63b52 100644 --- a/arch/arm/oprofile/op_counter.h +++ b/arch/arm/oprofile/op_counter.h @@ -10,8 +10,6 @@ #ifndef OP_COUNTER_H #define OP_COUNTER_H -#define OP_MAX_COUNTER 5 - /* Per performance monitor configuration as set via * oprofilefs. */ -- cgit v1.2.3 From 64e72e41acae0dab733fb0d5d789b76d115210c0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:56:33 +0100 Subject: Revert "[PATCH] MMCONFIG and new Intel motherboards" This reverts 4c6e052adfe285ede5884e4e8c4d33af33932c13 commit. Following Linus' i386 change: revert resource reservation for mmcfg config now. Will be revisited in .20 hopefully. --- arch/x86_64/pci/mmconfig.c | 32 -------------------------------- 1 file changed, 32 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index e61093b34c2..f8b6b2800a6 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -163,37 +163,6 @@ static __init void unreachable_devices(void) } } -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - void __init pci_mmcfg_init(int type) { int i; @@ -237,7 +206,6 @@ void __init pci_mmcfg_init(int type) } unreachable_devices(); - pci_mmcfg_insert_resources(); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; -- cgit v1.2.3 From 14f448e36192d6d2cd7dfd81cb044977b2f9dd9b Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 14 Nov 2006 16:57:45 +0100 Subject: [PATCH] x86-64: Fix partial page check to ensure unusable memory is not being marked usable. Fix partial page check in e820_register_active_regions to ensure partial pages are not being marked as active in the memory pool. Signed-off-by: Aaron Durbin Signed-off-by: Andi Kleen --- arch/x86_64/kernel/e820.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index a75c829c2b0..855b5611318 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -278,7 +278,7 @@ e820_register_active_regions(int nid, unsigned long start_pfn, >> PAGE_SHIFT; /* Skip map entries smaller than a page */ - if (ei_startpfn > ei_endpfn) + if (ei_startpfn >= ei_endpfn) continue; /* Check if end_pfn_map should be updated */ -- cgit v1.2.3 From 14679eb3c50897889ba62f9a37e3bcd8a205b5e7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Fix PTRACE_[SG]ET_THREAD_AREA regression with ia32 emulation. ptrace(PTRACE_[SG]ET_THREAD_AREA) calls from ia32 code should be passed onto the x86_64 implementation. The default case in sys32_ptrace used to call to sys_ptrace(), but is now EINVAL. This patch fixes a regression caused by that changed. Signed-off-by: Mike McCormack Signed-off-by: Andi Kleen --- arch/x86_64/ia32/ptrace32.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index 3a7561d4703..04566fe5de4 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -244,6 +244,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) case PTRACE_DETACH: case PTRACE_SYSCALL: case PTRACE_SETOPTIONS: + case PTRACE_SET_THREAD_AREA: + case PTRACE_GET_THREAD_AREA: return sys_ptrace(request, pid, addr, data); default: -- cgit v1.2.3 From 51d67a488b53a5cc8401460480c124eaec71e2d4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: shorten the x86_64 boot setup GDT to what the comment says Stephen Tweedie, Herbert Xu, and myself have been struggling with a very nasty bug in Xen. But it also pointed out a small bug in the x86_64 kernel boot setup. The GDT limit being setup by the initial bzImage code when entering into protected mode is way too big. The comment by the code states that the size of the GDT is 2048, but the actual size being set up is much bigger (32768). This happens simply because of one extra '0'. Instead of setting up a 0x800 size, 0x8000 is set up. On bare metal this is fine because the CPU wont load any segments unless they are explicitly used. But unfortunately, this breaks Xen on vmx FV, since it (for now) blindly loads all the segments into the VMCS if they are less than the gdt limit. Since the real mode segments are around 0x3000, we are getting junk into the VMCS and that later causes an exception. Stephen Tweedie has written up a patch to fix the Xen side and will be submitting that to those folks. But that doesn't excuse the GDT limit being a magnitude too big. AK: changed to compute true gdt size in assembler, fixed comment Signed-off-by: Steven Rostedt Signed-off-by: Andi Kleen --- arch/x86_64/boot/setup.S | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S index c3bfd223ab4..770940cc010 100644 --- a/arch/x86_64/boot/setup.S +++ b/arch/x86_64/boot/setup.S @@ -836,13 +836,12 @@ gdt: .word 0x9200 # data read/write .word 0x00CF # granularity = 4096, 386 # (+5th nibble of limit) +gdt_end: idt_48: .word 0 # idt limit = 0 .word 0, 0 # idt base = 0L gdt_48: - .word 0x8000 # gdt limit=2048, - # 256 GDT entries - + .word gdt_end-gdt-1 # gdt limit .word 0, 0 # gdt base (filled in later) # Include video setup & detection code -- cgit v1.2.3 From 5e58a02a8f6a7a1c9ae41f39286bcd3aea0d6f24 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Handle reserve_bootmem_generic beyond end_pfn This can happen on kexec kernels with some configurations, in particularly on Unisys ES7000 systems. Analysis by Amul Shah Cc: Amul Shah Signed-off-by: Andi Kleen --- arch/x86_64/mm/init.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 971dc1181e6..f1f977aafae 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -655,9 +655,22 @@ void free_initrd_mem(unsigned long start, unsigned long end) void __init reserve_bootmem_generic(unsigned long phys, unsigned len) { - /* Should check here against the e820 map to avoid double free */ #ifdef CONFIG_NUMA int nid = phys_to_nid(phys); +#endif + unsigned long pfn = phys >> PAGE_SHIFT; + if (pfn >= end_pfn) { + /* This can happen with kdump kernels when accessing firmware + tables. */ + if (pfn < end_pfn_map) + return; + printk(KERN_ERR "reserve_bootmem: illegal reserve %lx %u\n", + phys, len); + return; + } + + /* Should check here against the e820 map to avoid double free */ +#ifdef CONFIG_NUMA reserve_bootmem_node(NODE_DATA(nid), phys, len); #else reserve_bootmem(phys, len); -- cgit v1.2.3 From 15803a43288da434d34d41c4ed650c3c1728d42c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: setup saved_max_pfn correctly (kdump) x86_64: setup saved_max_pfn correctly 2.6.19-rc4 has broken CONFIG_CRASH_DUMP support on x86_64. It is impossible to read out the kernel contents from /proc/vmcore because saved_max_pfn is set to zero instead of the max_pfn value before the user map is setup. This happens because saved_max_pfn is initialized at parse_early_param() time, and at this time no active regions have been registered. save_max_pfn is setup from e820_end_of_ram(), more exact find_max_pfn_with_active_regions() which returns 0 because no regions exist. This patch fixes this by registering before and removing after the call to e820_end_of_ram(). Signed-off-by: Magnus Damm Signed-off-by: Andi Kleen --- arch/x86_64/kernel/e820.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 855b5611318..6fe191c5808 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -594,7 +594,9 @@ static int __init parse_memmap_opt(char *p) * size before original memory map is * reset. */ + e820_register_active_regions(0, 0, -1UL); saved_max_pfn = e820_end_of_ram(); + remove_all_active_ranges(); #endif end_pfn_map = 0; e820.nr_map = 0; -- cgit v1.2.3 From fa18f477d0987c011cce047a7c3cd1284f547a14 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86: Add acpi_user_timer_override option for Asus boards Timer overrides are normally disabled on Nvidia board because they are commonly wrong, except on new ones with HPET support. Unfortunately there are quite some Asus boards around that don't have HPET, but need a timer override. We don't know yet how to handle this transparently, but at least add a command line option to force the timer override and let them boot. Cc: len.brown@intel.com Signed-off-by: Andi Kleen --- arch/i386/kernel/acpi/boot.c | 8 ++++++++ arch/i386/kernel/acpi/earlyquirk.c | 8 +++++++- arch/x86_64/kernel/early-quirks.c | 8 ++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 22e4c466e5a..d12fb97a533 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -82,6 +82,7 @@ EXPORT_SYMBOL(acpi_strict); acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; +int acpi_use_timer_override __initdata; #ifdef CONFIG_X86_LOCAL_APIC static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -1300,6 +1301,13 @@ static int __init parse_acpi_skip_timer_override(char *arg) return 0; } early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); + +static int __init parse_acpi_use_timer_override(char *arg) +{ + acpi_use_timer_override = 1; + return 0; +} +early_param("acpi_use_timer_override", parse_acpi_use_timer_override); #endif /* CONFIG_X86_IO_APIC */ static int __init setup_acpi_sci(char *s) diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index fe799b11ac0..c9841692bb7 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -27,11 +27,17 @@ static int __init check_bridge(int vendor, int device) #ifdef CONFIG_ACPI /* According to Nvidia all timer overrides are bogus unless HPET is enabled. */ - if (vendor == PCI_VENDOR_ID_NVIDIA) { + if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + printk(KERN_INFO "If you got timer trouble " + "try acpi_use_timer_override\n"); + } } #endif diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 2b1245d8625..68273bff58c 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -45,7 +45,13 @@ static void nvidia_bugs(void) /* * All timer overrides on Nvidia are * wrong unless HPET is enabled. + * Unfortunately that's not true on many Asus boards. + * We don't know yet how to detect this automatically, but + * at least allow a command line override. */ + if (acpi_use_timer_override) + return; + nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { @@ -53,6 +59,8 @@ static void nvidia_bugs(void) printk(KERN_INFO "Nvidia board " "detected. Ignoring ACPI " "timer override.\n"); + printk(KERN_INFO "If you got timer trouble " + "try acpi_use_timer_override\n"); } #endif /* RED-PEN skip them on mptables too? */ -- cgit v1.2.3 From 8c131af1db510793f87dc43edbc8950a35370df3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Fix vgetcpu when CONFIG_HOTPLUG_CPU is disabled The vgetcpu per CPU initialization previously relied on CPU hotplug events for all CPUs to initialize the per CPU state. That only worked only on kernels with CONFIG_HOTPLUG_CPU enabled. On the others some CPUs didn't get their state initialized properly and vgetcpu wouldn't work. Change the initialization sequence to instead run in a normal initcall (which runs after the normal CPU bootup) and initialize all running CPUs there. Later hotplug CPUs are still handled with an hotplug notifier. This actually simplifies the code somewhat. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smp.c | 3 +-- arch/x86_64/kernel/time.c | 11 ----------- arch/x86_64/kernel/vsyscall.c | 45 ++++++++++++++++++++++++------------------- 3 files changed, 26 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 4f67697f503..9f74c883568 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -376,9 +376,8 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, /* prevent preemption and reschedule on another processor */ int me = get_cpu(); if (cpu == me) { - WARN_ON(1); put_cpu(); - return -EBUSY; + return 0; } spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 88722f11ca1..e3ef544d2cf 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -876,15 +876,6 @@ static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; -static int __cpuinit -time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu) -{ - unsigned cpu = (unsigned long) hcpu; - if (action == CPU_ONLINE) - vsyscall_set_cpu(cpu); - return NOTIFY_DONE; -} - void __init time_init(void) { if (nohpet) @@ -925,8 +916,6 @@ void __init time_init(void) vxtime.last_tsc = get_cycles_sync(); set_cyc2ns_scale(cpu_khz); setup_irq(0, &irq0); - hotcpu_notifier(time_cpu_notifier, 0); - time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id()); #ifndef CONFIG_SMP time_init_gtod(); diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index a98b460af6a..a730bacecb0 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include #include @@ -243,32 +246,17 @@ static ctl_table kernel_root_table2[] = { #endif -static void __cpuinit write_rdtscp_cb(void *info) -{ - write_rdtscp_aux((unsigned long)info); -} - -void __cpuinit vsyscall_set_cpu(int cpu) +/* Assume __initcall executes before all user space. Hopefully kmod + doesn't violate that. We'll find out if it does. */ +static void __cpuinit vsyscall_set_cpu(int cpu) { unsigned long *d; unsigned long node = 0; #ifdef CONFIG_NUMA node = cpu_to_node[cpu]; #endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { - void *info = (void *)((node << 12) | cpu); - /* Can happen on preemptive kernel */ - if (get_cpu() == cpu) - write_rdtscp_cb(info); -#ifdef CONFIG_SMP - else { - /* the notifier is unfortunately not executed on the - target CPU */ - smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); - } -#endif - put_cpu(); - } + if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) + write_rdtscp_aux((node << 12) | cpu); /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. @@ -280,6 +268,21 @@ void __cpuinit vsyscall_set_cpu(int cpu) *d |= (node >> 4) << 48; } +static void __cpuinit cpu_vsyscall_init(void *arg) +{ + /* preemption should be already off */ + vsyscall_set_cpu(raw_smp_processor_id()); +} + +static int __cpuinit +cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) +{ + long cpu = (long)arg; + if (action == CPU_ONLINE) + smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); + return NOTIFY_DONE; +} + static void __init map_vsyscall(void) { extern char __vsyscall_0; @@ -299,6 +302,8 @@ static int __init vsyscall_init(void) #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); #endif + on_each_cpu(cpu_vsyscall_init, NULL, 0, 1); + hotcpu_notifier(cpu_vsyscall_notifier, 0); return 0; } -- cgit v1.2.3 From 9446868b5383eb87f76b2d4389dea4bb968a6657 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Fix race in exit_idle When another interrupt happens in exit_idle the exit idle notifier could be called an incorrect number of times. Add a test_and_clear_bit_pda and use it handle the bit atomically against interrupts to avoid this. Pointed out by Stephane Eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/process.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 49f7fac6229..f6226055d53 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -88,9 +88,8 @@ void enter_idle(void) static void __exit_idle(void) { - if (read_pda(isidle) == 0) + if (test_and_clear_bit_pda(0, isidle) == 0) return; - write_pda(isidle, 0); atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } -- cgit v1.2.3 From f3ac84324fd949f671e6cf5620add5de02498386 Mon Sep 17 00:00:00 2001 From: Daniel Ritz Date: Tue, 14 Nov 2006 02:03:25 -0800 Subject: [PATCH] fix via586 irq routing for pirq 5 Fix interrupt routing for via 586 bridges. pirq can be 5 which needs to be mapped to INTD. But currently the access functions can handle only pirq 1-4. this is similar to the other via chipsets where pirq 4 and 5 are both mapped to INTD. Fixes bugzilla #7490 Cc: Daniel Paschka Cc: Adrian Bunk Signed-off-by: Daniel Ritz Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/pci/irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index dbc4aae9195..69163998ade 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -255,13 +255,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i */ static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; return read_config_nybble(router, 0x55, pirqmap[pirq-1]); } static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static const unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); return 1; } -- cgit v1.2.3 From 68589bc353037f233fe510ad9ff432338c95db66 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 14 Nov 2006 02:03:32 -0800 Subject: [PATCH] hugetlb: prepare_hugepage_range check offset too (David:) If hugetlbfs_file_mmap() returns a failure to do_mmap_pgoff() - for example, because the given file offset is not hugepage aligned - then do_mmap_pgoff will go to the unmap_and_free_vma backout path. But at this stage the vma hasn't been marked as hugepage, and the backout path will call unmap_region() on it. That will eventually call down to the non-hugepage version of unmap_page_range(). On ppc64, at least, that will cause serious problems if there are any existing hugepage pagetable entries in the vicinity - for example if there are any other hugepage mappings under the same PUD. unmap_page_range() will trigger a bad_pud() on the hugepage pud entries. I suspect this will also cause bad problems on ia64, though I don't have a machine to test it on. (Hugh:) prepare_hugepage_range() should check file offset alignment when it checks virtual address and length, to stop MAP_FIXED with a bad huge offset from unmapping before it fails further down. PowerPC should apply the same prepare_hugepage_range alignment checks as ia64 and all the others do. Then none of the alignment checks in hugetlbfs_file_mmap are required (nor is the check for too small a mapping); but even so, move up setting of VM_HUGETLB and add a comment to warn of what David Gibson discovered - if hugetlbfs_file_mmap fails before setting it, do_mmap_pgoff's unmap_region when unwinding from error will go the non-huge way, which may cause bad behaviour on architectures (powerpc and ia64) which segregate their huge mappings into a separate region of the address space. Signed-off-by: Hugh Dickins Cc: "Luck, Tony" Cc: "David S. Miller" Acked-by: Adam Litke Acked-by: David Gibson Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/mm/hugetlbpage.c | 4 +++- arch/powerpc/mm/hugetlbpage.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index eee5c1cfbe3..f3a9585e98a 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -70,8 +70,10 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) * Don't actually need to do any preparation, but need to make sure * the address is in the right region. */ -int prepare_hugepage_range(unsigned long addr, unsigned long len) +int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) { + if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) + return -EINVAL; if (len & ~HPAGE_MASK) return -EINVAL; if (addr & ~HPAGE_MASK) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index fd68b74c07c..506d89768d4 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -491,11 +491,15 @@ static int open_high_hpage_areas(struct mm_struct *mm, u16 newareas) return 0; } -int prepare_hugepage_range(unsigned long addr, unsigned long len) +int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) { int err = 0; - if ( (addr+len) < addr ) + if (pgoff & (~HPAGE_MASK >> PAGE_SHIFT)) + return -EINVAL; + if (len & ~HPAGE_MASK) + return -EINVAL; + if (addr & ~HPAGE_MASK) return -EINVAL; if (addr < 0x100000000UL) -- cgit v1.2.3 From 45c99533252ef2297f37c5fdd672a3e0eb566870 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Tue, 14 Nov 2006 10:52:12 -0700 Subject: [PATCH] Use delayed disable mode of ioapic edge triggered interrupts Komuro reports that ISA interrupts do not work after a disable_irq(), causing some PCMCIA drivers to not work, with messages like eth0: Asix AX88190: io 0x300, irq 3, hw_addr xx:xx:xx:xx:xx:xx eth0: found link beat eth0: autonegotiation complete: 100baseT-FD selected eth0: interrupt(s) dropped! eth0: interrupt(s) dropped! eth0: interrupt(s) dropped! ... Linus Torvalds said: "Now, edge-triggered interrupts are a _lot_ harder to mask, because the Intel APIC is an unbelievable piece of sh*t, and has the edge-detect logic _before_ the mask logic, so if a edge happens _while_ the device is masked, you'll never ever see the edge ever again (unmasking will not cause a new edge, so you simply lost the interrupt). So when you "mask" an edge-triggered IRQ, you can't really mask it at all, because if you did that, you'd lose it forever if the IRQ comes in while you masked it. Instead, we're supposed to leave it active, and set a flag, and IF the IRQ comes in, we just remember it, and mask it at that point instead, and then on unmasking, we have to replay it by sending a self-IPI." This trivial patch solves the problem. Signed-off-by: Eric W. Biederman Cc: Ingo Molnar Acked-by: Komuro Signed-off-by: Linus Torvalds --- arch/i386/kernel/io_apic.c | 4 +++- arch/x86_64/kernel/io_apic.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index ad84bc2802a..3b7a63e0ed1 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1287,9 +1287,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) trigger == IOAPIC_LEVEL) set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + else { + irq_desc[irq].status |= IRQ_DELAYED_DISABLE; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } set_intr_gate(vector, interrupt[irq]); } diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 41bfc49301a..14654e68241 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -790,9 +790,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) trigger == IOAPIC_LEVEL) set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_fasteoi_irq, "fasteoi"); - else + else { + irq_desc[irq].status |= IRQ_DELAYED_DISABLE; set_irq_chip_and_handler_name(irq, &ioapic_chip, handle_edge_irq, "edge"); + } } static void __init setup_IO_APIC_irqs(void) -- cgit v1.2.3 From cbf093e8c7447a202e376199cc017161262bd7cd Mon Sep 17 00:00:00 2001 From: Robin Holt Date: Tue, 14 Nov 2006 20:50:59 -0600 Subject: [IA64] bte_unaligned_copy() transfers one extra cache line. When called to do a transfer that has a start offset within the cache line which is uneven between source and destination and a length which terminates the source of the copy exactly on a cache line, one extra line gets copied into a temporary buffer. This is normally not an issue since the buffer is a kernel buffer and only the requested information gets copied into the user buffer. The problem arises when the source ends at the very last physical page of memory. That last cache line does not exist and results in the SHUB chip raising an MCA. Signed-off-by: Robin Holt Signed-off-by: Dean Nelson Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/bte.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index 7f73ad4408a..ff1c5560117 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c @@ -381,14 +381,13 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) * bcopy to the destination. */ - /* Add the leader from source */ - headBteLen = len + (src & L1_CACHE_MASK); - /* Add the trailing bytes from footer. */ - headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK); - headBteSource = src & ~L1_CACHE_MASK; headBcopySrcOffset = src & L1_CACHE_MASK; headBcopyDest = dest; headBcopyLen = len; + + headBteSource = src - headBcopySrcOffset; + /* Add the leading and trailing bytes from source */ + headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset); } if (headBcopyLen > 0) { -- cgit v1.2.3 From 351a58390aad350bd5e22c7cc468f44a9330685c Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 16 Nov 2006 00:42:58 -0800 Subject: [IA64] irqs: use `name' not `typename' `typename' is going away and is usually uninitialised anwyay. Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/kernel/iosapic.c | 2 +- arch/ia64/kernel/irq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 9bf15fefa7e..c195fafc7aa 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -664,7 +664,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, - idesc->chip->typename, irq_type->typename); + idesc->chip->name, irq_type->name); idesc->chip = irq_type; } return 0; diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index f07c0864b0b..6fe404dff44 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); } #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].chip->name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) -- cgit v1.2.3 From 06344db3162323247e9ac8d76d5acdb79d05f3c0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 16 Nov 2006 00:43:02 -0800 Subject: [IA64] typename -> name conversion convert irq chip typename -> name. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/hp/sim/hpsim_irq.c | 2 +- arch/ia64/kernel/iosapic.c | 4 ++-- arch/ia64/kernel/irq_lsapic.c | 2 +- arch/ia64/sn/kernel/irq.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c index 8145547bb52..c2f58ff364e 100644 --- a/arch/ia64/hp/sim/hpsim_irq.c +++ b/arch/ia64/hp/sim/hpsim_irq.c @@ -27,7 +27,7 @@ hpsim_set_affinity_noop (unsigned int a, cpumask_t b) } static struct hw_interrupt_type irq_type_hp_sim = { - .typename = "hpsim", + .name = "hpsim", .startup = hpsim_irq_startup, .shutdown = hpsim_irq_noop, .enable = hpsim_irq_noop, diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index c195fafc7aa..60d64950e3c 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -426,7 +426,7 @@ iosapic_end_level_irq (unsigned int irq) #define iosapic_ack_level_irq nop struct hw_interrupt_type irq_type_iosapic_level = { - .typename = "IO-SAPIC-level", + .name = "IO-SAPIC-level", .startup = iosapic_startup_level_irq, .shutdown = iosapic_shutdown_level_irq, .enable = iosapic_enable_level_irq, @@ -473,7 +473,7 @@ iosapic_ack_edge_irq (unsigned int irq) #define iosapic_end_edge_irq nop struct hw_interrupt_type irq_type_iosapic_edge = { - .typename = "IO-SAPIC-edge", + .name = "IO-SAPIC-edge", .startup = iosapic_startup_edge_irq, .shutdown = iosapic_disable_edge_irq, .enable = iosapic_enable_edge_irq, diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c index 1ab58b09f3d..c2f07beb175 100644 --- a/arch/ia64/kernel/irq_lsapic.c +++ b/arch/ia64/kernel/irq_lsapic.c @@ -34,7 +34,7 @@ static int lsapic_retrigger(unsigned int irq) } struct hw_interrupt_type irq_type_ia64_lsapic = { - .typename = "LSAPIC", + .name = "LSAPIC", .startup = lsapic_noop_startup, .shutdown = lsapic_noop, .enable = lsapic_noop, diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 7bb6ad188ba..0b49459a878 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -201,7 +201,7 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) } struct hw_interrupt_type irq_type_sn = { - .typename = "SN hub", + .name = "SN hub", .startup = sn_startup_irq, .shutdown = sn_shutdown_irq, .enable = sn_enable_irq, -- cgit v1.2.3 From 5fbb004aba15bbca64c3fb611113295bda7ee9ea Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 16 Nov 2006 00:43:07 -0800 Subject: [IA64] use generic_handle_irq() Use generic_handle_irq() to handle mixed-type irq handling. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/kernel/irq.c | 2 +- arch/ia64/kernel/irq_ia64.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index 6fe404dff44..54d55e4d64f 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c @@ -197,7 +197,7 @@ void fixup_irqs(void) struct pt_regs *old_regs = set_irq_regs(NULL); vectors_in_migration[irq]=0; - __do_IRQ(irq); + generic_handle_irq(irq); set_irq_regs(old_regs); } } diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9c6dafa2d0d..ba3ba8bc50b 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -186,7 +186,7 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs) ia64_setreg(_IA64_REG_CR_TPR, vector); ia64_srlz_d(); - __do_IRQ(local_vector_to_irq(vector)); + generic_handle_irq(local_vector_to_irq(vector)); /* * Disable interrupts and send EOI: @@ -242,7 +242,7 @@ void ia64_process_pending_intr(void) * Probably could shared code. */ vectors_in_migration[local_vector_to_irq(vector)]=0; - __do_IRQ(local_vector_to_irq(vector)); + generic_handle_irq(local_vector_to_irq(vector)); set_irq_regs(old_regs); /* -- cgit v1.2.3 From cea196bb2eb918c30f97a2b752bcec929d761f64 Mon Sep 17 00:00:00 2001 From: "Luck, Tony" Date: Thu, 16 Nov 2006 00:43:12 -0800 Subject: [IA64] a fix towards allmodconfig build The HP_SIMSCSI driver can't be built as a module (unhealthy dependencies on things that shouldn't really be exported). Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/hp/sim/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig index 18ccb1266e1..f92306bbedb 100644 --- a/arch/ia64/hp/sim/Kconfig +++ b/arch/ia64/hp/sim/Kconfig @@ -13,8 +13,8 @@ config HP_SIMSERIAL_CONSOLE depends on HP_SIMSERIAL config HP_SIMSCSI - tristate "Simulated SCSI disk" - depends on SCSI + bool "Simulated SCSI disk" + depends on SCSI=y endmenu -- cgit v1.2.3 From 6b3d1a95ba714bfb1cc81362f7f3e01b7654b4f3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 16 Nov 2006 10:22:03 +0100 Subject: [PATCH] x86-64: Fix vsyscall.c compilation on UP Broken by earlier patch by me. Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/vsyscall.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index a730bacecb0..92546c1526f 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -274,6 +274,7 @@ static void __cpuinit cpu_vsyscall_init(void *arg) vsyscall_set_cpu(raw_smp_processor_id()); } +#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) { @@ -282,6 +283,7 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); return NOTIFY_DONE; } +#endif static void __init map_vsyscall(void) { -- cgit v1.2.3 From ccf9ff524ccb195d648ecb0b168340560b42532c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 16 Nov 2006 11:49:16 +0100 Subject: [PATCH] x86_64: fix CONFIG_CC_STACKPROTECTOR build bug on x86_64, the CONFIG_CC_STACKPROTECTOR build fails if used in a distcc setup that has "CC" defined to "distcc gcc": gcc: gcc: linker input file unused because linking not done gcc: gcc: linker input file unused because linking not done gcc: gcc: linker input file unused because linking not done this is because the gcc-x86_64-has-stack-protector.sh script has a 2-parameters assumption. Fix this by passing $(CC) as a single parameter. Signed-off-by: Ingo Molnar Please-Use-Me-More: make randconfig Signed-off-by: Linus Torvalds --- arch/x86_64/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 13972148058..6e38d4daeed 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -66,8 +66,8 @@ AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) -cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) -cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) +cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector ) +cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh "$(CC)" -fstack-protector-all ) CFLAGS += $(cflags-y) CFLAGS_KERNEL += $(cflags-kernel-y) -- cgit v1.2.3 From 0796bdb7e9e4a48b401f4fba1ee5dc79a45528ef Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 17 Nov 2006 05:57:49 +0100 Subject: [PATCH] x86_64: stack unwinder crash fix the new dwarf2 unwinder crashes while trying to dump the stack: Leftover inexact backtrace: Unable to handle kernel paging request at ffffffff82800000 RIP: [] dump_trace+0x35b/0x3d2 PGD 203027 PUD 205027 PMD 0 Oops: 0000 [2] PREEMPT SMP CPU 0 Modules linked in: Pid: 30, comm: khelper Not tainted 2.6.19-rc6-rt1 #11 RIP: 0010:[] [] dump_trace+0x35b/0x3d2 RSP: 0000:ffff81003fb9d848 EFLAGS: 00010006 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000000 RSI: ffffffff805b3520 RDI: 0000000000000000 RBP: ffffffff827ffff9 R08: ffffffff80aad000 R09: 0000000000000005 R10: ffffffff80aae000 R11: ffffffff8037961b R12: ffff81003fb9d858 R13: 0000000000000000 R14: ffffffff80598460 R15: ffffffff80ab1fc0 FS: 0000000000000000(0000) GS:ffffffff806c4200(0000) knlGS:0000000000000000 CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b CR2: ffffffff82800000 CR3: 0000000000201000 CR4: 00000000000006e0 this crash happened because it did not sanitize the dwarf2 data it got, and got an unaligned stack pointer - which happily walked past the process stack (and eventually reached the end of kernel memory and pagefaulted there) due to this naive iteration condition: HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); note that i386 is alot more conservative when it comes to trusting stack pointers: static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) { return p > (void *)tinfo && p < (void *)tinfo + THREAD_SIZE - 3; } but the x86_64 code did not take this bit of i386 code. The fix is to align the stack pointer. Signed-off-by: Ingo Molnar Cc: Andi Kleen Cc: Jan Beulich Cc: Thomas Gleixner Cc: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/traps.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 7819022a8db..a153d0a01b7 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -290,6 +290,12 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s if (tsk && tsk != current) stack = (unsigned long *)tsk->thread.rsp; } + /* + * Align the stack pointer on word boundary, later loops + * rely on that (and corruption / debug info bugs can cause + * unaligned values here): + */ + stack = (unsigned long *)((unsigned long)stack & ~(sizeof(long)-1)); /* * Print function call entries within a stack. 'cond' is the -- cgit v1.2.3 From dc1829a4c378d793fb3b95d56135d89a0d7ff72a Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 17 Nov 2006 14:26:18 +0100 Subject: [PATCH] i386/x86_64: ACPI cpu_idle_wait() fix The scheduler on Andreas Friedrich's hyperthreading system stopped working properly: the scheduler would never move tasks to another CPU! The lask known working kernel was 2.6.8. After a couple of attempts to corner the bug, the following smoking gun was found: BIOS reported wrong ACPI idfor the processor CPU#1: set_cpus_allowed(), swapper:1, 3 -> 2 [] show_trace_log_lvl+0x34/0x4a [] show_trace+0x2c/0x2e [] dump_stack+0x2b/0x2d [] set_cpus_allowed+0x52/0xec [] cpu_idle_wait+0x2e/0x100 [] acpi_processor_power_exit+0x45/0x58 [] acpi_processor_remove+0x46/0xea [] acpi_start_single_object+0x47/0x54 [] acpi_bus_register_driver+0xa4/0xd3 [] acpi_processor_init+0x57/0x77 [] init+0x146/0x2fd [] kernel_thread_helper+0x7/0x10 a quick look at cpu_idle_wait() shows how broken that code is on i386: it changes the init task's affinity map but never restores it ... and because all userspace tasks get forked by init, they all inherited that single-CPU affinity mask. x86_64 cloned this bug too. Signed-off-by: Ingo Molnar Cc: Andreas Friedrich Cc: Wolfgang Erig Cc: Andrew Morton Cc: Adrian Bunk Signed-off-by: Linus Torvalds --- arch/i386/kernel/process.c | 4 +++- arch/x86_64/kernel/process.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 1e1fa3e391a..dd53c58f64f 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -205,7 +205,7 @@ void cpu_idle(void) void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); - cpumask_t map; + cpumask_t map, tmp = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); put_cpu(); @@ -227,6 +227,8 @@ void cpu_idle_wait(void) } cpus_and(map, map, cpu_online_map); } while (!cpus_empty(map)); + + set_cpus_allowed(current, tmp); } EXPORT_SYMBOL_GPL(cpu_idle_wait); diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index f6226055d53..7451a4c43c1 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -144,7 +144,7 @@ static void poll_idle (void) void cpu_idle_wait(void) { unsigned int cpu, this_cpu = get_cpu(); - cpumask_t map; + cpumask_t map, tmp = current->cpus_allowed; set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); put_cpu(); @@ -167,6 +167,8 @@ void cpu_idle_wait(void) } cpus_and(map, map, cpu_online_map); } while (!cpus_empty(map)); + + set_cpus_allowed(current, tmp); } EXPORT_SYMBOL_GPL(cpu_idle_wait); -- cgit v1.2.3 From 808dbbb6bb61173bf52946a28f99089d2efa4c55 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 17 Nov 2006 11:14:56 -0800 Subject: x86: be more careful when walking back the frame pointer chain When showing the stack backtrace, make sure that we never accept not only an unchanging frame pointer, but also a frame pointer that moves back down the stack frame. It must always grow up (toward older stack frames). I doubt this has triggered, but a subtly corrupt stack with extremely unlucky contents could cause us to loop forever on a bogus endless frame pointer chain. This review was triggered by much worse problems happening in some of the other stack unwinding code. Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 00489b706d2..fe9c5e8e7e6 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -129,15 +129,19 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, #ifdef CONFIG_FRAME_POINTER while (valid_stack_ptr(tinfo, (void *)ebp)) { + unsigned long new_ebp; addr = *(unsigned long *)(ebp + 4); ops->address(data, addr); /* * break out of recursive entries (such as - * end_of_stack_stop_unwind_function): + * end_of_stack_stop_unwind_function). Also, + * we can never allow a frame pointer to + * move downwards! */ - if (ebp == *(unsigned long *)ebp) + new_ebp = *(unsigned long *)ebp; + if (new_ebp <= ebp) break; - ebp = *(unsigned long *)ebp; + ebp = new_ebp; } #else while (valid_stack_ptr(tinfo, stack)) { -- cgit v1.2.3 From eb370f0bd409f8bcdc88583ae04f94453e19d882 Mon Sep 17 00:00:00 2001 From: Martin Michlmayr Date: Fri, 17 Nov 2006 00:14:35 +0100 Subject: [ARM] 3933/1: Source drivers/ata/Kconfig ARM doesn't source drivers/Kconfig like most architectures do, so the newly added drivers/ata is currently not made available on ARM. SATA is used on some ARM machines, like the Thecus N2100, so we need to source drivers/ata/Kconfig. Signed-off-by: Martin Michlmayr Signed-off-by: Russell King --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index adb05de40e2..ce00c570459 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -879,6 +879,8 @@ endif source "drivers/scsi/Kconfig" +source "drivers/ata/Kconfig" + source "drivers/md/Kconfig" source "drivers/message/fusion/Kconfig" -- cgit v1.2.3 From 8de35efb6afa75f25415d54e21221eea759db261 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 20 Nov 2006 15:59:10 +0000 Subject: [ARM] ebsa110: fix warnings generated by asm/arch/io.h Remove two warnings: drivers/serial/8250_early.c:136: warning: unused variable 'mapsize' include/linux/io.h:47: warning: passing argument 1 of '__readb' discards qualifiers from pointer target type Signed-off-by: Russell King --- arch/arm/mach-ebsa110/io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c index c648bfb676a..db38afb2aa8 100644 --- a/arch/arm/mach-ebsa110/io.c +++ b/arch/arm/mach-ebsa110/io.c @@ -28,7 +28,7 @@ #include #include -static void __iomem *__isamem_convert_addr(void __iomem *addr) +static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr) { u32 ret, a = (u32 __force) addr; @@ -63,7 +63,7 @@ static void __iomem *__isamem_convert_addr(void __iomem *addr) /* * read[bwl] and write[bwl] */ -u8 __readb(void __iomem *addr) +u8 __readb(const volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); u32 ret; @@ -75,7 +75,7 @@ u8 __readb(void __iomem *addr) return ret; } -u16 __readw(void __iomem *addr) +u16 __readw(const volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); @@ -85,7 +85,7 @@ u16 __readw(void __iomem *addr) return __raw_readw(a); } -u32 __readl(void __iomem *addr) +u32 __readl(const volatile void __iomem *addr) { void __iomem *a = __isamem_convert_addr(addr); u32 ret; -- cgit v1.2.3 From 8243229f0940ab4e9f501879d3ffb7476b02ee6a Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Sat, 18 Nov 2006 22:19:40 -0800 Subject: [PATCH] x86_64: fix memory hotplug build with NUMA=n This is to fix compile error of x86-64 memory hotplug without any NUMA option. CC arch/x86_64/mm/init.o arch/x86_64/mm/init.c:501: error: redefinition of 'memory_add_physaddr_to_nid' include/linux/memory_hotplug.h:71: error: previous definition of 'memory_add_phys addr_to_nid' was here arch/x86_64/mm/init.c:509: error: redefinition of 'memory_add_physaddr_to_nid' arch/x86_64/mm/init.c:501: error: previous definition of 'memory_add_physaddr_to_ nid' was here I confirmed compile completion with !NUMA, (NUMA & !ACPI_NUMA), or (NUMA & ACPI_NUMA). Signed-off-by: Yasunori Goto Acked-by: Andi Kleen Cc: "Randy.Dunlap" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/mm/init.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index f1f977aafae..4c0c00ef3ca 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -496,7 +496,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#ifndef CONFIG_ACPI_NUMA +#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA) int memory_add_physaddr_to_nid(u64 start) { return 0; @@ -504,13 +504,6 @@ int memory_add_physaddr_to_nid(u64 start) EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif -#ifndef CONFIG_ACPI_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return 0; -} -#endif - #endif /* CONFIG_MEMORY_HOTPLUG */ #ifdef CONFIG_MEMORY_HOTPLUG_RESERVE -- cgit v1.2.3 From ace5f1d425beaa272b6e91cecc87b2c075d7feb2 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 20 Nov 2006 15:46:22 +1000 Subject: [PATCH] m68knommu: fix up for the irq_handler_t changes Switch to using irq_handler_t for interrupt function handler pointers. Change name of m68knommu's irq_hanlder_t data structure so it doesn't clash with the common type (include/linux/interrupt.h). Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/setup.c | 2 +- arch/m68knommu/kernel/time.c | 2 +- arch/m68knommu/platform/5307/ints.c | 17 ++++++++--------- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index bde9811cf98..7b21959eaea 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -62,7 +62,7 @@ int (*mach_kbdrate) (struct kbd_repeat *); void (*mach_kbd_leds) (unsigned int); /* machine dependent irq functions */ void (*mach_init_IRQ) (void); -irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *); +irq_handler_t mach_default_handler; int (*mach_get_irq_list) (struct seq_file *, void *); void (*mach_process_int) (int irq, struct pt_regs *fp); void (*mach_trap_init) (void); diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index c5667bdddd5..9226264abf1 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c @@ -54,7 +54,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) update_process_times(user_mode(regs)); #endif if (current->pid) - profile_tick(CPU_PROFILING, regs); + profile_tick(CPU_PROFILING); /* * If we have an externally synchronized Linux clock, then update diff --git a/arch/m68knommu/platform/5307/ints.c b/arch/m68knommu/platform/5307/ints.c index b4b55093ae7..a57239ec6c8 100644 --- a/arch/m68knommu/platform/5307/ints.c +++ b/arch/m68knommu/platform/5307/ints.c @@ -33,7 +33,7 @@ /* * This table stores the address info for each vector handler. */ -irq_handler_t irq_list[SYS_IRQS]; +struct irq_entry irq_list[SYS_IRQS]; #define NUM_IRQ_NODES 16 static irq_node_t nodes[NUM_IRQ_NODES]; @@ -44,7 +44,7 @@ volatile unsigned int num_spurious; unsigned int local_bh_count[NR_CPUS]; unsigned int local_irq_count[NR_CPUS]; -static irqreturn_t default_irq_handler(int irq, void *ptr, struct pt_regs *regs) +static irqreturn_t default_irq_handler(int irq, void *ptr) { #if 1 printk(KERN_INFO "%s(%d): default irq handler vec=%d [0x%x]\n", @@ -70,7 +70,7 @@ void __init init_IRQ(void) for (i = 0; i < SYS_IRQS; i++) { if (mach_default_handler) - irq_list[i].handler = (*mach_default_handler)[i]; + irq_list[i].handler = mach_default_handler; else irq_list[i].handler = default_irq_handler; irq_list[i].flags = IRQ_FLG_STD; @@ -100,7 +100,7 @@ irq_node_t *new_irq_node(void) int request_irq( unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), + irq_handler_t handler, unsigned long flags, const char *devname, void *dev_id) @@ -157,7 +157,7 @@ void free_irq(unsigned int irq, void *dev_id) } if (mach_default_handler) - irq_list[irq].handler = (*mach_default_handler)[irq]; + irq_list[irq].handler = mach_default_handler; else irq_list[irq].handler = default_irq_handler; irq_list[irq].flags = IRQ_FLG_STD; @@ -168,8 +168,7 @@ void free_irq(unsigned int irq, void *dev_id) EXPORT_SYMBOL(free_irq); -int sys_request_irq(unsigned int irq, - irqreturn_t (*handler)(int, void *, struct pt_regs *), +int sys_request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *devname, void *dev_id) { if (irq > IRQ7) { @@ -211,7 +210,7 @@ void sys_free_irq(unsigned int irq, void *dev_id) printk(KERN_WARNING "%s: Removing probably wrong IRQ %d from %s\n", __FUNCTION__, irq, irq_list[irq].devname); - irq_list[irq].handler = (*mach_default_handler)[irq]; + irq_list[irq].handler = mach_default_handler; irq_list[irq].flags = 0; irq_list[irq].dev_id = NULL; irq_list[irq].devname = NULL; @@ -241,7 +240,7 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp) if (vec >= VEC_INT1 && vec <= VEC_INT7) { vec -= VEC_SPUR; kstat_cpu(0).irqs[vec]++; - irq_list[vec].handler(vec, irq_list[vec].dev_id, fp); + irq_list[vec].handler(vec, irq_list[vec].dev_id); } else { if (mach_process_int) mach_process_int(vec, fp); -- cgit v1.2.3 From 3af9815328bba76e8d11d71d6dbbd6f38beafe58 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Mon, 20 Nov 2006 11:29:09 -0500 Subject: [PATCH] x86_64: Align data segment to PAGE_SIZE boundary o Explicitly align data segment to PAGE_SIZE boundary otherwise depending on config options and tool chain it might be placed on a non PAGE_SIZE aligned boundary and vmlinux loaders like kexec fail when they encounter a PT_LOAD type segment which is not aligned to PAGE_SIZE boundary. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/x86_64/kernel/vmlinux.lds.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index edb24aa714b..d9534e750d4 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -60,6 +60,7 @@ SECTIONS } #endif + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) -- cgit v1.2.3 From 6c12c18dfb0ccae21816de3e0c323b5250450d82 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 21 Nov 2006 10:31:08 -0600 Subject: [POWERPC] Revert "[POWERPC] Enable generic rtc hook for the MPC8349 mITX" This reverts commit a8ed4f7ec3aa472134d7de6176f823b2667e450b. As advised by David Brownell: http://marc.theaimsgroup.com/?l=linux-kernel&m=116387226902131&w=2 Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/83xx/mpc834x_itx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index 5446bab08ec..e2bcaaf6b32 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -108,10 +108,6 @@ static int __init mpc834x_itx_probe(void) return 1; } -#ifdef CONFIG_RTC_CLASS -late_initcall(rtc_class_hookup); -#endif - define_machine(mpc834x_itx) { .name = "MPC834x ITX", .probe = mpc834x_itx_probe, -- cgit v1.2.3 From df9c23095fc8652798c41dd860676d3dafb2f1dc Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 21 Nov 2006 10:31:14 -0600 Subject: [POWERPC] Revert "[POWERPC] Add powerpc get/set_rtc_time interface to new generic rtc class" This reverts commit 7a69af63e788a324d162201a0b23df41bcf158dd. As advised by David Brownell: http://marc.theaimsgroup.com/?l=linux-kernel&m=116387226902131&w=2 Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 42 ------------------------------------------ 1 file changed, 42 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index a1b5e4b1615..46a24de36fe 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -1014,48 +1014,6 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); } -#ifdef CONFIG_RTC_CLASS -static int set_rtc_class_time(struct rtc_time *tm) -{ - int err; - struct class_device *class_dev = - rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - - if (class_dev == NULL) - return -ENODEV; - - err = rtc_set_time(class_dev, tm); - - rtc_class_close(class_dev); - - return 0; -} - -static void get_rtc_class_time(struct rtc_time *tm) -{ - int err; - struct class_device *class_dev = - rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); - - if (class_dev == NULL) - return; - - err = rtc_read_time(class_dev, tm); - - rtc_class_close(class_dev); - - return; -} - -int __init rtc_class_hookup(void) -{ - ppc_md.get_rtc_time = get_rtc_class_time; - ppc_md.set_rtc_time = set_rtc_class_time; - - return 0; -} -#endif /* CONFIG_RTC_CLASS */ - #define FEBRUARY 2 #define STARTOFTIME 1970 -- cgit v1.2.3 From 8746ed3dae14e87e9f7ad8e44649b72e22b33274 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Tue, 21 Nov 2006 18:19:42 -0600 Subject: [POWERPC] Fix ucc_geth of_device discovery on mpc832x mpc832x, as in mpc8360, needs to explicitly find and create the platform device for ucc_geth in 2.6.19. This code will likely be readapted to Benh's new of_ methods for 2.6.20. Signed-off-by: Kim Phillips Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/83xx/mpc832x_mds.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index 54dea9d42dc..a43ac71ab74 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -136,6 +137,24 @@ static void __init mpc832x_sys_setup_arch(void) #endif } +static int __init mpc832x_declare_of_platform_devices(void) +{ + struct device_node *np; + + for (np = NULL; (np = of_find_compatible_node(np, "network", + "ucc_geth")) != NULL;) { + int ucc_num; + char bus_id[BUS_ID_SIZE]; + + ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; + snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); + of_platform_device_create(np, bus_id, NULL); + } + + return 0; +} +device_initcall(mpc832x_declare_of_platform_devices); + void __init mpc832x_sys_init_IRQ(void) { -- cgit v1.2.3 From 52bad64d95bd89e08c49ec5a071fa6dcbe5a1a9c Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:54:01 +0000 Subject: WorkStruct: Separate delayable and non-delayable events. Separate delayable work items from non-delayable work items be splitting them into a separate structure (delayed_work), which incorporates a work_struct and the timer_list removed from work_struct. The work_struct struct is huge, and this limits it's usefulness. On a 64-bit architecture it's nearly 100 bytes in size. This reduces that by half for the non-delayable type of event. Signed-Off-By: David Howells --- arch/x86_64/kernel/mce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index bbea88801d8..5306f263090 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -307,7 +307,7 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) static int check_interval = 5 * 60; /* 5 minutes */ static void mcheck_timer(void *data); -static DECLARE_WORK(mcheck_work, mcheck_timer, NULL); +static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer, NULL); static void mcheck_check_cpu(void *info) { -- cgit v1.2.3 From 65f27f38446e1976cc98fd3004b110fedcddd189 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:55:48 +0000 Subject: WorkStruct: Pass the work_struct pointer instead of context data Pass the work_struct pointer to the work function rather than context data. The work function can use container_of() to work out the data. For the cases where the container of the work_struct may go away the moment the pending bit is cleared, it is made possible to defer the release of the structure by deferring the clearing of the pending bit. To make this work, an extra flag is introduced into the management side of the work_struct. This governs auto-release of the structure upon execution. Ordinarily, the work queue executor would release the work_struct for further scheduling or deallocation by clearing the pending bit prior to jumping to the work function. This means that, unless the driver makes some guarantee itself that the work_struct won't go away, the work function may not access anything else in the work_struct or its container lest they be deallocated.. This is a problem if the auxiliary data is taken away (as done by the last patch). However, if the pending bit is *not* cleared before jumping to the work function, then the work function *may* access the work_struct and its container with no problems. But then the work function must itself release the work_struct by calling work_release(). In most cases, automatic release is fine, so this is the default. Special initiators exist for the non-auto-release case (ending in _NAR). Signed-Off-By: David Howells --- arch/x86_64/kernel/mce.c | 6 +++--- arch/x86_64/kernel/smpboot.c | 12 +++++++----- arch/x86_64/kernel/time.c | 4 ++-- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 5306f263090..c7587fc3901 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -306,8 +306,8 @@ void mce_log_therm_throt_event(unsigned int cpu, __u64 status) */ static int check_interval = 5 * 60; /* 5 minutes */ -static void mcheck_timer(void *data); -static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer, NULL); +static void mcheck_timer(struct work_struct *work); +static DECLARE_DELAYED_WORK(mcheck_work, mcheck_timer); static void mcheck_check_cpu(void *info) { @@ -315,7 +315,7 @@ static void mcheck_check_cpu(void *info) do_machine_check(NULL, 0); } -static void mcheck_timer(void *data) +static void mcheck_timer(struct work_struct *work) { on_each_cpu(mcheck_check_cpu, NULL, 1, 1); schedule_delayed_work(&mcheck_work, check_interval * HZ); diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 62c2e747af5..9800147c4c6 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -753,14 +753,16 @@ static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int sta } struct create_idle { + struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; -void do_fork_idle(void *_c_idle) +void do_fork_idle(struct work_struct *work) { - struct create_idle *c_idle = _c_idle; + struct create_idle *c_idle = + container_of(work, struct create_idle, work); c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -775,10 +777,10 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) int timeout; unsigned long start_rip; struct create_idle c_idle = { + .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done), }; - DECLARE_WORK(work, do_fork_idle, &c_idle); /* allocate memory for gdts of secondary cpus. Hotplug is considered */ if (!cpu_gdt_descr[cpu].address && @@ -825,9 +827,9 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) * thread. */ if (!keventd_up() || current_is_keventd()) - work.func(work.data); + c_idle.work.func(&c_idle.work); else { - schedule_work(&work); + schedule_work(&c_idle.work); wait_for_completion(&c_idle.done); } diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index e3ef544d2cf..9f05bc9b2da 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -563,7 +563,7 @@ static unsigned int cpufreq_delayed_issched = 0; static unsigned int cpufreq_init = 0; static struct work_struct cpufreq_delayed_get_work; -static void handle_cpufreq_delayed_get(void *v) +static void handle_cpufreq_delayed_get(struct work_struct *v) { unsigned int cpu; for_each_online_cpu(cpu) { @@ -639,7 +639,7 @@ static struct notifier_block time_cpufreq_notifier_block = { static int __init cpufreq_tsc(void) { - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get); if (!cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER)) cpufreq_init = 1; -- cgit v1.2.3 From c4028958b6ecad064b1a6303a6a5906d4fe48d73 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:57:56 +0000 Subject: WorkStruct: make allyesconfig Fix up for make allyesconfig. Signed-Off-By: David Howells --- arch/i386/kernel/cpu/mcheck/non-fatal.c | 6 +++--- arch/i386/kernel/smpboot.c | 11 ++++++----- arch/i386/kernel/tsc.c | 4 ++-- arch/powerpc/platforms/pseries/eeh_event.c | 6 +++--- 4 files changed, 14 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mcheck/non-fatal.c b/arch/i386/kernel/cpu/mcheck/non-fatal.c index 1f9153ae5b0..6b5d3518a1c 100644 --- a/arch/i386/kernel/cpu/mcheck/non-fatal.c +++ b/arch/i386/kernel/cpu/mcheck/non-fatal.c @@ -51,10 +51,10 @@ static void mce_checkregs (void *info) } } -static void mce_work_fn(void *data); -static DECLARE_WORK(mce_work, mce_work_fn, NULL); +static void mce_work_fn(struct work_struct *work); +static DECLARE_DELAYED_WORK(mce_work, mce_work_fn); -static void mce_work_fn(void *data) +static void mce_work_fn(struct work_struct *work) { on_each_cpu(mce_checkregs, NULL, 1, 1); schedule_delayed_work(&mce_work, MCE_RATE); diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 4bb8b77cd65..02a9b66b6ac 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1049,13 +1049,15 @@ void cpu_exit_clear(void) struct warm_boot_cpu_info { struct completion *complete; + struct work_struct task; int apicid; int cpu; }; -static void __cpuinit do_warm_boot_cpu(void *p) +static void __cpuinit do_warm_boot_cpu(struct work_struct *work) { - struct warm_boot_cpu_info *info = p; + struct warm_boot_cpu_info *info = + container_of(work, struct warm_boot_cpu_info, task); do_boot_cpu(info->apicid, info->cpu); complete(info->complete); } @@ -1064,7 +1066,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) { DECLARE_COMPLETION_ONSTACK(done); struct warm_boot_cpu_info info; - struct work_struct task; int apicid, ret; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); @@ -1089,7 +1090,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) info.complete = &done; info.apicid = apicid; info.cpu = cpu; - INIT_WORK(&task, do_warm_boot_cpu, &info); + INIT_WORK(&info.task, do_warm_boot_cpu); tsc_sync_disabled = 1; @@ -1097,7 +1098,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, KERNEL_PGD_PTRS); flush_tlb_all(); - schedule_work(&task); + schedule_work(&info.task); wait_for_completion(&done); tsc_sync_disabled = 0; diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index fbc95828cd7..9810c8c9075 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -217,7 +217,7 @@ static unsigned int cpufreq_delayed_issched = 0; static unsigned int cpufreq_init = 0; static struct work_struct cpufreq_delayed_get_work; -static void handle_cpufreq_delayed_get(void *v) +static void handle_cpufreq_delayed_get(struct work_struct *work) { unsigned int cpu; @@ -306,7 +306,7 @@ static int __init cpufreq_tsc(void) { int ret; - INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get, NULL); + INIT_WORK(&cpufreq_delayed_get_work, handle_cpufreq_delayed_get); ret = cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); if (!ret) diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 13707745131..49037edf7d3 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c @@ -37,8 +37,8 @@ /* EEH event workqueue setup. */ static DEFINE_SPINLOCK(eeh_eventlist_lock); LIST_HEAD(eeh_eventlist); -static void eeh_thread_launcher(void *); -DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); +static void eeh_thread_launcher(struct work_struct *); +DECLARE_WORK(eeh_event_wq, eeh_thread_launcher); /* Serialize reset sequences for a given pci device */ DEFINE_MUTEX(eeh_event_mutex); @@ -103,7 +103,7 @@ static int eeh_event_handler(void * dummy) * eeh_thread_launcher * @dummy - unused */ -static void eeh_thread_launcher(void *dummy) +static void eeh_thread_launcher(struct work_struct *dummy) { if (kernel_thread(eeh_event_handler, NULL, CLONE_KERNEL) < 0) printk(KERN_ERR "Failed to start EEH daemon\n"); -- cgit v1.2.3 From 105ef9a0af1469a9dd906839dd4628aa9c013f58 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 21 Nov 2006 22:57:23 +0100 Subject: [ARM] 3942/1: ARM: comment: consistent_sync should not be called directly /* * Note: Drivers should NOT use this function directly, as it will break * platforms with CONFIG_DMABOUNCE. * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mm/consistent.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 50e6b6bfb2e..b797217e82b 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -476,6 +476,9 @@ core_initcall(consistent_init); /* * Make an area consistent for devices. + * Note: Drivers should NOT use this function directly, as it will break + * platforms with CONFIG_DMABOUNCE. + * Use the driver DMA support - see dma-mapping.h (dma_sync_*) */ void consistent_sync(void *vaddr, size_t size, int direction) { -- cgit v1.2.3 From eb4828750852b84703f64747b3bedf6394d629ef Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Thu, 16 Nov 2006 22:13:54 +0000 Subject: [MIPS] Hack for SB1 cache issues Removing flush_icache_page a while ago broke SB1 which was using an empty flush_data_cache_page function. This glues things well enough so a more efficient but also more intrusive solution can be found later. Signed-Off-By: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/mm/c-sb1.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index d0ddb4a768a..3a8afd47fea 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include @@ -242,6 +243,25 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign __attribute__((alias("local_sb1_flush_cache_page"))); #endif +#ifdef CONFIG_SMP +static void sb1_flush_cache_data_page_ipi(void *info) +{ + unsigned long start = (unsigned long)info; + + __sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE); +} + +static void sb1_flush_cache_data_page(unsigned long addr) +{ + if (in_atomic()) + __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE); + else + on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1); +} +#else +void sb1_flush_cache_data_page(unsigned long) + __attribute__((alias("local_sb1_flush_cache_data_page"))); +#endif /* * Invalidate all caches on this CPU @@ -481,7 +501,7 @@ void sb1_cache_init(void) flush_cache_sigtramp = sb1_flush_cache_sigtramp; local_flush_data_cache_page = (void *) sb1_nop; - flush_data_cache_page = (void *) sb1_nop; + flush_data_cache_page = sb1_flush_cache_data_page; /* Full flush */ __flush_cache_all = sb1___flush_cache_all; -- cgit v1.2.3 From 5d48545e5e88ab7a27ba6a5cb1e8fff617754b61 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Sat, 25 Nov 2006 11:09:39 -0800 Subject: [PATCH] uml: make execvp safe for our usage Reimplement execvp for our purposes - after we call fork() it is fundamentally unsafe to use the kernel allocator - current is not valid there. So we simply pass to our modified execvp() a preallocated buffer. This fixes a real bug and works very well in testing (I've seen indirectly warning messages from the forked thread - they went on the pipe connected to its stdout and where read as a number by UML, when calling read_output(). I verified the obtained number corresponded to "BUG:"). The added use of __cant_sleep() is not a new bug since __cant_sleep() is already used in the same function - passing an atomicity parameter would be better but it would require huge change, stating that this function must not be called in atomic context and can sleep is a better idea (will make sure of this gradually). Signed-off-by: Paolo 'Blaisorblade' Giarrusso Acked-by: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/os.h | 2 + arch/um/os-Linux/Makefile | 10 ++-- arch/um/os-Linux/execvp.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++ arch/um/os-Linux/helper.c | 14 +++-- 4 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 arch/um/os-Linux/execvp.c (limited to 'arch') diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 6516f6dca96..13a86bd383d 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -233,6 +233,8 @@ extern unsigned long __do_user_copy(void *to, const void *from, int n, void (*op)(void *to, const void *from, int n), int *faulted_out); +/* execvp.c */ +extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); /* helper.c */ extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, unsigned long *stack_out); diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index b4183929b32..2f8c7946401 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile @@ -3,8 +3,8 @@ # Licensed under the GPL # -obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ - signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ +obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ + sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ user_syms.o util.o drivers/ sys-$(SUBARCH)/ obj-$(CONFIG_MODE_SKAS) += skas/ @@ -15,9 +15,9 @@ user-objs-$(CONFIG_MODE_TT) += tt.o obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o -USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ - process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \ - uaccess.o umid.o util.o +USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ + main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \ + tls.o uaccess.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c new file mode 100644 index 00000000000..66e583a4031 --- /dev/null +++ b/arch/um/os-Linux/execvp.c @@ -0,0 +1,149 @@ +/* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c. + Original copyright notice follows: + + Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; 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 + +#ifndef TEST +#include "um_malloc.h" +#else +#include +#define um_kmalloc malloc +#endif +#include "os.h" + +/* Execute FILE, searching in the `PATH' environment variable if it contains + no slashes, with arguments ARGV and environment from `environ'. */ +int execvp_noalloc(char *buf, const char *file, char *const argv[]) +{ + if (*file == '\0') { + return -ENOENT; + } + + if (strchr (file, '/') != NULL) { + /* Don't search when it contains a slash. */ + execv(file, argv); + } else { + int got_eacces; + size_t len, pathlen; + char *name, *p; + char *path = getenv("PATH"); + if (path == NULL) + path = ":/bin:/usr/bin"; + + len = strlen(file) + 1; + pathlen = strlen(path); + /* Copy the file name at the top. */ + name = memcpy(buf + pathlen + 1, file, len); + /* And add the slash. */ + *--name = '/'; + + got_eacces = 0; + p = path; + do { + char *startp; + + path = p; + //Let's avoid this GNU extension. + //p = strchrnul (path, ':'); + p = strchr(path, ':'); + if (!p) + p = strchr(path, '\0'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + of `PATH' means to search the current directory. */ + startp = name + 1; + else + startp = memcpy(name - (p - path), path, p - path); + + /* Try to execute this name. If it works, execv will not return. */ + execv(startp, argv); + + /* + if (errno == ENOEXEC) { + } + */ + + switch (errno) { + case EACCES: + /* Record the we got a `Permission denied' error. If we end + up finding no executable we can use, we want to diagnose + that we did find one but were denied access. */ + got_eacces = 1; + case ENOENT: + case ESTALE: + case ENOTDIR: + /* Those errors indicate the file is missing or not executable + by us, in which case we want to just try the next path + directory. */ + case ENODEV: + case ETIMEDOUT: + /* Some strange filesystems like AFS return even + stranger error numbers. They cannot reasonably mean + anything else so ignore those, too. */ + case ENOEXEC: + /* We won't go searching for the shell + * if it is not executable - the Linux + * kernel already handles this enough, + * for us. */ + break; + + default: + /* Some other error means we found an executable file, but + something went wrong executing it; return the error to our + caller. */ + return -errno; + } + } while (*p++ != '\0'); + + /* We tried every element and none of them worked. */ + if (got_eacces) + /* At least one failure was due to permissions, so report that + error. */ + return -EACCES; + } + + /* Return the error from the last attempt (probably ENOENT). */ + return -errno; +} +#ifdef TEST +int main(int argc, char**argv) +{ + char buf[PATH_MAX]; + int ret; + argc--; + if (!argc) { + fprintf(stderr, "Not enough arguments\n"); + return 1; + } + argv++; + if (ret = execvp_noalloc(buf, argv[0], argv)) { + errno = -ret; + perror("execvp_noalloc"); + } + return 0; +} +#endif diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index d13299cfa31..c7ad6306e22 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c @@ -8,18 +8,21 @@ #include #include #include +#include #include #include #include "user.h" #include "kern_util.h" #include "user_util.h" #include "os.h" +#include "um_malloc.h" struct helper_data { void (*pre_exec)(void*); void *pre_data; char **argv; int fd; + char *buf; }; /* Debugging aid, changed only from gdb */ @@ -41,9 +44,8 @@ static int helper_child(void *arg) } if (data->pre_exec != NULL) (*data->pre_exec)(data->pre_data); - execvp(argv[0], argv); - errval = -errno; - printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); + errval = execvp_noalloc(data->buf, argv[0], argv); + printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); os_write_file(data->fd, &errval, sizeof(errval)); kill(os_getpid(), SIGKILL); return 0; @@ -84,11 +86,13 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; + data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) : + um_kmalloc(PATH_MAX); pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); if (pid < 0) { ret = -errno; printk("run_helper : clone failed, errno = %d\n", errno); - goto out_close; + goto out_free2; } close(fds[1]); @@ -109,6 +113,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, CATCH_EINTR(waitpid(pid, NULL, 0)); } +out_free2: + kfree(data.buf); out_close: if (fds[1] != -1) close(fds[1]); -- cgit v1.2.3 From d00ec458cb9235025d20cf2783d3ddcd879a6c48 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 25 Nov 2006 16:19:23 +0000 Subject: [ARM] Add PM_LEGACY defaults Eliminate two warnings: kernel/power/pm.c:205: warning: 'pm_register' is deprecated (declared at kernel/power/pm.c:64) kernel/power/pm.c:206: warning: 'pm_send_all' is deprecated (declared at kernel/power/pm.c:180) by updating defconfig files to contain a sensible PM_LEGACY default. Signed-off-by: Russell King --- arch/arm/configs/assabet_defconfig | 1 + arch/arm/configs/cerfcube_defconfig | 1 + arch/arm/configs/corgi_defconfig | 1 + arch/arm/configs/h3600_defconfig | 1 + arch/arm/configs/integrator_defconfig | 1 + arch/arm/configs/jornada720_defconfig | 1 + arch/arm/configs/lart_defconfig | 1 + arch/arm/configs/neponset_defconfig | 1 + arch/arm/configs/simpad_defconfig | 1 + arch/arm/configs/spitz_defconfig | 1 + 10 files changed, 10 insertions(+) (limited to 'arch') diff --git a/arch/arm/configs/assabet_defconfig b/arch/arm/configs/assabet_defconfig index 089c9d59840..b1cd331aaec 100644 --- a/arch/arm/configs/assabet_defconfig +++ b/arch/arm/configs/assabet_defconfig @@ -184,6 +184,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig index f81a60005cd..09b7acd7f64 100644 --- a/arch/arm/configs/cerfcube_defconfig +++ b/arch/arm/configs/cerfcube_defconfig @@ -194,6 +194,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 3c3461e8339..c41c04fa502 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -208,6 +208,7 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index 7a0da0b7fac..8f986e9f1c6 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig @@ -194,6 +194,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index d1ba7fdde81..692ab57ba1c 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -190,6 +190,7 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig index ad1048db96f..80a6fd97eb3 100644 --- a/arch/arm/configs/jornada720_defconfig +++ b/arch/arm/configs/jornada720_defconfig @@ -182,6 +182,7 @@ CONFIG_BINFMT_AOUT=m # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set # CONFIG_APM is not set # diff --git a/arch/arm/configs/lart_defconfig b/arch/arm/configs/lart_defconfig index c3a93284416..a1cc34f2560 100644 --- a/arch/arm/configs/lart_defconfig +++ b/arch/arm/configs/lart_defconfig @@ -180,6 +180,7 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set CONFIG_APM=m # diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig index 3d35255c64e..df8168e57b7 100644 --- a/arch/arm/configs/neponset_defconfig +++ b/arch/arm/configs/neponset_defconfig @@ -190,6 +190,7 @@ CONFIG_BINFMT_AOUT=y # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig index 2e5a616cc98..140056a3507 100644 --- a/arch/arm/configs/simpad_defconfig +++ b/arch/arm/configs/simpad_defconfig @@ -180,6 +180,7 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set CONFIG_APM=y # diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index d1ace3abfd8..bd03238968c 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -207,6 +207,7 @@ CONFIG_BINFMT_MISC=m # Power management options # CONFIG_PM=y +# CONFIG_PM_LEGACY is not set CONFIG_APM=y # -- cgit v1.2.3 From e730bf96c89b27b2a90ae3e8054dae6133b4f90b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 25 Nov 2006 20:15:12 +0000 Subject: [ARM] Export smp_call_function() smp_call_function() will be used with the MP/core oprofile support patch. Export it as _GPL. Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index a07d202143c..070bcb7a630 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -451,6 +451,7 @@ int smp_call_function(void (*func)(void *info), void *info, int retry, return smp_call_function_on_cpu(func, info, retry, wait, cpu_online_map); } +EXPORT_SYMBOL_GPL(smp_call_function); void show_ipi_list(struct seq_file *p) { -- cgit v1.2.3 From 24d7bb3396c51ceb2285e0e7b0c1bd1865652c43 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 28 Nov 2006 09:14:05 +0100 Subject: [PATCH] x86_64: fix 'earlyprintk=...,keep' regression Commit 2c8c0e6b8d7700a990da8d24eff767f9ca223b96 ("[PATCH] Convert x86-64 to early param") broke the earlyprintk=...,keep feature. This restores that functionality. Tested on x86_64. Must-have for v2.6.19, no risk. Signed-off-by: Ingo Molnar Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/early_printk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/early_printk.c b/arch/x86_64/kernel/early_printk.c index e22ecd54870..47b6d90349d 100644 --- a/arch/x86_64/kernel/early_printk.c +++ b/arch/x86_64/kernel/early_printk.c @@ -224,7 +224,7 @@ static int __init setup_early_printk(char *buf) return 0; early_console_initialized = 1; - if (!strcmp(buf,"keep")) + if (strstr(buf, "keep")) keep_early = 1; if (!strncmp(buf, "serial", 6)) { -- cgit v1.2.3 From f7a23328a738b45124400d85eaf78a76939da726 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 28 Nov 2006 20:12:59 +0100 Subject: [PATCH] x86-64: Fix warning in io_apic.c --- arch/x86_64/kernel/io_apic.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 14654e68241..c80081a6ba4 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -754,10 +754,8 @@ void __setup_vector_irq(int cpu) { /* Initialize vector_irq on a new cpu */ /* This function must be called with vector_lock held */ - unsigned long flags; int irq, vector; - /* Mark the inuse vectors */ for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) { if (!cpu_isset(cpu, irq_domain[irq])) -- cgit v1.2.3 From c547c77ee4d0408907847f64c403df1bf2f9c7a0 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 28 Nov 2006 20:12:59 +0100 Subject: [PATCH] x86-64: Use stricter in process stack check for unwinder Previously it would check for alignment only, which could break if the stack pointer was unaligned. Now explicitely check if the stack pointer is in the stack page of the current process. Ported from i386. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index a153d0a01b7..0d65b22f229 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -242,12 +242,19 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +{ + void *t = (void *)tinfo; + return p > t && p < t + THREAD_SIZE - 3; +} + void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, struct stacktrace_ops *ops, void *data) { const unsigned cpu = smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; + struct thread_info *tinfo; if (!tsk) tsk = current; @@ -370,7 +377,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s /* * This handles the process stack: */ - HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); + tinfo = current_thread_info(); + HANDLE_STACK (valid_stack_ptr(tinfo, stack)); #undef HANDLE_STACK } EXPORT_SYMBOL(dump_trace); -- cgit v1.2.3 From 177b2927e2eea73c598a218680b4dc9043c51dcb Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 24 Nov 2006 12:17:51 +0000 Subject: [MIPS] Fix Bonito bootup message. Even when enabling Bonito IOBC coherence the kernel would actually claim it was disabling it. Signed-off-by: Ralf Baechle --- arch/mips/mips-boards/malta/malta_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index ab460f805be..282f3e52eea 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -159,7 +159,7 @@ void __init plat_mem_setup(void) BONITO_PCIMEMBASECFG |= (BONITO_PCIMEMBASECFG_MEMBASE0_CACHED | BONITO_PCIMEMBASECFG_MEMBASE1_CACHED); - printk("Disabled Bonito IOBC coherency\n"); + printk("Enabled Bonito IOBC coherency\n"); } } else -- cgit v1.2.3 From f5d6c63a67a8f124ddae88511427249d1dd87880 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 29 Nov 2006 15:04:08 +0000 Subject: [MIPS] Do topology_init even on uniprocessor kernels. Otherwise CPU 0 doesn't show up in sysfs which breaks some software. Signed-off-by: Ralf Baechle --- arch/mips/kernel/Makefile | 2 +- arch/mips/kernel/smp.c | 23 ----------------------- arch/mips/kernel/topology.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 24 deletions(-) create mode 100644 arch/mips/kernel/topology.c (limited to 'arch') diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index cd9cec9e39e..6bfbbed0897 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ - time.o traps.o unaligned.o + time.o topology.o traps.o unaligned.o binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index db80957ada8..49db516789e 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -463,28 +463,5 @@ void flush_tlb_one(unsigned long vaddr) smp_on_each_tlb(flush_tlb_one_ipi, (void *) vaddr); } -static DEFINE_PER_CPU(struct cpu, cpu_devices); - -static int __init topology_init(void) -{ - int i, ret; - -#ifdef CONFIG_NUMA - for_each_online_node(i) - register_one_node(i); -#endif /* CONFIG_NUMA */ - - for_each_present_cpu(i) { - ret = register_cpu(&per_cpu(cpu_devices, i), i); - if (ret) - printk(KERN_WARNING "topology_init: register_cpu %d " - "failed (%d)\n", i, ret); - } - - return 0; -} - -subsys_initcall(topology_init); - EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(flush_tlb_one); diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c new file mode 100644 index 00000000000..660e44ed44d --- /dev/null +++ b/arch/mips/kernel/topology.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include +#include + +static DEFINE_PER_CPU(struct cpu, cpu_devices); + +static int __init topology_init(void) +{ + int i, ret; + +#ifdef CONFIG_NUMA + for_each_online_node(i) + register_one_node(i); +#endif /* CONFIG_NUMA */ + + for_each_present_cpu(i) { + ret = register_cpu(&per_cpu(cpu_devices, i), i); + if (ret) + printk(KERN_WARNING "topology_init: register_cpu %d " + "failed (%d)\n", i, ret); + } + + return 0; +} + +subsys_initcall(topology_init); -- cgit v1.2.3 From 99e3b942c62f42c8d5added63305e12372b06daf Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:19:59 +0200 Subject: [MIPS] page.h: remove __pa() usages. __pa() was used by virt_to_page() and virt_addr_valid(). These latter are used when kernel is initialised so __pa() is not appropriate, we use virt_to_phys() instead. Futhermore __pa() is going to take care of CKSEG0/XKPHYS address mix for 64 bit kernels. This makes __pa() more complex than virt_to_phys() and this extra work is not needed by virt_to_page() and virt_addr_valid(). Eventually it consolidates virt_to_phys() prototype by making its argument 'const'. this avoids some warnings that was due to some virt_to_page() usages which pass const pointer. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/mm/init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 2de4d3c367a..304991263f6 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -90,9 +90,9 @@ unsigned long setup_zero_pages(void) if (!empty_zero_page) panic("Oh boy, that early out of memory?"); - page = virt_to_page(empty_zero_page); + page = virt_to_page((void *)empty_zero_page); split_page(page, order); - while (page < virt_to_page(empty_zero_page + (PAGE_SIZE << order))) { + while (page < virt_to_page((void *)(empty_zero_page + (PAGE_SIZE << order)))) { SetPageReserved(page); page++; } @@ -448,8 +448,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) unsigned long addr; for (addr = begin; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page(addr)); - init_page_count(virt_to_page(addr)); + ClearPageReserved(virt_to_page((void *)addr)); + init_page_count(virt_to_page((void *)addr)); memset((void *)addr, 0xcc, PAGE_SIZE); free_page(addr); totalram_pages++; -- cgit v1.2.3 From d4df6d4e7a66b7a9bd57f5dc7d80d6b55dc12dbb Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:01 +0200 Subject: [MIPS] setup.c: get ride of CPHYSADDR() and use new __pa() implementation instead introduced by the previous patch. Indeed this macro can be used now even by the 64 bit kernels with CONFIG_BUILD_ELF64=n config. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 8f6e89697cc..715451a9d5d 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -204,12 +204,12 @@ static void __init finalize_initrd(void) printk(KERN_INFO "Initrd not found or empty"); goto disable; } - if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { + if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("Initrd extends beyond end of memory"); goto disable; } - reserve_bootmem(CPHYSADDR(initrd_start), size); + reserve_bootmem(__pa(initrd_start), size); initrd_below_start_ok = 1; printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", @@ -260,7 +260,7 @@ static void __init bootmem_init(void) * of usable memory. */ reserved_end = init_initrd(); - reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); + reserved_end = PFN_UP(__pa(max(reserved_end, (unsigned long)&_end))); /* * Find the highest page frame number we have available. -- cgit v1.2.3 From f5bffe3a9bcd6e5319b5fd3a8109625f8638425a Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:03 +0200 Subject: [MIPS] setup.c: use __pa_symbol() where needed It should fix the broken code in resource_init() too. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 715451a9d5d..b52cc976376 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -260,7 +260,7 @@ static void __init bootmem_init(void) * of usable memory. */ reserved_end = init_initrd(); - reserved_end = PFN_UP(__pa(max(reserved_end, (unsigned long)&_end))); + reserved_end = PFN_UP(max(__pa(reserved_end), __pa_symbol(&_end))); /* * Find the highest page frame number we have available. @@ -432,10 +432,10 @@ static void __init resource_init(void) if (UNCAC_BASE != IO_BASE) return; - code_resource.start = virt_to_phys(&_text); - code_resource.end = virt_to_phys(&_etext) - 1; - data_resource.start = virt_to_phys(&_etext); - data_resource.end = virt_to_phys(&_edata) - 1; + code_resource.start = __pa_symbol(&_text); + code_resource.end = __pa_symbol(&_etext) - 1; + data_resource.start = __pa_symbol(&_etext); + data_resource.end = __pa_symbol(&_edata) - 1; /* * Request address space for all standard RAM. -- cgit v1.2.3 From a7837b76b6de932c31d0b7c71176ca8d1213a3ce Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:04 +0200 Subject: [MIPS] setup.c: clean up initrd related code Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 75 +++++++++++++++++++++++++++++++----------------- arch/mips/mm/init.c | 5 ---- 2 files changed, 48 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index b52cc976376..89440a0d852 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -145,13 +145,12 @@ static int __init rd_start_early(char *p) unsigned long start = memparse(p, &p); #ifdef CONFIG_64BIT - /* HACK: Guess if the sign extension was forgotten */ - if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000UL; + /* Guess if the sign extension was forgotten by bootloader */ + if (start < XKPHYS) + start = (int)start; #endif initrd_start = start; initrd_end += start; - return 0; } early_param("rd_start", rd_start_early); @@ -159,41 +158,64 @@ early_param("rd_start", rd_start_early); static int __init rd_size_early(char *p) { initrd_end += memparse(p, &p); - return 0; } early_param("rd_size", rd_size_early); +/* it returns the next free pfn after initrd */ static unsigned long __init init_initrd(void) { - unsigned long tmp, end, size; + unsigned long end; u32 *initrd_header; - ROOT_DEV = Root_RAM0; - /* * Board specific code or command line parser should have * already set up initrd_start and initrd_end. In these cases * perfom sanity checks and use them if all looks good. */ - size = initrd_end - initrd_start; - if (initrd_end == 0 || size == 0) { - initrd_start = 0; - initrd_end = 0; - } else - return initrd_end; - - end = (unsigned long)&_end; - tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; - if (tmp < end) - tmp += PAGE_SIZE; - - initrd_header = (u32 *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; + if (initrd_start && initrd_end > initrd_start) + goto sanitize; + + /* + * See if initrd has been added to the kernel image by + * arch/mips/boot/addinitrd.c. In that case a header is + * prepended to initrd and is made up by 8 bytes. The fisrt + * word is a magic number and the second one is the size of + * initrd. Initrd start must be page aligned in any cases. + */ + initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; + if (initrd_header[0] != 0x494E5244) + goto disable; + initrd_start = (unsigned long)(initrd_header + 2); + initrd_end = initrd_start + initrd_header[1]; + +sanitize: + if (initrd_start & ~PAGE_MASK) { + printk(KERN_ERR "initrd start must be page aligned\n"); + goto disable; } - return initrd_end; + if (initrd_start < PAGE_OFFSET) { + printk(KERN_ERR "initrd start < PAGE_OFFSET\n"); + goto disable; + } + + /* + * Sanitize initrd addresses. For example firmware + * can't guess if they need to pass them through + * 64-bits values if the kernel has been built in pure + * 32-bit. We need also to switch from KSEG0 to XKPHYS + * addresses now, so the code can now safely use __pa(). + */ + end = __pa(initrd_end); + initrd_end = (unsigned long)__va(end); + initrd_start = (unsigned long)__va(__pa(initrd_start)); + + ROOT_DEV = Root_RAM0; + return PFN_UP(end); +disable: + initrd_start = 0; + initrd_end = 0; + return 0; } static void __init finalize_initrd(void) @@ -259,8 +281,7 @@ static void __init bootmem_init(void) * not selected. Once that done we can determine the low bound * of usable memory. */ - reserved_end = init_initrd(); - reserved_end = PFN_UP(max(__pa(reserved_end), __pa_symbol(&_end))); + reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); /* * Find the highest page frame number we have available. diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 304991263f6..4076963c601 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -460,11 +460,6 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { -#ifdef CONFIG_64BIT - /* Switch from KSEG0 to XKPHYS addresses */ - start = (unsigned long)phys_to_virt(CPHYSADDR(start)); - end = (unsigned long)phys_to_virt(CPHYSADDR(end)); -#endif free_init_pages("initrd memory", start, end); } #endif -- cgit v1.2.3 From acd86b8622099c3206e0a1665545ae2318089b9c Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Thu, 19 Oct 2006 13:20:05 +0200 Subject: [MIPS] Make free_init_pages() arguments to be physical addresses It allows caller of this function to not care about CKSEG0/XKPHYS address mixes. It's now automatically done by free_init_pages(). We can now safely remove hack needed by 64 bit kernels with CONFIG_BUILD_ELF64=n in free_initmem(). Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/mm/init.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 4076963c601..9e29ba9205f 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -443,15 +443,18 @@ void __init mem_init(void) } #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -void free_init_pages(char *what, unsigned long begin, unsigned long end) +static void free_init_pages(char *what, unsigned long begin, unsigned long end) { - unsigned long addr; + unsigned long pfn; - for (addr = begin; addr < end; addr += PAGE_SIZE) { - ClearPageReserved(virt_to_page((void *)addr)); - init_page_count(virt_to_page((void *)addr)); - memset((void *)addr, 0xcc, PAGE_SIZE); - free_page(addr); + for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) { + struct page *page = pfn_to_page(pfn); + void *addr = phys_to_virt(PFN_PHYS(pfn)); + + ClearPageReserved(page); + init_page_count(page); + memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); + __free_page(page); totalram_pages++; } printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); @@ -460,7 +463,9 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { - free_init_pages("initrd memory", start, end); + free_init_pages("initrd memory", + virt_to_phys((void *)start), + virt_to_phys((void *)end)); } #endif @@ -468,17 +473,13 @@ extern unsigned long prom_free_prom_memory(void); void free_initmem(void) { - unsigned long start, end, freed; + unsigned long freed; freed = prom_free_prom_memory(); if (freed) printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); - start = (unsigned long)(&__init_begin); - end = (unsigned long)(&__init_end); -#ifdef CONFIG_64BIT - start = PAGE_OFFSET | CPHYSADDR(start); - end = PAGE_OFFSET | CPHYSADDR(end); -#endif - free_init_pages("unused kernel memory", start, end); + free_init_pages("unused kernel memory", + __pa_symbol(&__init_begin), + __pa_symbol(&__init_end)); } -- cgit v1.2.3 From 56ae58333031bb0564c141f955d1e42276cade55 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Sat, 14 Oct 2006 00:25:04 +0900 Subject: [MIPS] Rewrite GALILEO_INL/GALILEO_OUTL to GT_READ/GT_WRITE This patch has rewritten GALILEO_INL/GALILEO_OUTL using GT_READ/GT_WRITE. This patch tested on Cobalt Qube2. Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/cobalt/irq.c | 31 ++++++++++++++----------------- arch/mips/cobalt/setup.c | 16 ++++++++-------- arch/mips/pci/fixup-cobalt.c | 11 +++++------ arch/mips/pci/ops-gt64111.c | 16 ++++++++-------- 4 files changed, 35 insertions(+), 39 deletions(-) (limited to 'arch') diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index 82e569d5b02..4c46f0e7378 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c @@ -45,25 +45,22 @@ static inline void galileo_irq(void) { unsigned int mask, pending, devfn; - mask = GALILEO_INL(GT_INTRMASK_OFS); - pending = GALILEO_INL(GT_INTRCAUSE_OFS) & mask; + mask = GT_READ(GT_INTRMASK_OFS); + pending = GT_READ(GT_INTRCAUSE_OFS) & mask; - if (pending & GALILEO_INTR_T0EXP) { - - GALILEO_OUTL(~GALILEO_INTR_T0EXP, GT_INTRCAUSE_OFS); + if (pending & GT_INTR_T0EXP_MSK) { + GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_T0EXP_MSK); do_IRQ(COBALT_GALILEO_IRQ); - - } else if (pending & GALILEO_INTR_RETRY_CTR) { - - devfn = GALILEO_INL(GT_PCI0_CFGADDR_OFS) >> 8; - GALILEO_OUTL(~GALILEO_INTR_RETRY_CTR, GT_INTRCAUSE_OFS); - printk(KERN_WARNING "Galileo: PCI retry count exceeded (%02x.%u)\n", - PCI_SLOT(devfn), PCI_FUNC(devfn)); - + } else if (pending & GT_INTR_RETRYCTR0_MSK) { + devfn = GT_READ(GT_PCI0_CFGADDR_OFS) >> 8; + GT_WRITE(GT_INTRCAUSE_OFS, ~GT_INTR_RETRYCTR0_MSK); + printk(KERN_WARNING + "Galileo: PCI retry count exceeded (%02x.%u)\n", + PCI_SLOT(devfn), PCI_FUNC(devfn)); } else { - - GALILEO_OUTL(mask & ~pending, GT_INTRMASK_OFS); - printk(KERN_WARNING "Galileo: masking unexpected interrupt %08x\n", pending); + GT_WRITE(GT_INTRMASK_OFS, mask & ~pending); + printk(KERN_WARNING + "Galileo: masking unexpected interrupt %08x\n", pending); } } @@ -104,7 +101,7 @@ void __init arch_init_irq(void) * Mask all Galileo interrupts. The Galileo * handler is set in cobalt_timer_setup() */ - GALILEO_OUTL(0, GT_INTRMASK_OFS); + GT_WRITE(GT_INTRMASK_OFS, 0); init_i8259_irqs(); /* 0 ... 15 */ mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index bf9dc72b972..e8f0f20b852 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c @@ -51,23 +51,23 @@ const char *get_system_type(void) void __init plat_timer_setup(struct irqaction *irq) { /* Load timer value for HZ (TCLK is 50MHz) */ - GALILEO_OUTL(50*1000*1000 / HZ, GT_TC0_OFS); + GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ); /* Enable timer */ - GALILEO_OUTL(GALILEO_ENTC0 | GALILEO_SELTC0, GT_TC_CONTROL_OFS); + GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); /* Register interrupt */ setup_irq(COBALT_GALILEO_IRQ, irq); /* Enable interrupt */ - GALILEO_OUTL(GALILEO_INTR_T0EXP | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); + GT_WRITE(GT_INTRMASK_OFS, GT_INTR_T0EXP_MSK | GT_READ(GT_INTRMASK_OFS)); } extern struct pci_ops gt64111_pci_ops; static struct resource cobalt_mem_resource = { - .start = GT64111_MEM_BASE, - .end = GT64111_MEM_END, + .start = GT_DEF_PCI0_MEM0_BASE, + .end = GT_DEF_PCI0_MEM0_BASE + GT_DEF_PCI0_MEM0_SIZE - 1, .name = "PCI memory", .flags = IORESOURCE_MEM }; @@ -115,7 +115,7 @@ static struct pci_controller cobalt_pci_controller = { .mem_resource = &cobalt_mem_resource, .mem_offset = 0, .io_resource = &cobalt_io_resource, - .io_offset = 0 - GT64111_IO_BASE + .io_offset = 0 - GT_DEF_PCI0_IO_BASE, }; void __init plat_mem_setup(void) @@ -128,7 +128,7 @@ void __init plat_mem_setup(void) _machine_halt = cobalt_machine_halt; pm_power_off = cobalt_machine_power_off; - set_io_port_base(CKSEG1ADDR(GT64111_IO_BASE)); + set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE)); /* I/O port resource must include UART and LCD/buttons */ ioport_resource.end = 0x0fffffff; @@ -139,7 +139,7 @@ void __init plat_mem_setup(void) /* Read the cobalt id register out of the PCI config space */ PCI_CFG_SET(devfn, (VIA_COBALT_BRD_ID_REG & ~0x3)); - cobalt_board_id = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + cobalt_board_id = GT_READ(GT_PCI0_CFGDATA_OFS); cobalt_board_id >>= ((VIA_COBALT_BRD_ID_REG & 3) * 8); cobalt_board_id = VIA_COBALT_BRD_REG_to_ID(cobalt_board_id); diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index 75a01e76489..7d5f6bbf7a9 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c @@ -94,22 +94,21 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) #if 0 if (galileo_id >= 0x10) { /* New Galileo, assumes PCI stop line to VIA is connected. */ - GALILEO_OUTL(0x4020, GT_PCI0_TOR_OFS); + GT_WRITE(GT_PCI0_TOR_OFS, 0x4020); } else if (galileo_id == 0x1 || galileo_id == 0x2) #endif { signed int timeo; /* XXX WE MUST DO THIS ELSE GALILEO LOCKS UP! -DaveM */ - timeo = GALILEO_INL(GT_PCI0_TOR_OFS); + timeo = GT_READ(GT_PCI0_TOR_OFS); /* Old Galileo, assumes PCI STOP line to VIA is disconnected. */ - GALILEO_OUTL( + GT_WRITE(GT_PCI0_TOR_OFS, (0xff << 16) | /* retry count */ (0xff << 8) | /* timeout 1 */ - 0xff, /* timeout 0 */ - GT_PCI0_TOR_OFS); + 0xff); /* timeout 0 */ /* enable PCI retry exceeded interrupt */ - GALILEO_OUTL(GALILEO_INTR_RETRY_CTR | GALILEO_INL(GT_INTRMASK_OFS), GT_INTRMASK_OFS); + GT_WRITE(GT_INTRMASK_OFS, GT_INTR_RETRYCTR0_MSK | GT_READ(GT_INTRMASK_OFS)); } } diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c index 13de45940b1..ecd3991bd0e 100644 --- a/arch/mips/pci/ops-gt64111.c +++ b/arch/mips/pci/ops-gt64111.c @@ -38,18 +38,18 @@ static int gt64111_pci_read_config(struct pci_bus *bus, unsigned int devfn, switch (size) { case 4: PCI_CFG_SET(devfn, where); - *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + *val = GT_READ(GT_PCI0_CFGDATA_OFS); return PCIBIOS_SUCCESSFUL; case 2: PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) + *val = GT_READ(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; case 1: PCI_CFG_SET(devfn, (where & ~0x3)); - *val = GALILEO_INL(GT_PCI0_CFGDATA_OFS) + *val = GT_READ(GT_PCI0_CFGDATA_OFS) >> ((where & 3) * 8); return PCIBIOS_SUCCESSFUL; } @@ -68,25 +68,25 @@ static int gt64111_pci_write_config(struct pci_bus *bus, unsigned int devfn, switch (size) { case 4: PCI_CFG_SET(devfn, where); - GALILEO_OUTL(val, GT_PCI0_CFGDATA_OFS); + GT_WRITE(GT_PCI0_CFGDATA_OFS, val); return PCIBIOS_SUCCESSFUL; case 2: PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xffff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); return PCIBIOS_SUCCESSFUL; case 1: PCI_CFG_SET(devfn, (where & ~0x3)); - tmp = GALILEO_INL(GT_PCI0_CFGDATA_OFS); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); tmp &= ~(0xff << ((where & 0x3) * 8)); tmp |= (val << ((where & 0x3) * 8)); - GALILEO_OUTL(tmp, GT_PCI0_CFGDATA_OFS); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); return PCIBIOS_SUCCESSFUL; } -- cgit v1.2.3 From 656be92f9ae194ed62bc81310a4589a7cd765f13 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 26 Oct 2006 00:08:31 +0900 Subject: [MIPS] Load modules to CKSEG0 if CONFIG_BUILD_ELF64=n This is a patch to load 64-bit modules to CKSEG0 so that can be compiled with -msym32 option. This makes each module ~10% smaller. * introduce MODULE_START and MODULE_END * custom module_alloc() * PGD for modules * change XTLB refill handler synthesizer * enable -msym32 for modules again (revert ca78b1a5c6a6e70e052d3ea253828e49b5d07c8a) New XTLB refill handler looks like this: 80000080 dmfc0 k0,C0_BADVADDR 80000084 bltz k0,800000e4 # goto l_module_alloc 80000088 lui k1,0x8046 # %high(pgd_current) 8000008c ld k1,24600(k1) # %low(pgd_current) 80000090 dsrl k0,k0,0x1b # l_vmalloc_done: 80000094 andi k0,k0,0x1ff8 80000098 daddu k1,k1,k0 8000009c dmfc0 k0,C0_BADVADDR 800000a0 ld k1,0(k1) 800000a4 dsrl k0,k0,0x12 800000a8 andi k0,k0,0xff8 800000ac daddu k1,k1,k0 800000b0 dmfc0 k0,C0_XCONTEXT 800000b4 ld k1,0(k1) 800000b8 andi k0,k0,0xff0 800000bc daddu k1,k1,k0 800000c0 ld k0,0(k1) 800000c4 ld k1,8(k1) 800000c8 dsrl k0,k0,0x6 800000cc mtc0 k0,C0_ENTRYLO0 800000d0 dsrl k1,k1,0x6 800000d4 mtc0 k1,C0_ENTRYL01 800000d8 nop 800000dc tlbwr 800000e0 eret 800000e4 dsll k1,k0,0x2 # l_module_alloc: 800000e8 bgez k1,80000008 # goto l_vmalloc 800000ec lui k1,0xc000 800000f0 dsubu k0,k0,k1 800000f4 lui k1,0x8046 # %high(module_pg_dir) 800000f8 beq zero,zero,80000000 800000fc nop 80000000 beq zero,zero,80000090 # goto l_vmalloc_done 80000004 daddiu k1,k1,0x4000 80000008 dsll32 k1,k1,0x0 # l_vmalloc: 8000000c dsubu k0,k0,k1 80000010 beq zero,zero,80000090 # goto l_vmalloc_done 80000014 lui k1,0x8046 # %high(swapper_pg_dir) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Makefile | 4 +--- arch/mips/kernel/head.S | 3 +++ arch/mips/kernel/module.c | 15 +++++++++++++ arch/mips/mm/fault.c | 4 ++++ arch/mips/mm/pgtable-64.c | 3 +++ arch/mips/mm/tlbex.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/Makefile b/arch/mips/Makefile index d580d46f967..641aa30b363 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -63,9 +63,7 @@ cflags-y += -mabi=64 ifdef CONFIG_BUILD_ELF64 cflags-y += $(call cc-option,-mno-explicit-relocs) else -# -msym32 can not be used for modules since they are loaded into XKSEG -CFLAGS_MODULE += $(call cc-option,-mno-explicit-relocs) -CFLAGS_KERNEL += $(call cc-option,-msym32) +cflags-y += $(call cc-option,-msym32) endif endif diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index ddc1b71c937..a2e095adaa3 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -250,6 +250,9 @@ NESTED(smp_bootstrap, 16, sp) */ page swapper_pg_dir, _PGD_ORDER #ifdef CONFIG_64BIT +#if defined(CONFIG_MODULES) && !defined(CONFIG_BUILD_ELF64) + page module_pg_dir, _PGD_ORDER +#endif page invalid_pmd_table, _PMD_ORDER #endif page invalid_pte_table, _PTE_ORDER diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index d7bf0215bc1..cb0801437b6 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -29,6 +29,7 @@ #include #include #include +#include /* MODULE_START */ struct mips_hi16 { struct mips_hi16 *next; @@ -43,9 +44,23 @@ static DEFINE_SPINLOCK(dbe_lock); void *module_alloc(unsigned long size) { +#ifdef MODULE_START + struct vm_struct *area; + + size = PAGE_ALIGN(size); + if (!size) + return NULL; + + area = __get_vm_area(size, VM_ALLOC, MODULE_START, MODULE_END); + if (!area) + return NULL; + + return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); +#else if (size == 0) return NULL; return vmalloc(size); +#endif } /* Free memory returned from module_alloc */ diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 8423d859077..6f90e7ef66a 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -60,6 +60,10 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, */ if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END)) goto vmalloc_fault; +#ifdef MODULE_START + if (unlikely(address >= MODULE_START && address < MODULE_END)) + goto vmalloc_fault; +#endif /* * If we're in an interrupt or have no user diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c index 8d600d307d5..c46eb651bf0 100644 --- a/arch/mips/mm/pgtable-64.c +++ b/arch/mips/mm/pgtable-64.c @@ -58,6 +58,9 @@ void __init pagetable_init(void) /* Initialize the entire pgd. */ pgd_init((unsigned long)swapper_pg_dir); +#ifdef MODULE_START + pgd_init((unsigned long)module_pg_dir); +#endif pmd_init((unsigned long)invalid_pmd_table, (unsigned long)invalid_pte_table); pgd_base = swapper_pg_dir; diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index fec318a1c8c..492c518e7ba 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c @@ -423,6 +423,9 @@ enum label_id { label_invalid, label_second_part, label_leave, +#ifdef MODULE_START + label_module_alloc, +#endif label_vmalloc, label_vmalloc_done, label_tlbw_hazard, @@ -455,6 +458,9 @@ static __init void build_label(struct label **lab, u32 *addr, L_LA(_second_part) L_LA(_leave) +#ifdef MODULE_START +L_LA(_module_alloc) +#endif L_LA(_vmalloc) L_LA(_vmalloc_done) L_LA(_tlbw_hazard) @@ -686,6 +692,13 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg, i_bgezl(p, reg, 0); } +static void __init __attribute__((unused)) +il_bgez(u32 **p, struct reloc **r, unsigned int reg, enum label_id l) +{ + r_mips_pc16(r, *p, l); + i_bgez(p, reg, 0); +} + /* The only general purpose registers allowed in TLB handlers. */ #define K0 26 #define K1 27 @@ -970,7 +983,11 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, * The vmalloc handling is not in the hotpath. */ i_dmfc0(p, tmp, C0_BADVADDR); +#ifdef MODULE_START + il_bltz(p, r, tmp, label_module_alloc); +#else il_bltz(p, r, tmp, label_vmalloc); +#endif /* No i_nop needed here, since the next insn doesn't touch TMP. */ #ifdef CONFIG_SMP @@ -1023,8 +1040,46 @@ build_get_pgd_vmalloc64(u32 **p, struct label **l, struct reloc **r, { long swpd = (long)swapper_pg_dir; +#ifdef MODULE_START + long modd = (long)module_pg_dir; + + l_module_alloc(l, *p); + /* + * Assumption: + * VMALLOC_START >= 0xc000000000000000UL + * MODULE_START >= 0xe000000000000000UL + */ + i_SLL(p, ptr, bvaddr, 2); + il_bgez(p, r, ptr, label_vmalloc); + + if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START)) { + i_lui(p, ptr, rel_hi(MODULE_START)); /* delay slot */ + } else { + /* unlikely configuration */ + i_nop(p); /* delay slot */ + i_LA(p, ptr, MODULE_START); + } + i_dsubu(p, bvaddr, bvaddr, ptr); + + if (in_compat_space_p(modd) && !rel_lo(modd)) { + il_b(p, r, label_vmalloc_done); + i_lui(p, ptr, rel_hi(modd)); + } else { + i_LA_mostly(p, ptr, modd); + il_b(p, r, label_vmalloc_done); + i_daddiu(p, ptr, ptr, rel_lo(modd)); + } + + l_vmalloc(l, *p); + if (in_compat_space_p(MODULE_START) && !rel_lo(MODULE_START) && + MODULE_START << 32 == VMALLOC_START) + i_dsll32(p, ptr, ptr, 0); /* typical case */ + else + i_LA(p, ptr, VMALLOC_START); +#else l_vmalloc(l, *p); i_LA(p, ptr, VMALLOC_START); +#endif i_dsubu(p, bvaddr, bvaddr, ptr); if (in_compat_space_p(swpd) && !rel_lo(swpd)) { -- cgit v1.2.3 From 5b10496b6e6577f65b032a5c4c97d0d3a841273c Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 11 Sep 2006 17:50:29 +0900 Subject: [MIPS] Fast path for rdhwr emulation for TLS Add special short path for emulationg RDHWR which is used to support TLS. Add an extra prologue for cpu_has_vtag_icache case. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/genex.S | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/traps.c | 15 +++++++++++- 2 files changed, 77 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 5baca16993d..aacd4a005c5 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -19,6 +19,7 @@ #include #include #include +#include #define PANIC_PIC(msg) \ .set push; \ @@ -378,6 +379,68 @@ NESTED(nmi_handler, PT_SIZE, sp) BUILD_HANDLER dsp dsp sti silent /* #26 */ BUILD_HANDLER reserved reserved sti verbose /* others */ + .align 5 + LEAF(handle_ri_rdhwr_vivt) +#ifdef CONFIG_MIPS_MT_SMTC + PANIC_PIC("handle_ri_rdhwr_vivt called") +#else + .set push + .set noat + .set noreorder + /* check if TLB contains a entry for EPC */ + MFC0 k1, CP0_ENTRYHI + andi k1, 0xff /* ASID_MASK */ + MFC0 k0, CP0_EPC + PTR_SRL k0, PAGE_SHIFT + 1 + PTR_SLL k0, PAGE_SHIFT + 1 + or k1, k0 + MTC0 k1, CP0_ENTRYHI + mtc0_tlbw_hazard + tlbp + tlb_probe_hazard + mfc0 k1, CP0_INDEX + .set pop + bltz k1, handle_ri /* slow path */ + /* fall thru */ +#endif + END(handle_ri_rdhwr_vivt) + + LEAF(handle_ri_rdhwr) + .set push + .set noat + .set noreorder + /* 0x7c03e83b: rdhwr v1,$29 */ + MFC0 k1, CP0_EPC + lui k0, 0x7c03 + lw k1, (k1) + ori k0, 0xe83b + .set reorder + bne k0, k1, handle_ri /* if not ours */ + /* The insn is rdhwr. No need to check CAUSE.BD here. */ + get_saved_sp /* k1 := current_thread_info */ + .set noreorder + MFC0 k0, CP0_EPC +#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) + ori k1, _THREAD_MASK + xori k1, _THREAD_MASK + LONG_L v1, TI_TP_VALUE(k1) + LONG_ADDIU k0, 4 + jr k0 + rfe +#else + LONG_ADDIU k0, 4 /* stall on $k0 */ + MTC0 k0, CP0_EPC + /* I hope three instructions between MTC0 and ERET are enough... */ + ori k1, _THREAD_MASK + xori k1, _THREAD_MASK + LONG_L v1, TI_TP_VALUE(k1) + .set mips3 + eret + .set mips0 +#endif + .set pop + END(handle_ri_rdhwr) + #ifdef CONFIG_64BIT /* A temporary overflow handler used by check_daddi(). */ diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 9fda1b8be3a..6eccfb49ae6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -54,6 +54,8 @@ extern asmlinkage void handle_dbe(void); extern asmlinkage void handle_sys(void); extern asmlinkage void handle_bp(void); extern asmlinkage void handle_ri(void); +extern asmlinkage void handle_ri_rdhwr_vivt(void); +extern asmlinkage void handle_ri_rdhwr(void); extern asmlinkage void handle_cpu(void); extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); @@ -1423,6 +1425,15 @@ void __init set_uncached_handler (unsigned long offset, void *addr, unsigned lon memcpy((void *)(uncached_ebase + offset), addr, size); } +static int __initdata rdhwr_noopt; +static int __init set_rdhwr_noopt(char *str) +{ + rdhwr_noopt = 1; + return 1; +} + +__setup("rdhwr_noopt", set_rdhwr_noopt); + void __init trap_init(void) { extern char except_vec3_generic, except_vec3_r4000; @@ -1502,7 +1513,9 @@ void __init trap_init(void) set_except_vector(8, handle_sys); set_except_vector(9, handle_bp); - set_except_vector(10, handle_ri); + set_except_vector(10, rdhwr_noopt ? handle_ri : + (cpu_has_vtag_icache ? + handle_ri_rdhwr_vivt : handle_ri_rdhwr)); set_except_vector(11, handle_cpu); set_except_vector(12, handle_ov); set_except_vector(13, handle_tr); -- cgit v1.2.3 From c237923009da464881d89f4bc27c3b5b1a93d61b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:44 +0000 Subject: [MIPS] Don't print presence of WAIT instruction on bootup. Not useful and quite a big of noise on bootup of large systems. Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 8485af340ee..442839e9578 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -110,9 +110,8 @@ static inline void check_wait(void) { struct cpuinfo_mips *c = ¤t_cpu_data; - printk("Checking for 'wait' instruction... "); if (nowait) { - printk (" disabled.\n"); + printk("Wait instruction disabled.\n"); return; } @@ -120,11 +119,9 @@ static inline void check_wait(void) case CPU_R3081: case CPU_R3081E: cpu_wait = r3081_wait; - printk(" available.\n"); break; case CPU_TX3927: cpu_wait = r39xx_wait; - printk(" available.\n"); break; case CPU_R4200: /* case CPU_R4300: */ @@ -146,33 +143,23 @@ static inline void check_wait(void) case CPU_74K: case CPU_PR4450: cpu_wait = r4k_wait; - printk(" available.\n"); break; case CPU_TX49XX: cpu_wait = r4k_wait_irqoff; - printk(" available.\n"); break; case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: case CPU_AU1550: case CPU_AU1200: - if (allow_au1k_wait) { + if (allow_au1k_wait) cpu_wait = au1k_wait; - printk(" available.\n"); - } else - printk(" unavailable.\n"); break; case CPU_RM9000: - if ((c->processor_id & 0x00ff) >= 0x40) { + if ((c->processor_id & 0x00ff) >= 0x40) cpu_wait = r4k_wait; - printk(" available.\n"); - } else { - printk(" unavailable.\n"); - } break; default: - printk(" unavailable.\n"); break; } } -- cgit v1.2.3 From 583bb86fbb9e85287f020fe4eb5352a0ec3c66a3 Mon Sep 17 00:00:00 2001 From: Nicolas Schichan Date: Wed, 18 Oct 2006 15:14:55 +0200 Subject: [MIPS] Add support for kexec A tiny userland application loading the kernel and invoking kexec_load for mips is available here: http://chac.le-poulpe.net/~nico/kexec/kexec-2006-10-18.tar.gz Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 17 ++++++++ arch/mips/kernel/Makefile | 2 + arch/mips/kernel/machine_kexec.c | 85 ++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/relocate_kernel.S | 80 +++++++++++++++++++++++++++++++++++ arch/mips/kernel/scall32-o32.S | 2 +- arch/mips/kernel/scall64-64.S | 2 +- arch/mips/kernel/scall64-n32.S | 2 +- arch/mips/kernel/scall64-o32.S | 2 +- 8 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 arch/mips/kernel/machine_kexec.c create mode 100644 arch/mips/kernel/relocate_kernel.S (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1443024b1c7..c0da0ffe8d5 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -766,6 +766,23 @@ config TOSHIBA_RBTX4938 endchoice +config KEXEC + bool "Kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is indepedent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similiarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + source "arch/mips/ddb5xxx/Kconfig" source "arch/mips/gt64120/ev64120/Kconfig" source "arch/mips/jazz/Kconfig" diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 6bfbbed0897..f35b739d0a1 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -67,6 +67,8 @@ obj-$(CONFIG_64BIT) += cpu-bugs64.o obj-$(CONFIG_I8253) += i8253.o +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o + CFLAGS_cpu-bugs64.o = $(shell if $(CC) $(CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi) EXTRA_AFLAGS := $(CFLAGS) diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c new file mode 100644 index 00000000000..e0ad754c7ed --- /dev/null +++ b/arch/mips/kernel/machine_kexec.c @@ -0,0 +1,85 @@ +/* + * machine_kexec.c for kexec + * Created by on Thu Oct 12 15:15:06 2006 + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include + +#include +#include + +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; + +extern unsigned long kexec_start_address; +extern unsigned long kexec_indirection_page; + +int +machine_kexec_prepare(struct kimage *kimage) +{ + return 0; +} + +void +machine_kexec_cleanup(struct kimage *kimage) +{ +} + +void +machine_shutdown(void) +{ +} + +void +machine_crash_shutdown(struct pt_regs *regs) +{ +} + +void +machine_kexec(struct kimage *image) +{ + unsigned long reboot_code_buffer; + unsigned long entry; + unsigned long *ptr; + + reboot_code_buffer = + (unsigned long)page_address(image->control_code_page); + + kexec_start_address = image->start; + kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK); + + memcpy((void*)reboot_code_buffer, relocate_new_kernel, + relocate_new_kernel_size); + + /* + * The generic kexec code builds a page list with physical + * addresses. they are directly accessible through KSEG0 (or + * CKSEG0 or XPHYS if on 64bit system), hence the + * pys_to_virt() call. + */ + for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE); + ptr = (entry & IND_INDIRECTION) ? + phys_to_virt(entry & PAGE_MASK) : ptr + 1) { + if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION || + *ptr & IND_DESTINATION) + *ptr = phys_to_virt(*ptr); + } + + /* + * we do not want to be bothered. + */ + local_irq_disable(); + + flush_icache_range(reboot_code_buffer, + reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); + + printk("Will call new kernel at %08x\n", image->start); + printk("Bye ...\n"); + flush_cache_all(); + ((void (*)(void))reboot_code_buffer)(); +} diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S new file mode 100644 index 00000000000..a3f0d00c133 --- /dev/null +++ b/arch/mips/kernel/relocate_kernel.S @@ -0,0 +1,80 @@ +/* + * relocate_kernel.S for kexec + * Created by on Thu Oct 12 17:49:57 2006 + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + + .globl relocate_new_kernel +relocate_new_kernel: + + PTR_L s0, kexec_indirection_page + PTR_L s1, kexec_start_address + +process_entry: + PTR_L s2, (s0) + PTR_ADD s0, s0, SZREG + + /* destination page */ + and s3, s2, 0x1 + beq s3, zero, 1f + and s4, s2, ~0x1 /* store destination addr in s4 */ + move a0, s4 + b process_entry + +1: + /* indirection page, update s0 */ + and s3, s2, 0x2 + beq s3, zero, 1f + and s0, s2, ~0x2 + b process_entry + +1: + /* done page */ + and s3, s2, 0x4 + beq s3, zero, 1f + b done +1: + /* source page */ + and s3, s2, 0x8 + beq s3, zero, process_entry + and s2, s2, ~0x8 + li s6, (1 << PAGE_SHIFT) / SZREG + +copy_word: + /* copy page word by word */ + REG_L s5, (s2) + REG_S s5, (s4) + INT_ADD s4, s4, SZREG + INT_ADD s2, s2, SZREG + INT_SUB s6, s6, 1 + beq s6, zero, process_entry + b copy_word + b process_entry + +done: + /* jump to kexec_start_address */ + j s1 + + .globl kexec_start_address +kexec_start_address: + .long 0x0 + + .globl kexec_indirection_page +kexec_indirection_page: + .long 0x0 + +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .long relocate_new_kernel_end - relocate_new_kernel diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index a95f37de080..7c0b3936ba4 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -653,7 +653,7 @@ einval: li v0, -EINVAL sys sys_move_pages 6 sys sys_set_robust_list 2 sys sys_get_robust_list 3 /* 4310 */ - sys sys_ni_syscall 0 + sys sys_kexec_load 4 sys sys_getcpu 3 sys sys_epoll_pwait 6 .endm diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 8fb0f60f657..e569b846e9a 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -468,6 +468,6 @@ sys_call_table: PTR sys_move_pages PTR sys_set_robust_list PTR sys_get_robust_list - PTR sys_ni_syscall /* 5270 */ + PTR sys_kexec_load /* 5270 */ PTR sys_getcpu PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 0da5ca2040f..5b18f265d75 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -394,6 +394,6 @@ EXPORT(sysn32_call_table) PTR sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list - PTR sys_ni_syscall + PTR compat_sys_kexec_load PTR sys_getcpu PTR sys_epoll_pwait diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b9d00cae8b5..e91379c1be1 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -516,7 +516,7 @@ sys_call_table: PTR compat_sys_move_pages PTR compat_sys_set_robust_list PTR compat_sys_get_robust_list /* 4310 */ - PTR sys_ni_syscall + PTR compat_sys_kexec_load PTR sys_getcpu PTR sys_epoll_pwait .size sys_call_table,.-sys_call_table -- cgit v1.2.3 From 714cfe7865e5182a3b25be6a95c0b17aa8e64aa9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 23 Oct 2006 00:44:02 +0100 Subject: [MIPS] Oprofile: kernel support for the R10000. Signed-off-by: Ralf Baechle --- arch/mips/oprofile/Makefile | 1 + arch/mips/oprofile/common.c | 3 +++ arch/mips/oprofile/op_model_mipsxx.c | 32 +++++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 0a50aad5bbe..bf3be6fcf7f 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile @@ -12,5 +12,6 @@ oprofile-y := $(DRIVER_OBJS) common.o oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o +oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 65eb55400d7..4e0a90b3916 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -83,6 +83,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_74K: case CPU_SB1: case CPU_SB1A: + case CPU_R10000: + case CPU_R12000: + case CPU_R14000: lmodel = &op_model_mipsxx_ops; break; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 1fb240c57ba..455d76ad06d 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -18,7 +18,7 @@ #define M_PERFCTL_SUPERVISOR (1UL << 2) #define M_PERFCTL_USER (1UL << 3) #define M_PERFCTL_INTERRUPT_ENABLE (1UL << 4) -#define M_PERFCTL_EVENT(event) ((event) << 5) +#define M_PERFCTL_EVENT(event) (((event) & 0x3f) << 5) #define M_PERFCTL_VPEID(vpe) ((vpe) << 16) #define M_PERFCTL_MT_EN(filter) ((filter) << 20) #define M_TC_EN_ALL M_PERFCTL_MT_EN(0) @@ -218,13 +218,23 @@ static inline int __n_counters(void) static inline int n_counters(void) { - int counters = __n_counters(); + int counters; + + switch (current_cpu_data.cputype) { + case CPU_R10000: + counters = 2; + + case CPU_R12000: + case CPU_R14000: + counters = 4; + + default: + counters = __n_counters(); + } #ifdef CONFIG_MIPS_MT_SMP - if (current_cpu_data.cputype == CPU_34K) - return counters >> 1; + counters >> 1; #endif - return counters; } @@ -284,6 +294,18 @@ static int __init mipsxx_init(void) op_model_mipsxx_ops.cpu_type = "mips/5K"; break; + case CPU_R10000: + if ((current_cpu_data.processor_id & 0xff) == 0x20) + op_model_mipsxx_ops.cpu_type = "mips/r10000-v2.x"; + else + op_model_mipsxx_ops.cpu_type = "mips/r10000"; + break; + + case CPU_R12000: + case CPU_R14000: + op_model_mipsxx_ops.cpu_type = "mips/r12000"; + break; + case CPU_SB1: case CPU_SB1A: op_model_mipsxx_ops.cpu_type = "mips/sb1"; -- cgit v1.2.3 From 0d02f0734f8d2310497fae4f960c978f679f66d9 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 1 Nov 2006 18:40:15 +0900 Subject: [MIPS] PB1200: Remove duplicate definitions Signed-off-by: Yoichi Yuasa Signed-off-by: Ralf Baechle --- arch/mips/au1000/pb1200/board_setup.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c index 8b953b9fc25..043302b7fe5 100644 --- a/arch/mips/au1000/pb1200/board_setup.c +++ b/arch/mips/au1000/pb1200/board_setup.c @@ -55,7 +55,7 @@ #endif extern void _board_init_irq(void); -extern void (*board_init_irq)(void); +extern void (*board_init_irq)(void); void board_reset (void) { @@ -151,11 +151,7 @@ void __init board_setup(void) #endif /* Setup Pb1200 External Interrupt Controller */ - { - extern void (*board_init_irq)(void); - extern void _board_init_irq(void); - board_init_irq = _board_init_irq; - } + board_init_irq = _board_init_irq; } int -- cgit v1.2.3 From c87b6ebaea034c0e0ce86127870cf1511a307b64 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 28 Oct 2006 01:14:37 +0900 Subject: [MIPS] mips hpt cleanup: get rid of mips_hpt_init Currently nobody outside time.c require mips_hpt_init(). Remove it and call c0_hpt_timer_init() directly if R4k counter was used for timer interrupt. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/time.c | 22 ++++++++-------------- arch/mips/pmc-sierra/yosemite/smp.c | 2 -- 2 files changed, 8 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index e535f86efa2..111d1baa3b2 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -88,12 +88,6 @@ static unsigned int null_hpt_read(void) return 0; } -static void __init null_hpt_init(void) -{ - /* nothing */ -} - - /* * Timer ack for an R4k-compatible timer of a known frequency. */ @@ -133,7 +127,6 @@ static void __init c0_hpt_timer_init(void) int (*mips_timer_state)(void); void (*mips_timer_ack)(void); unsigned int (*mips_hpt_read)(void); -void (*mips_hpt_init)(void) __initdata = null_hpt_init; unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ @@ -383,16 +376,20 @@ void __init time_init(void) if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ - mips_hpt_init = c0_hpt_timer_init; mips_timer_ack = c0_timer_ack; + /* Calculate cache parameters. */ + cycles_per_jiffy = + (mips_hpt_frequency + HZ / 2) / HZ; + /* + * This sets up the high precision + * timer for the first interrupt. + */ + c0_hpt_timer_init(); } } if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); - /* Calculate cache parameters. */ - cycles_per_jiffy = (mips_hpt_frequency + HZ / 2) / HZ; - /* Report the high precision timer rate for a reference. */ printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, @@ -403,9 +400,6 @@ void __init time_init(void) /* No timer interrupt ack (e.g. i8254). */ mips_timer_ack = null_timer_ack; - /* This sets up the high precision timer for the first interrupt. */ - mips_hpt_init(); - /* * Call board specific timer interrupt setup. * diff --git a/arch/mips/pmc-sierra/yosemite/smp.c b/arch/mips/pmc-sierra/yosemite/smp.c index 3cc0436db6c..305491e74db 100644 --- a/arch/mips/pmc-sierra/yosemite/smp.c +++ b/arch/mips/pmc-sierra/yosemite/smp.c @@ -99,8 +99,6 @@ void prom_cpus_done(void) */ void prom_init_secondary(void) { - mips_hpt_init(); - set_c0_status(ST0_CO | ST0_IE | ST0_IM); } -- cgit v1.2.3 From 1603b5aca4f15b34848fb5594d0c7b6333b99144 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 2 Nov 2006 02:08:36 +0900 Subject: [MIPS] IRQ cleanups This is a big irq cleanup patch. * Use set_irq_chip() to register irq_chip. * Initialize .mask, .unmask, .mask_ack field. Functions for these method are already exist in most case. * Do not initialize .startup, .shutdown, .enable, .disable fields if default routines provided by irq_chip_set_defaults() were suitable. * Remove redundant irq_desc initializations. * Remove unnecessary local_irq_save/local_irq_restore, spin_lock. With this cleanup, it would be easy to switch to slightly lightwait irq flow handlers (handle_level_irq(), etc.) instead of __do_IRQ(). Though whole this patch is quite large, changes in each irq_chip are not quite simple. Please review and test on your platform. Thanks. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/irq.c | 63 +++---- arch/mips/ddb5xxx/ddb5477/irq_5477.c | 23 +-- arch/mips/dec/ecc-berr.c | 6 - arch/mips/dec/ioasic-irq.c | 72 ++------ arch/mips/dec/kn02-irq.c | 53 +----- arch/mips/emma2rh/common/irq_emma2rh.c | 34 +--- arch/mips/emma2rh/markeins/irq_markeins.c | 55 ++----- arch/mips/gt64120/ev64120/irq.c | 40 +---- arch/mips/jazz/irq.c | 27 +-- arch/mips/jmr3927/rbhma3100/irq.c | 32 +--- arch/mips/kernel/i8259.c | 21 +-- arch/mips/kernel/irq-msc01.c | 45 +---- arch/mips/kernel/irq-mv6434x.c | 53 +----- arch/mips/kernel/irq-rm7000.c | 53 +----- arch/mips/kernel/irq-rm9000.c | 45 ++--- arch/mips/kernel/irq.c | 13 -- arch/mips/kernel/irq_cpu.c | 77 ++------- arch/mips/lasat/interrupt.c | 36 +--- arch/mips/mips-boards/atlas/atlas_int.c | 28 +--- arch/mips/momentum/ocelot_c/cpci-irq.c | 53 +----- arch/mips/momentum/ocelot_c/uart-irq.c | 56 +------ arch/mips/philips/pnx8550/common/int.c | 66 ++------ arch/mips/sgi-ip22/ip22-eisa.c | 33 +--- arch/mips/sgi-ip22/ip22-int.c | 109 ++---------- arch/mips/sgi-ip27/ip27-irq.c | 17 +- arch/mips/sgi-ip27/ip27-timer.c | 27 +-- arch/mips/sgi-ip32/ip32-irq.c | 133 +++------------ arch/mips/sibyte/bcm1480/irq.c | 30 +--- arch/mips/sibyte/sb1250/irq.c | 30 +--- arch/mips/sni/irq.c | 40 +---- arch/mips/tx4927/common/tx4927_irq.c | 162 ++---------------- .../tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 183 ++------------------- arch/mips/tx4938/common/irq.c | 113 ++----------- arch/mips/tx4938/toshiba_rbtx4938/irq.c | 53 +----- arch/mips/vr41xx/common/icu.c | 46 ++---- arch/mips/vr41xx/nec-cmbvr4133/irq.c | 20 +-- 36 files changed, 292 insertions(+), 1655 deletions(-) (limited to 'arch') diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index 2abe132bb07..9cf7b671583 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c @@ -70,7 +70,6 @@ extern irq_cpustat_t irq_stat [NR_CPUS]; extern void mips_timer_interrupt(void); static void setup_local_irq(unsigned int irq, int type, int int_req); -static unsigned int startup_irq(unsigned int irq); static void end_irq(unsigned int irq_nr); static inline void mask_and_ack_level_irq(unsigned int irq_nr); static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr); @@ -84,20 +83,6 @@ void (*board_init_irq)(void); static DEFINE_SPINLOCK(irq_lock); -static unsigned int startup_irq(unsigned int irq_nr) -{ - local_enable_irq(irq_nr); - return 0; -} - - -static void shutdown_irq(unsigned int irq_nr) -{ - local_disable_irq(irq_nr); - return; -} - - inline void local_enable_irq(unsigned int irq_nr) { if (irq_nr > AU1000_LAST_INTC0_INT) { @@ -249,41 +234,37 @@ void restore_local_and_enable(int controller, unsigned long mask) static struct irq_chip rise_edge_irq_type = { .typename = "Au1000 Rise Edge", - .startup = startup_irq, - .shutdown = shutdown_irq, - .enable = local_enable_irq, - .disable = local_disable_irq, .ack = mask_and_ack_rise_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_rise_edge_irq, + .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip fall_edge_irq_type = { .typename = "Au1000 Fall Edge", - .startup = startup_irq, - .shutdown = shutdown_irq, - .enable = local_enable_irq, - .disable = local_disable_irq, .ack = mask_and_ack_fall_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_fall_edge_irq, + .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip either_edge_irq_type = { .typename = "Au1000 Rise or Fall Edge", - .startup = startup_irq, - .shutdown = shutdown_irq, - .enable = local_enable_irq, - .disable = local_disable_irq, .ack = mask_and_ack_either_edge_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_either_edge_irq, + .unmask = local_enable_irq, .end = end_irq, }; static struct irq_chip level_irq_type = { .typename = "Au1000 Level", - .startup = startup_irq, - .shutdown = shutdown_irq, - .enable = local_enable_irq, - .disable = local_disable_irq, .ack = mask_and_ack_level_irq, + .mask = local_disable_irq, + .mask_ack = mask_and_ack_level_irq, + .unmask = local_enable_irq, .end = end_irq, }; @@ -328,31 +309,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &rise_edge_irq_type; + set_irq_chip(irq_nr, &rise_edge_irq_type); break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].chip = &fall_edge_irq_type; + set_irq_chip(irq_nr, &fall_edge_irq_type); break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &either_edge_irq_type; + set_irq_chip(irq_nr, &either_edge_irq_type); break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &level_irq_type; + set_irq_chip(irq_nr, &level_irq_type); break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].chip = &level_irq_type; + set_irq_chip(irq_nr, &level_irq_type); break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<(irq_nr-32), IC1_CFG0CLR); @@ -380,31 +361,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1< #include #include -#include #include #include @@ -231,13 +230,10 @@ irqreturn_t dec_ecc_be_interrupt(int irq, void *dev_id) static inline void dec_kn02_be_init(void) { volatile u32 *csr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); - unsigned long flags; kn0x_erraddr = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_ERRADDR); kn0x_chksyn = (void *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CHKSYN); - spin_lock_irqsave(&kn02_lock, flags); - /* Preset write-only bits of the Control Register cache. */ cached_kn02_csr = *csr | KN02_CSR_LEDS; @@ -247,8 +243,6 @@ static inline void dec_kn02_be_init(void) cached_kn02_csr |= KN02_CSR_CORRECT; *csr = cached_kn02_csr; iob(); - - spin_unlock_irqrestore(&kn02_lock, flags); } static inline void dec_kn03_be_init(void) diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index 41cd2a96148..d0af08bdbb4 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -21,8 +20,6 @@ #include -static DEFINE_SPINLOCK(ioasic_lock); - static int ioasic_irq_base; @@ -52,65 +49,31 @@ static inline void clear_ioasic_irq(unsigned int irq) ioasic_write(IO_REG_SIR, sir); } -static inline void enable_ioasic_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&ioasic_lock, flags); - unmask_ioasic_irq(irq); - spin_unlock_irqrestore(&ioasic_lock, flags); -} - -static inline void disable_ioasic_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&ioasic_lock, flags); - mask_ioasic_irq(irq); - spin_unlock_irqrestore(&ioasic_lock, flags); -} - - -static inline unsigned int startup_ioasic_irq(unsigned int irq) -{ - enable_ioasic_irq(irq); - return 0; -} - -#define shutdown_ioasic_irq disable_ioasic_irq - static inline void ack_ioasic_irq(unsigned int irq) { - spin_lock(&ioasic_lock); mask_ioasic_irq(irq); - spin_unlock(&ioasic_lock); fast_iob(); } static inline void end_ioasic_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_ioasic_irq(irq); + unmask_ioasic_irq(irq); } static struct irq_chip ioasic_irq_type = { .typename = "IO-ASIC", - .startup = startup_ioasic_irq, - .shutdown = shutdown_ioasic_irq, - .enable = enable_ioasic_irq, - .disable = disable_ioasic_irq, .ack = ack_ioasic_irq, + .mask = mask_ioasic_irq, + .mask_ack = ack_ioasic_irq, + .unmask = unmask_ioasic_irq, .end = end_ioasic_irq, }; -#define startup_ioasic_dma_irq startup_ioasic_irq - -#define shutdown_ioasic_dma_irq shutdown_ioasic_irq - -#define enable_ioasic_dma_irq enable_ioasic_irq +#define unmask_ioasic_dma_irq unmask_ioasic_irq -#define disable_ioasic_dma_irq disable_ioasic_irq +#define mask_ioasic_dma_irq mask_ioasic_irq #define ack_ioasic_dma_irq ack_ioasic_irq @@ -123,11 +86,10 @@ static inline void end_ioasic_dma_irq(unsigned int irq) static struct irq_chip ioasic_dma_irq_type = { .typename = "IO-ASIC-DMA", - .startup = startup_ioasic_dma_irq, - .shutdown = shutdown_ioasic_dma_irq, - .enable = enable_ioasic_dma_irq, - .disable = disable_ioasic_dma_irq, .ack = ack_ioasic_dma_irq, + .mask = mask_ioasic_dma_irq, + .mask_ack = ack_ioasic_dma_irq, + .unmask = unmask_ioasic_dma_irq, .end = end_ioasic_dma_irq, }; @@ -140,18 +102,10 @@ void __init init_ioasic_irqs(int base) ioasic_write(IO_REG_SIMR, 0); fast_iob(); - for (i = base; i < base + IO_INR_DMA; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &ioasic_irq_type; - } - for (; i < base + IO_IRQ_LINES; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &ioasic_dma_irq_type; - } + for (i = base; i < base + IO_INR_DMA; i++) + set_irq_chip(i, &ioasic_irq_type); + for (; i < base + IO_IRQ_LINES; i++) + set_irq_chip(i, &ioasic_dma_irq_type); ioasic_irq_base = base; } diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index 04a367a60a5..c761d97787e 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -29,7 +28,6 @@ * There is no default value -- it has to be initialized. */ u32 cached_kn02_csr; -DEFINE_SPINLOCK(kn02_lock); static int kn02_irq_base; @@ -53,54 +51,24 @@ static inline void mask_kn02_irq(unsigned int irq) *csr = cached_kn02_csr; } -static inline void enable_kn02_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&kn02_lock, flags); - unmask_kn02_irq(irq); - spin_unlock_irqrestore(&kn02_lock, flags); -} - -static inline void disable_kn02_irq(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&kn02_lock, flags); - mask_kn02_irq(irq); - spin_unlock_irqrestore(&kn02_lock, flags); -} - - -static unsigned int startup_kn02_irq(unsigned int irq) -{ - enable_kn02_irq(irq); - return 0; -} - -#define shutdown_kn02_irq disable_kn02_irq - static void ack_kn02_irq(unsigned int irq) { - spin_lock(&kn02_lock); mask_kn02_irq(irq); - spin_unlock(&kn02_lock); iob(); } static void end_kn02_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_kn02_irq(irq); + unmask_kn02_irq(irq); } static struct irq_chip kn02_irq_type = { .typename = "KN02-CSR", - .startup = startup_kn02_irq, - .shutdown = shutdown_kn02_irq, - .enable = enable_kn02_irq, - .disable = disable_kn02_irq, .ack = ack_kn02_irq, + .mask = mask_kn02_irq, + .mask_ack = ack_kn02_irq, + .unmask = unmask_kn02_irq, .end = end_kn02_irq, }; @@ -109,22 +77,15 @@ void __init init_kn02_irqs(int base) { volatile u32 *csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); - unsigned long flags; int i; /* Mask interrupts. */ - spin_lock_irqsave(&kn02_lock, flags); cached_kn02_csr &= ~KN02_CSR_IOINTEN; *csr = cached_kn02_csr; iob(); - spin_unlock_irqrestore(&kn02_lock, flags); - - for (i = base; i < base + KN02_IRQ_LINES; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &kn02_irq_type; - } + + for (i = base; i < base + KN02_IRQ_LINES; i++) + set_irq_chip(i, &kn02_irq_type); kn02_irq_base = base; } diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c index 197ed4c2ba0..bf1b83ba925 100644 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/arch/mips/emma2rh/common/irq_emma2rh.c @@ -56,22 +56,6 @@ static void emma2rh_irq_disable(unsigned int irq) ll_emma2rh_irq_disable(irq - emma2rh_irq_base); } -static unsigned int emma2rh_irq_startup(unsigned int irq) -{ - emma2rh_irq_enable(irq); - return 0; -} - -#define emma2rh_irq_shutdown emma2rh_irq_disable - -static void emma2rh_irq_ack(unsigned int irq) -{ - /* disable interrupt - some handler will re-enable the irq - * and if the interrupt is leveled, we will have infinite loop - */ - ll_emma2rh_irq_disable(irq - emma2rh_irq_base); -} - static void emma2rh_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -80,25 +64,19 @@ static void emma2rh_irq_end(unsigned int irq) struct irq_chip emma2rh_irq_controller = { .typename = "emma2rh_irq", - .startup = emma2rh_irq_startup, - .shutdown = emma2rh_irq_shutdown, - .enable = emma2rh_irq_enable, - .disable = emma2rh_irq_disable, - .ack = emma2rh_irq_ack, + .ack = emma2rh_irq_disable, + .mask = emma2rh_irq_disable, + .mask_ack = emma2rh_irq_disable, + .unmask = emma2rh_irq_enable, .end = emma2rh_irq_end, - .set_affinity = NULL /* no affinity stuff for UP */ }; void emma2rh_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &emma2rh_irq_controller; - } + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) + set_irq_chip(i, &emma2rh_irq_controller); emma2rh_irq_base = irq_base; } diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c index 0b36eb001e6..8e5f08a4245 100644 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/arch/mips/emma2rh/markeins/irq_markeins.c @@ -48,19 +48,6 @@ static void emma2rh_sw_irq_disable(unsigned int irq) ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); } -static unsigned int emma2rh_sw_irq_startup(unsigned int irq) -{ - emma2rh_sw_irq_enable(irq); - return 0; -} - -#define emma2rh_sw_irq_shutdown emma2rh_sw_irq_disable - -static void emma2rh_sw_irq_ack(unsigned int irq) -{ - ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); -} - static void emma2rh_sw_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -69,25 +56,19 @@ static void emma2rh_sw_irq_end(unsigned int irq) struct irq_chip emma2rh_sw_irq_controller = { .typename = "emma2rh_sw_irq", - .startup = emma2rh_sw_irq_startup, - .shutdown = emma2rh_sw_irq_shutdown, - .enable = emma2rh_sw_irq_enable, - .disable = emma2rh_sw_irq_disable, - .ack = emma2rh_sw_irq_ack, + .ack = emma2rh_sw_irq_disable, + .mask = emma2rh_sw_irq_disable, + .mask_ack = emma2rh_sw_irq_disable, + .unmask = emma2rh_sw_irq_enable, .end = emma2rh_sw_irq_end, - .set_affinity = NULL, }; void emma2rh_sw_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 2; - irq_desc[i].chip = &emma2rh_sw_irq_controller; - } + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) + set_irq_chip(i, &emma2rh_sw_irq_controller); emma2rh_sw_irq_base = irq_base; } @@ -126,14 +107,6 @@ static void emma2rh_gpio_irq_disable(unsigned int irq) ll_emma2rh_gpio_irq_disable(irq - emma2rh_gpio_irq_base); } -static unsigned int emma2rh_gpio_irq_startup(unsigned int irq) -{ - emma2rh_gpio_irq_enable(irq); - return 0; -} - -#define emma2rh_gpio_irq_shutdown emma2rh_gpio_irq_disable - static void emma2rh_gpio_irq_ack(unsigned int irq) { irq -= emma2rh_gpio_irq_base; @@ -149,25 +122,19 @@ static void emma2rh_gpio_irq_end(unsigned int irq) struct irq_chip emma2rh_gpio_irq_controller = { .typename = "emma2rh_gpio_irq", - .startup = emma2rh_gpio_irq_startup, - .shutdown = emma2rh_gpio_irq_shutdown, - .enable = emma2rh_gpio_irq_enable, - .disable = emma2rh_gpio_irq_disable, .ack = emma2rh_gpio_irq_ack, + .mask = emma2rh_gpio_irq_disable, + .mask_ack = emma2rh_gpio_irq_ack, + .unmask = emma2rh_gpio_irq_enable, .end = emma2rh_gpio_irq_end, - .set_affinity = NULL, }; void emma2rh_gpio_irq_init(u32 irq_base) { u32 i; - for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 2; - irq_desc[i].chip = &emma2rh_gpio_irq_controller; - } + for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_GPIO; i++) + set_irq_chip(i, &emma2rh_gpio_irq_controller); emma2rh_gpio_irq_base = irq_base; } diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index ed4d82b9a24..b3e5796c81d 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c @@ -66,38 +66,21 @@ asmlinkage void plat_irq_dispatch(void) static void disable_ev64120_irq(unsigned int irq_nr) { - unsigned long flags; - - local_irq_save(flags); if (irq_nr >= 8) { // All PCI interrupts are on line 5 or 2 clear_c0_status(9 << 10); } else { clear_c0_status(1 << (irq_nr + 8)); } - local_irq_restore(flags); } static void enable_ev64120_irq(unsigned int irq_nr) { - unsigned long flags; - - local_irq_save(flags); if (irq_nr >= 8) // All PCI interrupts are on line 5 or 2 set_c0_status(9 << 10); else set_c0_status(1 << (irq_nr + 8)); - local_irq_restore(flags); -} - -static unsigned int startup_ev64120_irq(unsigned int irq) -{ - enable_ev64120_irq(irq); - return 0; /* Never anything pending */ } -#define shutdown_ev64120_irq disable_ev64120_irq -#define mask_and_ack_ev64120_irq disable_ev64120_irq - static void end_ev64120_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -106,13 +89,11 @@ static void end_ev64120_irq(unsigned int irq) static struct irq_chip ev64120_irq_type = { .typename = "EV64120", - .startup = startup_ev64120_irq, - .shutdown = shutdown_ev64120_irq, - .enable = enable_ev64120_irq, - .disable = disable_ev64120_irq, - .ack = mask_and_ack_ev64120_irq, + .ack = disable_ev64120_irq, + .mask = disable_ev64120_irq, + .mask_ack = disable_ev64120_irq, + .unmask = enable_ev64120_irq, .end = end_ev64120_irq, - .set_affinity = NULL }; void gt64120_irq_setup(void) @@ -122,8 +103,6 @@ void gt64120_irq_setup(void) */ clear_c0_status(ST0_IM); - local_irq_disable(); - /* * Enable timer. Other interrupts will be enabled as they are * registered. @@ -133,16 +112,5 @@ void gt64120_irq_setup(void) void __init arch_init_irq(void) { - int i; - - /* Let's initialize our IRQ descriptors */ - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = 0; - irq_desc[i].chip = &no_irq_chip; - irq_desc[i].action = NULL; - irq_desc[i].depth = 0; - spin_lock_init(&irq_desc[i].lock); - } - gt64120_irq_setup(); } diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index d5bd6b3a093..4bbb6cb08d6 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -28,14 +28,6 @@ static void enable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } -static unsigned int startup_r4030_irq(unsigned int irq) -{ - enable_r4030_irq(irq); - return 0; /* never anything pending */ -} - -#define shutdown_r4030_irq disable_r4030_irq - void disable_r4030_irq(unsigned int irq) { unsigned int mask = ~(1 << (irq - JAZZ_PARALLEL_IRQ)); @@ -47,8 +39,6 @@ void disable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } -#define mask_and_ack_r4030_irq disable_r4030_irq - static void end_r4030_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -57,11 +47,10 @@ static void end_r4030_irq(unsigned int irq) static struct irq_chip r4030_irq_type = { .typename = "R4030", - .startup = startup_r4030_irq, - .shutdown = shutdown_r4030_irq, - .enable = enable_r4030_irq, - .disable = disable_r4030_irq, - .ack = mask_and_ack_r4030_irq, + .ack = disable_r4030_irq, + .mask = disable_r4030_irq, + .mask_ack = disable_r4030_irq, + .unmask = enable_r4030_irq, .end = end_r4030_irq, }; @@ -69,12 +58,8 @@ void __init init_r4030_ints(void) { int i; - for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &r4030_irq_type; - } + for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) + set_irq_chip(i, &r4030_irq_type); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index de4a238c28b..3da49c5aaf4 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c @@ -90,17 +90,6 @@ static unsigned char irc_level[TX3927_NUM_IR] = { static void jmr3927_irq_disable(unsigned int irq_nr); static void jmr3927_irq_enable(unsigned int irq_nr); -static DEFINE_SPINLOCK(jmr3927_irq_lock); - -static unsigned int jmr3927_irq_startup(unsigned int irq) -{ - jmr3927_irq_enable(irq); - - return 0; -} - -#define jmr3927_irq_shutdown jmr3927_irq_disable - static void jmr3927_irq_ack(unsigned int irq) { if (irq == JMR3927_IRQ_IRC_TMR0) @@ -118,9 +107,7 @@ static void jmr3927_irq_end(unsigned int irq) static void jmr3927_irq_disable(unsigned int irq_nr) { struct tb_irq_space* sp; - unsigned long flags; - spin_lock_irqsave(&jmr3927_irq_lock, flags); for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { @@ -130,15 +117,12 @@ static void jmr3927_irq_disable(unsigned int irq_nr) break; } } - spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } static void jmr3927_irq_enable(unsigned int irq_nr) { struct tb_irq_space* sp; - unsigned long flags; - spin_lock_irqsave(&jmr3927_irq_lock, flags); for (sp = tb_irq_spaces; sp; sp = sp->next) { if (sp->start_irqno <= irq_nr && irq_nr < sp->start_irqno + sp->nr_irqs) { @@ -148,7 +132,6 @@ static void jmr3927_irq_enable(unsigned int irq_nr) break; } } - spin_unlock_irqrestore(&jmr3927_irq_lock, flags); } /* @@ -457,11 +440,10 @@ void __init arch_init_irq(void) static struct irq_chip jmr3927_irq_controller = { .typename = "jmr3927_irq", - .startup = jmr3927_irq_startup, - .shutdown = jmr3927_irq_shutdown, - .enable = jmr3927_irq_enable, - .disable = jmr3927_irq_disable, .ack = jmr3927_irq_ack, + .mask = jmr3927_irq_disable, + .mask_ack = jmr3927_irq_ack, + .unmask = jmr3927_irq_enable, .end = jmr3927_irq_end, }; @@ -469,12 +451,8 @@ void jmr3927_irq_init(u32 irq_base) { u32 i; - for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &jmr3927_irq_controller; - } + for (i= irq_base; i< irq_base + JMR3927_NR_IRQ_IRC + JMR3927_NR_IRQ_IOC; i++) + set_irq_chip(i, &jmr3927_irq_controller); jmr3927_irq_base = irq_base; } diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 48e3418c217..2526c0ca4d8 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -40,21 +40,10 @@ static void end_8259A_irq (unsigned int irq) enable_8259A_irq(irq); } -#define shutdown_8259A_irq disable_8259A_irq - void mask_and_ack_8259A(unsigned int); -static unsigned int startup_8259A_irq(unsigned int irq) -{ - enable_8259A_irq(irq); - - return 0; /* never anything pending */ -} - static struct irq_chip i8259A_irq_type = { .typename = "XT-PIC", - .startup = startup_8259A_irq, - .shutdown = shutdown_8259A_irq, .enable = enable_8259A_irq, .disable = disable_8259A_irq, .ack = mask_and_ack_8259A, @@ -120,7 +109,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &i8259A_irq_type; + set_irq_chip(irq, &i8259A_irq_type); enable_irq(irq); } @@ -323,12 +312,8 @@ void __init init_i8259_irqs (void) init_8259A(0); - for (i = 0; i < 16; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &i8259A_irq_type; - } + for (i = 0; i < 16; i++) + set_irq_chip(i, &i8259A_irq_type); setup_irq(2, &irq2); } diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 650a80ca374..e1880b27381 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -44,31 +44,6 @@ static inline void unmask_msc_irq(unsigned int irq) MSCIC_WRITE(MSC01_IC_ENAH, 1<<(irq - irq_base - 32)); } -/* - * Enables the IRQ on SOC-it - */ -static void enable_msc_irq(unsigned int irq) -{ - unmask_msc_irq(irq); -} - -/* - * Initialize the IRQ on SOC-it - */ -static unsigned int startup_msc_irq(unsigned int irq) -{ - unmask_msc_irq(irq); - return 0; -} - -/* - * Disables the IRQ on SOC-it - */ -static void disable_msc_irq(unsigned int irq) -{ - mask_msc_irq(irq); -} - /* * Masks and ACKs an IRQ */ @@ -136,25 +111,21 @@ msc_bind_eic_interrupt (unsigned int irq, unsigned int set) (irq<im_type) { case MSC01_IRQ_EDGE: - irq_desc[base+n].chip = &msc_edgeirq_type; + set_irq_chip(base+n, &msc_edgeirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_desc[base+n].chip = &msc_levelirq_type; + set_irq_chip(base+n, &msc_levelirq_type); if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 37d106202b8..5012b9df1b5 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -66,39 +66,6 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } -/* - * Enables the IRQ on Marvell Chip - */ -static void enable_mv64340_irq(unsigned int irq) -{ - unmask_mv64340_irq(irq); -} - -/* - * Initialize the IRQ on Marvell Chip - */ -static unsigned int startup_mv64340_irq(unsigned int irq) -{ - unmask_mv64340_irq(irq); - return 0; -} - -/* - * Disables the IRQ on Marvell Chip - */ -static void disable_mv64340_irq(unsigned int irq) -{ - mask_mv64340_irq(irq); -} - -/* - * Masks and ACKs an IRQ - */ -static void mask_and_ack_mv64340_irq(unsigned int irq) -{ - mask_mv64340_irq(irq); -} - /* * End IRQ processing */ @@ -133,15 +100,12 @@ void ll_mv64340_irq(void) do_IRQ(ls1bit32(irq_src_high) + irq_base + 32); } -#define shutdown_mv64340_irq disable_mv64340_irq - struct irq_chip mv64340_irq_type = { .typename = "MV-64340", - .startup = startup_mv64340_irq, - .shutdown = shutdown_mv64340_irq, - .enable = enable_mv64340_irq, - .disable = disable_mv64340_irq, - .ack = mask_and_ack_mv64340_irq, + .ack = mask_mv64340_irq, + .mask = mask_mv64340_irq, + .mask_ack = mask_mv64340_irq, + .unmask = unmask_mv64340_irq, .end = end_mv64340_irq, }; @@ -149,13 +113,8 @@ void __init mv64340_irq_init(unsigned int base) { int i; - /* Reset irq handlers pointers to NULL */ - for (i = base; i < base + 64; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 2; - irq_desc[i].chip = &mv64340_irq_type; - } + for (i = base; i < base + 64; i++) + set_irq_chip(i, &mv64340_irq_type); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 6b54c7109e2..6a297e3b889 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -29,42 +29,6 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } -static inline void rm7k_cpu_irq_enable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - unmask_rm7k_irq(irq); - local_irq_restore(flags); -} - -static void rm7k_cpu_irq_disable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - mask_rm7k_irq(irq); - local_irq_restore(flags); -} - -static unsigned int rm7k_cpu_irq_startup(unsigned int irq) -{ - rm7k_cpu_irq_enable(irq); - - return 0; -} - -#define rm7k_cpu_irq_shutdown rm7k_cpu_irq_disable - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for rm7k_cpu_irq_end. - */ -static void rm7k_cpu_irq_ack(unsigned int irq) -{ - mask_rm7k_irq(irq); -} - static void rm7k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -73,11 +37,10 @@ static void rm7k_cpu_irq_end(unsigned int irq) static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", - .startup = rm7k_cpu_irq_startup, - .shutdown = rm7k_cpu_irq_shutdown, - .enable = rm7k_cpu_irq_enable, - .disable = rm7k_cpu_irq_disable, - .ack = rm7k_cpu_irq_ack, + .ack = mask_rm7k_irq, + .mask = mask_rm7k_irq, + .mask_ack = mask_rm7k_irq, + .unmask = unmask_rm7k_irq, .end = rm7k_cpu_irq_end, }; @@ -87,12 +50,8 @@ void __init rm7k_cpu_irq_init(int base) clear_c0_intcontrol(0x00000f00); /* Mask all */ - for (i = base; i < base + 4; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &rm7k_irq_controller; - } + for (i = base; i < base + 4; i++) + set_irq_chip(i, &rm7k_irq_controller); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 62f011ba97a..977538445cf 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -48,15 +48,6 @@ static void rm9k_cpu_irq_disable(unsigned int irq) local_irq_restore(flags); } -static unsigned int rm9k_cpu_irq_startup(unsigned int irq) -{ - rm9k_cpu_irq_enable(irq); - - return 0; -} - -#define rm9k_cpu_irq_shutdown rm9k_cpu_irq_disable - /* * Performance counter interrupts are global on all processors. */ @@ -89,16 +80,6 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for rm9k_cpu_irq_end. - */ -static void rm9k_cpu_irq_ack(unsigned int irq) -{ - mask_rm9k_irq(irq); -} - static void rm9k_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -107,11 +88,10 @@ static void rm9k_cpu_irq_end(unsigned int irq) static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", - .startup = rm9k_cpu_irq_startup, - .shutdown = rm9k_cpu_irq_shutdown, - .enable = rm9k_cpu_irq_enable, - .disable = rm9k_cpu_irq_disable, - .ack = rm9k_cpu_irq_ack, + .ack = mask_rm9k_irq, + .mask = mask_rm9k_irq, + .mask_ack = mask_rm9k_irq, + .unmask = unmask_rm9k_irq, .end = rm9k_cpu_irq_end, }; @@ -119,9 +99,10 @@ static struct irq_chip rm9k_perfcounter_irq = { .typename = "RM9000", .startup = rm9k_perfcounter_irq_startup, .shutdown = rm9k_perfcounter_irq_shutdown, - .enable = rm9k_cpu_irq_enable, - .disable = rm9k_cpu_irq_disable, - .ack = rm9k_cpu_irq_ack, + .ack = mask_rm9k_irq, + .mask = mask_rm9k_irq, + .mask_ack = mask_rm9k_irq, + .unmask = unmask_rm9k_irq, .end = rm9k_cpu_irq_end, }; @@ -135,15 +116,11 @@ void __init rm9k_cpu_irq_init(int base) clear_c0_intcontrol(0x0000f000); /* Mask all */ - for (i = base; i < base + 4; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &rm9k_irq_controller; - } + for (i = base; i < base + 4; i++) + set_irq_chip(i, &rm9k_irq_controller); rm9000_perfcount_irq = base + 1; - irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; + set_irq_chip(rm9000_perfcount_irq, &rm9k_perfcounter_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 9b0e49d63d7..e997c9454f4 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -172,19 +172,6 @@ __setup("nokgdb", nokgdb); void __init init_IRQ(void) { - int i; - - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &no_irq_chip; - spin_lock_init(&irq_desc[i].lock); -#ifdef CONFIG_MIPS_MT_SMTC - irq_hwmask[i] = 0; -#endif /* CONFIG_MIPS_MT_SMTC */ - } - arch_init_irq(); #ifdef CONFIG_KGDB diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 9bb21c7f214..3b7cfa407e8 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -50,44 +50,6 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } -static inline void mips_cpu_irq_enable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - unmask_mips_irq(irq); - back_to_back_c0_hazard(); - local_irq_restore(flags); -} - -static void mips_cpu_irq_disable(unsigned int irq) -{ - unsigned long flags; - - local_irq_save(flags); - mask_mips_irq(irq); - back_to_back_c0_hazard(); - local_irq_restore(flags); -} - -static unsigned int mips_cpu_irq_startup(unsigned int irq) -{ - mips_cpu_irq_enable(irq); - - return 0; -} - -#define mips_cpu_irq_shutdown mips_cpu_irq_disable - -/* - * While we ack the interrupt interrupts are disabled and thus we don't need - * to deal with concurrency issues. Same for mips_cpu_irq_end. - */ -static void mips_cpu_irq_ack(unsigned int irq) -{ - mask_mips_irq(irq); -} - static void mips_cpu_irq_end(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -96,11 +58,10 @@ static void mips_cpu_irq_end(unsigned int irq) static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", - .startup = mips_cpu_irq_startup, - .shutdown = mips_cpu_irq_shutdown, - .enable = mips_cpu_irq_enable, - .disable = mips_cpu_irq_disable, - .ack = mips_cpu_irq_ack, + .ack = mask_mips_irq, + .mask = mask_mips_irq, + .mask_ack = mask_mips_irq, + .unmask = unmask_mips_irq, .end = mips_cpu_irq_end, }; @@ -110,8 +71,6 @@ static struct irq_chip mips_cpu_irq_controller = { #define unmask_mips_mt_irq unmask_mips_irq #define mask_mips_mt_irq mask_mips_irq -#define mips_mt_cpu_irq_enable mips_cpu_irq_enable -#define mips_mt_cpu_irq_disable mips_cpu_irq_disable static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) { @@ -119,13 +78,11 @@ static unsigned int mips_mt_cpu_irq_startup(unsigned int irq) clear_c0_cause(0x100 << (irq - mips_cpu_irq_base)); evpe(vpflags); - mips_mt_cpu_irq_enable(irq); + unmask_mips_mt_irq(irq); return 0; } -#define mips_mt_cpu_irq_shutdown mips_mt_cpu_irq_disable - /* * While we ack the interrupt interrupts are disabled and thus we don't need * to deal with concurrency issues. Same for mips_cpu_irq_end. @@ -143,10 +100,10 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, - .shutdown = mips_mt_cpu_irq_shutdown, - .enable = mips_mt_cpu_irq_enable, - .disable = mips_mt_cpu_irq_disable, .ack = mips_mt_cpu_irq_ack, + .mask = mask_mips_mt_irq, + .mask_ack = mips_mt_cpu_irq_ack, + .unmask = unmask_mips_mt_irq, .end = mips_mt_cpu_irq_end, }; @@ -163,19 +120,11 @@ void __init mips_cpu_irq_init(int irq_base) * leave them uninitialized for other processors. */ if (cpu_has_mipsmt) - for (i = irq_base; i < irq_base + 2; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_mt_cpu_irq_controller; - } - - for (i = irq_base + 2; i < irq_base + 8; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = NULL; - irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_cpu_irq_controller; - } + for (i = irq_base; i < irq_base + 2; i++) + set_irq_chip(i, &mips_mt_cpu_irq_controller); + + for (i = irq_base + 2; i < irq_base + 8; i++) + set_irq_chip(i, &mips_cpu_irq_controller); mips_cpu_irq_base = irq_base; } diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index a144a002dcc..cac82afe5eb 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -36,33 +36,14 @@ static volatile int lasat_int_mask_shift; void disable_lasat_irq(unsigned int irq_nr) { - unsigned long flags; - - local_irq_save(flags); *lasat_int_mask &= ~(1 << irq_nr) << lasat_int_mask_shift; - local_irq_restore(flags); } void enable_lasat_irq(unsigned int irq_nr) { - unsigned long flags; - - local_irq_save(flags); *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; - local_irq_restore(flags); } -static unsigned int startup_lasat_irq(unsigned int irq) -{ - enable_lasat_irq(irq); - - return 0; /* never anything pending */ -} - -#define shutdown_lasat_irq disable_lasat_irq - -#define mask_and_ack_lasat_irq disable_lasat_irq - static void end_lasat_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -71,11 +52,10 @@ static void end_lasat_irq(unsigned int irq) static struct irq_chip lasat_irq_type = { .typename = "Lasat", - .startup = startup_lasat_irq, - .shutdown = shutdown_lasat_irq, - .enable = enable_lasat_irq, - .disable = disable_lasat_irq, - .ack = mask_and_ack_lasat_irq, + .ack = disable_lasat_irq, + .mask = disable_lasat_irq, + .mask_ack = disable_lasat_irq, + .unmask = enable_lasat_irq, .end = end_lasat_irq, }; @@ -152,10 +132,6 @@ void __init arch_init_irq(void) panic("arch_init_irq: mips_machtype incorrect"); } - for (i = 0; i <= LASATINT_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &lasat_irq_type; - } + for (i = 0; i <= LASATINT_END; i++) + set_irq_chip(i, &lasat_irq_type); } diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index be624b8c3b0..7c710040d3f 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c @@ -62,16 +62,6 @@ void enable_atlas_irq(unsigned int irq_nr) iob(); } -static unsigned int startup_atlas_irq(unsigned int irq) -{ - enable_atlas_irq(irq); - return 0; /* never anything pending */ -} - -#define shutdown_atlas_irq disable_atlas_irq - -#define mask_and_ack_atlas_irq disable_atlas_irq - static void end_atlas_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -80,11 +70,10 @@ static void end_atlas_irq(unsigned int irq) static struct irq_chip atlas_irq_type = { .typename = "Atlas", - .startup = startup_atlas_irq, - .shutdown = shutdown_atlas_irq, - .enable = enable_atlas_irq, - .disable = disable_atlas_irq, - .ack = mask_and_ack_atlas_irq, + .ack = disable_atlas_irq, + .mask = disable_atlas_irq, + .mask_ack = disable_atlas_irq, + .unmask = enable_atlas_irq, .end = end_atlas_irq, }; @@ -217,13 +206,8 @@ static inline void init_atlas_irqs (int base) */ atlas_hw0_icregs->intrsten = 0xffffffff; - for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &atlas_irq_type; - spin_lock_init(&irq_desc[i].lock); - } + for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) + set_irq_chip(i, &atlas_irq_type); } static struct irqaction atlasirq = { diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c index 47e3fa32b07..7723f099894 100644 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -65,39 +65,6 @@ static inline void unmask_cpci_irq(unsigned int irq) value = OCELOT_FPGA_READ(INTMASK); } -/* - * Enables the IRQ in the FPGA - */ -static void enable_cpci_irq(unsigned int irq) -{ - unmask_cpci_irq(irq); -} - -/* - * Initialize the IRQ in the FPGA - */ -static unsigned int startup_cpci_irq(unsigned int irq) -{ - unmask_cpci_irq(irq); - return 0; -} - -/* - * Disables the IRQ in the FPGA - */ -static void disable_cpci_irq(unsigned int irq) -{ - mask_cpci_irq(irq); -} - -/* - * Masks and ACKs an IRQ - */ -static void mask_and_ack_cpci_irq(unsigned int irq) -{ - mask_cpci_irq(irq); -} - /* * End IRQ processing */ @@ -125,15 +92,12 @@ void ll_cpci_irq(void) do_IRQ(ls1bit8(irq_src) + CPCI_IRQ_BASE); } -#define shutdown_cpci_irq disable_cpci_irq - struct irq_chip cpci_irq_type = { .typename = "CPCI/FPGA", - .startup = startup_cpci_irq, - .shutdown = shutdown_cpci_irq, - .enable = enable_cpci_irq, - .disable = disable_cpci_irq, - .ack = mask_and_ack_cpci_irq, + .ack = mask_cpci_irq, + .mask = mask_cpci_irq, + .mask_ack = mask_cpci_irq, + .unmask = unmask_cpci_irq, .end = end_cpci_irq, }; @@ -141,11 +105,6 @@ void cpci_irq_init(void) { int i; - /* Reset irq handlers pointers to NULL */ - for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 2; - irq_desc[i].chip = &cpci_irq_type; - } + for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) + set_irq_chip(i, &cpci_irq_type); } diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c index 510257dc205..72faf81b36c 100644 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/arch/mips/momentum/ocelot_c/uart-irq.c @@ -59,39 +59,6 @@ static inline void unmask_uart_irq(unsigned int irq) value = OCELOT_FPGA_READ(UART_INTMASK); } -/* - * Enables the IRQ in the FPGA - */ -static void enable_uart_irq(unsigned int irq) -{ - unmask_uart_irq(irq); -} - -/* - * Initialize the IRQ in the FPGA - */ -static unsigned int startup_uart_irq(unsigned int irq) -{ - unmask_uart_irq(irq); - return 0; -} - -/* - * Disables the IRQ in the FPGA - */ -static void disable_uart_irq(unsigned int irq) -{ - mask_uart_irq(irq); -} - -/* - * Masks and ACKs an IRQ - */ -static void mask_and_ack_uart_irq(unsigned int irq) -{ - mask_uart_irq(irq); -} - /* * End IRQ processing */ @@ -118,28 +85,17 @@ void ll_uart_irq(void) do_IRQ(ls1bit8(irq_src) + 74); } -#define shutdown_uart_irq disable_uart_irq - struct irq_chip uart_irq_type = { .typename = "UART/FPGA", - .startup = startup_uart_irq, - .shutdown = shutdown_uart_irq, - .enable = enable_uart_irq, - .disable = disable_uart_irq, - .ack = mask_and_ack_uart_irq, + .ack = mask_uart_irq, + .mask = mask_uart_irq, + .mask_ack = mask_uart_irq, + .unmask = unmask_uart_irq, .end = end_uart_irq, }; void uart_irq_init(void) { - /* Reset irq handlers pointers to NULL */ - irq_desc[80].status = IRQ_DISABLED; - irq_desc[80].action = 0; - irq_desc[80].depth = 2; - irq_desc[80].chip = &uart_irq_type; - - irq_desc[81].status = IRQ_DISABLED; - irq_desc[81].action = 0; - irq_desc[81].depth = 2; - irq_desc[81].chip = &uart_irq_type; + set_irq_chip(80, &uart_irq_type); + set_irq_chip(81, &uart_irq_type); } diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index 710611615ca..e4bf494dd43 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c @@ -38,8 +38,6 @@ #include #include -static DEFINE_SPINLOCK(irq_lock); - /* default prio for interrupts */ /* first one is a no-no so therefore always prio 0 (disabled) */ static char gic_prio[PNX8550_INT_GIC_TOTINT] = { @@ -149,38 +147,6 @@ static inline void unmask_irq(unsigned int irq_nr) } } -#define pnx8550_disable pnx8550_ack -static void pnx8550_ack(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - mask_irq(irq); - spin_unlock_irqrestore(&irq_lock, flags); -} - -#define pnx8550_enable pnx8550_unmask -static void pnx8550_unmask(unsigned int irq) -{ - unsigned long flags; - - spin_lock_irqsave(&irq_lock, flags); - unmask_irq(irq); - spin_unlock_irqrestore(&irq_lock, flags); -} - -static unsigned int startup_irq(unsigned int irq_nr) -{ - pnx8550_unmask(irq_nr); - return 0; -} - -static void shutdown_irq(unsigned int irq_nr) -{ - pnx8550_ack(irq_nr); - return; -} - int pnx8550_set_gic_priority(int irq, int priority) { int gic_irq = irq-PNX8550_INT_GIC_MIN; @@ -192,26 +158,19 @@ int pnx8550_set_gic_priority(int irq, int priority) return prev_priority; } -static inline void mask_and_ack_level_irq(unsigned int irq) -{ - pnx8550_disable(irq); - return; -} - static void end_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { - pnx8550_enable(irq); + unmask_irq(irq); } } static struct irq_chip level_irq_type = { .typename = "PNX Level IRQ", - .startup = startup_irq, - .shutdown = shutdown_irq, - .enable = pnx8550_enable, - .disable = pnx8550_disable, - .ack = mask_and_ack_level_irq, + .ack = mask_irq, + .mask = mask_irq, + .mask_ack = mask_irq, + .unmask = unmask_irq, .end = end_irq, }; @@ -233,8 +192,8 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - irq_desc[i].chip = &level_irq_type; - pnx8550_ack(i); /* mask the irq just in case */ + set_irq_chip(i, &level_irq_type); + mask_irq(i); /* mask the irq just in case */ } /* init of GIC/IPC interrupts */ @@ -270,7 +229,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - irq_desc[i].chip = &level_irq_type; + set_irq_chip(i, &level_irq_type); } /* Priority level 0 */ @@ -279,20 +238,19 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - irq_desc[MIPS_CPU_GIC_IRQ].chip = &level_irq_type; + set_irq_chip(MIPS_CPU_GIC_IRQ, &level_irq_type); setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ - for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { - irq_desc[i].chip = &level_irq_type; - } + for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) + set_irq_chip(i, &level_irq_type); /* Stop Timer 1-3 */ configPR = read_c0_config7(); configPR |= 0x00000038; write_c0_config7(configPR); - irq_desc[MIPS_CPU_TIMER_IRQ].chip = &level_irq_type; + set_irq_chip(MIPS_CPU_TIMER_IRQ, &level_irq_type); setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/arch/mips/sgi-ip22/ip22-eisa.c b/arch/mips/sgi-ip22/ip22-eisa.c index 0d18ed47c47..a1a9af6da7b 100644 --- a/arch/mips/sgi-ip22/ip22-eisa.c +++ b/arch/mips/sgi-ip22/ip22-eisa.c @@ -95,16 +95,11 @@ static irqreturn_t ip22_eisa_intr(int irq, void *dev_id) static void enable_eisa1_irq(unsigned int irq) { - unsigned long flags; u8 mask; - local_irq_save(flags); - mask = inb(EISA_INT1_MASK); mask &= ~((u8) (1 << irq)); outb(mask, EISA_INT1_MASK); - - local_irq_restore(flags); } static unsigned int startup_eisa1_irq(unsigned int irq) @@ -130,8 +125,6 @@ static void disable_eisa1_irq(unsigned int irq) outb(mask, EISA_INT1_MASK); } -#define shutdown_eisa1_irq disable_eisa1_irq - static void mask_and_ack_eisa1_irq(unsigned int irq) { disable_eisa1_irq(irq); @@ -148,25 +141,20 @@ static void end_eisa1_irq(unsigned int irq) static struct irq_chip ip22_eisa1_irq_type = { .typename = "IP22 EISA", .startup = startup_eisa1_irq, - .shutdown = shutdown_eisa1_irq, - .enable = enable_eisa1_irq, - .disable = disable_eisa1_irq, .ack = mask_and_ack_eisa1_irq, + .mask = disable_eisa1_irq, + .mask_ack = mask_and_ack_eisa1_irq, + .unmask = enable_eisa1_irq, .end = end_eisa1_irq, }; static void enable_eisa2_irq(unsigned int irq) { - unsigned long flags; u8 mask; - local_irq_save(flags); - mask = inb(EISA_INT2_MASK); mask &= ~((u8) (1 << (irq - 8))); outb(mask, EISA_INT2_MASK); - - local_irq_restore(flags); } static unsigned int startup_eisa2_irq(unsigned int irq) @@ -192,8 +180,6 @@ static void disable_eisa2_irq(unsigned int irq) outb(mask, EISA_INT2_MASK); } -#define shutdown_eisa2_irq disable_eisa2_irq - static void mask_and_ack_eisa2_irq(unsigned int irq) { disable_eisa2_irq(irq); @@ -210,10 +196,10 @@ static void end_eisa2_irq(unsigned int irq) static struct irq_chip ip22_eisa2_irq_type = { .typename = "IP22 EISA", .startup = startup_eisa2_irq, - .shutdown = shutdown_eisa2_irq, - .enable = enable_eisa2_irq, - .disable = disable_eisa2_irq, .ack = mask_and_ack_eisa2_irq, + .mask = disable_eisa2_irq, + .mask_ack = mask_and_ack_eisa2_irq, + .unmask = enable_eisa2_irq, .end = end_eisa2_irq, }; @@ -275,13 +261,10 @@ int __init ip22_eisa_init(void) outb(0, EISA_DMA2_WRITE_SINGLE); for (i = SGINT_EISA; i < (SGINT_EISA + EISA_MAX_IRQ); i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; if (i < (SGINT_EISA + 8)) - irq_desc[i].chip = &ip22_eisa1_irq_type; + set_irq_chip(i, &ip22_eisa1_irq_type); else - irq_desc[i].chip = &ip22_eisa2_irq_type; + set_irq_chip(i, &ip22_eisa2_irq_type); } /* Cannot use request_irq because of kmalloc not being ready at such diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index af518898eaa..8e2074b4ce4 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -40,34 +40,17 @@ extern int ip22_eisa_init(void); static void enable_local0_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_0_IRQ) sgint->imask0 |= (1 << (irq - SGINT_LOCAL0)); - local_irq_restore(flags); -} - -static unsigned int startup_local0_irq(unsigned int irq) -{ - enable_local0_irq(irq); - return 0; /* Never anything pending */ } static void disable_local0_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); - local_irq_restore(flags); } -#define shutdown_local0_irq disable_local0_irq -#define mask_and_ack_local0_irq disable_local0_irq - static void end_local0_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -76,44 +59,26 @@ static void end_local0_irq (unsigned int irq) static struct irq_chip ip22_local0_irq_type = { .typename = "IP22 local 0", - .startup = startup_local0_irq, - .shutdown = shutdown_local0_irq, - .enable = enable_local0_irq, - .disable = disable_local0_irq, - .ack = mask_and_ack_local0_irq, + .ack = disable_local0_irq, + .mask = disable_local0_irq, + .mask_ack = disable_local0_irq, + .unmask = enable_local0_irq, .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); /* don't allow mappable interrupt to be enabled from setup_irq, * we have our own way to do so */ if (irq != SGI_MAP_1_IRQ) sgint->imask1 |= (1 << (irq - SGINT_LOCAL1)); - local_irq_restore(flags); -} - -static unsigned int startup_local1_irq(unsigned int irq) -{ - enable_local1_irq(irq); - return 0; /* Never anything pending */ } void disable_local1_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); - local_irq_restore(flags); } -#define shutdown_local1_irq disable_local1_irq -#define mask_and_ack_local1_irq disable_local1_irq - static void end_local1_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -122,44 +87,26 @@ static void end_local1_irq (unsigned int irq) static struct irq_chip ip22_local1_irq_type = { .typename = "IP22 local 1", - .startup = startup_local1_irq, - .shutdown = shutdown_local1_irq, - .enable = enable_local1_irq, - .disable = disable_local1_irq, - .ack = mask_and_ack_local1_irq, + .ack = disable_local1_irq, + .mask = disable_local1_irq, + .mask_ack = disable_local1_irq, + .unmask = enable_local1_irq, .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2)); - local_irq_restore(flags); -} - -static unsigned int startup_local2_irq(unsigned int irq) -{ - enable_local2_irq(irq); - return 0; /* Never anything pending */ } void disable_local2_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2)); if (!sgint->cmeimask0) sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); - local_irq_restore(flags); } -#define shutdown_local2_irq disable_local2_irq -#define mask_and_ack_local2_irq disable_local2_irq - static void end_local2_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -168,44 +115,26 @@ static void end_local2_irq (unsigned int irq) static struct irq_chip ip22_local2_irq_type = { .typename = "IP22 local 2", - .startup = startup_local2_irq, - .shutdown = shutdown_local2_irq, - .enable = enable_local2_irq, - .disable = disable_local2_irq, - .ack = mask_and_ack_local2_irq, + .ack = disable_local2_irq, + .mask = disable_local2_irq, + .mask_ack = disable_local2_irq, + .unmask = enable_local2_irq, .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3)); - local_irq_restore(flags); -} - -static unsigned int startup_local3_irq(unsigned int irq) -{ - enable_local3_irq(irq); - return 0; /* Never anything pending */ } void disable_local3_irq(unsigned int irq) { - unsigned long flags; - - local_irq_save(flags); sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3)); if (!sgint->cmeimask1) sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); - local_irq_restore(flags); } -#define shutdown_local3_irq disable_local3_irq -#define mask_and_ack_local3_irq disable_local3_irq - static void end_local3_irq (unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -214,11 +143,10 @@ static void end_local3_irq (unsigned int irq) static struct irq_chip ip22_local3_irq_type = { .typename = "IP22 local 3", - .startup = startup_local3_irq, - .shutdown = shutdown_local3_irq, - .enable = enable_local3_irq, - .disable = disable_local3_irq, - .ack = mask_and_ack_local3_irq, + .ack = disable_local3_irq, + .mask = disable_local3_irq, + .mask_ack = disable_local3_irq, + .unmask = enable_local3_irq, .end = end_local3_irq, }; @@ -430,10 +358,7 @@ void __init arch_init_irq(void) else handler = &ip22_local3_irq_type; - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = handler; + set_irq_chip(i, handler); } /* vector handler. this register the IRQ as non-sharable */ diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 270ecd3e6b4..824320281a3 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -332,11 +332,6 @@ static inline void disable_bridge_irq(unsigned int irq) intr_disconnect_level(cpu, swlevel); } -static void mask_and_ack_bridge_irq(unsigned int irq) -{ - disable_bridge_irq(irq); -} - static void end_bridge_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && @@ -348,18 +343,16 @@ static struct irq_chip bridge_irq_type = { .typename = "bridge", .startup = startup_bridge_irq, .shutdown = shutdown_bridge_irq, - .enable = enable_bridge_irq, - .disable = disable_bridge_irq, - .ack = mask_and_ack_bridge_irq, + .ack = disable_bridge_irq, + .mask = disable_bridge_irq, + .mask_ack = disable_bridge_irq, + .unmask = enable_bridge_irq, .end = end_bridge_irq, }; void __devinit register_bridge_irq(unsigned int irq) { - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = 0; - irq_desc[irq].depth = 1; - irq_desc[irq].chip = &bridge_irq_type; + set_irq_chip(irq, &bridge_irq_type); } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 5e82a268e3c..86ba7fc10c3 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -172,15 +172,6 @@ static __init unsigned long get_m48t35_time(void) return mktime(year, month, date, hour, min, sec); } -static unsigned int startup_rt_irq(unsigned int irq) -{ - return 0; -} - -static void shutdown_rt_irq(unsigned int irq) -{ -} - static void enable_rt_irq(unsigned int irq) { } @@ -189,21 +180,16 @@ static void disable_rt_irq(unsigned int irq) { } -static void mask_and_ack_rt(unsigned int irq) -{ -} - static void end_rt_irq(unsigned int irq) { } static struct irq_chip rt_irq_type = { .typename = "SN HUB RT timer", - .startup = startup_rt_irq, - .shutdown = shutdown_rt_irq, - .enable = enable_rt_irq, - .disable = disable_rt_irq, - .ack = mask_and_ack_rt, + .ack = disable_rt_irq, + .mask = disable_rt_irq, + .mask_ack = disable_rt_irq, + .unmask = enable_rt_irq, .end = end_rt_irq, }; @@ -221,10 +207,7 @@ void __init plat_timer_setup(struct irqaction *irq) if (irqno < 0) panic("Can't allocate interrupt number for timer interrupt"); - irq_desc[irqno].status = IRQ_DISABLED; - irq_desc[irqno].action = NULL; - irq_desc[irqno].depth = 1; - irq_desc[irqno].chip = &rt_irq_type; + set_irq_chip(irqno, &rt_irq_type); /* over-write the handler, we use our own way */ irq->handler = no_action; diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index c9acadd0846..ae063864c02 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -113,12 +113,6 @@ static void inline flush_mace_bus(void) * is quite different anyway. */ -/* - * IRQ spinlock - Ralf says not to disable CPU interrupts, - * and I think he knows better. - */ -static DEFINE_SPINLOCK(ip32_irq_lock); - /* Some initial interrupts to set up */ extern irqreturn_t crime_memerr_intr(int irq, void *dev_id); extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id); @@ -138,12 +132,6 @@ static void enable_cpu_irq(unsigned int irq) set_c0_status(STATUSF_IP7); } -static unsigned int startup_cpu_irq(unsigned int irq) -{ - enable_cpu_irq(irq); - return 0; -} - static void disable_cpu_irq(unsigned int irq) { clear_c0_status(STATUSF_IP7); @@ -155,16 +143,12 @@ static void end_cpu_irq(unsigned int irq) enable_cpu_irq (irq); } -#define shutdown_cpu_irq disable_cpu_irq -#define mask_and_ack_cpu_irq disable_cpu_irq - static struct irq_chip ip32_cpu_interrupt = { .typename = "IP32 CPU", - .startup = startup_cpu_irq, - .shutdown = shutdown_cpu_irq, - .enable = enable_cpu_irq, - .disable = disable_cpu_irq, - .ack = mask_and_ack_cpu_irq, + .ack = disable_cpu_irq, + .mask = disable_cpu_irq, + .mask_ack = disable_cpu_irq, + .unmask = enable_cpu_irq, .end = end_cpu_irq, }; @@ -177,45 +161,27 @@ static uint64_t crime_mask; static void enable_crime_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; - spin_unlock_irqrestore(&ip32_irq_lock, flags); -} - -static unsigned int startup_crime_irq(unsigned int irq) -{ - enable_crime_irq(irq); - return 0; /* This is probably not right; we could have pending irqs */ } static void disable_crime_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); - spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void mask_and_ack_crime_irq(unsigned int irq) { - unsigned long flags; - /* Edge triggered interrupts must be cleared. */ if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { uint64_t crime_int; - spin_lock_irqsave(&ip32_irq_lock, flags); crime_int = crime->hard_int; crime_int &= ~(1 << (irq - 1)); crime->hard_int = crime_int; - spin_unlock_irqrestore(&ip32_irq_lock, flags); } disable_crime_irq(irq); } @@ -226,15 +192,12 @@ static void end_crime_irq(unsigned int irq) enable_crime_irq(irq); } -#define shutdown_crime_irq disable_crime_irq - static struct irq_chip ip32_crime_interrupt = { .typename = "IP32 CRIME", - .startup = startup_crime_irq, - .shutdown = shutdown_crime_irq, - .enable = enable_crime_irq, - .disable = disable_crime_irq, .ack = mask_and_ack_crime_irq, + .mask = disable_crime_irq, + .mask_ack = mask_and_ack_crime_irq, + .unmask = enable_crime_irq, .end = end_crime_irq, }; @@ -248,34 +211,20 @@ static unsigned long macepci_mask; static void enable_macepci_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); macepci_mask |= MACEPCI_CONTROL_INT(irq - 9); mace->pci.control = macepci_mask; crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; - spin_unlock_irqrestore(&ip32_irq_lock, flags); -} - -static unsigned int startup_macepci_irq(unsigned int irq) -{ - enable_macepci_irq (irq); - return 0; } static void disable_macepci_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9); mace->pci.control = macepci_mask; flush_mace_bus(); - spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void end_macepci_irq(unsigned int irq) @@ -284,16 +233,12 @@ static void end_macepci_irq(unsigned int irq) enable_macepci_irq(irq); } -#define shutdown_macepci_irq disable_macepci_irq -#define mask_and_ack_macepci_irq disable_macepci_irq - static struct irq_chip ip32_macepci_interrupt = { .typename = "IP32 MACE PCI", - .startup = startup_macepci_irq, - .shutdown = shutdown_macepci_irq, - .enable = enable_macepci_irq, - .disable = disable_macepci_irq, - .ack = mask_and_ack_macepci_irq, + .ack = disable_macepci_irq, + .mask = disable_macepci_irq, + .mask_ack = disable_macepci_irq, + .unmask = enable_macepci_irq, .end = end_macepci_irq, }; @@ -339,7 +284,6 @@ static unsigned long maceisa_mask; static void enable_maceisa_irq (unsigned int irq) { unsigned int crime_int = 0; - unsigned long flags; DBG ("maceisa enable: %u\n", irq); @@ -355,26 +299,16 @@ static void enable_maceisa_irq (unsigned int irq) break; } DBG ("crime_int %08x enabled\n", crime_int); - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= crime_int; crime->imask = crime_mask; maceisa_mask |= 1 << (irq - 33); mace->perif.ctrl.imask = maceisa_mask; - spin_unlock_irqrestore(&ip32_irq_lock, flags); -} - -static unsigned int startup_maceisa_irq(unsigned int irq) -{ - enable_maceisa_irq(irq); - return 0; } static void disable_maceisa_irq(unsigned int irq) { unsigned int crime_int = 0; - unsigned long flags; - spin_lock_irqsave(&ip32_irq_lock, flags); maceisa_mask &= ~(1 << (irq - 33)); if(!(maceisa_mask & MACEISA_AUDIO_INT)) crime_int |= MACE_AUDIO_INT; @@ -387,23 +321,20 @@ static void disable_maceisa_irq(unsigned int irq) flush_crime_bus(); mace->perif.ctrl.imask = maceisa_mask; flush_mace_bus(); - spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void mask_and_ack_maceisa_irq(unsigned int irq) { - unsigned long mace_int, flags; + unsigned long mace_int; switch (irq) { case MACEISA_PARALLEL_IRQ: case MACEISA_SERIAL1_TDMAPR_IRQ: case MACEISA_SERIAL2_TDMAPR_IRQ: /* edge triggered */ - spin_lock_irqsave(&ip32_irq_lock, flags); mace_int = mace->perif.ctrl.istat; mace_int &= ~(1 << (irq - 33)); mace->perif.ctrl.istat = mace_int; - spin_unlock_irqrestore(&ip32_irq_lock, flags); break; } disable_maceisa_irq(irq); @@ -415,15 +346,12 @@ static void end_maceisa_irq(unsigned irq) enable_maceisa_irq(irq); } -#define shutdown_maceisa_irq disable_maceisa_irq - static struct irq_chip ip32_maceisa_interrupt = { .typename = "IP32 MACE ISA", - .startup = startup_maceisa_irq, - .shutdown = shutdown_maceisa_irq, - .enable = enable_maceisa_irq, - .disable = disable_maceisa_irq, .ack = mask_and_ack_maceisa_irq, + .mask = disable_maceisa_irq, + .mask_ack = mask_and_ack_maceisa_irq, + .unmask = enable_maceisa_irq, .end = end_maceisa_irq, }; @@ -433,29 +361,15 @@ static struct irq_chip ip32_maceisa_interrupt = { static void enable_mace_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask |= 1 << (irq - 1); crime->imask = crime_mask; - spin_unlock_irqrestore(&ip32_irq_lock, flags); -} - -static unsigned int startup_mace_irq(unsigned int irq) -{ - enable_mace_irq(irq); - return 0; } static void disable_mace_irq(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&ip32_irq_lock, flags); crime_mask &= ~(1 << (irq - 1)); crime->imask = crime_mask; flush_crime_bus(); - spin_unlock_irqrestore(&ip32_irq_lock, flags); } static void end_mace_irq(unsigned int irq) @@ -464,16 +378,12 @@ static void end_mace_irq(unsigned int irq) enable_mace_irq(irq); } -#define shutdown_mace_irq disable_mace_irq -#define mask_and_ack_mace_irq disable_mace_irq - static struct irq_chip ip32_mace_interrupt = { .typename = "IP32 MACE", - .startup = startup_mace_irq, - .shutdown = shutdown_mace_irq, - .enable = enable_mace_irq, - .disable = disable_mace_irq, - .ack = mask_and_ack_mace_irq, + .ack = disable_mace_irq, + .mask = disable_mace_irq, + .mask_ack = disable_mace_irq, + .unmask = enable_mace_irq, .end = end_mace_irq, }; @@ -586,10 +496,7 @@ void __init arch_init_irq(void) else controller = &ip32_maceisa_interrupt; - irq_desc[irq].status = IRQ_DISABLED; - irq_desc[irq].action = 0; - irq_desc[irq].depth = 0; - irq_desc[irq].chip = controller; + set_irq_chip(irq, controller); } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 8b1f4148492..2e8f6b2e242 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c @@ -45,11 +45,9 @@ */ -#define shutdown_bcm1480_irq disable_bcm1480_irq static void end_bcm1480_irq(unsigned int irq); static void enable_bcm1480_irq(unsigned int irq); static void disable_bcm1480_irq(unsigned int irq); -static unsigned int startup_bcm1480_irq(unsigned int irq); static void ack_bcm1480_irq(unsigned int irq); #ifdef CONFIG_SMP static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask); @@ -85,11 +83,10 @@ extern char sb1250_duart_present[]; static struct irq_chip bcm1480_irq_type = { .typename = "BCM1480-IMR", - .startup = startup_bcm1480_irq, - .shutdown = shutdown_bcm1480_irq, - .enable = enable_bcm1480_irq, - .disable = disable_bcm1480_irq, .ack = ack_bcm1480_irq, + .mask = disable_bcm1480_irq, + .mask_ack = ack_bcm1480_irq, + .unmask = enable_bcm1480_irq, .end = end_bcm1480_irq, #ifdef CONFIG_SMP .set_affinity = bcm1480_set_affinity @@ -188,14 +185,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) /*****************************************************************************/ -static unsigned int startup_bcm1480_irq(unsigned int irq) -{ - bcm1480_unmask_irq(bcm1480_irq_owner[irq], irq); - - return 0; /* never anything pending */ -} - - static void disable_bcm1480_irq(unsigned int irq) { bcm1480_mask_irq(bcm1480_irq_owner[irq], irq); @@ -270,16 +259,9 @@ void __init init_bcm1480_irqs(void) { int i; - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - if (i < BCM1480_NR_IRQS) { - irq_desc[i].chip = &bcm1480_irq_type; - bcm1480_irq_owner[i] = 0; - } else { - irq_desc[i].chip = &no_irq_chip; - } + for (i = 0; i < BCM1480_NR_IRQS; i++) { + set_irq_chip(i, &bcm1480_irq_type); + bcm1480_irq_owner[i] = 0; } } diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index d5d26770daf..82ce7533053 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c @@ -44,11 +44,9 @@ */ -#define shutdown_sb1250_irq disable_sb1250_irq static void end_sb1250_irq(unsigned int irq); static void enable_sb1250_irq(unsigned int irq); static void disable_sb1250_irq(unsigned int irq); -static unsigned int startup_sb1250_irq(unsigned int irq); static void ack_sb1250_irq(unsigned int irq); #ifdef CONFIG_SMP static void sb1250_set_affinity(unsigned int irq, cpumask_t mask); @@ -70,11 +68,10 @@ extern char sb1250_duart_present[]; static struct irq_chip sb1250_irq_type = { .typename = "SB1250-IMR", - .startup = startup_sb1250_irq, - .shutdown = shutdown_sb1250_irq, - .enable = enable_sb1250_irq, - .disable = disable_sb1250_irq, .ack = ack_sb1250_irq, + .mask = disable_sb1250_irq, + .mask_ack = ack_sb1250_irq, + .unmask = enable_sb1250_irq, .end = end_sb1250_irq, #ifdef CONFIG_SMP .set_affinity = sb1250_set_affinity @@ -163,14 +160,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask) /*****************************************************************************/ -static unsigned int startup_sb1250_irq(unsigned int irq) -{ - sb1250_unmask_irq(sb1250_irq_owner[irq], irq); - - return 0; /* never anything pending */ -} - - static void disable_sb1250_irq(unsigned int irq) { sb1250_mask_irq(sb1250_irq_owner[irq], irq); @@ -239,16 +228,9 @@ void __init init_sb1250_irqs(void) { int i; - for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - if (i < SB1250_NR_IRQS) { - irq_desc[i].chip = &sb1250_irq_type; - sb1250_irq_owner[i] = 0; - } else { - irq_desc[i].chip = &no_irq_chip; - } + for (i = 0; i < SB1250_NR_IRQS; i++) { + set_irq_chip(i, &sb1250_irq_type); + sb1250_irq_owner[i] = 0; } } diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 48fb74a7aae..8511bcc6d99 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c @@ -11,44 +11,25 @@ #include #include #include -#include #include #include #include -DEFINE_SPINLOCK(pciasic_lock); - static void enable_pciasic_irq(unsigned int irq) { unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); - unsigned long flags; - spin_lock_irqsave(&pciasic_lock, flags); *(volatile u8 *) PCIMT_IRQSEL |= mask; - spin_unlock_irqrestore(&pciasic_lock, flags); -} - -static unsigned int startup_pciasic_irq(unsigned int irq) -{ - enable_pciasic_irq(irq); - return 0; /* never anything pending */ } -#define shutdown_pciasic_irq disable_pciasic_irq - void disable_pciasic_irq(unsigned int irq) { unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); - unsigned long flags; - spin_lock_irqsave(&pciasic_lock, flags); *(volatile u8 *) PCIMT_IRQSEL &= mask; - spin_unlock_irqrestore(&pciasic_lock, flags); } -#define mask_and_ack_pciasic_irq disable_pciasic_irq - static void end_pciasic_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -57,11 +38,10 @@ static void end_pciasic_irq(unsigned int irq) static struct irq_chip pciasic_irq_type = { .typename = "ASIC-PCI", - .startup = startup_pciasic_irq, - .shutdown = shutdown_pciasic_irq, - .enable = enable_pciasic_irq, - .disable = disable_pciasic_irq, - .ack = mask_and_ack_pciasic_irq, + .ack = disable_pciasic_irq, + .mask = disable_pciasic_irq, + .mask_ack = disable_pciasic_irq, + .unmask = enable_pciasic_irq, .end = end_pciasic_irq, }; @@ -178,12 +158,8 @@ asmlinkage void plat_irq_dispatch(void) void __init init_pciasic(void) { - unsigned long flags; - - spin_lock_irqsave(&pciasic_lock, flags); * (volatile u8 *) PCIMT_IRQSEL = IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD; - spin_unlock_irqrestore(&pciasic_lock, flags); } /* @@ -199,12 +175,8 @@ void __init arch_init_irq(void) init_pciasic(); /* Actually we've got more interrupts to handle ... */ - for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &pciasic_irq_type; - } + for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) + set_irq_chip(i, &pciasic_irq_type); change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); } diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 8266a88a3f8..2c57ced5c68 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -64,19 +64,13 @@ #define TX4927_IRQ_NEST4 ( 1 << 9 ) #define TX4927_IRQ_CP0_INIT ( 1 << 10 ) -#define TX4927_IRQ_CP0_STARTUP ( 1 << 11 ) -#define TX4927_IRQ_CP0_SHUTDOWN ( 1 << 12 ) #define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) #define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) -#define TX4927_IRQ_CP0_MASK ( 1 << 15 ) #define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) #define TX4927_IRQ_PIC_INIT ( 1 << 20 ) -#define TX4927_IRQ_PIC_STARTUP ( 1 << 21 ) -#define TX4927_IRQ_PIC_SHUTDOWN ( 1 << 22 ) #define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) #define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) -#define TX4927_IRQ_PIC_MASK ( 1 << 25 ) #define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) #define TX4927_IRQ_ALL 0xffffffff @@ -87,18 +81,12 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE | TX4927_IRQ_INFO | TX4927_IRQ_WARN | TX4927_IRQ_EROR // | TX4927_IRQ_CP0_INIT -// | TX4927_IRQ_CP0_STARTUP -// | TX4927_IRQ_CP0_SHUTDOWN // | TX4927_IRQ_CP0_ENABLE // | TX4927_IRQ_CP0_DISABLE -// | TX4927_IRQ_CP0_MASK // | TX4927_IRQ_CP0_ENDIRQ // | TX4927_IRQ_PIC_INIT -// | TX4927_IRQ_PIC_STARTUP -// | TX4927_IRQ_PIC_SHUTDOWN // | TX4927_IRQ_PIC_ENABLE // | TX4927_IRQ_PIC_DISABLE -// | TX4927_IRQ_PIC_MASK // | TX4927_IRQ_PIC_ENDIRQ // | TX4927_IRQ_INIT // | TX4927_IRQ_NEST1 @@ -124,49 +112,36 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE * Forwad definitions for all pic's */ -static unsigned int tx4927_irq_cp0_startup(unsigned int irq); -static void tx4927_irq_cp0_shutdown(unsigned int irq); static void tx4927_irq_cp0_enable(unsigned int irq); static void tx4927_irq_cp0_disable(unsigned int irq); -static void tx4927_irq_cp0_mask_and_ack(unsigned int irq); static void tx4927_irq_cp0_end(unsigned int irq); -static unsigned int tx4927_irq_pic_startup(unsigned int irq); -static void tx4927_irq_pic_shutdown(unsigned int irq); static void tx4927_irq_pic_enable(unsigned int irq); static void tx4927_irq_pic_disable(unsigned int irq); -static void tx4927_irq_pic_mask_and_ack(unsigned int irq); static void tx4927_irq_pic_end(unsigned int irq); /* * Kernel structs for all pic's */ -static DEFINE_SPINLOCK(tx4927_cp0_lock); -static DEFINE_SPINLOCK(tx4927_pic_lock); - #define TX4927_CP0_NAME "TX4927-CP0" static struct irq_chip tx4927_irq_cp0_type = { .typename = TX4927_CP0_NAME, - .startup = tx4927_irq_cp0_startup, - .shutdown = tx4927_irq_cp0_shutdown, - .enable = tx4927_irq_cp0_enable, - .disable = tx4927_irq_cp0_disable, - .ack = tx4927_irq_cp0_mask_and_ack, + .ack = tx4927_irq_cp0_disable, + .mask = tx4927_irq_cp0_disable, + .mask_ack = tx4927_irq_cp0_disable, + .unmask = tx4927_irq_cp0_enable, .end = tx4927_irq_cp0_end, - .set_affinity = NULL }; #define TX4927_PIC_NAME "TX4927-PIC" static struct irq_chip tx4927_irq_pic_type = { .typename = TX4927_PIC_NAME, - .startup = tx4927_irq_pic_startup, - .shutdown = tx4927_irq_pic_shutdown, - .enable = tx4927_irq_pic_enable, - .disable = tx4927_irq_pic_disable, - .ack = tx4927_irq_pic_mask_and_ack, + .ack = tx4927_irq_pic_disable, + .mask = tx4927_irq_pic_disable, + .mask_ack = tx4927_irq_pic_disable, + .unmask = tx4927_irq_pic_enable, .end = tx4927_irq_pic_end, - .set_affinity = NULL }; #define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } @@ -211,8 +186,6 @@ tx4927_irq_cp0_modify(unsigned cp0_reg, unsigned clr_bits, unsigned set_bits) break; } } - - return; } static void __init tx4927_irq_cp0_init(void) @@ -222,71 +195,22 @@ static void __init tx4927_irq_cp0_init(void) TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_INIT, "beg=%d end=%d\n", TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); - for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &tx4927_irq_cp0_type; - } - - return; -} - -static unsigned int tx4927_irq_cp0_startup(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_STARTUP, "irq=%d \n", irq); - - tx4927_irq_cp0_enable(irq); - - return (0); -} - -static void tx4927_irq_cp0_shutdown(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_SHUTDOWN, "irq=%d \n", irq); - - tx4927_irq_cp0_disable(irq); - - return; + for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) + set_irq_chip(i, &tx4927_irq_cp0_type); } static void tx4927_irq_cp0_enable(unsigned int irq) { - unsigned long flags; - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENABLE, "irq=%d \n", irq); - spin_lock_irqsave(&tx4927_cp0_lock, flags); - tx4927_irq_cp0_modify(CCP0_STATUS, 0, tx4927_irq_cp0_mask(irq)); - - spin_unlock_irqrestore(&tx4927_cp0_lock, flags); - - return; } static void tx4927_irq_cp0_disable(unsigned int irq) { - unsigned long flags; - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_DISABLE, "irq=%d \n", irq); - spin_lock_irqsave(&tx4927_cp0_lock, flags); - tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); - - spin_unlock_irqrestore(&tx4927_cp0_lock, flags); - - return; -} - -static void tx4927_irq_cp0_mask_and_ack(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_MASK, "irq=%d \n", irq); - - tx4927_irq_cp0_disable(irq); - - return; } static void tx4927_irq_cp0_end(unsigned int irq) @@ -296,8 +220,6 @@ static void tx4927_irq_cp0_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_cp0_enable(irq); } - - return; } /* @@ -418,94 +340,38 @@ static void tx4927_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, val &= (~clr_bits); val |= (set_bits); TX4927_WR(pic_reg, val); - - return; } static void __init tx4927_irq_pic_init(void) { - unsigned long flags; int i; TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_INIT, "beg=%d end=%d\n", TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); - for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 2; - irq_desc[i].chip = &tx4927_irq_pic_type; - } + for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) + set_irq_chip(i, &tx4927_irq_pic_type); setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); - spin_lock_irqsave(&tx4927_pic_lock, flags); - TX4927_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ TX4927_WR(0xff1ff600, TX4927_RD(0xff1ff600) | 0x1); /* irq enable */ - - spin_unlock_irqrestore(&tx4927_pic_lock, flags); - - return; -} - -static unsigned int tx4927_irq_pic_startup(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_STARTUP, "irq=%d\n", irq); - - tx4927_irq_pic_enable(irq); - - return (0); -} - -static void tx4927_irq_pic_shutdown(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_SHUTDOWN, "irq=%d\n", irq); - - tx4927_irq_pic_disable(irq); - - return; } static void tx4927_irq_pic_enable(unsigned int irq) { - unsigned long flags; - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENABLE, "irq=%d\n", irq); - spin_lock_irqsave(&tx4927_pic_lock, flags); - tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), 0, tx4927_irq_pic_mask(irq)); - - spin_unlock_irqrestore(&tx4927_pic_lock, flags); - - return; } static void tx4927_irq_pic_disable(unsigned int irq) { - unsigned long flags; - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_DISABLE, "irq=%d\n", irq); - spin_lock_irqsave(&tx4927_pic_lock, flags); - tx4927_irq_pic_modify(tx4927_irq_pic_addr(irq), tx4927_irq_pic_mask(irq), 0); - - spin_unlock_irqrestore(&tx4927_pic_lock, flags); - - return; -} - -static void tx4927_irq_pic_mask_and_ack(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_MASK, "irq=%d\n", irq); - - tx4927_irq_pic_disable(irq); - - return; } static void tx4927_irq_pic_end(unsigned int irq) @@ -515,8 +381,6 @@ static void tx4927_irq_pic_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { tx4927_irq_pic_enable(irq); } - - return; } /* @@ -533,8 +397,6 @@ void __init tx4927_irq_init(void) tx4927_irq_pic_init(); TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); - - return; } static int tx4927_irq_nested(void) diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 0c3c3f66823..1fdace89ae6 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -151,16 +151,11 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_EROR ( 1 << 2 ) #define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_STARTUP ( 1 << 11 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN ( 1 << 12 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) #define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_MASK ( 1 << 15 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) #define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) -#define TOSHIBA_RBTX4927_IRQ_ISA_STARTUP ( 1 << 21 ) -#define TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN ( 1 << 22 ) #define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) #define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) #define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) @@ -175,15 +170,10 @@ static const u32 toshiba_rbtx4927_irq_debug_flag = (TOSHIBA_RBTX4927_IRQ_NONE | TOSHIBA_RBTX4927_IRQ_INFO | TOSHIBA_RBTX4927_IRQ_WARN | TOSHIBA_RBTX4927_IRQ_EROR // | TOSHIBA_RBTX4927_IRQ_IOC_INIT -// | TOSHIBA_RBTX4927_IRQ_IOC_STARTUP -// | TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN // | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE // | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE -// | TOSHIBA_RBTX4927_IRQ_IOC_MASK // | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ // | TOSHIBA_RBTX4927_IRQ_ISA_INIT -// | TOSHIBA_RBTX4927_IRQ_ISA_STARTUP -// | TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN // | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE // | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE // | TOSHIBA_RBTX4927_IRQ_ISA_MASK @@ -231,35 +221,25 @@ extern void disable_8259A_irq(unsigned int irq); extern void mask_and_ack_8259A(unsigned int irq); #endif -static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq); -static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); -static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); #ifdef CONFIG_TOSHIBA_FPCIB0 -static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq); -static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq); static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); #endif -static DEFINE_SPINLOCK(toshiba_rbtx4927_ioc_lock); - - #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { .typename = TOSHIBA_RBTX4927_IOC_NAME, - .startup = toshiba_rbtx4927_irq_ioc_startup, - .shutdown = toshiba_rbtx4927_irq_ioc_shutdown, - .enable = toshiba_rbtx4927_irq_ioc_enable, - .disable = toshiba_rbtx4927_irq_ioc_disable, - .ack = toshiba_rbtx4927_irq_ioc_mask_and_ack, + .ack = toshiba_rbtx4927_irq_ioc_disable, + .mask = toshiba_rbtx4927_irq_ioc_disable, + .mask_ack = toshiba_rbtx4927_irq_ioc_disable, + .unmask = toshiba_rbtx4927_irq_ioc_enable, .end = toshiba_rbtx4927_irq_ioc_end, - .set_affinity = NULL }; #define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 #define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 @@ -269,13 +249,11 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { #define TOSHIBA_RBTX4927_ISA_NAME "RBTX4927-ISA" static struct irq_chip toshiba_rbtx4927_irq_isa_type = { .typename = TOSHIBA_RBTX4927_ISA_NAME, - .startup = toshiba_rbtx4927_irq_isa_startup, - .shutdown = toshiba_rbtx4927_irq_isa_shutdown, - .enable = toshiba_rbtx4927_irq_isa_enable, - .disable = toshiba_rbtx4927_irq_isa_disable, .ack = toshiba_rbtx4927_irq_isa_mask_and_ack, + .mask = toshiba_rbtx4927_irq_isa_disable, + .mask_ack = toshiba_rbtx4927_irq_isa_mask_and_ack, + .unmask = toshiba_rbtx4927_irq_isa_enable, .end = toshiba_rbtx4927_irq_isa_end, - .set_affinity = NULL }; #endif @@ -363,58 +341,15 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) TOSHIBA_RBTX4927_IRQ_IOC_END); for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 3; - irq_desc[i].chip = &toshiba_rbtx4927_irq_ioc_type; - } + i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) + set_irq_chip(i, &toshiba_rbtx4927_irq_ioc_type); setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, &toshiba_rbtx4927_irq_ioc_action); - - return; } -static unsigned int toshiba_rbtx4927_irq_ioc_startup(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_STARTUP, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - toshiba_rbtx4927_irq_ioc_enable(irq); - - return (0); -} - - -static void toshiba_rbtx4927_irq_ioc_shutdown(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_SHUTDOWN, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - toshiba_rbtx4927_irq_ioc_disable(irq); - - return; -} - - static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) { - unsigned long flags; volatile unsigned char v; TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENABLE, @@ -427,21 +362,14 @@ static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq) panic("\n"); } - spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); - v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v |= (1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); - - spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); - - return; } static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) { - unsigned long flags; volatile unsigned char v; TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_DISABLE, @@ -454,36 +382,11 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) panic("\n"); } - spin_lock_irqsave(&toshiba_rbtx4927_ioc_lock, flags); - v = TX4927_RD08(TOSHIBA_RBTX4927_IOC_INTR_ENAB); v &= ~(1 << (irq - TOSHIBA_RBTX4927_IRQ_IOC_BEG)); TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); - - spin_unlock_irqrestore(&toshiba_rbtx4927_ioc_lock, flags); - - return; } - -static void toshiba_rbtx4927_irq_ioc_mask_and_ack(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_MASK, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - toshiba_rbtx4927_irq_ioc_disable(irq); - - return; -} - - static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) { TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, @@ -499,8 +402,6 @@ static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { toshiba_rbtx4927_irq_ioc_enable(irq); } - - return; } @@ -520,13 +421,8 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) TOSHIBA_RBTX4927_IRQ_ISA_END); for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; - i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = - ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); - irq_desc[i].chip = &toshiba_rbtx4927_irq_isa_type; - } + i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) + set_irq_chip(i, &toshiba_rbtx4927_irq_isa_type); setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, &toshiba_rbtx4927_irq_isa_master); @@ -536,48 +432,6 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) /* make sure we are looking at IRR (not ISR) */ outb(0x0A, 0x20); outb(0x0A, 0xA0); - - return; -} -#endif - - -#ifdef CONFIG_TOSHIBA_FPCIB0 -static unsigned int toshiba_rbtx4927_irq_isa_startup(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_STARTUP, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG - || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - toshiba_rbtx4927_irq_isa_enable(irq); - - return (0); -} -#endif - - -#ifdef CONFIG_TOSHIBA_FPCIB0 -static void toshiba_rbtx4927_irq_isa_shutdown(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_SHUTDOWN, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG - || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - toshiba_rbtx4927_irq_isa_disable(irq); - - return; } #endif @@ -596,8 +450,6 @@ static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq) } enable_8259A_irq(irq); - - return; } #endif @@ -616,8 +468,6 @@ static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq) } disable_8259A_irq(irq); - - return; } #endif @@ -636,8 +486,6 @@ static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) } mask_and_ack_8259A(irq); - - return; } #endif @@ -658,8 +506,6 @@ static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { toshiba_rbtx4927_irq_isa_enable(irq); } - - return; } #endif @@ -668,8 +514,6 @@ void __init arch_init_irq(void) { extern void tx4927_irq_init(void); - local_irq_disable(); - tx4927_irq_init(); toshiba_rbtx4927_irq_ioc_init(); #ifdef CONFIG_TOSHIBA_FPCIB0 @@ -681,8 +525,6 @@ void __init arch_init_irq(void) #endif wbflush(); - - return; } void toshiba_rbtx4927_irq_dump(char *key) @@ -715,7 +557,6 @@ void toshiba_rbtx4927_irq_dump(char *key) } } #endif - return; } void toshiba_rbtx4927_irq_dump_pics(char *s) @@ -780,6 +621,4 @@ void toshiba_rbtx4927_irq_dump_pics(char *s) level5_s); TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_INFO, "[%s]\n", s); - - return; } diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 77fe2454f5b..19c9ee9e3d0 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c @@ -37,48 +37,36 @@ /* Forwad definitions for all pic's */ /**********************************************************************************/ -static unsigned int tx4938_irq_cp0_startup(unsigned int irq); -static void tx4938_irq_cp0_shutdown(unsigned int irq); static void tx4938_irq_cp0_enable(unsigned int irq); static void tx4938_irq_cp0_disable(unsigned int irq); -static void tx4938_irq_cp0_mask_and_ack(unsigned int irq); static void tx4938_irq_cp0_end(unsigned int irq); -static unsigned int tx4938_irq_pic_startup(unsigned int irq); -static void tx4938_irq_pic_shutdown(unsigned int irq); static void tx4938_irq_pic_enable(unsigned int irq); static void tx4938_irq_pic_disable(unsigned int irq); -static void tx4938_irq_pic_mask_and_ack(unsigned int irq); static void tx4938_irq_pic_end(unsigned int irq); /**********************************************************************************/ /* Kernel structs for all pic's */ /**********************************************************************************/ -DEFINE_SPINLOCK(tx4938_cp0_lock); -DEFINE_SPINLOCK(tx4938_pic_lock); #define TX4938_CP0_NAME "TX4938-CP0" static struct irq_chip tx4938_irq_cp0_type = { .typename = TX4938_CP0_NAME, - .startup = tx4938_irq_cp0_startup, - .shutdown = tx4938_irq_cp0_shutdown, - .enable = tx4938_irq_cp0_enable, - .disable = tx4938_irq_cp0_disable, - .ack = tx4938_irq_cp0_mask_and_ack, + .ack = tx4938_irq_cp0_disable, + .mask = tx4938_irq_cp0_disable, + .mask_ack = tx4938_irq_cp0_disable, + .unmask = tx4938_irq_cp0_enable, .end = tx4938_irq_cp0_end, - .set_affinity = NULL }; #define TX4938_PIC_NAME "TX4938-PIC" static struct irq_chip tx4938_irq_pic_type = { .typename = TX4938_PIC_NAME, - .startup = tx4938_irq_pic_startup, - .shutdown = tx4938_irq_pic_shutdown, - .enable = tx4938_irq_pic_enable, - .disable = tx4938_irq_pic_disable, - .ack = tx4938_irq_pic_mask_and_ack, + .ack = tx4938_irq_pic_disable, + .mask = tx4938_irq_pic_disable, + .mask_ack = tx4938_irq_pic_disable, + .unmask = tx4938_irq_pic_enable, .end = tx4938_irq_pic_end, - .set_affinity = NULL }; static struct irqaction tx4938_irq_pic_action = { @@ -99,56 +87,20 @@ tx4938_irq_cp0_init(void) { int i; - for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 1; - irq_desc[i].chip = &tx4938_irq_cp0_type; - } -} - -static unsigned int -tx4938_irq_cp0_startup(unsigned int irq) -{ - tx4938_irq_cp0_enable(irq); - - return 0; -} - -static void -tx4938_irq_cp0_shutdown(unsigned int irq) -{ - tx4938_irq_cp0_disable(irq); + for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) + set_irq_chip(i, &tx4938_irq_cp0_type); } static void tx4938_irq_cp0_enable(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&tx4938_cp0_lock, flags); - set_c0_status(tx4938_irq_cp0_mask(irq)); - - spin_unlock_irqrestore(&tx4938_cp0_lock, flags); } static void tx4938_irq_cp0_disable(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&tx4938_cp0_lock, flags); - clear_c0_status(tx4938_irq_cp0_mask(irq)); - - spin_unlock_irqrestore(&tx4938_cp0_lock, flags); -} - -static void -tx4938_irq_cp0_mask_and_ack(unsigned int irq) -{ - tx4938_irq_cp0_disable(irq); } static void @@ -290,70 +242,29 @@ tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits) static void __init tx4938_irq_pic_init(void) { - unsigned long flags; int i; - for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 2; - irq_desc[i].chip = &tx4938_irq_pic_type; - } + for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) + set_irq_chip(i, &tx4938_irq_pic_type); setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); - spin_lock_irqsave(&tx4938_pic_lock, flags); - TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */ - - spin_unlock_irqrestore(&tx4938_pic_lock, flags); -} - -static unsigned int -tx4938_irq_pic_startup(unsigned int irq) -{ - tx4938_irq_pic_enable(irq); - - return 0; -} - -static void -tx4938_irq_pic_shutdown(unsigned int irq) -{ - tx4938_irq_pic_disable(irq); } static void tx4938_irq_pic_enable(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&tx4938_pic_lock, flags); - tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0, tx4938_irq_pic_mask(irq)); - - spin_unlock_irqrestore(&tx4938_pic_lock, flags); } static void tx4938_irq_pic_disable(unsigned int irq) { - unsigned long flags; - - spin_lock_irqsave(&tx4938_pic_lock, flags); - tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), tx4938_irq_pic_mask(irq), 0); - - spin_unlock_irqrestore(&tx4938_pic_lock, flags); -} - -static void -tx4938_irq_pic_mask_and_ack(unsigned int irq) -{ - tx4938_irq_pic_disable(irq); } static void diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 102e473c10a..2735ffe9ec2 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -87,25 +87,18 @@ IRQ Device #include #include -static unsigned int toshiba_rbtx4938_irq_ioc_startup(unsigned int irq); -static void toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); -static void toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq); -DEFINE_SPINLOCK(toshiba_rbtx4938_ioc_lock); - #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .typename = TOSHIBA_RBTX4938_IOC_NAME, - .startup = toshiba_rbtx4938_irq_ioc_startup, - .shutdown = toshiba_rbtx4938_irq_ioc_shutdown, - .enable = toshiba_rbtx4938_irq_ioc_enable, - .disable = toshiba_rbtx4938_irq_ioc_disable, - .ack = toshiba_rbtx4938_irq_ioc_mask_and_ack, + .ack = toshiba_rbtx4938_irq_ioc_disable, + .mask = toshiba_rbtx4938_irq_ioc_disable, + .mask_ack = toshiba_rbtx4938_irq_ioc_disable, + .unmask = toshiba_rbtx4938_irq_ioc_enable, .end = toshiba_rbtx4938_irq_ioc_end, - .set_affinity = NULL }; #define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000 @@ -142,69 +135,35 @@ toshiba_rbtx4938_irq_ioc_init(void) int i; for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; - i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) { - irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].action = 0; - irq_desc[i].depth = 3; - irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; - } + i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) + set_irq_chip(i, &toshiba_rbtx4938_irq_ioc_type); setup_irq(RBTX4938_IRQ_IOCINT, &toshiba_rbtx4938_irq_ioc_action); } -static unsigned int -toshiba_rbtx4938_irq_ioc_startup(unsigned int irq) -{ - toshiba_rbtx4938_irq_ioc_enable(irq); - - return 0; -} - -static void -toshiba_rbtx4938_irq_ioc_shutdown(unsigned int irq) -{ - toshiba_rbtx4938_irq_ioc_disable(irq); -} - static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq) { - unsigned long flags; volatile unsigned char v; - spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags); - v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); v |= (1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); mmiowb(); TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); - - spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags); } static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) { - unsigned long flags; volatile unsigned char v; - spin_lock_irqsave(&toshiba_rbtx4938_ioc_lock, flags); - v = TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); v &= ~(1 << (irq - TOSHIBA_RBTX4938_IRQ_IOC_BEG)); TX4938_WR08(TOSHIBA_RBTX4938_IOC_INTR_ENAB, v); mmiowb(); TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); - - spin_unlock_irqrestore(&toshiba_rbtx4938_ioc_lock, flags); -} - -static void -toshiba_rbtx4938_irq_ioc_mask_and_ack(unsigned int irq) -{ - toshiba_rbtx4938_irq_ioc_disable(irq); } static void diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index c215c0d39fa..33d70a6547a 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -417,14 +417,7 @@ void vr41xx_disable_bcuint(void) EXPORT_SYMBOL(vr41xx_disable_bcuint); -static unsigned int startup_sysint1_irq(unsigned int irq) -{ - icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); - - return 0; /* never anything pending */ -} - -static void shutdown_sysint1_irq(unsigned int irq) +static void disable_sysint1_irq(unsigned int irq) { icu1_clear(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } @@ -434,9 +427,6 @@ static void enable_sysint1_irq(unsigned int irq) icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } -#define disable_sysint1_irq shutdown_sysint1_irq -#define ack_sysint1_irq shutdown_sysint1_irq - static void end_sysint1_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -445,22 +435,14 @@ static void end_sysint1_irq(unsigned int irq) static struct irq_chip sysint1_irq_type = { .typename = "SYSINT1", - .startup = startup_sysint1_irq, - .shutdown = shutdown_sysint1_irq, - .enable = enable_sysint1_irq, - .disable = disable_sysint1_irq, - .ack = ack_sysint1_irq, + .ack = disable_sysint1_irq, + .mask = disable_sysint1_irq, + .mask_ack = disable_sysint1_irq, + .unmask = enable_sysint1_irq, .end = end_sysint1_irq, }; -static unsigned int startup_sysint2_irq(unsigned int irq) -{ - icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); - - return 0; /* never anything pending */ -} - -static void shutdown_sysint2_irq(unsigned int irq) +static void disable_sysint2_irq(unsigned int irq) { icu2_clear(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } @@ -470,9 +452,6 @@ static void enable_sysint2_irq(unsigned int irq) icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } -#define disable_sysint2_irq shutdown_sysint2_irq -#define ack_sysint2_irq shutdown_sysint2_irq - static void end_sysint2_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) @@ -481,11 +460,10 @@ static void end_sysint2_irq(unsigned int irq) static struct irq_chip sysint2_irq_type = { .typename = "SYSINT2", - .startup = startup_sysint2_irq, - .shutdown = shutdown_sysint2_irq, - .enable = enable_sysint2_irq, - .disable = disable_sysint2_irq, - .ack = ack_sysint2_irq, + .ack = disable_sysint2_irq, + .mask = disable_sysint2_irq, + .mask_ack = disable_sysint2_irq, + .unmask = enable_sysint2_irq, .end = end_sysint2_irq, }; @@ -723,10 +701,10 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - irq_desc[i].chip = &sysint1_irq_type; + set_irq_chip(i, &sysint1_irq_type); for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - irq_desc[i].chip = &sysint2_irq_type; + set_irq_chip(i, &sysint2_irq_type); cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c index 2483487344c..a039bb7251f 100644 --- a/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -30,17 +30,6 @@ extern void init_8259A(int hoge); extern int vr4133_rockhopper; -static unsigned int startup_i8259_irq(unsigned int irq) -{ - enable_8259A_irq(irq - I8259_IRQ_BASE); - return 0; -} - -static void shutdown_i8259_irq(unsigned int irq) -{ - disable_8259A_irq(irq - I8259_IRQ_BASE); -} - static void enable_i8259_irq(unsigned int irq) { enable_8259A_irq(irq - I8259_IRQ_BASE); @@ -64,11 +53,10 @@ static void end_i8259_irq(unsigned int irq) static struct irq_chip i8259_irq_type = { .typename = "XT-PIC", - .startup = startup_i8259_irq, - .shutdown = shutdown_i8259_irq, - .enable = enable_i8259_irq, - .disable = disable_i8259_irq, .ack = ack_i8259_irq, + .mask = disable_i8259_irq, + .mask_ack = ack_i8259_irq, + .unmask = enable_i8259_irq, .end = end_i8259_irq, }; @@ -104,7 +92,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - irq_desc[i].chip = &i8259_irq_type; + set_irq_chip(i, &i8259_irq_type); setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); -- cgit v1.2.3 From 1417836e81c0ab8f5a0bfeafa90d3eaa41b2a067 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 14 Nov 2006 01:13:18 +0900 Subject: [MIPS] use generic_handle_irq, handle_level_irq, handle_percpu_irq Further incorporation of generic irq framework. Replacing __do_IRQ() by proper flow handler would make the irq handling path a bit simpler and faster. * use generic_handle_irq() instead of __do_IRQ(). * use handle_level_irq for obvious level-type irq chips. * use handle_percpu_irq for irqs marked as IRQ_PER_CPU. * setup .eoi routine for irq chips possibly used with handle_percpu_irq. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/dec/ioasic-irq.c | 6 ++++-- arch/mips/dec/kn02-irq.c | 2 +- arch/mips/emma2rh/common/irq_emma2rh.c | 3 ++- arch/mips/emma2rh/markeins/irq_markeins.c | 3 ++- arch/mips/jazz/irq.c | 2 +- arch/mips/kernel/irq-msc01.c | 2 ++ arch/mips/kernel/irq-mv6434x.c | 3 ++- arch/mips/kernel/irq-rm7000.c | 3 ++- arch/mips/kernel/irq-rm9000.c | 6 ++++-- arch/mips/kernel/irq_cpu.c | 5 ++++- arch/mips/kernel/smp-mt.c | 2 ++ arch/mips/kernel/smtc.c | 1 + arch/mips/lasat/interrupt.c | 2 +- arch/mips/mips-boards/atlas/atlas_int.c | 3 ++- arch/mips/mips-boards/generic/time.c | 1 + arch/mips/mips-boards/sim/sim_time.c | 3 ++- arch/mips/momentum/ocelot_c/cpci-irq.c | 2 +- arch/mips/momentum/ocelot_c/uart-irq.c | 4 ++-- arch/mips/philips/pnx8550/common/int.c | 12 +++++++----- arch/mips/sgi-ip22/ip22-int.c | 2 +- arch/mips/sgi-ip27/ip27-irq.c | 2 +- arch/mips/sgi-ip27/ip27-timer.c | 3 ++- arch/mips/tx4927/common/tx4927_irq.c | 6 ++++-- arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 3 ++- arch/mips/tx4938/common/irq.c | 6 ++++-- arch/mips/tx4938/toshiba_rbtx4938/irq.c | 3 ++- arch/mips/vr41xx/common/icu.c | 6 ++++-- 27 files changed, 63 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index d0af08bdbb4..269b22b3431 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -103,9 +103,11 @@ void __init init_ioasic_irqs(int base) fast_iob(); for (i = base; i < base + IO_INR_DMA; i++) - set_irq_chip(i, &ioasic_irq_type); + set_irq_chip_and_handler(i, &ioasic_irq_type, + handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - set_irq_chip(i, &ioasic_dma_irq_type); + set_irq_chip_and_handler(i, &ioasic_dma_irq_type, + handle_level_irq); ioasic_irq_base = base; } diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index c761d97787e..5a9be4c9358 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -85,7 +85,7 @@ void __init init_kn02_irqs(int base) iob(); for (i = base; i < base + KN02_IRQ_LINES; i++) - set_irq_chip(i, &kn02_irq_type); + set_irq_chip_and_handler(i, &kn02_irq_type, handle_level_irq); kn02_irq_base = base; } diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c index bf1b83ba925..59b98299c89 100644 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/arch/mips/emma2rh/common/irq_emma2rh.c @@ -76,7 +76,8 @@ void emma2rh_irq_init(u32 irq_base) u32 i; for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ; i++) - set_irq_chip(i, &emma2rh_irq_controller); + set_irq_chip_and_handler(i, &emma2rh_irq_controller, + handle_level_irq); emma2rh_irq_base = irq_base; } diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c index 8e5f08a4245..3ac4e405ecd 100644 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/arch/mips/emma2rh/markeins/irq_markeins.c @@ -68,7 +68,8 @@ void emma2rh_sw_irq_init(u32 irq_base) u32 i; for (i = irq_base; i < irq_base + NUM_EMMA2RH_IRQ_SW; i++) - set_irq_chip(i, &emma2rh_sw_irq_controller); + set_irq_chip_and_handler(i, &emma2rh_sw_irq_controller, + handle_level_irq); emma2rh_sw_irq_base = irq_base; } diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 4bbb6cb08d6..5c4f50cdf15 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -59,7 +59,7 @@ void __init init_r4030_ints(void) int i; for (i = JAZZ_PARALLEL_IRQ; i <= JAZZ_TIMER_IRQ; i++) - set_irq_chip(i, &r4030_irq_type); + set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq); r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index e1880b27381..bcaad669608 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c @@ -117,6 +117,7 @@ struct irq_chip msc_levelirq_type = { .mask = mask_msc_irq, .mask_ack = level_mask_and_ack_msc_irq, .unmask = unmask_msc_irq, + .eoi = unmask_msc_irq, .end = end_msc_irq, }; @@ -126,6 +127,7 @@ struct irq_chip msc_edgeirq_type = { .mask = mask_msc_irq, .mask_ack = edge_mask_and_ack_msc_irq, .unmask = unmask_msc_irq, + .eoi = unmask_msc_irq, .end = end_msc_irq, }; diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 5012b9df1b5..6cfb31cafde 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -114,7 +114,8 @@ void __init mv64340_irq_init(unsigned int base) int i; for (i = base; i < base + 64; i++) - set_irq_chip(i, &mv64340_irq_type); + set_irq_chip_and_handler(i, &mv64340_irq_type, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index 6a297e3b889..ddcc2a5f8a0 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -51,7 +51,8 @@ void __init rm7k_cpu_irq_init(int base) clear_c0_intcontrol(0x00000f00); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip(i, &rm7k_irq_controller); + set_irq_chip_and_handler(i, &rm7k_irq_controller, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index 977538445cf..ba6440c88ab 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -117,10 +117,12 @@ void __init rm9k_cpu_irq_init(int base) clear_c0_intcontrol(0x0000f000); /* Mask all */ for (i = base; i < base + 4; i++) - set_irq_chip(i, &rm9k_irq_controller); + set_irq_chip_and_handler(i, &rm9k_irq_controller, + handle_level_irq); rm9000_perfcount_irq = base + 1; - set_irq_chip(rm9000_perfcount_irq, &rm9k_perfcounter_irq); + set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq, + handle_level_irq); irq_base = base; } diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index 3b7cfa407e8..be5ac23d381 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -62,6 +62,7 @@ static struct irq_chip mips_cpu_irq_controller = { .mask = mask_mips_irq, .mask_ack = mask_mips_irq, .unmask = unmask_mips_irq, + .eoi = unmask_mips_irq, .end = mips_cpu_irq_end, }; @@ -104,6 +105,7 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .mask = mask_mips_mt_irq, .mask_ack = mips_mt_cpu_irq_ack, .unmask = unmask_mips_mt_irq, + .eoi = unmask_mips_mt_irq, .end = mips_mt_cpu_irq_end, }; @@ -124,7 +126,8 @@ void __init mips_cpu_irq_init(int irq_base) set_irq_chip(i, &mips_mt_cpu_irq_controller); for (i = irq_base + 2; i < irq_base + 8; i++) - set_irq_chip(i, &mips_cpu_irq_controller); + set_irq_chip_and_handler(i, &mips_cpu_irq_controller, + handle_level_irq); mips_cpu_irq_base = irq_base; } diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 2ac19a6cbf6..1ee689c0e0c 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -278,7 +278,9 @@ void __init plat_prepare_cpus(unsigned int max_cpus) /* need to mark IPI's as IRQ_PER_CPU */ irq_desc[cpu_ipi_resched_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_resched_irq, handle_percpu_irq); irq_desc[cpu_ipi_call_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_call_irq, handle_percpu_irq); } /* diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 3b78caf112f..802febed7df 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1009,6 +1009,7 @@ void setup_cross_vpe_interrupts(void) setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU; + set_irq_handler(cpu_ipi_irq, handle_percpu_irq); } /* diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index cac82afe5eb..4a84a7beac5 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -133,5 +133,5 @@ void __init arch_init_irq(void) } for (i = 0; i <= LASATINT_END; i++) - set_irq_chip(i, &lasat_irq_type); + set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq); } diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index 7c710040d3f..43dba6ce660 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c @@ -74,6 +74,7 @@ static struct irq_chip atlas_irq_type = { .mask = disable_atlas_irq, .mask_ack = disable_atlas_irq, .unmask = enable_atlas_irq, + .eoi = enable_atlas_irq, .end = end_atlas_irq, }; @@ -207,7 +208,7 @@ static inline void init_atlas_irqs (int base) atlas_hw0_icregs->intrsten = 0xffffffff; for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) - set_irq_chip(i, &atlas_irq_type); + set_irq_chip_and_handler(i, &atlas_irq_type, handle_level_irq); } static struct irqaction atlasirq = { diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index d817c60c5ca..e4604c73f02 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c @@ -288,6 +288,7 @@ void __init plat_timer_setup(struct irqaction *irq) The effect is that the int remains disabled on the second cpu. Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; + set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif /* to generate the first timer interrupt */ diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c index 24a4ed00cc0..f2d998d2c16 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mips-boards/sim/sim_time.c @@ -203,7 +203,8 @@ void __init plat_timer_setup(struct irqaction *irq) on seperate cpu's the first one tries to handle the second interrupt. The effect is that the int remains disabled on the second cpu. Mark the interrupt with IRQ_PER_CPU to avoid any confusion */ - irq_desc[mips_cpu_timer_irq].status |= IRQ_PER_CPU; + irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU; + set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq); #endif /* to generate the first timer interrupt */ diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c index 7723f099894..e5a4a0a8a7f 100644 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -106,5 +106,5 @@ void cpci_irq_init(void) int i; for (i = CPCI_IRQ_BASE; i < (CPCI_IRQ_BASE + 8); i++) - set_irq_chip(i, &cpci_irq_type); + set_irq_chip_and_handler(i, &cpci_irq_type, handle_level_irq); } diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c index 72faf81b36c..0029f0008de 100644 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/arch/mips/momentum/ocelot_c/uart-irq.c @@ -96,6 +96,6 @@ struct irq_chip uart_irq_type = { void uart_irq_init(void) { - set_irq_chip(80, &uart_irq_type); - set_irq_chip(81, &uart_irq_type); + set_irq_chip_and_handler(80, &uart_irq_type, handle_level_irq); + set_irq_chip_and_handler(81, &uart_irq_type, handle_level_irq); } diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index e4bf494dd43..0dc23930edb 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c @@ -192,7 +192,7 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - set_irq_chip(i, &level_irq_type); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); mask_irq(i); /* mask the irq just in case */ } @@ -229,7 +229,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - set_irq_chip(i, &level_irq_type); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); } /* Priority level 0 */ @@ -238,19 +238,21 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - set_irq_chip(MIPS_CPU_GIC_IRQ, &level_irq_type); + set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type, + handle_level_irq); setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) - set_irq_chip(i, &level_irq_type); + set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq); /* Stop Timer 1-3 */ configPR = read_c0_config7(); configPR |= 0x00000038; write_c0_config7(configPR); - set_irq_chip(MIPS_CPU_TIMER_IRQ, &level_irq_type); + set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type, + handle_level_irq); setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index 8e2074b4ce4..c7b13805315 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -358,7 +358,7 @@ void __init arch_init_irq(void) else handler = &ip22_local3_irq_type; - set_irq_chip(i, handler); + set_irq_chip_and_handler(i, handler, handle_level_irq); } /* vector handler. this register the IRQ as non-sharable */ diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 824320281a3..5f8835b4e84 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -352,7 +352,7 @@ static struct irq_chip bridge_irq_type = { void __devinit register_bridge_irq(unsigned int irq) { - set_irq_chip(irq, &bridge_irq_type); + set_irq_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 86ba7fc10c3..e5441c3a0b0 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -190,6 +190,7 @@ static struct irq_chip rt_irq_type = { .mask = disable_rt_irq, .mask_ack = disable_rt_irq, .unmask = enable_rt_irq, + .eoi = enable_rt_irq, .end = end_rt_irq, }; @@ -207,7 +208,7 @@ void __init plat_timer_setup(struct irqaction *irq) if (irqno < 0) panic("Can't allocate interrupt number for timer interrupt"); - set_irq_chip(irqno, &rt_irq_type); + set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq); /* over-write the handler, we use our own way */ irq->handler = no_action; diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 2c57ced5c68..21873de49aa 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -196,7 +196,8 @@ static void __init tx4927_irq_cp0_init(void) TX4927_IRQ_CP0_BEG, TX4927_IRQ_CP0_END); for (i = TX4927_IRQ_CP0_BEG; i <= TX4927_IRQ_CP0_END; i++) - set_irq_chip(i, &tx4927_irq_cp0_type); + set_irq_chip_and_handler(i, &tx4927_irq_cp0_type, + handle_level_irq); } static void tx4927_irq_cp0_enable(unsigned int irq) @@ -350,7 +351,8 @@ static void __init tx4927_irq_pic_init(void) TX4927_IRQ_PIC_BEG, TX4927_IRQ_PIC_END); for (i = TX4927_IRQ_PIC_BEG; i <= TX4927_IRQ_PIC_END; i++) - set_irq_chip(i, &tx4927_irq_pic_type); + set_irq_chip_and_handler(i, &tx4927_irq_pic_type, + handle_level_irq); setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 1fdace89ae6..34cdb2a240e 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -342,7 +342,8 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) for (i = TOSHIBA_RBTX4927_IRQ_IOC_BEG; i <= TOSHIBA_RBTX4927_IRQ_IOC_END; i++) - set_irq_chip(i, &toshiba_rbtx4927_irq_ioc_type); + set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type, + handle_level_irq); setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, &toshiba_rbtx4927_irq_ioc_action); diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 19c9ee9e3d0..42e127683ae 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c @@ -88,7 +88,8 @@ tx4938_irq_cp0_init(void) int i; for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) - set_irq_chip(i, &tx4938_irq_cp0_type); + set_irq_chip_and_handler(i, &tx4938_irq_cp0_type, + handle_level_irq); } static void @@ -245,7 +246,8 @@ tx4938_irq_pic_init(void) int i; for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) - set_irq_chip(i, &tx4938_irq_pic_type); + set_irq_chip_and_handler(i, &tx4938_irq_pic_type, + handle_level_irq); setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 2735ffe9ec2..8c87a35f306 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -136,7 +136,8 @@ toshiba_rbtx4938_irq_ioc_init(void) for (i = TOSHIBA_RBTX4938_IRQ_IOC_BEG; i <= TOSHIBA_RBTX4938_IRQ_IOC_END; i++) - set_irq_chip(i, &toshiba_rbtx4938_irq_ioc_type); + set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type, + handle_level_irq); setup_irq(RBTX4938_IRQ_IOCINT, &toshiba_rbtx4938_irq_ioc_action); diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 33d70a6547a..54b92a74c7a 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -701,10 +701,12 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - set_irq_chip(i, &sysint1_irq_type); + set_irq_chip_and_handler(i, &sysint1_irq_type, + handle_level_irq); for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - set_irq_chip(i, &sysint2_irq_type); + set_irq_chip_and_handler(i, &sysint2_irq_type, + handle_level_irq); cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); -- cgit v1.2.3 From dd6bfd627c4f4df771b9b73e4df75c6c0c177b09 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Tue, 7 Nov 2006 09:56:24 +0100 Subject: [MIPS] Fix double inclusions Signed-off-by: Nicolas Kaiser Signed-off-by: Ralf Baechle --- arch/mips/kernel/signal_n32.c | 1 - arch/mips/mips-boards/sim/sim_time.c | 15 ++++----------- arch/mips/sibyte/bcm1480/time.c | 2 -- arch/mips/tx4938/common/setup.c | 1 - 4 files changed, 4 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 477c5334ec1..a67c18555ed 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -17,7 +17,6 @@ */ #include #include -#include #include #include #include diff --git a/arch/mips/mips-boards/sim/sim_time.c b/arch/mips/mips-boards/sim/sim_time.c index f2d998d2c16..30711d016fe 100644 --- a/arch/mips/mips-boards/sim/sim_time.c +++ b/arch/mips/mips-boards/sim/sim_time.c @@ -3,31 +3,24 @@ #include #include #include - -#include -#include -#include -#include -#include -#include - #include #include #include + #include +#include #include -#include #include #include #include +#include #include #include +#include #include #include #include -#include -#include unsigned long cpu_khz; diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index e136bde5248..03d5822d3a7 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -94,8 +94,6 @@ void bcm1480_time_init(void) */ } -#include - void bcm1480_timer_interrupt(void) { int cpu = smp_processor_id(); diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c index f415a1f18fb..dc87d92bb08 100644 --- a/arch/mips/tx4938/common/setup.c +++ b/arch/mips/tx4938/common/setup.c @@ -31,7 +31,6 @@ #include #include #include -#include #include extern void toshiba_rbtx4938_setup(void); -- cgit v1.2.3 From e56798824456bd907cefe840ca127df0518942e3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:47 +0000 Subject: [MIPS] Work around bogus gcc warnings. Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6eccfb49ae6..0ae19e1fa86 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -399,19 +399,6 @@ asmlinkage void do_be(struct pt_regs *regs) force_sig(SIGBUS, current); } -static inline int get_insn_opcode(struct pt_regs *regs, unsigned int *opcode) -{ - unsigned int __user *epc; - - epc = (unsigned int __user *) regs->cp0_epc + - ((regs->cp0_cause & CAUSEF_BD) != 0); - if (!get_user(*opcode, epc)) - return 0; - - force_sig(SIGSEGV, current); - return 1; -} - /* * ll/sc emulation */ @@ -546,8 +533,8 @@ static inline int simulate_llsc(struct pt_regs *regs) { unsigned int opcode; - if (unlikely(get_insn_opcode(regs, &opcode))) - return -EFAULT; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; if ((opcode & OPCODE) == LL) { simulate_ll(regs, opcode); @@ -559,6 +546,10 @@ static inline int simulate_llsc(struct pt_regs *regs) } return -EFAULT; /* Strange things going on ... */ + +out_sigsegv: + force_sig(SIGSEGV, current); + return -EFAULT; } /* @@ -571,8 +562,8 @@ static inline int simulate_rdhwr(struct pt_regs *regs) struct thread_info *ti = task_thread_info(current); unsigned int opcode; - if (unlikely(get_insn_opcode(regs, &opcode))) - return -EFAULT; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; if (unlikely(compute_return_epc(regs))) return -EFAULT; @@ -591,6 +582,10 @@ static inline int simulate_rdhwr(struct pt_regs *regs) /* Not ours. */ return -EFAULT; + +out_sigsegv: + force_sig(SIGSEGV, current); + return -EFAULT; } asmlinkage void do_ov(struct pt_regs *regs) @@ -676,8 +671,8 @@ asmlinkage void do_bp(struct pt_regs *regs) die_if_kernel("Break instruction in kernel code", regs); - if (get_insn_opcode(regs, &opcode)) - return; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; /* * There is the ancient bug in the MIPS assemblers that the break @@ -710,6 +705,9 @@ asmlinkage void do_bp(struct pt_regs *regs) default: force_sig(SIGTRAP, current); } + +out_sigsegv: + force_sig(SIGSEGV, current); } asmlinkage void do_tr(struct pt_regs *regs) @@ -719,8 +717,8 @@ asmlinkage void do_tr(struct pt_regs *regs) die_if_kernel("Trap instruction in kernel code", regs); - if (get_insn_opcode(regs, &opcode)) - return; + if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) + goto out_sigsegv; /* Immediate versions don't provide a code. */ if (!(opcode & OPCODE)) @@ -747,6 +745,9 @@ asmlinkage void do_tr(struct pt_regs *regs) default: force_sig(SIGTRAP, current); } + +out_sigsegv: + force_sig(SIGSEGV, current); } asmlinkage void do_ri(struct pt_regs *regs) -- cgit v1.2.3 From 0550d9d13e02b30efa117d47fcadea450bb23d23 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 22 Aug 2006 21:15:47 +0900 Subject: [MIPS] Remove redundant r4k_blast_icache() calls r4k_flush_cache_all() and r4k_flush_cache_mm() case: these are noop if the CPU did not have dc_aliases. It would mean we do not need to care about icache here. r4k_flush_cache_range case: if r4k_flush_cache_mm() did not need to care about icache, it would be same for this function. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/mm/c-r4k.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index cc895dad71d..0138cb2e456 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -323,7 +323,6 @@ static void __init r4k_blast_scache_setup(void) static inline void local_r4k_flush_cache_all(void * args) { r4k_blast_dcache(); - r4k_blast_icache(); } static void r4k_flush_cache_all(void) @@ -359,21 +358,19 @@ static void r4k___flush_cache_all(void) static inline void local_r4k_flush_cache_range(void * args) { struct vm_area_struct *vma = args; - int exec; if (!(cpu_context(smp_processor_id(), vma->vm_mm))) return; - exec = vma->vm_flags & VM_EXEC; - if (cpu_has_dc_aliases || exec) - r4k_blast_dcache(); - if (exec) - r4k_blast_icache(); + r4k_blast_dcache(); } static void r4k_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { + if (!cpu_has_dc_aliases) + return; + r4k_on_each_cpu(local_r4k_flush_cache_range, vma, 1, 1); } @@ -385,7 +382,6 @@ static inline void local_r4k_flush_cache_mm(void * args) return; r4k_blast_dcache(); - r4k_blast_icache(); /* * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we -- cgit v1.2.3 From 617667ba724d46ffeccb88ee99e1379f29b0bfa7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:48 +0000 Subject: [MIPS] Avoid dupliate D-cache flush on R400C / R4400 SC and MC variants. Signed-off-by: Ralf Baechle --- arch/mips/mm/c-r4k.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 0138cb2e456..df04a315d83 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -381,17 +381,21 @@ static inline void local_r4k_flush_cache_mm(void * args) if (!cpu_context(smp_processor_id(), mm)) return; - r4k_blast_dcache(); - /* * Kludge alert. For obscure reasons R4000SC and R4400SC go nuts if we * only flush the primary caches but R10000 and R12000 behave sane ... + * R4000SC and R4400SC indexed S-cache ops also invalidate primary + * caches, so we can bail out early. */ if (current_cpu_data.cputype == CPU_R4000SC || current_cpu_data.cputype == CPU_R4000MC || current_cpu_data.cputype == CPU_R4400SC || - current_cpu_data.cputype == CPU_R4400MC) + current_cpu_data.cputype == CPU_R4400MC) { r4k_blast_scache(); + return; + } + + r4k_blast_dcache(); } static void r4k_flush_cache_mm(struct mm_struct *mm) -- cgit v1.2.3 From 187933f23679c413706030aefad9e85e79164c44 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 25 Oct 2006 23:57:04 +0900 Subject: [MIPS] do_IRQ cleanup Now we have both function and macro version of do_IRQ() and the former is used only by DEC and non-preemptive kernel. This patch makes everyone use the macro version and removes the function version. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/dec/int-handler.S | 2 +- arch/mips/dec/setup.c | 6 ++++++ arch/mips/kernel/irq.c | 19 ------------------- 3 files changed, 7 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 31dd47d1002..b251ef864c3 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S @@ -267,7 +267,7 @@ handle_it: LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) PTR_LA ra, ret_from_irq - j do_IRQ + j dec_irq_dispatch nop #ifdef CONFIG_32BIT diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index 6b7481e97be..d34032ac492 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c @@ -761,3 +761,9 @@ void __init arch_init_irq(void) if (dec_interrupt[DEC_IRQ_HALT] >= 0) setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq); } + +asmlinkage unsigned int dec_irq_dispatch(unsigned int irq) +{ + do_IRQ(irq); + return 0; +} diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index e997c9454f4..b339798b317 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -88,25 +88,6 @@ atomic_t irq_err_count; unsigned long irq_hwmask[NR_IRQS]; #endif /* CONFIG_MIPS_MT_SMTC */ -#undef do_IRQ - -/* - * do_IRQ handles all normal device IRQ's (the special - * SMP cross-CPU interrupts have their own specific - * handlers). - */ -asmlinkage unsigned int do_IRQ(unsigned int irq) -{ - irq_enter(); - - __DO_IRQ_SMTC_HOOK(); - __do_IRQ(irq); - - irq_exit(); - - return 1; -} - /* * Generic, controller-independent functions: */ -- cgit v1.2.3 From 005985609ff72df3257fde6b29aa9d71342c2a6b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 12 Nov 2006 00:10:28 +0900 Subject: [MIPS] mips HPT cleanup: make clocksource_mips public Make clocksource_mips public and get rid of mips_hpt_read, mips_hpt_mask. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/dec/time.c | 4 ++-- arch/mips/jmr3927/rbhma3100/setup.c | 4 ++-- arch/mips/kernel/time.c | 42 ++++++++++++++----------------------- arch/mips/sgi-ip27/ip27-timer.c | 4 ++-- arch/mips/sibyte/bcm1480/time.c | 4 ++-- arch/mips/sibyte/sb1250/time.c | 8 +++---- 6 files changed, 28 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 69e424e9ab6..8b7e0c17ac3 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c @@ -151,7 +151,7 @@ static void dec_timer_ack(void) CMOS_READ(RTC_REG_C); /* Ack the RTC interrupt. */ } -static unsigned int dec_ioasic_hpt_read(void) +static cycle_t dec_ioasic_hpt_read(void) { /* * The free-running counter is 32-bit which is good for about @@ -171,7 +171,7 @@ void __init dec_time_init(void) if (!cpu_has_counter && IOASIC) /* For pre-R4k systems we use the I/O ASIC's counter. */ - mips_hpt_read = dec_ioasic_hpt_read; + clocksource_mips.read = dec_ioasic_hpt_read; /* Set up the rate of periodic DS1287 interrupts. */ CMOS_WRITE(RTC_REF_CLCK_32KHZ | (16 - __ffs(HZ)), RTC_REG_A); diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 16e5dfe7aa8..138f25efe38 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c @@ -170,7 +170,7 @@ static void jmr3927_machine_power_off(void) while (1); } -static unsigned int jmr3927_hpt_read(void) +static cycle_t jmr3927_hpt_read(void) { /* We assume this function is called xtime_lock held. */ return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; @@ -182,7 +182,7 @@ extern void rtc_ds1742_init(unsigned long base); #endif static void __init jmr3927_time_init(void) { - mips_hpt_read = jmr3927_hpt_read; + clocksource_mips.read = jmr3927_hpt_read; mips_hpt_frequency = JMR3927_TIMER_CLK; #ifdef USE_RTC_DS1742 if (jmr3927_have_nvram()) { diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 111d1baa3b2..11aab6d6bfe 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -11,7 +11,6 @@ * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. */ -#include #include #include #include @@ -83,7 +82,7 @@ static void null_timer_ack(void) { /* nothing */ } /* * Null high precision timer functions for systems lacking one. */ -static unsigned int null_hpt_read(void) +static cycle_t null_hpt_read(void) { return 0; } @@ -112,7 +111,7 @@ static void c0_timer_ack(void) /* * High precision timer functions for a R4k-compatible timer. */ -static unsigned int c0_hpt_read(void) +static cycle_t c0_hpt_read(void) { return read_c0_count(); } @@ -126,8 +125,6 @@ static void __init c0_hpt_timer_init(void) int (*mips_timer_state)(void); void (*mips_timer_ack)(void); -unsigned int (*mips_hpt_read)(void); -unsigned int mips_hpt_mask = 0xffffffff; /* last time when xtime and rtc are sync'ed up */ static long last_rtc_update; @@ -269,8 +266,7 @@ static struct irqaction timer_irqaction = { static unsigned int __init calibrate_hpt(void) { - u64 frequency; - u32 hpt_start, hpt_end, hpt_count, hz; + cycle_t frequency, hpt_start, hpt_end, hpt_count, hz; const int loops = HZ / 10; int log_2_loops = 0; @@ -296,28 +292,23 @@ static unsigned int __init calibrate_hpt(void) * during the calculated number of periods between timer * interrupts. */ - hpt_start = mips_hpt_read(); + hpt_start = clocksource_mips.read(); do { while (mips_timer_state()); while (!mips_timer_state()); } while (--i); - hpt_end = mips_hpt_read(); + hpt_end = clocksource_mips.read(); - hpt_count = (hpt_end - hpt_start) & mips_hpt_mask; + hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask; hz = HZ; - frequency = (u64)hpt_count * (u64)hz; + frequency = hpt_count * hz; return frequency >> log_2_loops; } -static cycle_t read_mips_hpt(void) -{ - return (cycle_t)mips_hpt_read(); -} - -static struct clocksource clocksource_mips = { +struct clocksource clocksource_mips = { .name = "MIPS", - .read = read_mips_hpt, + .mask = 0xffffffff, .is_continuous = 1, }; @@ -326,7 +317,7 @@ static void __init init_mips_clocksource(void) u64 temp; u32 shift; - if (!mips_hpt_frequency || mips_hpt_read == null_hpt_read) + if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) return; /* Calclate a somewhat reasonable rating value */ @@ -340,7 +331,6 @@ static void __init init_mips_clocksource(void) } clocksource_mips.shift = shift; clocksource_mips.mult = (u32)temp; - clocksource_mips.mask = mips_hpt_mask; clocksource_register(&clocksource_mips); } @@ -360,19 +350,19 @@ void __init time_init(void) -xtime.tv_sec, -xtime.tv_nsec); /* Choose appropriate high precision timer routines. */ - if (!cpu_has_counter && !mips_hpt_read) + if (!cpu_has_counter && !clocksource_mips.read) /* No high precision timer -- sorry. */ - mips_hpt_read = null_hpt_read; + clocksource_mips.read = null_hpt_read; else if (!mips_hpt_frequency && !mips_timer_state) { /* A high precision timer of unknown frequency. */ - if (!mips_hpt_read) + if (!clocksource_mips.read) /* No external high precision timer -- use R4k. */ - mips_hpt_read = c0_hpt_read; + clocksource_mips.read = c0_hpt_read; } else { /* We know counter frequency. Or we can get it. */ - if (!mips_hpt_read) { + if (!clocksource_mips.read) { /* No external high precision timer -- use R4k. */ - mips_hpt_read = c0_hpt_read; + clocksource_mips.read = c0_hpt_read; if (!mips_timer_state) { /* No external timer interrupt -- use R4k. */ diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index e5441c3a0b0..7d361726bbf 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -223,14 +223,14 @@ void __init plat_timer_setup(struct irqaction *irq) setup_irq(irqno, &rt_irqaction); } -static unsigned int ip27_hpt_read(void) +static cycle_t ip27_hpt_read(void) { return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT); } void __init ip27_time_init(void) { - mips_hpt_read = ip27_hpt_read; + clocksource_mips.read = ip27_hpt_read; mips_hpt_frequency = CYCLES_PER_SEC; xtime.tv_sec = get_m48t35_time(); xtime.tv_nsec = 0; diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c index 03d5822d3a7..6f3f71bf424 100644 --- a/arch/mips/sibyte/bcm1480/time.c +++ b/arch/mips/sibyte/bcm1480/time.c @@ -117,7 +117,7 @@ void bcm1480_timer_interrupt(void) } } -static unsigned int bcm1480_hpt_read(void) +static cycle_t bcm1480_hpt_read(void) { /* We assume this function is called xtime_lock held. */ unsigned long count = @@ -127,6 +127,6 @@ static unsigned int bcm1480_hpt_read(void) void __init bcm1480_hpt_setup(void) { - mips_hpt_read = bcm1480_hpt_read; + clocksource_mips.read = bcm1480_hpt_read; mips_hpt_frequency = BCM1480_HPT_VALUE; } diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c index bcb74f2c194..2efffe15ff2 100644 --- a/arch/mips/sibyte/sb1250/time.c +++ b/arch/mips/sibyte/sb1250/time.c @@ -51,7 +51,7 @@ extern int sb1250_steal_irq(int irq); -static unsigned int sb1250_hpt_read(void); +static cycle_t sb1250_hpt_read(void); void __init sb1250_hpt_setup(void) { @@ -66,8 +66,8 @@ void __init sb1250_hpt_setup(void) IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG))); mips_hpt_frequency = V_SCD_TIMER_FREQ; - mips_hpt_read = sb1250_hpt_read; - mips_hpt_mask = M_SCD_TIMER_INIT; + clocksource_mips.read = sb1250_hpt_read; + clocksource_mips.mask = M_SCD_TIMER_INIT; } } @@ -143,7 +143,7 @@ void sb1250_timer_interrupt(void) * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over * again. */ -static unsigned int sb1250_hpt_read(void) +static cycle_t sb1250_hpt_read(void) { unsigned int count; -- cgit v1.2.3 From 63dc68a8cf60cb110b147dab1704d990808b39e2 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 16 Oct 2006 01:38:50 +0100 Subject: [MIPS] Use conditional traps for BUG_ON on MIPS II and better. This shaves of around 4kB and a few cycles for the average kernel that has CONFIG_BUG enabled. Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 0ae19e1fa86..2a932cada24 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -669,8 +669,6 @@ asmlinkage void do_bp(struct pt_regs *regs) unsigned int opcode, bcode; siginfo_t info; - die_if_kernel("Break instruction in kernel code", regs); - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; @@ -693,6 +691,7 @@ asmlinkage void do_bp(struct pt_regs *regs) switch (bcode) { case BRK_OVERFLOW << 10: case BRK_DIVZERO << 10: + die_if_kernel("Break instruction in kernel code", regs); if (bcode == (BRK_DIVZERO << 10)) info.si_code = FPE_INTDIV; else @@ -702,7 +701,11 @@ asmlinkage void do_bp(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; + case BRK_BUG: + die("Kernel bug detected", regs); + break; default: + die_if_kernel("Break instruction in kernel code", regs); force_sig(SIGTRAP, current); } @@ -715,8 +718,6 @@ asmlinkage void do_tr(struct pt_regs *regs) unsigned int opcode, tcode = 0; siginfo_t info; - die_if_kernel("Trap instruction in kernel code", regs); - if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) goto out_sigsegv; @@ -733,6 +734,7 @@ asmlinkage void do_tr(struct pt_regs *regs) switch (tcode) { case BRK_OVERFLOW: case BRK_DIVZERO: + die_if_kernel("Trap instruction in kernel code", regs); if (tcode == BRK_DIVZERO) info.si_code = FPE_INTDIV; else @@ -742,7 +744,11 @@ asmlinkage void do_tr(struct pt_regs *regs) info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); break; + case BRK_BUG: + die("Kernel bug detected", regs); + break; default: + die_if_kernel("Trap instruction in kernel code", regs); force_sig(SIGTRAP, current); } -- cgit v1.2.3 From aa414dff4f7bef29457592414551becdca72dd6b Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 30 Nov 2006 01:14:51 +0000 Subject: [MIPS] Remove duplicate ISA DMA code for 0 DMA channel case. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 11 ++++++----- arch/mips/kernel/Makefile | 1 - arch/mips/kernel/dma-no-isa.c | 28 ---------------------------- 3 files changed, 6 insertions(+), 34 deletions(-) delete mode 100644 arch/mips/kernel/dma-no-isa.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c0da0ffe8d5..96143670759 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -266,8 +266,8 @@ config MIPS_MALTA select BOOT_ELF32 select HAVE_STD_PC_SERIAL_PORT select DMA_NONCOHERENT - select IRQ_CPU select GENERIC_ISA_DMA + select IRQ_CPU select HW_HAS_PCI select I8259 select MIPS_BOARDS_GEN @@ -534,7 +534,7 @@ config SGI_IP22 select HW_HAS_EISA select IP22_CPU_SCACHE select IRQ_CPU - select NO_ISA if ISA + select GENERIC_ISA_DMA_SUPPORT_BROKEN select SWAP_IO_SPACE select SYS_HAS_CPU_R4X00 select SYS_HAS_CPU_R5000 @@ -881,6 +881,9 @@ config MIPS_NILE4 config MIPS_DISABLE_OBSOLETE_IDE bool +config GENERIC_ISA_DMA_SUPPORT_BROKEN + bool + # # Endianess selection. Suffiently obscure so many users don't know what to # answer,so we try hard to limit the available choices. Also the use of a @@ -1852,13 +1855,11 @@ source "drivers/pci/Kconfig" config ISA bool -config NO_ISA - bool - config EISA bool "EISA support" depends on HW_HAS_EISA select ISA + select GENERIC_ISA_DMA ---help--- The Extended Industry Standard Architecture (EISA) bus was developed as an open alternative to the IBM MicroChannel bus. diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index f35b739d0a1..bbbb8d7cb89 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -45,7 +45,6 @@ obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o -obj-$(CONFIG_NO_ISA) += dma-no-isa.o obj-$(CONFIG_I8259) += i8259.o obj-$(CONFIG_IRQ_CPU) += irq_cpu.o obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o diff --git a/arch/mips/kernel/dma-no-isa.c b/arch/mips/kernel/dma-no-isa.c deleted file mode 100644 index 6df8b07741e..00000000000 --- a/arch/mips/kernel/dma-no-isa.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004 by Ralf Baechle - * - * Dummy ISA DMA functions for systems that don't have ISA but share drivers - * with ISA such as legacy free PCI. - */ -#include -#include -#include - -DEFINE_SPINLOCK(dma_spin_lock); - -int request_dma(unsigned int dmanr, const char * device_id) -{ - return -EINVAL; -} - -void free_dma(unsigned int dmanr) -{ -} - -EXPORT_SYMBOL(dma_spin_lock); -EXPORT_SYMBOL(request_dma); -EXPORT_SYMBOL(free_dma); -- cgit v1.2.3 From 3cb2fccc5f48a4d6269dfd00b4db570fca2a04d5 Mon Sep 17 00:00:00 2001 From: Matt LaPlante Date: Thu, 30 Nov 2006 05:22:59 +0100 Subject: Fix misc Kconfig typos Fix various Kconfig typos. Signed-off-by: Matt LaPlante Acked-by: Randy Dunlap Signed-off-by: Adrian Bunk --- arch/arm/mach-ixp4xx/Kconfig | 2 +- arch/arm/mach-lh7a40x/Kconfig | 2 +- arch/arm/mach-s3c2410/Kconfig | 2 +- arch/arm/mm/Kconfig | 2 +- arch/cris/arch-v10/Kconfig | 2 +- arch/cris/arch-v10/drivers/Kconfig | 2 +- arch/cris/arch-v32/drivers/Kconfig | 8 ++++---- arch/m68knommu/Kconfig | 4 ++-- arch/mips/Kconfig | 4 ++-- arch/powerpc/Kconfig | 2 +- arch/powerpc/platforms/83xx/Kconfig | 4 ++-- arch/ppc/Kconfig | 2 +- arch/sh/Kconfig | 2 +- arch/sparc/Kconfig | 4 ++-- 14 files changed, 21 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 57f23b46539..e316bd93313 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -133,7 +133,7 @@ config IXP4XX_INDIRECT_PCI into the kernel and we can use the standard read[bwl]/write[bwl] macros. This is the preferred method due to speed but it limits the system to just 64MB of PCI memory. This can be - problamatic if using video cards and other memory-heavy devices. + problematic if using video cards and other memory-heavy devices. 2) If > 64MB of memory space is required, the IXP4xx can be configured to use indirect registers to access PCI This allows diff --git a/arch/arm/mach-lh7a40x/Kconfig b/arch/arm/mach-lh7a40x/Kconfig index 147b01928a9..6f4c6a1798c 100644 --- a/arch/arm/mach-lh7a40x/Kconfig +++ b/arch/arm/mach-lh7a40x/Kconfig @@ -8,7 +8,7 @@ config MACH_KEV7A400 help Say Y here if you are using the Sharp KEV7A400 development board. This hardware is discontinued, so I'd be very - suprised if you wanted this option. + surprised if you wanted this option. config MACH_LPD7A400 bool "LPD7A400 Card Engine" diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 63965c78de8..9aa26b99045 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -91,7 +91,7 @@ config SMDK2440_CPU2442 config MACH_S3C2413 bool help - Internal node for S3C2413 verison of SMDK2413, so that + Internal node for S3C2413 version of SMDK2413, so that machine_is_s3c2413() will work when MACH_SMDK2413 is selected diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c0bfb8212b7..b09a19f87d6 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -197,7 +197,7 @@ config CPU_ARM940T select CPU_CP15_MPU help ARM940T is a member of the ARM9TDMI family of general- - purpose microprocessors with MPU and seperate 4KB + purpose microprocessors with MPU and separate 4KB instruction and 4KB data cases, each with a 4-word line length. diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig index 44eb1b9accb..c7ea9efd010 100644 --- a/arch/cris/arch-v10/Kconfig +++ b/arch/cris/arch-v10/Kconfig @@ -323,7 +323,7 @@ config ETRAX_DEF_R_WAITSTATES depends on ETRAX_ARCH_V10 default "95a6" help - Waitstates for SRAM, Flash and peripherials (not DRAM). 95f8 is a + Waitstates for SRAM, Flash and peripherals (not DRAM). 95f8 is a good choice for most Axis products... config ETRAX_DEF_R_BUS_CONFIG diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index 734d5f3a530..e7e724bc0ba 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -839,7 +839,7 @@ config ETRAX_DS1302_TRICKLE_CHARGE default "0" help This controls the initial value of the trickle charge register. - 0 = disabled (use this if you are unsure or have a non rechargable battery) + 0 = disabled (use this if you are unsure or have a non rechargeable battery) Otherwise the following values can be OR:ed together to control the charge current: 1 = 2kohm, 2 = 4kohm, 3 = 4kohm diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index a33097f9536..f64624fc450 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -88,7 +88,7 @@ config ETRAX_SERIAL_PORT0_DMA7_IN help Enables the DMA7 input channel for ser0 (ttyS0). If you do not enable DMA, an interrupt for each character will be - used when receiveing data. + used when receiving data. Normally you want to use DMA, unless you use the DMA channel for something else. @@ -157,7 +157,7 @@ config ETRAX_SERIAL_PORT1_DMA5_IN help Enables the DMA5 input channel for ser1 (ttyS1). If you do not enable DMA, an interrupt for each character will be - used when receiveing data. + used when receiving data. Normally you want this on, unless you use the DMA channel for something else. @@ -228,7 +228,7 @@ config ETRAX_SERIAL_PORT2_DMA3_IN help Enables the DMA3 input channel for ser2 (ttyS2). If you do not enable DMA, an interrupt for each character will be - used when receiveing data. + used when receiving data. Normally you want to use DMA, unless you use the DMA channel for something else. @@ -297,7 +297,7 @@ config ETRAX_SERIAL_PORT3_DMA9_IN help Enables the DMA9 input channel for ser3 (ttyS3). If you do not enable DMA, an interrupt for each character will be - used when receiveing data. + used when receiving data. Normally you want to use DMA, unless you use the DMA channel for something else. diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index 6d920d4bdc3..c1bc22c6d0d 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -565,7 +565,7 @@ config ROMVEC depends on ROM help This is almost always the same as the base of the ROM. Since on all - 68000 type varients the vectors are at the base of the boot device + 68000 type variants the vectors are at the base of the boot device on system startup. config ROMVECSIZE @@ -574,7 +574,7 @@ config ROMVECSIZE depends on ROM help Define the size of the vector region in ROM. For most 68000 - varients this would be 0x400 bytes in size. Set to 0 if you do + variants this would be 0x400 bytes in size. Set to 0 if you do not want a vector region at the start of the ROM. config ROMSTART diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1443024b1c7..22bb540b5c0 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -865,7 +865,7 @@ config MIPS_DISABLE_OBSOLETE_IDE bool # -# Endianess selection. Suffiently obscure so many users don't know what to +# Endianess selection. Sufficiently obscure so many users don't know what to # answer,so we try hard to limit the available choices. Also the use of a # choice statement should be more obvious to the user. # @@ -874,7 +874,7 @@ choice help Some MIPS machines can be configured for either little or big endian byte order. These modes require different kernels and a different - Linux distribution. In general there is one prefered byteorder for a + Linux distribution. In general there is one preferred byteorder for a particular system but some systems are just as commonly used in the one or the other endianess. diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0673dbedb24..116d7d3683e 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -425,7 +425,7 @@ config PPC_MAPLE default n help This option enables support for the Maple 970FX Evaluation Board. - For more informations, refer to + For more information, refer to config PPC_PASEMI depends on PPC_MULTIPLATFORM && PPC64 diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig index 7edb6b46138..edcd5b875b6 100644 --- a/arch/powerpc/platforms/83xx/Kconfig +++ b/arch/powerpc/platforms/83xx/Kconfig @@ -21,7 +21,7 @@ config MPC834x_SYS Be aware that PCI buses can only function when SYS board is plugged into the PIB (Platform IO Board) board from Freescale which provide 3 PCI slots. The PIBs PCI initialization is the bootloader's - responsiblilty. + responsibility. config MPC834x_ITX bool "Freescale MPC834x ITX" @@ -30,7 +30,7 @@ config MPC834x_ITX This option enables support for the MPC 834x ITX evaluation board. Be aware that PCI initialization is the bootloader's - responsiblilty. + responsibility. config MPC8360E_PB bool "Freescale MPC8360E PB" diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 077711e6310..ef018e25fb0 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -724,7 +724,7 @@ config MPC834x_SYS Be aware that PCI buses can only function when SYS board is plugged into the PIB (Platform IO Board) board from Freescale which provide 3 PCI slots. The PIBs PCI initialization is the bootloader's - responsiblilty. + responsibility. config EV64360 bool "Marvell-EV64360BP" diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 6a461d4caef..bffc7e17697 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -217,7 +217,7 @@ config SH_SHMIN bool "SHMIN" select CPU_SUBTYPE_SH7706 help - Select SHMIN if configureing for the SHMIN board + Select SHMIN if configuring for the SHMIN board. config SH_UNKNOWN bool "BareCPU" diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 2f96610a83e..92a7c8a636d 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -212,8 +212,8 @@ config SPARC_LED tristate "Sun4m LED driver" help This driver toggles the front-panel LED on sun4m systems - in a user-specifyable manner. It's state can be probed - by reading /proc/led and it's blinking mode can be changed + in a user-specifiable manner. Its state can be probed + by reading /proc/led and its blinking mode can be changed via writes to /proc/led source "fs/Kconfig.binfmt" -- cgit v1.2.3 From 0779bf2d2ecc4d9b1e9437ae659f50e6776a7666 Mon Sep 17 00:00:00 2001 From: Matt LaPlante Date: Thu, 30 Nov 2006 05:24:39 +0100 Subject: Fix misc .c/.h comment typos Fix various .c/.h typos in comments (no code changes). Signed-off-by: Matt LaPlante Signed-off-by: Adrian Bunk --- arch/cris/arch-v10/drivers/eeprom.c | 6 +++--- arch/cris/arch-v10/drivers/i2c.c | 2 +- arch/cris/arch-v10/kernel/kgdb.c | 2 +- arch/ia64/hp/common/sba_iommu.c | 8 ++++---- arch/sh64/lib/dbg.c | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/drivers/eeprom.c b/arch/cris/arch-v10/drivers/eeprom.c index 6e1f191a71e..284ebfda03f 100644 --- a/arch/cris/arch-v10/drivers/eeprom.c +++ b/arch/cris/arch-v10/drivers/eeprom.c @@ -1,7 +1,7 @@ /*!***************************************************************************** *! -*! Implements an interface for i2c compatible eeproms to run under linux. -*! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustents by +*! Implements an interface for i2c compatible eeproms to run under Linux. +*! Supports 2k, 8k(?) and 16k. Uses adaptive timing adjustments by *! Johan.Adolfsson@axis.com *! *! Probing results: @@ -51,7 +51,7 @@ *! Revision 1.8 2001/06/15 13:24:29 jonashg *! * Added verification of pointers from userspace in read and write. *! * Made busy counter volatile. -*! * Added define for inital write delay. +*! * Added define for initial write delay. *! * Removed warnings by using loff_t instead of unsigned long. *! *! Revision 1.7 2001/06/14 15:26:54 jonashg diff --git a/arch/cris/arch-v10/drivers/i2c.c b/arch/cris/arch-v10/drivers/i2c.c index 6114596c3b3..092c724a645 100644 --- a/arch/cris/arch-v10/drivers/i2c.c +++ b/arch/cris/arch-v10/drivers/i2c.c @@ -47,7 +47,7 @@ *! Update Port B register and shadow even when running with hardware support *! to avoid glitches when reading bits *! Never set direction to out in i2c_inbyte -*! Removed incorrect clock togling at end of i2c_inbyte +*! Removed incorrect clock toggling at end of i2c_inbyte *! *! Revision 1.8 2002/08/13 06:31:53 starvik *! Made SDA and SCL line configurable diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c index 34528da9881..07628a13c6c 100644 --- a/arch/cris/arch-v10/kernel/kgdb.c +++ b/arch/cris/arch-v10/kernel/kgdb.c @@ -33,7 +33,7 @@ *! *! Revision 1.2 2002/11/19 14:35:24 starvik *! Changes from linux 2.4 -*! Changed struct initializer syntax to the currently prefered notation +*! Changed struct initializer syntax to the currently preferred notation *! *! Revision 1.1 2001/12/17 13:59:27 bjornw *! Initial revision diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index db8e1fcfa04..14691cda05c 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -75,7 +75,7 @@ ** If a device prefetches beyond the end of a valid pdir entry, it will cause ** a hard failure, ie. MCA. Version 3.0 and later of the zx1 LBA should ** disconnect on 4k boundaries and prevent such issues. If the device is -** particularly agressive, this option will keep the entire pdir valid such +** particularly aggressive, this option will keep the entire pdir valid such ** that prefetching will hit a valid address. This could severely impact ** error containment, and is therefore off by default. The page that is ** used for spill-over is poisoned, so that should help debugging somewhat. @@ -258,10 +258,10 @@ static u64 prefetch_spill_page; /* ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up -** (or rather not merge) DMA's into managable chunks. +** (or rather not merge) DMAs into manageable chunks. ** On parisc, this is more of the software/tuning constraint -** rather than the HW. I/O MMU allocation alogorithms can be -** faster with smaller size is (to some degree). +** rather than the HW. I/O MMU allocation algorithms can be +** faster with smaller sizes (to some degree). */ #define DMA_CHUNK_SIZE (BITS_PER_LONG*iovp_size) diff --git a/arch/sh64/lib/dbg.c b/arch/sh64/lib/dbg.c index 1326f45f31e..4310fc87444 100644 --- a/arch/sh64/lib/dbg.c +++ b/arch/sh64/lib/dbg.c @@ -383,7 +383,7 @@ void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs) /* ======================================================================= */ /* -** Depending on scan the MMU, Data or Instrction side +** Depending on scan the MMU, Data or Instruction side ** looking for a valid mapping matching Eaddr & asid. ** Return -1 if not found or the TLB id entry otherwise. ** Note: it works only for 4k pages! -- cgit v1.2.3 From 03a67a46af8647b2c7825107045ecae641e103d3 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Thu, 30 Nov 2006 05:32:19 +0100 Subject: Fix typos in doc and comments Changes persistant -> persistent. www.dictionary.com does not know persistant (with an A), but should it be one of those things you can spell in more than one correct way, let me know. Signed-off-by: Jan Engelhardt Signed-off-by: Adrian Bunk --- arch/um/drivers/chan_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 2f880cb167a..0cad3546cb8 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -120,7 +120,7 @@ static int winch_thread(void *arg) /* These are synchronization calls between various UML threads on the * host - since they are not different kernel threads, we cannot use * kernel semaphores. We don't use SysV semaphores because they are - * persistant. */ + * persistent. */ count = os_read_file(pipe_fd, &c, sizeof(c)); if(count != sizeof(c)) printk("winch_thread : failed to read synchronization byte, " -- cgit v1.2.3 From b729c09a452a659cdf4d29d83943aa798c5c4ffc Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Nov 2006 21:00:22 +0000 Subject: [ARM] Improve reliability of APM-emulation suspend The APM emulation can sometimes cause suspend to fail to work due to apparantly waiting for some process to acknowledge an event when it actually has already done so. We re-jig the event handling to work around this behaviour. Signed-off-by: Russell King --- arch/arm/kernel/apm.c | 178 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 123 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index ecf4f9472d9..bbe98e3b860 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -12,7 +12,6 @@ */ #include #include -#include #include #include #include @@ -26,6 +25,7 @@ #include #include #include +#include #include /* apm_power_info */ #include @@ -71,7 +71,8 @@ struct apm_user { #define SUSPEND_PENDING 1 /* suspend pending read */ #define SUSPEND_READ 2 /* suspend read, pending ack */ #define SUSPEND_ACKED 3 /* suspend acked */ -#define SUSPEND_DONE 4 /* suspend completed */ +#define SUSPEND_WAIT 4 /* waiting for suspend */ +#define SUSPEND_DONE 5 /* suspend completed */ struct apm_queue queue; }; @@ -101,6 +102,7 @@ static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); static DEFINE_SPINLOCK(kapmd_queue_lock); static struct apm_queue kapmd_queue; +static DECLARE_MUTEX(state_lock); static const char driver_version[] = "1.13"; /* no spaces */ @@ -148,38 +150,60 @@ static void queue_add_event(struct apm_queue *q, apm_event_t event) q->events[q->event_head] = event; } -static void queue_event_one_user(struct apm_user *as, apm_event_t event) +static void queue_event(apm_event_t event) { - if (as->suser && as->writer) { - switch (event) { - case APM_SYS_SUSPEND: - case APM_USER_SUSPEND: - /* - * If this user already has a suspend pending, - * don't queue another one. - */ - if (as->suspend_state != SUSPEND_NONE) - return; + struct apm_user *as; - as->suspend_state = SUSPEND_PENDING; - suspends_pending++; - break; - } + down_read(&user_list_lock); + list_for_each_entry(as, &apm_user_list, list) { + if (as->reader) + queue_add_event(&as->queue, event); } - queue_add_event(&as->queue, event); + up_read(&user_list_lock); + wake_up_interruptible(&apm_waitqueue); } -static void queue_event(apm_event_t event, struct apm_user *sender) +/* + * queue_suspend_event - queue an APM suspend event. + * + * Check that we're in a state where we can suspend. If not, + * return -EBUSY. Otherwise, queue an event to all "writer" + * users. If there are no "writer" users, return '1' to + * indicate that we can immediately suspend. + */ +static int queue_suspend_event(apm_event_t event, struct apm_user *sender) { struct apm_user *as; + int ret = 1; + down(&state_lock); down_read(&user_list_lock); + + /* + * If a thread is still processing, we can't suspend, so reject + * the request. + */ + list_for_each_entry(as, &apm_user_list, list) { + if (as != sender && as->reader && as->writer && as->suser && + as->suspend_state != SUSPEND_NONE) { + ret = -EBUSY; + goto out; + } + } + list_for_each_entry(as, &apm_user_list, list) { - if (as != sender && as->reader) - queue_event_one_user(as, event); + if (as != sender && as->reader && as->writer && as->suser) { + as->suspend_state = SUSPEND_PENDING; + suspends_pending++; + queue_add_event(&as->queue, event); + ret = 0; + } } + out: up_read(&user_list_lock); + up(&state_lock); wake_up_interruptible(&apm_waitqueue); + return ret; } static void apm_suspend(void) @@ -191,17 +215,22 @@ static void apm_suspend(void) * Anyone on the APM queues will think we're still suspended. * Send a message so everyone knows we're now awake again. */ - queue_event(APM_NORMAL_RESUME, NULL); + queue_event(APM_NORMAL_RESUME); /* * Finally, wake up anyone who is sleeping on the suspend. */ + down(&state_lock); down_read(&user_list_lock); list_for_each_entry(as, &apm_user_list, list) { - as->suspend_result = err; - as->suspend_state = SUSPEND_DONE; + if (as->suspend_state == SUSPEND_WAIT || + as->suspend_state == SUSPEND_ACKED) { + as->suspend_result = err; + as->suspend_state = SUSPEND_DONE; + } } up_read(&user_list_lock); + up(&state_lock); wake_up(&apm_suspend_waitqueue); } @@ -227,8 +256,11 @@ static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t if (copy_to_user(buf, &event, sizeof(event))) break; - if (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND) + down(&state_lock); + if (as->suspend_state == SUSPEND_PENDING && + (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND)) as->suspend_state = SUSPEND_READ; + up(&state_lock); buf += sizeof(event); i -= sizeof(event); @@ -270,9 +302,13 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) switch (cmd) { case APM_IOC_SUSPEND: + down(&state_lock); + as->suspend_result = -EINTR; if (as->suspend_state == SUSPEND_READ) { + int pending; + /* * If we read a suspend command from /dev/apm_bios, * then the corresponding APM_IOC_SUSPEND ioctl is @@ -280,47 +316,66 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) */ as->suspend_state = SUSPEND_ACKED; suspends_pending--; + pending = suspends_pending == 0; + up(&state_lock); + + /* + * If there are no further acknowledges required, + * suspend the system. + */ + if (pending) + apm_suspend(); + + /* + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + * + * Note: we need to ensure that the PM subsystem does + * not kick us out of the wait when it suspends the + * threads. + */ + flags = current->flags; + current->flags |= PF_NOFREEZE; + + wait_event(apm_suspend_waitqueue, + as->suspend_state == SUSPEND_DONE); } else { + up(&state_lock); + /* * Otherwise it is a request to suspend the system. * Queue an event for all readers, and expect an * acknowledge from all writers who haven't already * acknowledged. */ - queue_event(APM_USER_SUSPEND, as); - } + err = queue_suspend_event(APM_USER_SUSPEND, as); + if (err < 0) + break; - /* - * If there are no further acknowledges required, suspend - * the system. - */ - if (suspends_pending == 0) - apm_suspend(); + if (err > 0) + apm_suspend(); - /* - * Wait for the suspend/resume to complete. If there are - * pending acknowledges, we wait here for them. - * - * Note that we need to ensure that the PM subsystem does - * not kick us out of the wait when it suspends the threads. - */ - flags = current->flags; - current->flags |= PF_NOFREEZE; + /* + * Wait for the suspend/resume to complete. If there + * are pending acknowledges, we wait here for them. + * + * Note: we need to ensure that the PM subsystem does + * not kick us out of the wait when it suspends the + * threads. + */ + flags = current->flags; + current->flags |= PF_NOFREEZE; - /* - * Note: do not allow a thread which is acking the suspend - * to escape until the resume is complete. - */ - if (as->suspend_state == SUSPEND_ACKED) - wait_event(apm_suspend_waitqueue, - as->suspend_state == SUSPEND_DONE); - else wait_event_interruptible(apm_suspend_waitqueue, as->suspend_state == SUSPEND_DONE); + } current->flags = flags; + + down(&state_lock); err = as->suspend_result; as->suspend_state = SUSPEND_NONE; + up(&state_lock); break; } @@ -330,6 +385,8 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) static int apm_release(struct inode * inode, struct file * filp) { struct apm_user *as = filp->private_data; + int pending = 0; + filp->private_data = NULL; down_write(&user_list_lock); @@ -342,11 +399,14 @@ static int apm_release(struct inode * inode, struct file * filp) * need to balance suspends_pending, which means the * possibility of sleeping. */ + down(&state_lock); if (as->suspend_state != SUSPEND_NONE) { suspends_pending -= 1; - if (suspends_pending == 0) - apm_suspend(); + pending = suspends_pending == 0; } + up(&state_lock); + if (pending) + apm_suspend(); kfree(as); return 0; @@ -470,6 +530,7 @@ static int kapmd(void *arg) { do { apm_event_t event; + int ret; wait_event_interruptible(kapmd_wait, !queue_empty(&kapmd_queue) || kthread_should_stop()); @@ -489,13 +550,20 @@ static int kapmd(void *arg) case APM_LOW_BATTERY: case APM_POWER_STATUS_CHANGE: - queue_event(event, NULL); + queue_event(event); break; case APM_USER_SUSPEND: case APM_SYS_SUSPEND: - queue_event(event, NULL); - if (suspends_pending == 0) + ret = queue_suspend_event(event, NULL); + if (ret < 0) { + /* + * We were busy. Try again in 50ms. + */ + queue_add_event(&kapmd_queue, event); + msleep(50); + } + if (ret > 0) apm_suspend(); break; -- cgit v1.2.3 From df58d0359581bbd4ee741406d81e69456c684f9d Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Nov 2006 21:01:30 +0000 Subject: [ARM] Fix "apm -s" command hang Fix an apparant hang with the "apm -s" command. We omitted to wake up this process once resume had completed. Signed-off-by: Russell King --- arch/arm/kernel/apm.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index bbe98e3b860..845af0bc110 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -340,6 +340,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) wait_event(apm_suspend_waitqueue, as->suspend_state == SUSPEND_DONE); } else { + as->suspend_state = SUSPEND_WAIT; up(&state_lock); /* @@ -349,8 +350,14 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) * acknowledged. */ err = queue_suspend_event(APM_USER_SUSPEND, as); - if (err < 0) + if (err < 0) { + /* + * Avoid taking the lock here - this + * should be fine. + */ + as->suspend_state = SUSPEND_NONE; break; + } if (err > 0) apm_suspend(); -- cgit v1.2.3 From ee90dabcadd053d5dd69f3a7f8161afa2c751ace Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 9 Nov 2006 14:20:47 +0000 Subject: [ARM] Include asm/elf.h instead of asm/procinfo.h These files want to provide/access ELF hwcap information, so should be including asm/elf.h rather than asm/procinfo.h Signed-off-by: Russell King --- arch/arm/kernel/asm-offsets.c | 1 + arch/arm/kernel/head-nommu.S | 1 - arch/arm/kernel/head.S | 1 - arch/arm/kernel/signal.c | 1 + arch/arm/mach-integrator/platsmp.c | 1 - arch/arm/mm/proc-arm1020.S | 2 +- arch/arm/mm/proc-arm1020e.S | 2 +- arch/arm/mm/proc-arm1022.S | 2 +- arch/arm/mm/proc-arm1026.S | 2 +- arch/arm/mm/proc-arm6_7.S | 2 +- arch/arm/mm/proc-arm720.S | 2 +- arch/arm/mm/proc-arm740.S | 2 +- arch/arm/mm/proc-arm7tdmi.S | 2 +- arch/arm/mm/proc-arm920.S | 2 +- arch/arm/mm/proc-arm922.S | 2 +- arch/arm/mm/proc-arm925.S | 2 +- arch/arm/mm/proc-arm926.S | 2 +- arch/arm/mm/proc-arm940.S | 2 +- arch/arm/mm/proc-arm946.S | 2 +- arch/arm/mm/proc-arm9tdmi.S | 2 +- arch/arm/mm/proc-sa110.S | 2 +- arch/arm/mm/proc-sa1100.S | 2 +- arch/arm/mm/proc-v6.S | 2 +- arch/arm/mm/proc-xsc3.S | 2 +- arch/arm/mm/proc-xscale.S | 2 +- 25 files changed, 22 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index cc2d58d028e..3c078e34675 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -15,6 +15,7 @@ #include #include #include +#include /* * Make sure that the compiler and target are compatible. diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index f359a189dcf..0119c0d5f97 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index ebc3e74a794..bda0748ffb0 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 48cf7fffddf..f2b1d61fbc0 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-integrator/platsmp.c b/arch/arm/mach-integrator/platsmp.c index 1bc8534ef0c..613b841a10f 100644 --- a/arch/arm/mach-integrator/platsmp.c +++ b/arch/arm/mach-integrator/platsmp.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 1d8316f3cec..289b8e6f504 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -29,9 +29,9 @@ #include #include #include +#include #include #include -#include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 89b1d6d3d7c..bed9db6ba58 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -29,9 +29,9 @@ #include #include #include +#include #include #include -#include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S index a089528e6bc..d2a7c1b9cab 100644 --- a/arch/arm/mm/proc-arm1022.S +++ b/arch/arm/mm/proc-arm1022.S @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S index d6d84d92c7c..3247ce5c017 100644 --- a/arch/arm/mm/proc-arm1026.S +++ b/arch/arm/mm/proc-arm1026.S @@ -18,9 +18,9 @@ #include #include #include +#include #include #include -#include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 0432e480688..ce4f9eef763 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S @@ -15,9 +15,9 @@ #include #include #include +#include #include #include -#include #include ENTRY(cpu_arm6_dcache_clean_area) diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S index c2f0705bfd4..c04c194da78 100644 --- a/arch/arm/mm/proc-arm720.S +++ b/arch/arm/mm/proc-arm720.S @@ -36,9 +36,9 @@ #include #include #include +#include #include #include -#include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S index 40713818a87..7069f495cf9 100644 --- a/arch/arm/mm/proc-arm740.S +++ b/arch/arm/mm/proc-arm740.S @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include #include .text diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S index 22d7e3100ea..d091c257182 100644 --- a/arch/arm/mm/proc-arm7tdmi.S +++ b/arch/arm/mm/proc-arm7tdmi.S @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include #include .text diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 4adb46b3a4e..65cbb2851bf 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S @@ -28,9 +28,9 @@ #include #include #include +#include #include #include -#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S index 571f082f024..52761b70d73 100644 --- a/arch/arm/mm/proc-arm922.S +++ b/arch/arm/mm/proc-arm922.S @@ -29,9 +29,9 @@ #include #include #include +#include #include #include -#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S index 8d9a9f93b01..5b74339d158 100644 --- a/arch/arm/mm/proc-arm925.S +++ b/arch/arm/mm/proc-arm925.S @@ -52,9 +52,9 @@ #include #include #include +#include #include #include -#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index 44a7a652d62..8628ed29a95 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S @@ -28,9 +28,9 @@ #include #include #include +#include #include #include -#include #include #include #include "proc-macros.S" diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S index 2397f4b6e15..786c593778f 100644 --- a/arch/arm/mm/proc-arm940.S +++ b/arch/arm/mm/proc-arm940.S @@ -11,9 +11,9 @@ #include #include #include +#include #include #include -#include #include /* ARM940T has a 4KB DCache comprising 256 lines of 4 words */ diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S index e1861756442..a60c1421d45 100644 --- a/arch/arm/mm/proc-arm946.S +++ b/arch/arm/mm/proc-arm946.S @@ -13,9 +13,9 @@ #include #include #include +#include #include #include -#include #include /* diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S index 918ebf65d4f..4848eeac86b 100644 --- a/arch/arm/mm/proc-arm9tdmi.S +++ b/arch/arm/mm/proc-arm9tdmi.S @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include #include .text diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index c878064e9b8..cd7d865c9d1 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index b23b66a6155..b776653cc31 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 6f72549f884..b440c8a1d34 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -13,8 +13,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 4ace2d8090c..c4d778a8619 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 2749c1f88d7..906e9de7f83 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From 80bcddc19d08a6eee99fb1bf3470ad6257af8721 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 9 Nov 2006 14:45:22 +0000 Subject: [ARM] Convert apm.c to use mutexes instead of semaphores More semaphore-as-mutex to mutex conversions. Signed-off-by: Russell King --- arch/arm/kernel/apm.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index 845af0bc110..a11fb9a40c0 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -102,7 +102,7 @@ static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); static DEFINE_SPINLOCK(kapmd_queue_lock); static struct apm_queue kapmd_queue; -static DECLARE_MUTEX(state_lock); +static DEFINE_MUTEX(state_lock); static const char driver_version[] = "1.13"; /* no spaces */ @@ -176,7 +176,7 @@ static int queue_suspend_event(apm_event_t event, struct apm_user *sender) struct apm_user *as; int ret = 1; - down(&state_lock); + mutex_lock(&state_lock); down_read(&user_list_lock); /* @@ -201,7 +201,7 @@ static int queue_suspend_event(apm_event_t event, struct apm_user *sender) } out: up_read(&user_list_lock); - up(&state_lock); + mutex_unlock(&state_lock); wake_up_interruptible(&apm_waitqueue); return ret; } @@ -220,7 +220,7 @@ static void apm_suspend(void) /* * Finally, wake up anyone who is sleeping on the suspend. */ - down(&state_lock); + mutex_lock(&state_lock); down_read(&user_list_lock); list_for_each_entry(as, &apm_user_list, list) { if (as->suspend_state == SUSPEND_WAIT || @@ -230,7 +230,7 @@ static void apm_suspend(void) } } up_read(&user_list_lock); - up(&state_lock); + mutex_unlock(&state_lock); wake_up(&apm_suspend_waitqueue); } @@ -256,11 +256,11 @@ static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t if (copy_to_user(buf, &event, sizeof(event))) break; - down(&state_lock); + mutex_lock(&state_lock); if (as->suspend_state == SUSPEND_PENDING && (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND)) as->suspend_state = SUSPEND_READ; - up(&state_lock); + mutex_unlock(&state_lock); buf += sizeof(event); i -= sizeof(event); @@ -302,7 +302,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) switch (cmd) { case APM_IOC_SUSPEND: - down(&state_lock); + mutex_lock(&state_lock); as->suspend_result = -EINTR; @@ -317,7 +317,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) as->suspend_state = SUSPEND_ACKED; suspends_pending--; pending = suspends_pending == 0; - up(&state_lock); + mutex_unlock(&state_lock); /* * If there are no further acknowledges required, @@ -341,7 +341,7 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) as->suspend_state == SUSPEND_DONE); } else { as->suspend_state = SUSPEND_WAIT; - up(&state_lock); + mutex_unlock(&state_lock); /* * Otherwise it is a request to suspend the system. @@ -379,10 +379,10 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) current->flags = flags; - down(&state_lock); + mutex_lock(&state_lock); err = as->suspend_result; as->suspend_state = SUSPEND_NONE; - up(&state_lock); + mutex_unlock(&state_lock); break; } @@ -406,12 +406,12 @@ static int apm_release(struct inode * inode, struct file * filp) * need to balance suspends_pending, which means the * possibility of sleeping. */ - down(&state_lock); + mutex_lock(&state_lock); if (as->suspend_state != SUSPEND_NONE) { suspends_pending -= 1; pending = suspends_pending == 0; } - up(&state_lock); + mutex_unlock(&state_lock); if (pending) apm_suspend(); -- cgit v1.2.3 From eb8b0afc3a228cf6e0e1f9045127da3e72a6866b Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 9 Nov 2006 15:16:16 +0000 Subject: [ARM] Remove DEBUG_WAITQ DEBUG_WAITQ appears to have been removed by others, but no one removed the configuration option from ARM. Remote it from both Kconfig.debug and all default configurations. Signed-off-by: Russell King --- arch/arm/Kconfig.debug | 4 ---- arch/arm/configs/at91rm9200dk_defconfig | 1 - arch/arm/configs/at91rm9200ek_defconfig | 1 - arch/arm/configs/badge4_defconfig | 1 - arch/arm/configs/cerfcube_defconfig | 1 - arch/arm/configs/collie_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/csb337_defconfig | 1 - arch/arm/configs/csb637_defconfig | 1 - arch/arm/configs/ep93xx_defconfig | 1 - arch/arm/configs/h7202_defconfig | 1 - arch/arm/configs/hackkit_defconfig | 1 - arch/arm/configs/integrator_defconfig | 1 - arch/arm/configs/iop32x_defconfig | 1 - arch/arm/configs/iop33x_defconfig | 1 - arch/arm/configs/ixp2000_defconfig | 1 - arch/arm/configs/ixp23xx_defconfig | 1 - arch/arm/configs/ixp4xx_defconfig | 1 - arch/arm/configs/jornada720_defconfig | 1 - arch/arm/configs/kb9202_defconfig | 1 - arch/arm/configs/lpd270_defconfig | 1 - arch/arm/configs/lpd7a400_defconfig | 1 - arch/arm/configs/lpd7a404_defconfig | 1 - arch/arm/configs/lubbock_defconfig | 1 - arch/arm/configs/mainstone_defconfig | 1 - arch/arm/configs/mx1ads_defconfig | 1 - arch/arm/configs/neponset_defconfig | 1 - arch/arm/configs/netwinder_defconfig | 1 - arch/arm/configs/netx_defconfig | 1 - arch/arm/configs/onearm_defconfig | 1 - arch/arm/configs/pleb_defconfig | 1 - arch/arm/configs/pnx4008_defconfig | 1 - arch/arm/configs/pxa255-idp_defconfig | 1 - arch/arm/configs/realview-smp_defconfig | 1 - arch/arm/configs/realview_defconfig | 1 - arch/arm/configs/rpc_defconfig | 1 - arch/arm/configs/s3c2410_defconfig | 1 - arch/arm/configs/shark_defconfig | 1 - arch/arm/configs/simpad_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm/configs/versatile_defconfig | 1 - 41 files changed, 44 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index d22f38b957d..40c5eb1f55c 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -32,10 +32,6 @@ config DEBUG_USER 8 - SIGSEGV faults 16 - SIGBUS faults -config DEBUG_WAITQ - bool "Wait queue debugging" - depends on DEBUG_KERNEL - config DEBUG_ERRORS bool "Verbose kernel error messages" depends on DEBUG_KERNEL diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index b43041476e0..02164c1a301 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -979,7 +979,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index d96fc8386e2..bee410cc4e9 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -968,7 +968,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index cfe6bd8e81c..821865f7560 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig @@ -1216,7 +1216,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/cerfcube_defconfig b/arch/arm/configs/cerfcube_defconfig index 09b7acd7f64..ee130b528bd 100644 --- a/arch/arm/configs/cerfcube_defconfig +++ b/arch/arm/configs/cerfcube_defconfig @@ -851,7 +851,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/collie_defconfig b/arch/arm/configs/collie_defconfig index a3758913c0b..970c8c772eb 100644 --- a/arch/arm/configs/collie_defconfig +++ b/arch/arm/configs/collie_defconfig @@ -934,7 +934,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index c41c04fa502..e8980a9bb89 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -1513,7 +1513,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig index 20e68250d83..2cadd51506b 100644 --- a/arch/arm/configs/csb337_defconfig +++ b/arch/arm/configs/csb337_defconfig @@ -1113,7 +1113,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig index df8595ac031..807f7fc8d77 100644 --- a/arch/arm/configs/csb637_defconfig +++ b/arch/arm/configs/csb637_defconfig @@ -1062,7 +1062,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 3b4802a849e..58d5974f41d 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -1134,7 +1134,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -CONFIG_DEBUG_WAITQ=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/h7202_defconfig b/arch/arm/configs/h7202_defconfig index 9d62ed16bf5..0e739af5271 100644 --- a/arch/arm/configs/h7202_defconfig +++ b/arch/arm/configs/h7202_defconfig @@ -702,7 +702,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig index a45b57582b8..1c8fb89a673 100644 --- a/arch/arm/configs/hackkit_defconfig +++ b/arch/arm/configs/hackkit_defconfig @@ -740,7 +740,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -CONFIG_DEBUG_WAITQ=y CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/integrator_defconfig b/arch/arm/configs/integrator_defconfig index 692ab57ba1c..3ce96e60b40 100644 --- a/arch/arm/configs/integrator_defconfig +++ b/arch/arm/configs/integrator_defconfig @@ -835,7 +835,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig index 0d67f66e78c..b275c53728e 100644 --- a/arch/arm/configs/iop32x_defconfig +++ b/arch/arm/configs/iop32x_defconfig @@ -1204,7 +1204,6 @@ CONFIG_FRAME_POINTER=y # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig index 2a8fc153969..848e3ace906 100644 --- a/arch/arm/configs/iop33x_defconfig +++ b/arch/arm/configs/iop33x_defconfig @@ -1051,7 +1051,6 @@ CONFIG_FRAME_POINTER=y # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index 27b3e31a8ad..bbd2dcf91e5 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig @@ -1026,7 +1026,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index 7b18997083c..06deefaec1d 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig @@ -1305,7 +1305,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index fac7c3b240c..fabf74c51a8 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -1243,7 +1243,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/jornada720_defconfig b/arch/arm/configs/jornada720_defconfig index 80a6fd97eb3..0c556289a3f 100644 --- a/arch/arm/configs/jornada720_defconfig +++ b/arch/arm/configs/jornada720_defconfig @@ -889,7 +889,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig index b4cd4b41483..89e116f955b 100644 --- a/arch/arm/configs/kb9202_defconfig +++ b/arch/arm/configs/kb9202_defconfig @@ -753,7 +753,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/lpd270_defconfig b/arch/arm/configs/lpd270_defconfig index 4b29e099640..e146189ab54 100644 --- a/arch/arm/configs/lpd270_defconfig +++ b/arch/arm/configs/lpd270_defconfig @@ -949,7 +949,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/lpd7a400_defconfig b/arch/arm/configs/lpd7a400_defconfig index bf9cf9c6d2d..f8ac29d5c65 100644 --- a/arch/arm/configs/lpd7a400_defconfig +++ b/arch/arm/configs/lpd7a400_defconfig @@ -850,7 +850,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/lpd7a404_defconfig b/arch/arm/configs/lpd7a404_defconfig index 3a57be32e84..46a0f7fe1fa 100644 --- a/arch/arm/configs/lpd7a404_defconfig +++ b/arch/arm/configs/lpd7a404_defconfig @@ -1100,7 +1100,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/lubbock_defconfig b/arch/arm/configs/lubbock_defconfig index 81daadcbe0b..e544bfbbde5 100644 --- a/arch/arm/configs/lubbock_defconfig +++ b/arch/arm/configs/lubbock_defconfig @@ -772,7 +772,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/mainstone_defconfig b/arch/arm/configs/mainstone_defconfig index b112bd75bda..cc8c95b9929 100644 --- a/arch/arm/configs/mainstone_defconfig +++ b/arch/arm/configs/mainstone_defconfig @@ -766,7 +766,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/mx1ads_defconfig b/arch/arm/configs/mx1ads_defconfig index d16f6cd6e03..577d7e1b5d4 100644 --- a/arch/arm/configs/mx1ads_defconfig +++ b/arch/arm/configs/mx1ads_defconfig @@ -691,7 +691,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig index df8168e57b7..e86794a10fc 100644 --- a/arch/arm/configs/neponset_defconfig +++ b/arch/arm/configs/neponset_defconfig @@ -1115,7 +1115,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/netwinder_defconfig b/arch/arm/configs/netwinder_defconfig index 2cae1ead9f9..c1a63a35c58 100644 --- a/arch/arm/configs/netwinder_defconfig +++ b/arch/arm/configs/netwinder_defconfig @@ -994,7 +994,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/netx_defconfig b/arch/arm/configs/netx_defconfig index 61115a77338..57f32f39d0f 100644 --- a/arch/arm/configs/netx_defconfig +++ b/arch/arm/configs/netx_defconfig @@ -872,7 +872,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/onearm_defconfig b/arch/arm/configs/onearm_defconfig index 9b9f2155af3..0498ebd7d5d 100644 --- a/arch/arm/configs/onearm_defconfig +++ b/arch/arm/configs/onearm_defconfig @@ -1045,7 +1045,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/pleb_defconfig b/arch/arm/configs/pleb_defconfig index 24e8bdd4cb9..a6b47ea8e46 100644 --- a/arch/arm/configs/pleb_defconfig +++ b/arch/arm/configs/pleb_defconfig @@ -721,7 +721,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/pnx4008_defconfig b/arch/arm/configs/pnx4008_defconfig index a4989f44baa..b5e11aa2e29 100644 --- a/arch/arm/configs/pnx4008_defconfig +++ b/arch/arm/configs/pnx4008_defconfig @@ -1604,7 +1604,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/pxa255-idp_defconfig b/arch/arm/configs/pxa255-idp_defconfig index b71d31a4bb5..46e5089df0a 100644 --- a/arch/arm/configs/pxa255-idp_defconfig +++ b/arch/arm/configs/pxa255-idp_defconfig @@ -768,7 +768,6 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index ffd905ff19f..fc39ba1a89f 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig @@ -967,7 +967,6 @@ CONFIG_FORCED_INLINING=y # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 3f1ec4e304f..accbf529ce5 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig @@ -759,7 +759,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig index b498afdc03b..bc091264d35 100644 --- a/arch/arm/configs/rpc_defconfig +++ b/arch/arm/configs/rpc_defconfig @@ -910,7 +910,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index c0152393e49..3b31a33d008 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig @@ -1319,7 +1319,6 @@ CONFIG_FORCED_INLINING=y # CONFIG_HEADERS_CHECK is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/shark_defconfig b/arch/arm/configs/shark_defconfig index c48d1706226..9b6561d119a 100644 --- a/arch/arm/configs/shark_defconfig +++ b/arch/arm/configs/shark_defconfig @@ -965,7 +965,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set # CONFIG_DEBUG_ERRORS is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/configs/simpad_defconfig b/arch/arm/configs/simpad_defconfig index 140056a3507..03f783e696b 100644 --- a/arch/arm/configs/simpad_defconfig +++ b/arch/arm/configs/simpad_defconfig @@ -934,7 +934,6 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set CONFIG_FRAME_POINTER=y CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index bd03238968c..aa7a0117950 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -1406,7 +1406,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_FRAME_POINTER=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index f7bf6ef27d1..48dca69adda 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig @@ -972,7 +972,6 @@ CONFIG_FRAME_POINTER=y CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y CONFIG_DEBUG_LL=y # CONFIG_DEBUG_ICEDCC is not set -- cgit v1.2.3 From 10dd5ce28d78e2440e8fa1135d17e33399d75340 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 23 Nov 2006 11:41:32 +0000 Subject: [ARM] Remove compatibility layer for ARM irqs set_irq_chipdata -> set_irq_chip_data get_irq_chipdata -> get_irq_chip_data do_level_IRQ -> handle_level_irq do_edge_IRQ -> handle_edge_irq do_simple_IRQ -> handle_simple_irq irqdesc -> irq_desc irqchip -> irq_chip Signed-off-by: Russell King --- arch/arm/common/gic.c | 2 +- arch/arm/common/locomo.c | 84 ++++++++++++++++---------------- arch/arm/common/sa1111.c | 30 ++++++------ arch/arm/common/vic.c | 8 +-- arch/arm/kernel/ecard.c | 10 ++-- arch/arm/kernel/irq.c | 8 +-- arch/arm/mach-aaec2000/core.c | 4 +- arch/arm/mach-at91rm9200/gpio.c | 8 +-- arch/arm/mach-at91rm9200/irq.c | 2 +- arch/arm/mach-clps711x/irq.c | 8 +-- arch/arm/mach-clps7500/core.c | 28 +++++------ arch/arm/mach-ebsa110/core.c | 4 +- arch/arm/mach-ep93xx/core.c | 6 +-- arch/arm/mach-footbridge/common.c | 4 +- arch/arm/mach-footbridge/isa-irq.c | 10 ++-- arch/arm/mach-h720x/common.c | 22 ++++----- arch/arm/mach-h720x/cpu-h7202.c | 6 +-- arch/arm/mach-imx/irq.c | 14 +++--- arch/arm/mach-integrator/integrator_ap.c | 2 +- arch/arm/mach-integrator/integrator_cp.c | 8 +-- arch/arm/mach-iop32x/irq.c | 2 +- arch/arm/mach-iop33x/irq.c | 2 +- arch/arm/mach-ixp2000/core.c | 20 ++++---- arch/arm/mach-ixp2000/ixdp2x00.c | 8 +-- arch/arm/mach-ixp2000/ixdp2x01.c | 8 +-- arch/arm/mach-ixp23xx/core.c | 16 +++--- arch/arm/mach-ixp23xx/ixdp2351.c | 16 +++--- arch/arm/mach-ixp4xx/common.c | 4 +- arch/arm/mach-l7200/core.c | 4 +- arch/arm/mach-lh7a40x/arch-kev7a400.c | 4 +- arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 4 +- arch/arm/mach-lh7a40x/irq-kev7a400.c | 4 +- arch/arm/mach-lh7a40x/irq-lh7a400.c | 4 +- arch/arm/mach-lh7a40x/irq-lh7a404.c | 4 +- arch/arm/mach-lh7a40x/irq-lpd7a40x.c | 4 +- arch/arm/mach-netx/generic.c | 6 +-- arch/arm/mach-omap1/fpga.c | 6 +-- arch/arm/mach-omap1/irq.c | 2 +- arch/arm/mach-omap2/irq.c | 2 +- arch/arm/mach-pnx4008/irq.c | 10 ++-- arch/arm/mach-pxa/irq.c | 10 ++-- arch/arm/mach-pxa/lpd270.c | 4 +- arch/arm/mach-pxa/lubbock.c | 4 +- arch/arm/mach-pxa/mainstone.c | 4 +- arch/arm/mach-rpc/irq.c | 14 +++--- arch/arm/mach-s3c2410/bast-irq.c | 8 +-- arch/arm/mach-s3c2410/irq.c | 48 +++++++++--------- arch/arm/mach-s3c2410/irq.h | 2 +- arch/arm/mach-s3c2410/s3c2412-irq.c | 4 +- arch/arm/mach-s3c2410/s3c2440-irq.c | 10 ++-- arch/arm/mach-s3c2410/s3c244x-irq.c | 12 ++--- arch/arm/mach-sa1100/h3600.c | 6 +-- arch/arm/mach-sa1100/irq.c | 8 +-- arch/arm/mach-sa1100/neponset.c | 8 +-- arch/arm/mach-shark/irq.c | 2 +- arch/arm/mach-versatile/core.c | 4 +- arch/arm/plat-omap/gpio.c | 8 +-- 57 files changed, 277 insertions(+), 277 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index f3e020f2227..09b9d1b6844 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c @@ -160,7 +160,7 @@ void __init gic_dist_init(void __iomem *base) */ for (i = 29; i < max_irq; i++) { set_irq_chip(i, &gic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 80a72c75214..cfe6f4650bc 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -163,11 +163,11 @@ static struct locomo_dev_info locomo_devices[] = { #define LOCOMO_IRQ_LT_START (IRQ_LOCOMO_LT) #define LOCOMO_IRQ_SPI_START (IRQ_LOCOMO_SPI_RFR) -static void locomo_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_handler(unsigned int irq, struct irq_desc *desc) { int req, i; - struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + struct irq_desc *d; + void __iomem *mapbase = get_irq_chip_data(irq); /* Acknowledge the parent IRQ */ desc->chip->ack(irq); @@ -194,7 +194,7 @@ static void locomo_ack_irq(unsigned int irq) static void locomo_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_ICR); r &= ~(0x0010 << (irq - LOCOMO_IRQ_START)); @@ -203,7 +203,7 @@ static void locomo_mask_irq(unsigned int irq) static void locomo_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_ICR); r |= (0x0010 << (irq - LOCOMO_IRQ_START)); @@ -217,10 +217,10 @@ static struct irq_chip locomo_chip = { .unmask = locomo_unmask_irq, }; -static void locomo_key_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_key_handler(unsigned int irq, struct irq_desc *desc) { - struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + struct irq_desc *d; + void __iomem *mapbase = get_irq_chip_data(irq); if (locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC) & 0x0001) { d = irq_desc + LOCOMO_IRQ_KEY_START; @@ -230,7 +230,7 @@ static void locomo_key_handler(unsigned int irq, struct irqdesc *desc) static void locomo_key_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START)); @@ -239,7 +239,7 @@ static void locomo_key_ack_irq(unsigned int irq) static void locomo_key_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START)); @@ -248,7 +248,7 @@ static void locomo_key_mask_irq(unsigned int irq) static void locomo_key_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_KEYBOARD + LOCOMO_KIC); r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START)); @@ -262,11 +262,11 @@ static struct irq_chip locomo_key_chip = { .unmask = locomo_key_unmask_irq, }; -static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_gpio_handler(unsigned int irq, struct irq_desc *desc) { int req, i; - struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + struct irq_desc *d; + void __iomem *mapbase = get_irq_chip_data(irq); req = locomo_readl(mapbase + LOCOMO_GIR) & locomo_readl(mapbase + LOCOMO_GPD) & @@ -285,7 +285,7 @@ static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc) static void locomo_gpio_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GWE); r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -302,7 +302,7 @@ static void locomo_gpio_ack_irq(unsigned int irq) static void locomo_gpio_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -311,7 +311,7 @@ static void locomo_gpio_mask_irq(unsigned int irq) static void locomo_gpio_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_GIE); r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START)); @@ -325,10 +325,10 @@ static struct irq_chip locomo_gpio_chip = { .unmask = locomo_gpio_unmask_irq, }; -static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_lt_handler(unsigned int irq, struct irq_desc *desc) { - struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + struct irq_desc *d; + void __iomem *mapbase = get_irq_chip_data(irq); if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) { d = irq_desc + LOCOMO_IRQ_LT_START; @@ -338,7 +338,7 @@ static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc) static void locomo_lt_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START)); @@ -347,7 +347,7 @@ static void locomo_lt_ack_irq(unsigned int irq) static void locomo_lt_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START)); @@ -356,7 +356,7 @@ static void locomo_lt_mask_irq(unsigned int irq) static void locomo_lt_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_LTINT); r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START)); @@ -370,11 +370,11 @@ static struct irq_chip locomo_lt_chip = { .unmask = locomo_lt_unmask_irq, }; -static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc) +static void locomo_spi_handler(unsigned int irq, struct irq_desc *desc) { int req, i; - struct irqdesc *d; - void __iomem *mapbase = get_irq_chipdata(irq); + struct irq_desc *d; + void __iomem *mapbase = get_irq_chip_data(irq); req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; if (req) { @@ -391,7 +391,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc) static void locomo_spi_ack_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -408,7 +408,7 @@ static void locomo_spi_ack_irq(unsigned int irq) static void locomo_spi_mask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -417,7 +417,7 @@ static void locomo_spi_mask_irq(unsigned int irq) static void locomo_spi_unmask_irq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned int r; r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); @@ -440,55 +440,55 @@ static void locomo_setup_irq(struct locomo *lchip) * Install handler for IRQ_LOCOMO_HW. */ set_irq_type(lchip->irq, IRQT_FALLING); - set_irq_chipdata(lchip->irq, irqbase); + set_irq_chip_data(lchip->irq, irqbase); set_irq_chained_handler(lchip->irq, locomo_handler); /* Install handlers for IRQ_LOCOMO_*_BASE */ set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip); - set_irq_chipdata(IRQ_LOCOMO_KEY_BASE, irqbase); + set_irq_chip_data(IRQ_LOCOMO_KEY_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler); set_irq_flags(IRQ_LOCOMO_KEY_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip); - set_irq_chipdata(IRQ_LOCOMO_GPIO_BASE, irqbase); + set_irq_chip_data(IRQ_LOCOMO_GPIO_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler); set_irq_flags(IRQ_LOCOMO_GPIO_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip); - set_irq_chipdata(IRQ_LOCOMO_LT_BASE, irqbase); + set_irq_chip_data(IRQ_LOCOMO_LT_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler); set_irq_flags(IRQ_LOCOMO_LT_BASE, IRQF_VALID | IRQF_PROBE); set_irq_chip(IRQ_LOCOMO_SPI_BASE, &locomo_chip); - set_irq_chipdata(IRQ_LOCOMO_SPI_BASE, irqbase); + set_irq_chip_data(IRQ_LOCOMO_SPI_BASE, irqbase); set_irq_chained_handler(IRQ_LOCOMO_SPI_BASE, locomo_spi_handler); set_irq_flags(IRQ_LOCOMO_SPI_BASE, IRQF_VALID | IRQF_PROBE); /* install handlers for IRQ_LOCOMO_KEY_BASE generated interrupts */ set_irq_chip(LOCOMO_IRQ_KEY_START, &locomo_key_chip); - set_irq_chipdata(LOCOMO_IRQ_KEY_START, irqbase); - set_irq_handler(LOCOMO_IRQ_KEY_START, do_edge_IRQ); + set_irq_chip_data(LOCOMO_IRQ_KEY_START, irqbase); + set_irq_handler(LOCOMO_IRQ_KEY_START, handle_edge_irq); set_irq_flags(LOCOMO_IRQ_KEY_START, IRQF_VALID | IRQF_PROBE); /* install handlers for IRQ_LOCOMO_GPIO_BASE generated interrupts */ for (irq = LOCOMO_IRQ_GPIO_START; irq < LOCOMO_IRQ_GPIO_START + 16; irq++) { set_irq_chip(irq, &locomo_gpio_chip); - set_irq_chipdata(irq, irqbase); - set_irq_handler(irq, do_edge_IRQ); + set_irq_chip_data(irq, irqbase); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* install handlers for IRQ_LOCOMO_LT_BASE generated interrupts */ set_irq_chip(LOCOMO_IRQ_LT_START, &locomo_lt_chip); - set_irq_chipdata(LOCOMO_IRQ_LT_START, irqbase); - set_irq_handler(LOCOMO_IRQ_LT_START, do_edge_IRQ); + set_irq_chip_data(LOCOMO_IRQ_LT_START, irqbase); + set_irq_handler(LOCOMO_IRQ_LT_START, handle_edge_irq); set_irq_flags(LOCOMO_IRQ_LT_START, IRQF_VALID | IRQF_PROBE); /* install handlers for IRQ_LOCOMO_SPI_BASE generated interrupts */ for (irq = LOCOMO_IRQ_SPI_START; irq < LOCOMO_IRQ_SPI_START + 3; irq++) { set_irq_chip(irq, &locomo_spi_chip); - set_irq_chipdata(irq, irqbase); - set_irq_handler(irq, do_edge_IRQ); + set_irq_chip_data(irq, irqbase); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index d5f72010a6f..fe3f05901a2 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -147,7 +147,7 @@ void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *ho * will call us again if there are more interrupts to process. */ static void -sa1111_irq_handler(unsigned int irq, struct irqdesc *desc) +sa1111_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int stat0, stat1, i; void __iomem *base = get_irq_data(irq); @@ -187,7 +187,7 @@ static void sa1111_ack_irq(unsigned int irq) static void sa1111_mask_lowirq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ie0; ie0 = sa1111_readl(mapbase + SA1111_INTEN0); @@ -197,7 +197,7 @@ static void sa1111_mask_lowirq(unsigned int irq) static void sa1111_unmask_lowirq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ie0; ie0 = sa1111_readl(mapbase + SA1111_INTEN0); @@ -215,7 +215,7 @@ static void sa1111_unmask_lowirq(unsigned int irq) static int sa1111_retrigger_lowirq(unsigned int irq) { unsigned int mask = SA1111_IRQMASK_LO(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip0; int i; @@ -236,7 +236,7 @@ static int sa1111_retrigger_lowirq(unsigned int irq) static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) { unsigned int mask = SA1111_IRQMASK_LO(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip0; if (flags == IRQT_PROBE) @@ -259,7 +259,7 @@ static int sa1111_type_lowirq(unsigned int irq, unsigned int flags) static int sa1111_wake_lowirq(unsigned int irq, unsigned int on) { unsigned int mask = SA1111_IRQMASK_LO(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long we0; we0 = sa1111_readl(mapbase + SA1111_WAKEEN0); @@ -284,7 +284,7 @@ static struct irq_chip sa1111_low_chip = { static void sa1111_mask_highirq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ie1; ie1 = sa1111_readl(mapbase + SA1111_INTEN1); @@ -294,7 +294,7 @@ static void sa1111_mask_highirq(unsigned int irq) static void sa1111_unmask_highirq(unsigned int irq) { - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ie1; ie1 = sa1111_readl(mapbase + SA1111_INTEN1); @@ -312,7 +312,7 @@ static void sa1111_unmask_highirq(unsigned int irq) static int sa1111_retrigger_highirq(unsigned int irq) { unsigned int mask = SA1111_IRQMASK_HI(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip1; int i; @@ -333,7 +333,7 @@ static int sa1111_retrigger_highirq(unsigned int irq) static int sa1111_type_highirq(unsigned int irq, unsigned int flags) { unsigned int mask = SA1111_IRQMASK_HI(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long ip1; if (flags == IRQT_PROBE) @@ -356,7 +356,7 @@ static int sa1111_type_highirq(unsigned int irq, unsigned int flags) static int sa1111_wake_highirq(unsigned int irq, unsigned int on) { unsigned int mask = SA1111_IRQMASK_HI(irq); - void __iomem *mapbase = get_irq_chipdata(irq); + void __iomem *mapbase = get_irq_chip_data(irq); unsigned long we1; we1 = sa1111_readl(mapbase + SA1111_WAKEEN1); @@ -410,15 +410,15 @@ static void sa1111_setup_irq(struct sa1111 *sachip) for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) { set_irq_chip(irq, &sa1111_low_chip); - set_irq_chipdata(irq, irqbase); - set_irq_handler(irq, do_edge_IRQ); + set_irq_chip_data(irq, irqbase); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) { set_irq_chip(irq, &sa1111_high_chip); - set_irq_chipdata(irq, irqbase); - set_irq_handler(irq, do_edge_IRQ); + set_irq_chip_data(irq, irqbase); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index 43d27813452..c026fa2214a 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -27,14 +27,14 @@ static void vic_mask_irq(unsigned int irq) { - void __iomem *base = get_irq_chipdata(irq); + void __iomem *base = get_irq_chip_data(irq); irq &= 31; writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); } static void vic_unmask_irq(unsigned int irq) { - void __iomem *base = get_irq_chipdata(irq); + void __iomem *base = get_irq_chip_data(irq); irq &= 31; writel(1 << irq, base + VIC_INT_ENABLE); } @@ -88,10 +88,10 @@ void __init vic_init(void __iomem *base, unsigned int irq_start, unsigned int irq = irq_start + i; set_irq_chip(irq, &vic_chip); - set_irq_chipdata(irq, base); + set_irq_chip_data(irq, base); if (vic_sources & (1 << i)) { - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index b27513a0f11..a786f769035 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -529,7 +529,7 @@ static void ecard_dump_irq_state(void) } } -static void ecard_check_lockup(struct irqdesc *desc) +static void ecard_check_lockup(struct irq_desc *desc) { static unsigned long last; static int lockup; @@ -567,7 +567,7 @@ static void ecard_check_lockup(struct irqdesc *desc) } static void -ecard_irq_handler(unsigned int irq, struct irqdesc *desc) +ecard_irq_handler(unsigned int irq, struct irq_desc *desc) { ecard_t *ec; int called = 0; @@ -585,7 +585,7 @@ ecard_irq_handler(unsigned int irq, struct irqdesc *desc) pending = ecard_default_ops.irqpending(ec); if (pending) { - struct irqdesc *d = irq_desc + ec->irq; + struct irq_desc *d = irq_desc + ec->irq; desc_handle_irq(ec->irq, d); called ++; } @@ -609,7 +609,7 @@ static unsigned char first_set[] = }; static void -ecard_irqexp_handler(unsigned int irq, struct irqdesc *desc) +ecard_irqexp_handler(unsigned int irq, struct irq_desc *desc) { const unsigned int statusmask = 15; unsigned int status; @@ -1022,7 +1022,7 @@ ecard_probe(int slot, card_type_t type) if (slot < 8) { ec->irq = 32 + slot; set_irq_chip(ec->irq, &ecard_chip); - set_irq_handler(ec->irq, do_level_IRQ); + set_irq_handler(ec->irq, handle_level_irq); set_irq_flags(ec->irq, IRQF_VALID); } diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 2c4ff1cbe33..ec01f08f564 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -112,7 +112,7 @@ static struct irq_desc bad_irq_desc = { asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - struct irqdesc *desc = irq_desc + irq; + struct irq_desc *desc = irq_desc + irq; /* * Some hardware gives randomly wrong interrupts. Rather @@ -134,7 +134,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) void set_irq_flags(unsigned int irq, unsigned int iflags) { - struct irqdesc *desc; + struct irq_desc *desc; unsigned long flags; if (irq >= NR_IRQS) { @@ -171,7 +171,7 @@ void __init init_IRQ(void) #ifdef CONFIG_HOTPLUG_CPU -static void route_irq(struct irqdesc *desc, unsigned int irq, unsigned int cpu) +static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) { pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->cpu, cpu); @@ -190,7 +190,7 @@ void migrate_irqs(void) unsigned int i, cpu = smp_processor_id(); for (i = 0; i < NR_IRQS; i++) { - struct irqdesc *desc = irq_desc + i; + struct irq_desc *desc = irq_desc + i; if (desc->cpu == cpu) { unsigned int newcpu = any_online_cpu(desc->affinity); diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index fe3d297d682..a950160fcfb 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -82,7 +82,7 @@ static void aaec2000_int_unmask(unsigned int irq) IRQ_INTENS |= (1 << irq); } -static struct irqchip aaec2000_irq_chip = { +static struct irq_chip aaec2000_irq_chip = { .ack = aaec2000_int_ack, .mask = aaec2000_int_mask, .unmask = aaec2000_int_unmask, @@ -93,7 +93,7 @@ void __init aaec2000_init_irq(void) unsigned int i; for (i = 0; i < NR_IRQS; i++) { - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_chip(i, &aaec2000_irq_chip); set_irq_flags(i, IRQF_VALID); } diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index 7467d644f0a..cec3862651d 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -332,10 +332,10 @@ static struct irq_chip gpio_irqchip = { .set_wake = gpio_irq_set_wake, }; -static void gpio_irq_handler(unsigned irq, struct irqdesc *desc) +static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) { unsigned pin; - struct irqdesc *gpio; + struct irq_desc *gpio; void __iomem *pio; u32 isr; @@ -396,7 +396,7 @@ void __init at91_gpio_irq_setup(void) __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); - set_irq_chipdata(id, controller); + set_irq_chip_data(id, controller); for (i = 0; i < 32; i++, pin++) { /* @@ -404,7 +404,7 @@ void __init at91_gpio_irq_setup(void) * shorter, and the AIC handles interupts sanely. */ set_irq_chip(pin, &gpio_irqchip); - set_irq_handler(pin, do_simple_IRQ); + set_irq_handler(pin, handle_simple_irq); set_irq_flags(pin, IRQF_VALID); } diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index 3e488117ca9..cab0de9b8fa 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -139,7 +139,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS]) at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]); set_irq_chip(i, &at91_aic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); /* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */ diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c index 7ee926e5bad..ca102960f52 100644 --- a/arch/arm/mach-clps711x/irq.c +++ b/arch/arm/mach-clps711x/irq.c @@ -63,7 +63,7 @@ static void int1_unmask(unsigned int irq) clps_writel(intmr1, INTMR1); } -static struct irqchip int1_chip = { +static struct irq_chip int1_chip = { .ack = int1_ack, .mask = int1_mask, .unmask = int1_unmask, @@ -100,7 +100,7 @@ static void int2_unmask(unsigned int irq) clps_writel(intmr2, INTMR2); } -static struct irqchip int2_chip = { +static struct irq_chip int2_chip = { .ack = int2_ack, .mask = int2_mask, .unmask = int2_unmask, @@ -112,12 +112,12 @@ void __init clps711x_init_irq(void) for (i = 0; i < NR_IRQS; i++) { if (INT1_IRQS & (1 << i)) { - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_chip(i, &int1_chip); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } if (INT2_IRQS & (1 << i)) { - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_chip(i, &int2_chip); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index fb10cf25258..231b9000473 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -57,7 +57,7 @@ static void cl7500_unmask_irq_a(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKA); } -static struct irqchip clps7500_a_chip = { +static struct irq_chip clps7500_a_chip = { .ack = cl7500_ack_irq_a, .mask = cl7500_mask_irq_a, .unmask = cl7500_unmask_irq_a, @@ -81,7 +81,7 @@ static void cl7500_unmask_irq_b(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKB); } -static struct irqchip clps7500_b_chip = { +static struct irq_chip clps7500_b_chip = { .ack = cl7500_mask_irq_b, .mask = cl7500_mask_irq_b, .unmask = cl7500_unmask_irq_b, @@ -105,7 +105,7 @@ static void cl7500_unmask_irq_c(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKC); } -static struct irqchip clps7500_c_chip = { +static struct irq_chip clps7500_c_chip = { .ack = cl7500_mask_irq_c, .mask = cl7500_mask_irq_c, .unmask = cl7500_unmask_irq_c, @@ -129,7 +129,7 @@ static void cl7500_unmask_irq_d(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKD); } -static struct irqchip clps7500_d_chip = { +static struct irq_chip clps7500_d_chip = { .ack = cl7500_mask_irq_d, .mask = cl7500_mask_irq_d, .unmask = cl7500_unmask_irq_d, @@ -153,7 +153,7 @@ static void cl7500_unmask_irq_dma(unsigned int irq) iomd_writeb(val | mask, IOMD_DMAMASK); } -static struct irqchip clps7500_dma_chip = { +static struct irq_chip clps7500_dma_chip = { .ack = cl7500_mask_irq_dma, .mask = cl7500_mask_irq_dma, .unmask = cl7500_unmask_irq_dma, @@ -177,7 +177,7 @@ static void cl7500_unmask_irq_fiq(unsigned int irq) iomd_writeb(val | mask, IOMD_FIQMASK); } -static struct irqchip clps7500_fiq_chip = { +static struct irq_chip clps7500_fiq_chip = { .ack = cl7500_mask_irq_fiq, .mask = cl7500_mask_irq_fiq, .unmask = cl7500_unmask_irq_fiq, @@ -187,7 +187,7 @@ static void cl7500_no_action(unsigned int irq) { } -static struct irqchip clps7500_no_chip = { +static struct irq_chip clps7500_no_chip = { .ack = cl7500_no_action, .mask = cl7500_no_action, .unmask = cl7500_no_action, @@ -214,43 +214,43 @@ static void __init clps7500_init_irq(void) switch (irq) { case 0 ... 7: set_irq_chip(irq, &clps7500_a_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 8 ... 15: set_irq_chip(irq, &clps7500_b_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 16 ... 22: set_irq_chip(irq, &clps7500_dma_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 24 ... 31: set_irq_chip(irq, &clps7500_c_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 40 ... 47: set_irq_chip(irq, &clps7500_d_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 48 ... 55: set_irq_chip(irq, &clps7500_no_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 64 ... 72: set_irq_chip(irq, &clps7500_fiq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; } diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 90103ab373a..8459431cfd7 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -45,7 +45,7 @@ static void ebsa110_unmask_irq(unsigned int irq) __raw_writeb(1 << irq, IRQ_MSET); } -static struct irqchip ebsa110_irq_chip = { +static struct irq_chip ebsa110_irq_chip = { .ack = ebsa110_mask_irq, .mask = ebsa110_mask_irq, .unmask = ebsa110_unmask_irq, @@ -67,7 +67,7 @@ static void __init ebsa110_init_irq(void) for (irq = 0; irq < NR_IRQS; irq++) { set_irq_chip(irq, &ebsa110_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index e3fd1ab6adc..d649b39711d 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -245,7 +245,7 @@ EXPORT_SYMBOL(gpio_line_set); * EP93xx IRQ handling *************************************************************************/ static void ep93xx_gpio_ab_irq_handler(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned char status; int i; @@ -335,7 +335,7 @@ static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type) return 0; } -static struct irqchip ep93xx_gpio_ab_irq_chip = { +static struct irq_chip ep93xx_gpio_ab_irq_chip = { .ack = ep93xx_gpio_ab_irq_mask_ack, .mask = ep93xx_gpio_ab_irq_mask, .unmask = ep93xx_gpio_ab_irq_unmask, @@ -352,7 +352,7 @@ void __init ep93xx_init_irq(void) for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) { set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c index af900f4755a..ef29fc34ce6 100644 --- a/arch/arm/mach-footbridge/common.c +++ b/arch/arm/mach-footbridge/common.c @@ -78,7 +78,7 @@ static void fb_unmask_irq(unsigned int irq) *CSR_IRQ_ENABLE = fb_irq_mask[_DC21285_INR(irq)]; } -static struct irqchip fb_chip = { +static struct irq_chip fb_chip = { .ack = fb_mask_irq, .mask = fb_mask_irq, .unmask = fb_unmask_irq, @@ -96,7 +96,7 @@ static void __init __fb_init_irq(void) for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) { set_irq_chip(irq, &fb_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c index 888dedd501b..79443ffc891 100644 --- a/arch/arm/mach-footbridge/isa-irq.c +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -49,7 +49,7 @@ static void isa_unmask_pic_lo_irq(unsigned int irq) outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO); } -static struct irqchip isa_lo_chip = { +static struct irq_chip isa_lo_chip = { .ack = isa_ack_pic_lo_irq, .mask = isa_mask_pic_lo_irq, .unmask = isa_unmask_pic_lo_irq, @@ -78,14 +78,14 @@ static void isa_unmask_pic_hi_irq(unsigned int irq) outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI); } -static struct irqchip isa_hi_chip = { +static struct irq_chip isa_hi_chip = { .ack = isa_ack_pic_hi_irq, .mask = isa_mask_pic_hi_irq, .unmask = isa_unmask_pic_hi_irq, }; static void -isa_irq_handler(unsigned int irq, struct irqdesc *desc) +isa_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int isa_irq = *(unsigned char *)PCIIACK_BASE; @@ -150,13 +150,13 @@ void __init isa_init_irq(unsigned int host_irq) if (host_irq != (unsigned int)-1) { for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) { set_irq_chip(irq, &isa_lo_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) { set_irq_chip(irq, &isa_hi_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c index 4719229a1a7..7f31816896a 100644 --- a/arch/arm/mach-h720x/common.c +++ b/arch/arm/mach-h720x/common.c @@ -101,7 +101,7 @@ static void inline unmask_gpio_irq(u32 irq) static void h720x_gpio_handler(unsigned int mask, unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { IRQDBG("%s irq: %d\n",__FUNCTION__,irq); desc = irq_desc + irq; @@ -117,7 +117,7 @@ h720x_gpio_handler(unsigned int mask, unsigned int irq, } static void -h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -128,7 +128,7 @@ h720x_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; mask = CPU_REG(GPIO_B_VIRT,GPIO_STAT); @@ -138,7 +138,7 @@ h720x_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -149,7 +149,7 @@ h720x_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -161,7 +161,7 @@ h720x_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc) #ifdef CONFIG_CPU_H7202 static void -h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h720x_gpioe_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -172,13 +172,13 @@ h720x_gpioe_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } #endif -static struct irqchip h720x_global_chip = { +static struct irq_chip h720x_global_chip = { .ack = mask_global_irq, .mask = mask_global_irq, .unmask = unmask_global_irq, }; -static struct irqchip h720x_gpio_chip = { +static struct irq_chip h720x_gpio_chip = { .ack = ack_gpio_irq, .mask = mask_gpio_irq, .unmask = unmask_gpio_irq, @@ -203,14 +203,14 @@ void __init h720x_init_irq (void) /* Initialize global IRQ's, fast path */ for (irq = 0; irq < NR_GLBL_IRQS; irq++) { set_irq_chip(irq, &h720x_global_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } /* Initialize multiplexed IRQ's, slow path */ for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) { set_irq_chip(irq, &h720x_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler); @@ -221,7 +221,7 @@ void __init h720x_init_irq (void) #ifdef CONFIG_CPU_H7202 for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) { set_irq_chip(irq, &h720x_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler); diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index 06fecaefd8d..703870f30ad 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -106,7 +106,7 @@ static struct platform_device *devices[] __initdata = { * we have to handle all timer interrupts in one place. */ static void -h7202_timerx_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +h7202_timerx_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -162,7 +162,7 @@ static void inline unmask_timerx_irq (u32 irq) CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) |= bit; } -static struct irqchip h7202_timerx_chip = { +static struct irq_chip h7202_timerx_chip = { .ack = mask_timerx_irq, .mask = mask_timerx_irq, .unmask = unmask_timerx_irq, @@ -202,7 +202,7 @@ void __init h7202_init_irq (void) irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) { mask_timerx_irq(irq); set_irq_chip(irq, &h7202_timerx_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID ); } set_irq_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler); diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index 368b13b058a..0791b56caec 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -146,7 +146,7 @@ imx_gpio_unmask_irq(unsigned int irq) static void imx_gpio_handler(unsigned int mask, unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { desc = irq_desc + irq; while (mask) { @@ -161,7 +161,7 @@ imx_gpio_handler(unsigned int mask, unsigned int irq, } static void -imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpioa_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -171,7 +171,7 @@ imx_gpioa_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpiob_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -181,7 +181,7 @@ imx_gpiob_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpioc_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -191,7 +191,7 @@ imx_gpioc_demux_handler(unsigned int irq_unused, struct irqdesc *desc) } static void -imx_gpiod_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +imx_gpiod_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int mask, irq; @@ -230,13 +230,13 @@ imx_init_irq(void) for (irq = 0; irq < IMX_IRQS; irq++) { set_irq_chip(irq, &imx_internal_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } for (irq = IRQ_GPIOA(0); irq < IRQ_GPIOD(32); irq++) { set_irq_chip(irq, &imx_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 191c57a3b99..72280754354 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -183,7 +183,7 @@ static void __init ap_init_irq(void) for (i = 0; i < NR_IRQS; i++) { if (((1 << i) & INTEGRATOR_SC_VALID_INT) != 0) { set_irq_chip(i, &sc_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 771b65bffe6..913f64b2240 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -202,7 +202,7 @@ static struct irq_chip sic_chip = { }; static void -sic_handle_irq(unsigned int irq, struct irqdesc *desc) +sic_handle_irq(unsigned int irq, struct irq_desc *desc) { unsigned long status = sic_readl(INTCP_VA_SIC_BASE + IRQ_STATUS); @@ -238,7 +238,7 @@ static void __init intcp_init_irq(void) if (i == 29) break; set_irq_chip(i, &pic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } @@ -247,7 +247,7 @@ static void __init intcp_init_irq(void) for (i = IRQ_CIC_START; i <= IRQ_CIC_END; i++) { set_irq_chip(i, &cic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } @@ -256,7 +256,7 @@ static void __init intcp_init_irq(void) for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { set_irq_chip(i, &sic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c index 69d6302f40c..3ec1cd5c4f9 100644 --- a/arch/arm/mach-iop32x/irq.c +++ b/arch/arm/mach-iop32x/irq.c @@ -70,7 +70,7 @@ void __init iop32x_init_irq(void) for (i = 0; i < NR_IRQS; i++) { set_irq_chip(i, &ext_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c index 63304b3d0d7..00b37f32d72 100644 --- a/arch/arm/mach-iop33x/irq.c +++ b/arch/arm/mach-iop33x/irq.c @@ -121,7 +121,7 @@ void __init iop33x_init_irq(void) for (i = 0; i < NR_IRQS; i++) { set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index 22c98e9dad2..27b7480f4af 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c @@ -308,7 +308,7 @@ EXPORT_SYMBOL(gpio_line_config); /************************************************************************* * IRQ handling IXP2000 *************************************************************************/ -static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixp2000_GPIO_irq_handler(unsigned int irq, struct irq_desc *desc) { int i; unsigned long status = *IXP2000_GPIO_INST; @@ -373,7 +373,7 @@ static void ixp2000_GPIO_irq_unmask(unsigned int irq) ixp2000_reg_write(IXP2000_GPIO_INSR, (1 << (irq - IRQ_IXP2000_GPIO0))); } -static struct irqchip ixp2000_GPIO_irq_chip = { +static struct irq_chip ixp2000_GPIO_irq_chip = { .ack = ixp2000_GPIO_irq_mask_ack, .mask = ixp2000_GPIO_irq_mask, .unmask = ixp2000_GPIO_irq_unmask, @@ -401,7 +401,7 @@ static void ixp2000_pci_irq_unmask(unsigned int irq) /* * Error interrupts. These are used extensively by the microengine drivers */ -static void ixp2000_err_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixp2000_err_irq_handler(unsigned int irq, struct irq_desc *desc) { int i; unsigned long status = *IXP2000_IRQ_ERR_STATUS; @@ -426,13 +426,13 @@ static void ixp2000_err_irq_unmask(unsigned int irq) (1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR))); } -static struct irqchip ixp2000_err_irq_chip = { +static struct irq_chip ixp2000_err_irq_chip = { .ack = ixp2000_err_irq_mask, .mask = ixp2000_err_irq_mask, .unmask = ixp2000_err_irq_unmask }; -static struct irqchip ixp2000_pci_irq_chip = { +static struct irq_chip ixp2000_pci_irq_chip = { .ack = ixp2000_pci_irq_mask, .mask = ixp2000_pci_irq_mask, .unmask = ixp2000_pci_irq_unmask @@ -448,7 +448,7 @@ static void ixp2000_irq_unmask(unsigned int irq) ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << irq)); } -static struct irqchip ixp2000_irq_chip = { +static struct irq_chip ixp2000_irq_chip = { .ack = ixp2000_irq_mask, .mask = ixp2000_irq_mask, .unmask = ixp2000_irq_unmask @@ -484,7 +484,7 @@ void __init ixp2000_init_irq(void) for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) { if ((1 << irq) & IXP2000_VALID_IRQ_MASK) { set_irq_chip(irq, &ixp2000_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else set_irq_flags(irq, 0); } @@ -493,7 +493,7 @@ void __init ixp2000_init_irq(void) if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) & IXP2000_VALID_ERR_IRQ_MASK) { set_irq_chip(irq, &ixp2000_err_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else @@ -503,7 +503,7 @@ void __init ixp2000_init_irq(void) for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) { set_irq_chip(irq, &ixp2000_GPIO_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler); @@ -516,7 +516,7 @@ void __init ixp2000_init_irq(void) ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI)); for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) { set_irq_chip(irq, &ixp2000_pci_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } } diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index aa2655092d2..52b368b3434 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c @@ -106,7 +106,7 @@ static void ixdp2x00_irq_unmask(unsigned int irq) ixp2000_release_slowport(&old_cfg); } -static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2x00_irq_handler(unsigned int irq, struct irq_desc *desc) { volatile u32 ex_interrupt = 0; static struct slowport_cfg old_cfg; @@ -129,7 +129,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc) for(i = 0; i < board_irq_count; i++) { if(ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; + struct irq_desc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; desc_handle_irq(cpld_irq, cpld_desc); @@ -139,7 +139,7 @@ static void ixdp2x00_irq_handler(unsigned int irq, struct irqdesc *desc) desc->chip->unmask(irq); } -static struct irqchip ixdp2x00_cpld_irq_chip = { +static struct irq_chip ixdp2x00_cpld_irq_chip = { .ack = ixdp2x00_irq_mask, .mask = ixdp2x00_irq_mask, .unmask = ixdp2x00_irq_unmask @@ -162,7 +162,7 @@ void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) { set_irq_chip(irq, &ixdp2x00_cpld_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 9ccae9e63f7..3084a5fa751 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -63,7 +63,7 @@ static void ixdp2x01_irq_unmask(unsigned int irq) static u32 valid_irq_mask; -static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2x01_irq_handler(unsigned int irq, struct irq_desc *desc) { u32 ex_interrupt; int i; @@ -79,7 +79,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc) for (i = 0; i < IXP2000_BOARD_IRQS; i++) { if (ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; + struct irq_desc *cpld_desc; int cpld_irq = IXP2000_BOARD_IRQ(0) + i; cpld_desc = irq_desc + cpld_irq; desc_handle_irq(cpld_irq, cpld_desc); @@ -89,7 +89,7 @@ static void ixdp2x01_irq_handler(unsigned int irq, struct irqdesc *desc) desc->chip->unmask(irq); } -static struct irqchip ixdp2x01_irq_chip = { +static struct irq_chip ixdp2x01_irq_chip = { .mask = ixdp2x01_irq_mask, .ack = ixdp2x01_irq_mask, .unmask = ixdp2x01_irq_unmask @@ -119,7 +119,7 @@ void __init ixdp2x01_init_irq(void) for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) { if (irq & valid_irq_mask) { set_irq_chip(irq, &ixdp2x01_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } else { set_irq_flags(irq, 0); diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c index a704a182004..ce6ad635a00 100644 --- a/arch/arm/mach-ixp23xx/core.c +++ b/arch/arm/mach-ixp23xx/core.c @@ -224,14 +224,14 @@ static void ixp23xx_irq_edge_unmask(unsigned int irq) *intr_reg |= (1 << (irq % 32)); } -static struct irqchip ixp23xx_irq_level_chip = { +static struct irq_chip ixp23xx_irq_level_chip = { .ack = ixp23xx_irq_mask, .mask = ixp23xx_irq_mask, .unmask = ixp23xx_irq_level_unmask, .set_type = ixp23xx_irq_set_type }; -static struct irqchip ixp23xx_irq_edge_chip = { +static struct irq_chip ixp23xx_irq_edge_chip = { .ack = ixp23xx_irq_ack, .mask = ixp23xx_irq_mask, .unmask = ixp23xx_irq_edge_unmask, @@ -251,11 +251,11 @@ static void ixp23xx_pci_irq_unmask(unsigned int irq) /* * TODO: Should this just be done at ASM level? */ -static void pci_handler(unsigned int irq, struct irqdesc *desc) +static void pci_handler(unsigned int irq, struct irq_desc *desc) { u32 pci_interrupt; unsigned int irqno; - struct irqdesc *int_desc; + struct irq_desc *int_desc; pci_interrupt = *IXP23XX_PCI_XSCALE_INT_STATUS; @@ -276,7 +276,7 @@ static void pci_handler(unsigned int irq, struct irqdesc *desc) desc->chip->unmask(irq); } -static struct irqchip ixp23xx_pci_irq_chip = { +static struct irq_chip ixp23xx_pci_irq_chip = { .ack = ixp23xx_pci_irq_mask, .mask = ixp23xx_pci_irq_mask, .unmask = ixp23xx_pci_irq_unmask @@ -287,11 +287,11 @@ static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type) switch (type) { case IXP23XX_IRQ_LEVEL: set_irq_chip(irq, &ixp23xx_irq_level_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); break; case IXP23XX_IRQ_EDGE: set_irq_chip(irq, &ixp23xx_irq_edge_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); break; } set_irq_flags(irq, IRQF_VALID); @@ -322,7 +322,7 @@ void __init ixp23xx_init_irq(void) for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) { set_irq_chip(irq, &ixp23xx_pci_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index b6ab0e8bb5e..7a86a2516ea 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c @@ -60,7 +60,7 @@ static void ixdp2351_inta_unmask(unsigned int irq) *IXDP2351_CPLD_INTA_MASK_CLR_REG = IXDP2351_INTA_IRQ_MASK(irq); } -static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2351_inta_handler(unsigned int irq, struct irq_desc *desc) { u16 ex_interrupt = *IXDP2351_CPLD_INTA_STAT_REG & IXDP2351_INTA_IRQ_VALID; @@ -70,7 +70,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc) for (i = 0; i < IXDP2351_INTA_IRQ_NUM; i++) { if (ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; + struct irq_desc *cpld_desc; int cpld_irq = IXP23XX_MACH_IRQ(IXDP2351_INTA_IRQ_BASE + i); cpld_desc = irq_desc + cpld_irq; @@ -81,7 +81,7 @@ static void ixdp2351_inta_handler(unsigned int irq, struct irqdesc *desc) desc->chip->unmask(irq); } -static struct irqchip ixdp2351_inta_chip = { +static struct irq_chip ixdp2351_inta_chip = { .ack = ixdp2351_inta_mask, .mask = ixdp2351_inta_mask, .unmask = ixdp2351_inta_unmask @@ -97,7 +97,7 @@ static void ixdp2351_intb_unmask(unsigned int irq) *IXDP2351_CPLD_INTB_MASK_CLR_REG = IXDP2351_INTB_IRQ_MASK(irq); } -static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc) +static void ixdp2351_intb_handler(unsigned int irq, struct irq_desc *desc) { u16 ex_interrupt = *IXDP2351_CPLD_INTB_STAT_REG & IXDP2351_INTB_IRQ_VALID; @@ -107,7 +107,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc) for (i = 0; i < IXDP2351_INTB_IRQ_NUM; i++) { if (ex_interrupt & (1 << i)) { - struct irqdesc *cpld_desc; + struct irq_desc *cpld_desc; int cpld_irq = IXP23XX_MACH_IRQ(IXDP2351_INTB_IRQ_BASE + i); cpld_desc = irq_desc + cpld_irq; @@ -118,7 +118,7 @@ static void ixdp2351_intb_handler(unsigned int irq, struct irqdesc *desc) desc->chip->unmask(irq); } -static struct irqchip ixdp2351_intb_chip = { +static struct irq_chip ixdp2351_intb_chip = { .ack = ixdp2351_intb_mask, .mask = ixdp2351_intb_mask, .unmask = ixdp2351_intb_unmask @@ -142,7 +142,7 @@ void ixdp2351_init_irq(void) irq++) { if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) { set_irq_flags(irq, IRQF_VALID); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_chip(irq, &ixdp2351_inta_chip); } } @@ -153,7 +153,7 @@ void ixdp2351_init_irq(void) irq++) { if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) { set_irq_flags(irq, IRQF_VALID); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_chip(irq, &ixdp2351_intb_chip); } } diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index fbe288a8da6..074c9652024 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -195,7 +195,7 @@ static void ixp4xx_irq_unmask(unsigned int irq) *IXP4XX_ICMR |= (1 << irq); } -static struct irqchip ixp4xx_irq_chip = { +static struct irq_chip ixp4xx_irq_chip = { .name = "IXP4xx", .ack = ixp4xx_irq_ack, .mask = ixp4xx_irq_mask, @@ -224,7 +224,7 @@ void __init ixp4xx_init_irq(void) /* Default to all level triggered */ for(i = 0; i < NR_IRQS; i++) { set_irq_chip(i, &ixp4xx_irq_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c index b7af5640ea7..561a0fe7095 100644 --- a/arch/arm/mach-l7200/core.c +++ b/arch/arm/mach-l7200/core.c @@ -55,7 +55,7 @@ static void l7200_unmask_irq(unsigned int irq) IRQ_ENABLE = 1 << irq; } -static struct irqchip l7200_irq_chip = { +static struct irq_chip l7200_irq_chip = { .ack = l7200_mask_irq, .mask = l7200_mask_irq, .unmask = l7200_unmask_irq @@ -71,7 +71,7 @@ static void __init l7200_init_irq(void) for (irq = 0; irq < NR_IRQS; irq++) { set_irq_chip(irq, &l7200_irq_chip); set_irq_flags(irq, IRQF_VALID); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); } init_FIQ(); diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index 15fbcc911fe..6d26661d99f 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -71,7 +71,7 @@ static struct irq_chip kev7a400_cpld_chip = { }; -static void kev7a400_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void kev7a400_cpld_handler (unsigned int irq, struct irq_desc *desc) { u32 mask = CPLD_LATCHED_INTS; irq = IRQ_KEV7A400_CPLD; @@ -88,7 +88,7 @@ void __init lh7a40x_init_board_irq (void) for (irq = IRQ_KEV7A400_CPLD; irq < IRQ_KEV7A400_CPLD + NR_IRQ_BOARD; ++irq) { set_irq_chip (irq, &kev7a400_cpld_chip); - set_irq_handler (irq, do_edge_IRQ); + set_irq_handler (irq, handle_edge_irq); set_irq_flags (irq, IRQF_VALID); } set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index 8441e0a156c..fe64946f9e1 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -207,7 +207,7 @@ static struct irq_chip lpd7a40x_cpld_chip = { .unmask = lh7a40x_unmask_cpld_irq, }; -static void lpd7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void lpd7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc) { unsigned int mask = CPLD_INTERRUPTS; @@ -279,7 +279,7 @@ void __init lh7a40x_init_board_irq (void) for (irq = IRQ_BOARD_START; irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { set_irq_chip (irq, &lpd7a40x_cpld_chip); - set_irq_handler (irq, do_level_IRQ); + set_irq_handler (irq, handle_level_irq); set_irq_flags (irq, IRQF_VALID); } diff --git a/arch/arm/mach-lh7a40x/irq-kev7a400.c b/arch/arm/mach-lh7a40x/irq-kev7a400.c index 646071334b8..c7433b3c581 100644 --- a/arch/arm/mach-lh7a40x/irq-kev7a400.c +++ b/arch/arm/mach-lh7a40x/irq-kev7a400.c @@ -51,7 +51,7 @@ irq_chip lh7a400_cpld_chip = { }; static void -lh7a400_cpld_handler (unsigned int irq, struct irqdesc *desc) +lh7a400_cpld_handler (unsigned int irq, struct irq_desc *desc) { u32 mask = CPLD_LATCHED_INTS; irq = IRQ_KEV_7A400_CPLD; @@ -71,7 +71,7 @@ lh7a400_init_board_irq (void) for (irq = IRQ_KEV7A400_CPLD; irq < IRQ_KEV7A400_CPLD + NR_IRQ_KEV7A400_CPLD; ++irq) { set_irq_chip (irq, &lh7a400_cpld_chip); - set_irq_handler (irq, do_edge_IRQ); + set_irq_handler (irq, handle_edge_irq); set_irq_flags (irq, IRQF_VALID); } set_irq_chained_handler (IRQ_CPLD, kev7a400_cpld_handler); diff --git a/arch/arm/mach-lh7a40x/irq-lh7a400.c b/arch/arm/mach-lh7a40x/irq-lh7a400.c index 091b2dc58d2..0b938e8b4d9 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a400.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a400.c @@ -74,11 +74,11 @@ void __init lh7a400_init_irq (void) case IRQ_GPIO6INTR: case IRQ_GPIO7INTR: set_irq_chip (irq, &lh7a400_gpio_chip); - set_irq_handler (irq, do_level_IRQ); /* OK default */ + set_irq_handler (irq, handle_level_irq); /* OK default */ break; default: set_irq_chip (irq, &lh7a400_internal_chip); - set_irq_handler (irq, do_level_IRQ); + set_irq_handler (irq, handle_level_irq); } set_irq_flags (irq, IRQF_VALID); } diff --git a/arch/arm/mach-lh7a40x/irq-lh7a404.c b/arch/arm/mach-lh7a40x/irq-lh7a404.c index 7059b983724..5760f8c53e8 100644 --- a/arch/arm/mach-lh7a40x/irq-lh7a404.c +++ b/arch/arm/mach-lh7a40x/irq-lh7a404.c @@ -161,13 +161,13 @@ void __init lh7a404_init_irq (void) set_irq_chip (irq, irq < 32 ? &lh7a404_gpio_vic1_chip : &lh7a404_gpio_vic2_chip); - set_irq_handler (irq, do_level_IRQ); /* OK default */ + set_irq_handler (irq, handle_level_irq); /* OK default */ break; default: set_irq_chip (irq, irq < 32 ? &lh7a404_vic1_chip : &lh7a404_vic2_chip); - set_irq_handler (irq, do_level_IRQ); + set_irq_handler (irq, handle_level_irq); } set_irq_flags (irq, IRQF_VALID); } diff --git a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c index b20376804bb..15b9577023c 100644 --- a/arch/arm/mach-lh7a40x/irq-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/irq-lpd7a40x.c @@ -57,7 +57,7 @@ static struct irq_chip lh7a40x_cpld_chip = { .unmask = lh7a40x_unmask_cpld_irq, }; -static void lh7a40x_cpld_handler (unsigned int irq, struct irqdesc *desc) +static void lh7a40x_cpld_handler (unsigned int irq, struct irq_desc *desc) { unsigned int mask = CPLD_INTERRUPTS; @@ -118,7 +118,7 @@ void __init lh7a40x_init_board_irq (void) for (irq = IRQ_BOARD_START; irq < IRQ_BOARD_START + NR_IRQ_BOARD; ++irq) { set_irq_chip (irq, &lh7a40x_cpld_chip); - set_irq_handler (irq, do_edge_IRQ); + set_irq_handler (irq, handle_edge_irq); set_irq_flags (irq, IRQF_VALID); } diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c index edbbbdc3b06..b9ca8f98265 100644 --- a/arch/arm/mach-netx/generic.c +++ b/arch/arm/mach-netx/generic.c @@ -69,7 +69,7 @@ static struct platform_device *devices[] __initdata = { #endif static void -netx_hif_demux_handler(unsigned int irq_unused, struct irqdesc *desc) +netx_hif_demux_handler(unsigned int irq_unused, struct irq_desc *desc) { unsigned int irq = NETX_IRQ_HIF_CHAINED(0); unsigned int stat; @@ -160,7 +160,7 @@ netx_hif_unmask_irq(unsigned int _irq) DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, _irq); } -static struct irqchip netx_hif_chip = { +static struct irq_chip netx_hif_chip = { .ack = netx_hif_ack_irq, .mask = netx_hif_mask_irq, .unmask = netx_hif_unmask_irq, @@ -175,7 +175,7 @@ void __init netx_init_irq(void) for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) { set_irq_chip(irq, &netx_hif_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c index 8e40208b10b..30e18810904 100644 --- a/arch/arm/mach-omap1/fpga.c +++ b/arch/arm/mach-omap1/fpga.c @@ -84,9 +84,9 @@ static void fpga_mask_ack_irq(unsigned int irq) fpga_ack_irq(irq); } -void innovator_fpga_IRQ_demux(unsigned int irq, struct irqdesc *desc) +void innovator_fpga_IRQ_demux(unsigned int irq, struct irq_desc *desc) { - struct irqdesc *d; + struct irq_desc *d; u32 stat; int fpga_irq; @@ -168,7 +168,7 @@ void omap1510_fpga_init_irq(void) set_irq_chip(i, &omap_fpga_irq); } - set_irq_handler(i, do_edge_IRQ); + set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); } diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c index 3ea140bb9eb..6383a12ad97 100644 --- a/arch/arm/mach-omap1/irq.c +++ b/arch/arm/mach-omap1/irq.c @@ -229,7 +229,7 @@ void __init omap_init_irq(void) omap_irq_set_cfg(j, 0, 0, irq_trigger); set_irq_chip(j, &omap_irq_chip); - set_irq_handler(j, do_level_IRQ); + set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } } diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 11870093d7a..a39d3068030 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c @@ -130,7 +130,7 @@ void __init omap_init_irq(void) for (i = 0; i < nr_irqs; i++) { set_irq_chip(i, &omap_irq_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID); } } diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c index 3a4bcf3d91f..968d0b02759 100644 --- a/arch/arm/mach-pnx4008/irq.c +++ b/arch/arm/mach-pnx4008/irq.c @@ -59,22 +59,22 @@ static int pnx4008_set_irq_type(unsigned int irq, unsigned int type) case IRQT_RISING: __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /*rising edge */ - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); break; case IRQT_FALLING: __raw_writel(__raw_readl(INTC_ATR(irq)) | INTC_BIT(irq), INTC_ATR(irq)); /*edge sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*falling edge */ - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); break; case IRQT_LOW: __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) & ~INTC_BIT(irq), INTC_APR(irq)); /*low level */ - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); break; case IRQT_HIGH: __raw_writel(__raw_readl(INTC_ATR(irq)) & ~INTC_BIT(irq), INTC_ATR(irq)); /*level sensitive */ __raw_writel(__raw_readl(INTC_APR(irq)) | INTC_BIT(irq), INTC_APR(irq)); /* high level */ - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); break; /* IRQT_BOTHEDGE is not supported */ @@ -85,7 +85,7 @@ static int pnx4008_set_irq_type(unsigned int irq, unsigned int type) return 0; } -static struct irqchip pnx4008_irq_chip = { +static struct irq_chip pnx4008_irq_chip = { .ack = pnx4008_mask_ack_irq, .mask = pnx4008_mask_irq, .unmask = pnx4008_unmask_irq, diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index ab1a16025d5..f815678a9d6 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -143,7 +143,7 @@ static struct irq_chip pxa_low_gpio_chip = { * Demux handler for GPIO>=2 edge detect interrupts */ -static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc) +static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) { unsigned int mask; int loop; @@ -286,27 +286,27 @@ void __init pxa_init_irq(void) for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) { set_irq_chip(irq, &pxa_internal_chip_low); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } #if PXA_INTERNAL_IRQS > 32 for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) { set_irq_chip(irq, &pxa_internal_chip_high); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } #endif for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { set_irq_chip(irq, &pxa_low_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { set_irq_chip(irq, &pxa_muxed_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index 5749f6b72e1..8e27a64fa9f 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -75,7 +75,7 @@ static struct irq_chip lpd270_irq_chip = { .unmask = lpd270_unmask_irq, }; -static void lpd270_irq_handler(unsigned int irq, struct irqdesc *desc) +static void lpd270_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending; @@ -105,7 +105,7 @@ static void __init lpd270_init_irq(void) /* setup extra LogicPD PXA270 irqs */ for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) { set_irq_chip(irq, &lpd270_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler); diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 142c33c3dff..055de7f4f00 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -85,7 +85,7 @@ static struct irq_chip lubbock_irq_chip = { .unmask = lubbock_unmask_irq, }; -static void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc) +static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled; do { @@ -108,7 +108,7 @@ static void __init lubbock_init_irq(void) /* setup extra lubbock irqs */ for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) { set_irq_chip(irq, &lubbock_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 49c34d94a9f..56d94d88d5c 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -71,7 +71,7 @@ static struct irq_chip mainstone_irq_chip = { .unmask = mainstone_unmask_irq, }; -static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc) +static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled; do { @@ -94,7 +94,7 @@ static void __init mainstone_init_irq(void) /* setup extra Mainstone irqs */ for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) { set_irq_chip(irq, &mainstone_irq_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14)) set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN); else diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c index 56b2716f8cf..7a029621db4 100644 --- a/arch/arm/mach-rpc/irq.c +++ b/arch/arm/mach-rpc/irq.c @@ -34,7 +34,7 @@ static void iomd_unmask_irq_a(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKA); } -static struct irqchip iomd_a_chip = { +static struct irq_chip iomd_a_chip = { .ack = iomd_ack_irq_a, .mask = iomd_mask_irq_a, .unmask = iomd_unmask_irq_a, @@ -58,7 +58,7 @@ static void iomd_unmask_irq_b(unsigned int irq) iomd_writeb(val | mask, IOMD_IRQMASKB); } -static struct irqchip iomd_b_chip = { +static struct irq_chip iomd_b_chip = { .ack = iomd_mask_irq_b, .mask = iomd_mask_irq_b, .unmask = iomd_unmask_irq_b, @@ -82,7 +82,7 @@ static void iomd_unmask_irq_dma(unsigned int irq) iomd_writeb(val | mask, IOMD_DMAMASK); } -static struct irqchip iomd_dma_chip = { +static struct irq_chip iomd_dma_chip = { .ack = iomd_mask_irq_dma, .mask = iomd_mask_irq_dma, .unmask = iomd_unmask_irq_dma, @@ -106,7 +106,7 @@ static void iomd_unmask_irq_fiq(unsigned int irq) iomd_writeb(val | mask, IOMD_FIQMASK); } -static struct irqchip iomd_fiq_chip = { +static struct irq_chip iomd_fiq_chip = { .ack = iomd_mask_irq_fiq, .mask = iomd_mask_irq_fiq, .unmask = iomd_unmask_irq_fiq, @@ -134,19 +134,19 @@ void __init rpc_init_irq(void) switch (irq) { case 0 ... 7: set_irq_chip(irq, &iomd_a_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 8 ... 15: set_irq_chip(irq, &iomd_b_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; case 16 ... 21: set_irq_chip(irq, &iomd_dma_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, flags); break; diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c index 23d5beea556..379efe70778 100644 --- a/arch/arm/mach-s3c2410/bast-irq.c +++ b/arch/arm/mach-s3c2410/bast-irq.c @@ -88,7 +88,7 @@ bast_pc104_mask(unsigned int irqno) static void bast_pc104_maskack(unsigned int irqno) { - struct irqdesc *desc = irq_desc + IRQ_ISA; + struct irq_desc *desc = irq_desc + IRQ_ISA; bast_pc104_mask(irqno); desc->chip->ack(IRQ_ISA); @@ -104,7 +104,7 @@ bast_pc104_unmask(unsigned int irqno) __raw_writeb(temp, BAST_VA_PC104_IRQMASK); } -static struct irqchip bast_pc104_chip = { +static struct irq_chip bast_pc104_chip = { .mask = bast_pc104_mask, .unmask = bast_pc104_unmask, .ack = bast_pc104_maskack @@ -112,7 +112,7 @@ static struct irqchip bast_pc104_chip = { static void bast_irq_pc104_demux(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned int stat; unsigned int irqno; @@ -157,7 +157,7 @@ static __init int bast_irq_init(void) unsigned int irqno = bast_pc104_irqs[i]; set_irq_chip(irqno, &bast_pc104_chip); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } } diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 683b3491ba3..e7d2ad96ae6 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -180,7 +180,7 @@ s3c_irq_unmask(unsigned int irqno) __raw_writel(mask, S3C2410_INTMSK); } -struct irqchip s3c_irq_level_chip = { +struct irq_chip s3c_irq_level_chip = { .name = "s3c-level", .ack = s3c_irq_maskack, .mask = s3c_irq_mask, @@ -188,7 +188,7 @@ struct irqchip s3c_irq_level_chip = { .set_wake = s3c_irq_wake }; -static struct irqchip s3c_irq_chip = { +static struct irq_chip s3c_irq_chip = { .name = "s3c", .ack = s3c_irq_ack, .mask = s3c_irq_mask, @@ -344,7 +344,7 @@ s3c_irqext_type(unsigned int irq, unsigned int type) return 0; } -static struct irqchip s3c_irqext_chip = { +static struct irq_chip s3c_irqext_chip = { .name = "s3c-ext", .mask = s3c_irqext_mask, .unmask = s3c_irqext_unmask, @@ -353,7 +353,7 @@ static struct irqchip s3c_irqext_chip = { .set_wake = s3c_irqext_wake }; -static struct irqchip s3c_irq_eint0t4 = { +static struct irq_chip s3c_irq_eint0t4 = { .name = "s3c-ext0", .ack = s3c_irq_ack, .mask = s3c_irq_mask, @@ -390,7 +390,7 @@ s3c_irq_uart0_ack(unsigned int irqno) s3c_irqsub_maskack(irqno, INTMSK_UART0, 7); } -static struct irqchip s3c_irq_uart0 = { +static struct irq_chip s3c_irq_uart0 = { .name = "s3c-uart0", .mask = s3c_irq_uart0_mask, .unmask = s3c_irq_uart0_unmask, @@ -417,7 +417,7 @@ s3c_irq_uart1_ack(unsigned int irqno) s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3); } -static struct irqchip s3c_irq_uart1 = { +static struct irq_chip s3c_irq_uart1 = { .name = "s3c-uart1", .mask = s3c_irq_uart1_mask, .unmask = s3c_irq_uart1_unmask, @@ -444,7 +444,7 @@ s3c_irq_uart2_ack(unsigned int irqno) s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6); } -static struct irqchip s3c_irq_uart2 = { +static struct irq_chip s3c_irq_uart2 = { .name = "s3c-uart2", .mask = s3c_irq_uart2_mask, .unmask = s3c_irq_uart2_unmask, @@ -471,7 +471,7 @@ s3c_irq_adc_ack(unsigned int irqno) s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9); } -static struct irqchip s3c_irq_adc = { +static struct irq_chip s3c_irq_adc = { .name = "s3c-adc", .mask = s3c_irq_adc_mask, .unmask = s3c_irq_adc_unmask, @@ -480,11 +480,11 @@ static struct irqchip s3c_irq_adc = { /* irq demux for adc */ static void s3c_irq_demux_adc(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned int subsrc, submsk; unsigned int offset = 9; - struct irqdesc *mydesc; + struct irq_desc *mydesc; /* read the current pending interrupts, and the mask * for what it is available */ @@ -512,7 +512,7 @@ static void s3c_irq_demux_uart(unsigned int start) { unsigned int subsrc, submsk; unsigned int offset = start - IRQ_S3CUART_RX0; - struct irqdesc *desc; + struct irq_desc *desc; /* read the current pending interrupts, and the mask * for what it is available */ @@ -549,7 +549,7 @@ static void s3c_irq_demux_uart(unsigned int start) static void s3c_irq_demux_uart0(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { irq = irq; s3c_irq_demux_uart(IRQ_S3CUART_RX0); @@ -557,7 +557,7 @@ s3c_irq_demux_uart0(unsigned int irq, static void s3c_irq_demux_uart1(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { irq = irq; s3c_irq_demux_uart(IRQ_S3CUART_RX1); @@ -565,7 +565,7 @@ s3c_irq_demux_uart1(unsigned int irq, static void s3c_irq_demux_uart2(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { irq = irq; s3c_irq_demux_uart(IRQ_S3CUART_RX2); @@ -573,7 +573,7 @@ s3c_irq_demux_uart2(unsigned int irq, static void s3c_irq_demux_extint8(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); @@ -595,7 +595,7 @@ s3c_irq_demux_extint8(unsigned int irq, static void s3c_irq_demux_extint4t7(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); @@ -738,7 +738,7 @@ void __init s3c24xx_init_irq(void) case IRQ_UART2: case IRQ_ADCPARENT: set_irq_chip(irqno, &s3c_irq_level_chip); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); break; case IRQ_RESERVED6: @@ -749,7 +749,7 @@ void __init s3c24xx_init_irq(void) default: //irqdbf("registering irq %d (s3c irq)\n", irqno); set_irq_chip(irqno, &s3c_irq_chip); - set_irq_handler(irqno, do_edge_IRQ); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } } @@ -769,14 +769,14 @@ void __init s3c24xx_init_irq(void) for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { irqdbf("registering irq %d (ext int)\n", irqno); set_irq_chip(irqno, &s3c_irq_eint0t4); - set_irq_handler(irqno, do_edge_IRQ); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) { irqdbf("registering irq %d (extended s3c irq)\n", irqno); set_irq_chip(irqno, &s3c_irqext_chip); - set_irq_handler(irqno, do_edge_IRQ); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } @@ -787,28 +787,28 @@ void __init s3c24xx_init_irq(void) for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) { irqdbf("registering irq %d (s3c uart0 irq)\n", irqno); set_irq_chip(irqno, &s3c_irq_uart0); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) { irqdbf("registering irq %d (s3c uart1 irq)\n", irqno); set_irq_chip(irqno, &s3c_irq_uart1); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) { irqdbf("registering irq %d (s3c uart2 irq)\n", irqno); set_irq_chip(irqno, &s3c_irq_uart2); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) { irqdbf("registering irq %d (s3c adc irq)\n", irqno); set_irq_chip(irqno, &s3c_irq_adc); - set_irq_handler(irqno, do_edge_IRQ); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/arch/arm/mach-s3c2410/irq.h b/arch/arm/mach-s3c2410/irq.h index 842a9f42c97..3686a008224 100644 --- a/arch/arm/mach-s3c2410/irq.h +++ b/arch/arm/mach-s3c2410/irq.h @@ -17,7 +17,7 @@ #define EXTINT_OFF (IRQ_EINT4 - 4) -extern struct irqchip s3c_irq_level_chip; +extern struct irq_chip s3c_irq_level_chip; static inline void s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2410/s3c2412-irq.c index 7f741547658..ffcc30b23a8 100644 --- a/arch/arm/mach-s3c2410/s3c2412-irq.c +++ b/arch/arm/mach-s3c2410/s3c2412-irq.c @@ -98,7 +98,7 @@ s3c2412_irq_unmask(unsigned int irqno) __raw_writel(mask & ~bitval, S3C2410_INTMSK); } -static struct irqchip s3c2412_irq_eint0t4 = { +static struct irq_chip s3c2412_irq_eint0t4 = { .ack = s3c2412_irq_ack, .mask = s3c2412_irq_mask, .unmask = s3c2412_irq_unmask, @@ -112,7 +112,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev) for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { set_irq_chip(irqno, &s3c2412_irq_eint0t4); - set_irq_handler(irqno, do_edge_IRQ); + set_irq_handler(irqno, handle_edge_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2410/s3c2440-irq.c index 39db0752d53..1ba19b27ab0 100644 --- a/arch/arm/mach-s3c2410/s3c2440-irq.c +++ b/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -42,10 +42,10 @@ /* WDT/AC97 */ static void s3c_irq_demux_wdtac97(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned int subsrc, submsk; - struct irqdesc *mydesc; + struct irq_desc *mydesc; /* read the current pending interrupts, and the mask * for what it is available */ @@ -90,7 +90,7 @@ s3c_irq_wdtac97_ack(unsigned int irqno) s3c_irqsub_maskack(irqno, INTMSK_WDT, 3<<13); } -static struct irqchip s3c_irq_wdtac97 = { +static struct irq_chip s3c_irq_wdtac97 = { .mask = s3c_irq_wdtac97_mask, .unmask = s3c_irq_wdtac97_unmask, .ack = s3c_irq_wdtac97_ack, @@ -105,12 +105,12 @@ static int s3c2440_irq_add(struct sys_device *sysdev) /* add new chained handler for wdt, ac7 */ set_irq_chip(IRQ_WDT, &s3c_irq_level_chip); - set_irq_handler(IRQ_WDT, do_level_IRQ); + set_irq_handler(IRQ_WDT, handle_level_irq); set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97); for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) { set_irq_chip(irqno, &s3c_irq_wdtac97); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/mach-s3c2410/s3c244x-irq.c index 146f2109dd9..ede94636a72 100644 --- a/arch/arm/mach-s3c2410/s3c244x-irq.c +++ b/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -42,10 +42,10 @@ /* camera irq */ static void s3c_irq_demux_cam(unsigned int irq, - struct irqdesc *desc) + struct irq_desc *desc) { unsigned int subsrc, submsk; - struct irqdesc *mydesc; + struct irq_desc *mydesc; /* read the current pending interrupts, and the mask * for what it is available */ @@ -89,7 +89,7 @@ s3c_irq_cam_ack(unsigned int irqno) s3c_irqsub_maskack(irqno, INTMSK_CAM, 3<<11); } -static struct irqchip s3c_irq_cam = { +static struct irq_chip s3c_irq_cam = { .mask = s3c_irq_cam_mask, .unmask = s3c_irq_cam_unmask, .ack = s3c_irq_cam_ack, @@ -100,18 +100,18 @@ static int s3c244x_irq_add(struct sys_device *sysdev) unsigned int irqno; set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip); - set_irq_handler(IRQ_NFCON, do_level_IRQ); + set_irq_handler(IRQ_NFCON, handle_level_irq); set_irq_flags(IRQ_NFCON, IRQF_VALID); /* add chained handler for camera */ set_irq_chip(IRQ_CAM, &s3c_irq_level_chip); - set_irq_handler(IRQ_CAM, do_level_IRQ); + set_irq_handler(IRQ_CAM, handle_level_irq); set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam); for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) { set_irq_chip(irqno, &s3c_irq_cam); - set_irq_handler(irqno, do_level_IRQ); + set_irq_handler(irqno, handle_level_irq); set_irq_flags(irqno, IRQF_VALID); } diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index fa6dc71bd6a..b034ad69a32 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -702,7 +702,7 @@ static u32 gpio_irq_mask[] = { GPIO2_SD_CON_SLT, }; -static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc) +static void h3800_IRQ_demux(unsigned int irq, struct irq_desc *desc) { int i; @@ -719,14 +719,14 @@ static void h3800_IRQ_demux(unsigned int irq, struct irqdesc *desc) if (0) printk("%s KPIO 0x%08X\n", __FUNCTION__, irq); for (j = 0; j < H3800_KPIO_IRQ_COUNT; j++) if (irq & kpio_irq_mask[j]) - do_edge_IRQ(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j); + handle_edge_irq(H3800_KPIO_IRQ_COUNT + j, irq_desc + H3800_KPIO_IRQ_COUNT + j); /* GPIO2 */ irq = H3800_ASIC2_GPIINTFLAG; if (0) printk("%s GPIO 0x%08X\n", __FUNCTION__, irq); for (j = 0; j < H3800_GPIO_IRQ_COUNT; j++) if (irq & gpio_irq_mask[j]) - do_edge_IRQ(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j); + handle_edge_irq(H3800_GPIO_IRQ_COUNT + j, irq_desc + H3800_GPIO_IRQ_COUNT + j); } if (i >= MAX_ASIC_ISR_LOOPS) diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c index f4c6322ca33..5642aeca079 100644 --- a/arch/arm/mach-sa1100/irq.c +++ b/arch/arm/mach-sa1100/irq.c @@ -110,7 +110,7 @@ static struct irq_chip sa1100_low_gpio_chip = { * and call the handler. */ static void -sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc) +sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc) { unsigned int mask; @@ -327,19 +327,19 @@ void __init sa1100_init_irq(void) for (irq = 0; irq <= 10; irq++) { set_irq_chip(irq, &sa1100_low_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } for (irq = 12; irq <= 31; irq++) { set_irq_chip(irq, &sa1100_normal_chip); - set_irq_handler(irq, do_level_IRQ); + set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } for (irq = 32; irq <= 48; irq++) { set_irq_chip(irq, &sa1100_high_gpio_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 354d5e91da5..075d4d1d63b 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -29,12 +29,12 @@ * is rather unfortunate. */ static void -neponset_irq_handler(unsigned int irq, struct irqdesc *desc) +neponset_irq_handler(unsigned int irq, struct irq_desc *desc) { unsigned int irr; while (1) { - struct irqdesc *d; + struct irq_desc *d; /* * Acknowledge the parent IRQ. @@ -168,9 +168,9 @@ static int neponset_probe(struct platform_device *dev) * Setup other Neponset IRQs. SA1111 will be done by the * generic SA1111 code. */ - set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ); + set_irq_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq); set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); - set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ); + set_irq_handler(IRQ_NEPONSET_USAR, handle_simple_irq); set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); /* diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c index 297ecf13065..00a6c146686 100644 --- a/arch/arm/mach-shark/irq.c +++ b/arch/arm/mach-shark/irq.c @@ -82,7 +82,7 @@ void __init shark_init_irq(void) for (irq = 0; irq < NR_IRQS; irq++) { set_irq_chip(irq, &fb_chip); - set_irq_handler(irq, do_edge_IRQ); + set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3b8576111c1..dcc2ca3dcde 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -77,7 +77,7 @@ static struct irq_chip sic_chip = { }; static void -sic_handle_irq(unsigned int irq, struct irqdesc *desc) +sic_handle_irq(unsigned int irq, struct irq_desc *desc) { unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS); @@ -123,7 +123,7 @@ void __init versatile_init_irq(void) for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) { if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) { set_irq_chip(i, &sic_chip); - set_irq_handler(i, do_level_IRQ); + set_irq_handler(i, handle_level_irq); set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } } diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 8162eed8b50..4f2fd559133 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -410,7 +410,7 @@ static inline void set_24xx_gpio_triggering(void __iomem *base, int gpio, int tr trigger & __IRQT_RISEDGE); MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit, trigger & __IRQT_FALEDGE); - /* FIXME: Possibly do 'set_irq_handler(j, do_level_IRQ)' if only level + /* FIXME: Possibly do 'set_irq_handler(j, handle_level_irq)' if only level * triggering requested. */ } @@ -783,7 +783,7 @@ void omap_free_gpio(int gpio) * line's interrupt handler has been run, we may miss some nested * interrupts. */ -static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc) +static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) { void __iomem *isr_reg = NULL; u32 isr; @@ -853,7 +853,7 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc) gpio_irq = bank->virtual_irq_start; for (; isr != 0; isr >>= 1, gpio_irq++) { - struct irqdesc *d; + struct irq_desc *d; int irq_mask; if (!(isr & 1)) continue; @@ -1092,7 +1092,7 @@ static int __init _omap_gpio_init(void) set_irq_chip(j, &mpuio_irq_chip); else set_irq_chip(j, &gpio_irq_chip); - set_irq_handler(j, do_simple_IRQ); + set_irq_handler(j, handle_simple_irq); set_irq_flags(j, IRQF_VALID); } set_irq_chained_handler(bank->irq, gpio_irq_handler); -- cgit v1.2.3 From bf46878c4ef4cf04a3564f0ff2e7daae353ee2e2 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 20 Nov 2006 22:17:09 +0100 Subject: [ARM] 3939/1: don't reset SA11x0 clock counter Don't reset OSCR to zero as this prevents us from having a contiguous time source. The value returned by sched_clock() is reset to zero in the middle of the boot process otherwise, making CONFIG_PRINTK_TIME rather messed up. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-sa1100/time.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 4284bd6f7a1..29c89f9eb2c 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c @@ -118,6 +118,7 @@ static struct irqaction sa1100_timer_irq = { static void __init sa1100_timer_init(void) { struct timespec tv; + unsigned long flags; set_rtc = sa1100_set_rtc; @@ -126,12 +127,12 @@ static void __init sa1100_timer_init(void) do_settimeofday(&tv); OIER = 0; /* disable any timer interrupts */ - OSCR = LATCH*2; /* push OSCR out of the way */ - OSMR0 = LATCH; /* set initial match */ OSSR = 0xf; /* clear status on all timers */ setup_irq(IRQ_OST0, &sa1100_timer_irq); + local_irq_save(flags); OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer */ + OSMR0 = OSCR + LATCH; /* set initial match */ + local_irq_restore(flags); } #ifdef CONFIG_NO_IDLE_HZ -- cgit v1.2.3 From 46ec0ce8ce7eab6242188ea8a596538753c53b22 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 20 Nov 2006 22:19:29 +0100 Subject: [ARM] 3940/1: don't reset PXA2xx clock counter Don't reset OSCR to zero as this prevents us from having a contiguous time source. The value returned by sched_clock() is reset to zero in the middle of the boot process otherwise, making CONFIG_PRINTK_TIME rather messed up. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/time.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 3ac268fa419..b9146686102 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c @@ -124,6 +124,7 @@ static struct irqaction pxa_timer_irq = { static void __init pxa_timer_init(void) { struct timespec tv; + unsigned long flags; set_rtc = pxa_set_rtc; @@ -132,12 +133,12 @@ static void __init pxa_timer_init(void) do_settimeofday(&tv); OIER = 0; /* disable any timer interrupts */ - OSCR = LATCH*2; /* push OSCR out of the way */ - OSMR0 = LATCH; /* set initial match */ OSSR = 0xf; /* clear status on all timers */ setup_irq(IRQ_OST0, &pxa_timer_irq); + local_irq_save(flags); OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ - OSCR = 0; /* initialize free-running timer */ + OSMR0 = OSCR + LATCH; /* set initial match */ + local_irq_restore(flags); } #ifdef CONFIG_NO_IDLE_HZ -- cgit v1.2.3 From 3ff1559eae70d5fb542eaa087389223dce4e364f Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Nov 2006 13:53:54 +0000 Subject: [ARM] Fix nommu build Fix warnings and errors in arch/arm/mm for nommu build. Remove commented out function prototype in pgtable-nommu.h Signed-off-by: Russell King --- arch/arm/mm/mm.h | 5 +++++ arch/arm/mm/nommu.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index bb2bc9ab6bd..a44e3097063 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -1,4 +1,7 @@ /* the upper-most page table pointer */ + +#ifdef CONFIG_MMU + extern pmd_t *top_pmd; #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) @@ -13,6 +16,8 @@ static inline pmd_t *pmd_off_k(unsigned long virt) return pmd_off(pgd_offset_k(virt), virt); } +#endif + struct map_desc; struct meminfo; struct pglist_data; diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index d0e66424a59..05818fc0c70 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c @@ -6,10 +6,12 @@ #include #include #include +#include #include #include #include +#include #include "mm.h" @@ -76,7 +78,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, } EXPORT_SYMBOL(__ioremap); -void __iounmap(void __iomem *addr) +void __iounmap(volatile void __iomem *addr) { } EXPORT_SYMBOL(__iounmap); -- cgit v1.2.3 From 122214428a7bfab2c09b417f3acdb06222e81748 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 2 Nov 2006 16:41:18 +0100 Subject: [ARM] 3911/2: Simplify alloc_thread_info on ARM Remove ARM local cache of 4 struct thread_info. Can cause oops under certain circumstances. Russell indicated the original optimization was required on older kernels to avoid thread starvation on memory fragmentation, but may no longer be required. I've updated the patch to 19rc4 and ensured no dain-bramage slipped in this time (sorry about that). Original description follows: I was given some test results which pointed to an Oops in alloc_thread_info (happened 2x), and after looking at the code, I see that ARM has its own local cache of 4 struct thread_info. There wasn't any clear (to me) synchronization between the alloc_thread_info and the free_thread_info. I looked over the other arch, and they all simply allocate them on an as needed basis, so I simplified the ARM to do the same, based on the other arch (e.g. PPC) and the folks doing the testing have indicated that this fixed the oops. Signed-off-by: Paul Gortmaker Signed-off-by: Russell King --- arch/arm/kernel/process.c | 61 ----------------------------------------------- 1 file changed, 61 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index bf35c178a87..a9e8f7e55fd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -280,67 +280,6 @@ void show_fpregs(struct user_fp *regs) (unsigned long)regs->fpcr); } -/* - * Task structure and kernel stack allocation. - */ -struct thread_info_list { - unsigned long *head; - unsigned int nr; -}; - -static DEFINE_PER_CPU(struct thread_info_list, thread_info_list) = { NULL, 0 }; - -#define EXTRA_TASK_STRUCT 4 - -struct thread_info *alloc_thread_info(struct task_struct *task) -{ - struct thread_info *thread = NULL; - - if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - unsigned long *p = th->head; - - if (p) { - th->head = (unsigned long *)p[0]; - th->nr -= 1; - } - put_cpu_var(thread_info_list); - - thread = (struct thread_info *)p; - } - - if (!thread) - thread = (struct thread_info *) - __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); - -#ifdef CONFIG_DEBUG_STACK_USAGE - /* - * The stack must be cleared if you want SYSRQ-T to - * give sensible stack usage information - */ - if (thread) - memzero(thread, THREAD_SIZE); -#endif - return thread; -} - -void free_thread_info(struct thread_info *thread) -{ - if (EXTRA_TASK_STRUCT) { - struct thread_info_list *th = &get_cpu_var(thread_info_list); - if (th->nr < EXTRA_TASK_STRUCT) { - unsigned long *p = (unsigned long *)thread; - p[0] = (unsigned long)th->head; - th->head = p; - th->nr += 1; - put_cpu_var(thread_info_list); - return; - } - put_cpu_var(thread_info_list); - } - free_pages((unsigned long)thread, THREAD_SIZE_ORDER); -} - /* * Free current thread data structures etc.. */ -- cgit v1.2.3 From 4e4e520fd52cfdcc7232c4762a78016e7656cad2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Nov 2006 22:42:20 +0000 Subject: [ARM] Fix Versatile PB initialisation to use .init_machine There's no point having the Versatile PB initialisation using an arch_initcall() and then checking whether it's running on a Versatile PB board - this is what the .init_machine function pointer in the machine description is for. Use it. Signed-off-by: Russell King --- arch/arm/mach-versatile/versatile_pb.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 503725b166f..be439bb9d45 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -81,22 +81,18 @@ static struct amba_device *amba_devs[] __initdata = { &mmc1_device, }; -static int __init versatile_pb_init(void) +static void __init versatile_pb_init(void) { int i; - if (machine_is_versatile_pb()) { - for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { - struct amba_device *d = amba_devs[i]; - amba_device_register(d, &iomem_resource); - } - } + versatile_init(); - return 0; + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } } -arch_initcall(versatile_pb_init); - MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ .phys_io = 0x101f1000, @@ -105,5 +101,5 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") .map_io = versatile_map_io, .init_irq = versatile_init_irq, .timer = &versatile_timer, - .init_machine = versatile_init, + .init_machine = versatile_pb_init, MACHINE_END -- cgit v1.2.3 From 20127f6863990e1313178debe8c9cfe32d43b1dc Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 09:33:53 +0100 Subject: [ARM] 3945/1: AT91: Rename devices.c This patch renames the arch/arm/mach-at91rm9200/devices.c file to at91rm9200_devices.c. The file contains AT91RM9200-specific code, so we will need separate files for the SAM9 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91rm9200_devices.c | 813 ++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/devices.c | 813 -------------------------- 3 files changed, 815 insertions(+), 815 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91rm9200_devices.c delete mode 100644 arch/arm/mach-at91rm9200/devices.c (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index c174805c24e..568d8d76cde 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := clock.o irq.o gpio.o devices.o +obj-y := clock.o irq.o gpio.o obj-m := obj-n := obj- := @@ -10,7 +10,7 @@ obj- := obj-$(CONFIG_PM) += pm.o # CPU-specific support -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c obj-$(CONFIG_ARCH_AT91SAM9260) += obj-$(CONFIG_ARCH_AT91SAM9261) += diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91rm9200/at91rm9200_devices.c new file mode 100644 index 00000000000..2b3a23605bf --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91rm9200_devices.c @@ -0,0 +1,813 @@ +/* + * arch/arm/mach-at91rm9200/at91rm9200_devices.c + * + * Copyright (C) 2005 Thibaut VARENE + * Copyright (C) 2005 David Brownell + * + * 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. + * + */ +#include +#include + +#include + +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource at91_usbh_resources[] = { + [0] = { + .start = AT91RM9200_UHP_BASE, + .end = AT91RM9200_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UHP, + .end = AT91RM9200_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = at91_usbh_resources, + .num_resources = ARRAY_SIZE(at91_usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91rm9200_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource at91_udc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_UDP, + .end = AT91RM9200_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_UDP, + .end = AT91RM9200_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = at91_udc_resources, + .num_resources = ARRAY_SIZE(at91_udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + if (data->pullup_pin) + at91_set_gpio_output(data->pullup_pin, 0); + + udc_data = *data; + platform_device_register(&at91rm9200_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) +static u64 eth_dmamask = 0xffffffffUL; +static struct at91_eth_data eth_data; + +static struct resource at91_eth_resources[] = { + [0] = { + .start = AT91_VA_BASE_EMAC, + .end = AT91_VA_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_EMAC, + .end = AT91RM9200_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_eth_device = { + .name = "at91_ether", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ð_data, + }, + .resource = at91_eth_resources, + .num_resources = ARRAY_SIZE(at91_eth_resources), +}; + +void __init at91_add_device_eth(struct at91_eth_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ + at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ + at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ + at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ + } + + eth_data = *data; + platform_device_register(&at91rm9200_eth_device); +} +#else +void __init at91_add_device_eth(struct at91_eth_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Compact Flash / PCMCIA + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) +static struct at91_cf_data cf_data; + +static struct resource at91_cf_resources[] = { + [0] = { + .start = AT91_CF_BASE, + /* ties up CS4, CS5 and CS6 */ + .end = AT91_CF_BASE + (0x30000000 - 1), + .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, + }, +}; + +static struct platform_device at91rm9200_cf_device = { + .name = "at91_cf", + .id = -1, + .dev = { + .platform_data = &cf_data, + }, + .resource = at91_cf_resources, + .num_resources = ARRAY_SIZE(at91_cf_resources), +}; + +void __init at91_add_device_cf(struct at91_cf_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->irq_pin) { + at91_set_gpio_input(data->irq_pin, 1); + at91_set_deglitch(data->irq_pin, 1); + } + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + + /* outputs, initially off */ + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + at91_set_gpio_output(data->rst_pin, 0); + + /* force poweron defaults for these pins ... */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ + at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + + cf_data = *data; + platform_device_register(&at91rm9200_cf_device); +} +#else +void __init at91_add_device_cf(struct at91_cf_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource at91_mmc_resources[] = { + [0] = { + .start = AT91RM9200_BASE_MCI, + .end = AT91RM9200_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_MCI, + .end = AT91RM9200_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = at91_mmc_resources, + .num_resources = ARRAY_SIZE(at91_mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA27, 0); + + if (data->is_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA8, 0); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA9, 0); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA10, 0); + at91_set_B_periph(AT91_PIN_PA11, 0); + at91_set_B_periph(AT91_PIN_PA12, 0); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA28, 0); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA29, 0); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PB3, 0); + at91_set_B_periph(AT91_PIN_PB4, 0); + at91_set_B_periph(AT91_PIN_PB5, 0); + } + } + + mmc_data = *data; + platform_device_register(&at91rm9200_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +static struct resource at91_nand_resources[] = { + { + .start = AT91_SMARTMEDIA_BASE, + .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = at91_nand_resources, + .num_resources = ARRAY_SIZE(at91_nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + if (!data) + return; + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ + at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ + + nand_data = *data; + platform_device_register(&at91_nand_device); +} +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) +static struct platform_device at91rm9200_twi_device = { + .name = "at91_i2c", + .id = -1, + .num_resources = 0, +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA25, 1); + + at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA26, 1); + + platform_device_register(&at91rm9200_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource at91_spi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_SPI, + .end = AT91RM9200_BASE_SPI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_SPI, + .end = AT91RM9200_ID_SPI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91rm9200_spi_device = { + .name = "at91_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = at91_spi_resources, + .num_resources = ARRAY_SIZE(at91_spi_resources), +}; + +static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + + at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ + + /* Enable SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else + cs_pin = at91_spi_standard_cs[devices[i].chip_select]; + +#ifdef CONFIG_SPI_AT91_MANUAL_CS + at91_set_gpio_output(cs_pin, 1); +#else + at91_set_A_periph(cs_pin, 0); +#endif + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); + platform_device_register(&at91rm9200_spi_device); +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * RTC + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) +static struct platform_device at91rm9200_rtc_device = { + .name = "at91_rtc", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_rtc(void) +{ + platform_device_register(&at91rm9200_rtc_device); +} +#else +static void __init at91_add_device_rtc(void) {} +#endif + + +/* -------------------------------------------------------------------- + * Watchdog + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) +static struct platform_device at91rm9200_wdt_device = { + .name = "at91_wdt", + .id = -1, + .num_resources = 0, +}; + +static void __init at91_add_device_watchdog(void) +{ + platform_device_register(&at91rm9200_wdt_device); +} +#else +static void __init at91_add_device_watchdog(void) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91rm9200_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US0, + .end = AT91RM9200_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US0, + .end = AT91RM9200_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ + + /* + * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. + * We need to drive the pin manually. Default is off (RTS is active low). + */ + at91_set_gpio_output(AT91_PIN_PA21, 1); +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US1, + .end = AT91RM9200_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US1, + .end = AT91RM9200_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ + at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US2, + .end = AT91RM9200_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US2, + .end = AT91RM9200_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91RM9200_BASE_US3, + .end = AT91RM9200_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_US3, + .end = AT91RM9200_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91rm9200_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .platform_data = &uart3_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(void) +{ + at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ + at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91rm9200_uart0_device; + at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91rm9200_uart1_device; + at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91rm9200_uart2_device; + at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); + break; + case 3: + configure_usart3_pins(); + at91_uarts[i] = &at91rm9200_uart3_device; + at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); + break; + case 4: + configure_dbgu_pins(); + at91_uarts[i] = &at91rm9200_dbgu_device; + at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + at91_add_device_rtc(); + at91_add_device_watchdog(); + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91rm9200/devices.c b/arch/arm/mach-at91rm9200/devices.c deleted file mode 100644 index 05982437662..00000000000 --- a/arch/arm/mach-at91rm9200/devices.c +++ /dev/null @@ -1,813 +0,0 @@ -/* - * arch/arm/mach-at91rm9200/devices.c - * - * Copyright (C) 2005 Thibaut VARENE - * Copyright (C) 2005 David Brownell - * - * 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. - * - */ -#include -#include - -#include - -#include -#include -#include - -#include "generic.h" - -#define SZ_512 0x00000200 -#define SZ_256 0x00000100 -#define SZ_16 0x00000010 - -/* -------------------------------------------------------------------- - * USB Host - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) -static u64 ohci_dmamask = 0xffffffffUL; -static struct at91_usbh_data usbh_data; - -static struct resource at91_usbh_resources[] = { - [0] = { - .start = AT91RM9200_UHP_BASE, - .end = AT91RM9200_UHP_BASE + SZ_1M - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_UHP, - .end = AT91RM9200_ID_UHP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_usbh_device = { - .name = "at91_ohci", - .id = -1, - .dev = { - .dma_mask = &ohci_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &usbh_data, - }, - .resource = at91_usbh_resources, - .num_resources = ARRAY_SIZE(at91_usbh_resources), -}; - -void __init at91_add_device_usbh(struct at91_usbh_data *data) -{ - if (!data) - return; - - usbh_data = *data; - platform_device_register(&at91rm9200_usbh_device); -} -#else -void __init at91_add_device_usbh(struct at91_usbh_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * USB Device (Gadget) - * -------------------------------------------------------------------- */ - -#ifdef CONFIG_USB_GADGET_AT91 -static struct at91_udc_data udc_data; - -static struct resource at91_udc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_UDP, - .end = AT91RM9200_BASE_UDP + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_UDP, - .end = AT91RM9200_ID_UDP, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_udc_device = { - .name = "at91_udc", - .id = -1, - .dev = { - .platform_data = &udc_data, - }, - .resource = at91_udc_resources, - .num_resources = ARRAY_SIZE(at91_udc_resources), -}; - -void __init at91_add_device_udc(struct at91_udc_data *data) -{ - if (!data) - return; - - if (data->vbus_pin) { - at91_set_gpio_input(data->vbus_pin, 0); - at91_set_deglitch(data->vbus_pin, 1); - } - if (data->pullup_pin) - at91_set_gpio_output(data->pullup_pin, 0); - - udc_data = *data; - platform_device_register(&at91rm9200_udc_device); -} -#else -void __init at91_add_device_udc(struct at91_udc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Ethernet - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_ARM_AT91_ETHER) || defined(CONFIG_ARM_AT91_ETHER_MODULE) -static u64 eth_dmamask = 0xffffffffUL; -static struct at91_eth_data eth_data; - -static struct resource at91_eth_resources[] = { - [0] = { - .start = AT91_VA_BASE_EMAC, - .end = AT91_VA_BASE_EMAC + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_EMAC, - .end = AT91RM9200_ID_EMAC, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_eth_device = { - .name = "at91_ether", - .id = -1, - .dev = { - .dma_mask = ð_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = ð_data, - }, - .resource = at91_eth_resources, - .num_resources = ARRAY_SIZE(at91_eth_resources), -}; - -void __init at91_add_device_eth(struct at91_eth_data *data) -{ - if (!data) - return; - - if (data->phy_irq_pin) { - at91_set_gpio_input(data->phy_irq_pin, 0); - at91_set_deglitch(data->phy_irq_pin, 1); - } - - /* Pins used for MII and RMII */ - at91_set_A_periph(AT91_PIN_PA16, 0); /* EMDIO */ - at91_set_A_periph(AT91_PIN_PA15, 0); /* EMDC */ - at91_set_A_periph(AT91_PIN_PA14, 0); /* ERXER */ - at91_set_A_periph(AT91_PIN_PA13, 0); /* ERX1 */ - at91_set_A_periph(AT91_PIN_PA12, 0); /* ERX0 */ - at91_set_A_periph(AT91_PIN_PA11, 0); /* ECRS_ECRSDV */ - at91_set_A_periph(AT91_PIN_PA10, 0); /* ETX1 */ - at91_set_A_periph(AT91_PIN_PA9, 0); /* ETX0 */ - at91_set_A_periph(AT91_PIN_PA8, 0); /* ETXEN */ - at91_set_A_periph(AT91_PIN_PA7, 0); /* ETXCK_EREFCK */ - - if (!data->is_rmii) { - at91_set_B_periph(AT91_PIN_PB19, 0); /* ERXCK */ - at91_set_B_periph(AT91_PIN_PB18, 0); /* ECOL */ - at91_set_B_periph(AT91_PIN_PB17, 0); /* ERXDV */ - at91_set_B_periph(AT91_PIN_PB16, 0); /* ERX3 */ - at91_set_B_periph(AT91_PIN_PB15, 0); /* ERX2 */ - at91_set_B_periph(AT91_PIN_PB14, 0); /* ETXER */ - at91_set_B_periph(AT91_PIN_PB13, 0); /* ETX3 */ - at91_set_B_periph(AT91_PIN_PB12, 0); /* ETX2 */ - } - - eth_data = *data; - platform_device_register(&at91rm9200_eth_device); -} -#else -void __init at91_add_device_eth(struct at91_eth_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * Compact Flash / PCMCIA - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) -static struct at91_cf_data cf_data; - -static struct resource at91_cf_resources[] = { - [0] = { - .start = AT91_CF_BASE, - /* ties up CS4, CS5 and CS6 */ - .end = AT91_CF_BASE + (0x30000000 - 1), - .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, - }, -}; - -static struct platform_device at91rm9200_cf_device = { - .name = "at91_cf", - .id = -1, - .dev = { - .platform_data = &cf_data, - }, - .resource = at91_cf_resources, - .num_resources = ARRAY_SIZE(at91_cf_resources), -}; - -void __init at91_add_device_cf(struct at91_cf_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (data->irq_pin) { - at91_set_gpio_input(data->irq_pin, 1); - at91_set_deglitch(data->irq_pin, 1); - } - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - - /* outputs, initially off */ - if (data->vcc_pin) - at91_set_gpio_output(data->vcc_pin, 0); - at91_set_gpio_output(data->rst_pin, 0); - - /* force poweron defaults for these pins ... */ - at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */ - at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */ - at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ - at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ - - cf_data = *data; - platform_device_register(&at91rm9200_cf_device); -} -#else -void __init at91_add_device_cf(struct at91_cf_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * MMC / SD - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) -static u64 mmc_dmamask = 0xffffffffUL; -static struct at91_mmc_data mmc_data; - -static struct resource at91_mmc_resources[] = { - [0] = { - .start = AT91RM9200_BASE_MCI, - .end = AT91RM9200_BASE_MCI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_MCI, - .end = AT91RM9200_ID_MCI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_mmc_device = { - .name = "at91_mci", - .id = -1, - .dev = { - .dma_mask = &mmc_dmamask, - .coherent_dma_mask = 0xffffffff, - .platform_data = &mmc_data, - }, - .resource = at91_mmc_resources, - .num_resources = ARRAY_SIZE(at91_mmc_resources), -}; - -void __init at91_add_device_mmc(struct at91_mmc_data *data) -{ - if (!data) - return; - - /* input/irq */ - if (data->det_pin) { - at91_set_gpio_input(data->det_pin, 1); - at91_set_deglitch(data->det_pin, 1); - } - if (data->wp_pin) - at91_set_gpio_input(data->wp_pin, 1); - - /* CLK */ - at91_set_A_periph(AT91_PIN_PA27, 0); - - if (data->is_b) { - /* CMD */ - at91_set_B_periph(AT91_PIN_PA8, 0); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA9, 0); - if (data->wire4) { - at91_set_B_periph(AT91_PIN_PA10, 0); - at91_set_B_periph(AT91_PIN_PA11, 0); - at91_set_B_periph(AT91_PIN_PA12, 0); - } - } else { - /* CMD */ - at91_set_A_periph(AT91_PIN_PA28, 0); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA29, 0); - if (data->wire4) { - at91_set_B_periph(AT91_PIN_PB3, 0); - at91_set_B_periph(AT91_PIN_PB4, 0); - at91_set_B_periph(AT91_PIN_PB5, 0); - } - } - - mmc_data = *data; - platform_device_register(&at91rm9200_mmc_device); -} -#else -void __init at91_add_device_mmc(struct at91_mmc_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * NAND / SmartMedia - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) -static struct at91_nand_data nand_data; - -static struct resource at91_nand_resources[] = { - { - .start = AT91_SMARTMEDIA_BASE, - .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, - .flags = IORESOURCE_MEM, - } -}; - -static struct platform_device at91_nand_device = { - .name = "at91_nand", - .id = -1, - .dev = { - .platform_data = &nand_data, - }, - .resource = at91_nand_resources, - .num_resources = ARRAY_SIZE(at91_nand_resources), -}; - -void __init at91_add_device_nand(struct at91_nand_data *data) -{ - if (!data) - return; - - /* enable pin */ - if (data->enable_pin) - at91_set_gpio_output(data->enable_pin, 1); - - /* ready/busy pin */ - if (data->rdy_pin) - at91_set_gpio_input(data->rdy_pin, 1); - - /* card detect pin */ - if (data->det_pin) - at91_set_gpio_input(data->det_pin, 1); - - at91_set_A_periph(AT91_PIN_PC1, 0); /* SMOE */ - at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ - - nand_data = *data; - platform_device_register(&at91_nand_device); -} -#else -void __init at91_add_device_nand(struct at91_nand_data *data) {} -#endif - - -/* -------------------------------------------------------------------- - * TWI (i2c) - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) -static struct platform_device at91rm9200_twi_device = { - .name = "at91_i2c", - .id = -1, - .num_resources = 0, -}; - -void __init at91_add_device_i2c(void) -{ - /* pins used for TWI interface */ - at91_set_A_periph(AT91_PIN_PA25, 0); /* TWD */ - at91_set_multi_drive(AT91_PIN_PA25, 1); - - at91_set_A_periph(AT91_PIN_PA26, 0); /* TWCK */ - at91_set_multi_drive(AT91_PIN_PA26, 1); - - platform_device_register(&at91rm9200_twi_device); -} -#else -void __init at91_add_device_i2c(void) {} -#endif - - -/* -------------------------------------------------------------------- - * SPI - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) -static u64 spi_dmamask = 0xffffffffUL; - -static struct resource at91_spi_resources[] = { - [0] = { - .start = AT91RM9200_BASE_SPI, - .end = AT91RM9200_BASE_SPI + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_SPI, - .end = AT91RM9200_ID_SPI, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device at91rm9200_spi_device = { - .name = "at91_spi", - .id = 0, - .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = 0xffffffff, - }, - .resource = at91_spi_resources, - .num_resources = ARRAY_SIZE(at91_spi_resources), -}; - -static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; - -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) -{ - int i; - unsigned long cs_pin; - - at91_set_A_periph(AT91_PIN_PA0, 0); /* MISO */ - at91_set_A_periph(AT91_PIN_PA1, 0); /* MOSI */ - at91_set_A_periph(AT91_PIN_PA2, 0); /* SPCK */ - - /* Enable SPI chip-selects */ - for (i = 0; i < nr_devices; i++) { - if (devices[i].controller_data) - cs_pin = (unsigned long) devices[i].controller_data; - else - cs_pin = at91_spi_standard_cs[devices[i].chip_select]; - -#ifdef CONFIG_SPI_AT91_MANUAL_CS - at91_set_gpio_output(cs_pin, 1); -#else - at91_set_A_periph(cs_pin, 0); -#endif - - /* pass chip-select pin to driver */ - devices[i].controller_data = (void *) cs_pin; - } - - spi_register_board_info(devices, nr_devices); - at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); - platform_device_register(&at91rm9200_spi_device); -} -#else -void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} -#endif - - -/* -------------------------------------------------------------------- - * RTC - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) -static struct platform_device at91rm9200_rtc_device = { - .name = "at91_rtc", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_rtc(void) -{ - platform_device_register(&at91rm9200_rtc_device); -} -#else -static void __init at91_add_device_rtc(void) {} -#endif - - -/* -------------------------------------------------------------------- - * Watchdog - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) -static struct platform_device at91rm9200_wdt_device = { - .name = "at91_wdt", - .id = -1, - .num_resources = 0, -}; - -static void __init at91_add_device_watchdog(void) -{ - platform_device_register(&at91rm9200_wdt_device); -} -#else -static void __init at91_add_device_watchdog(void) {} -#endif - - -/* -------------------------------------------------------------------- - * LEDs - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_LEDS) -u8 at91_leds_cpu; -u8 at91_leds_timer; - -void __init at91_init_leds(u8 cpu_led, u8 timer_led) -{ - at91_leds_cpu = cpu_led; - at91_leds_timer = timer_led; -} -#else -void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} -#endif - - -/* -------------------------------------------------------------------- - * UART - * -------------------------------------------------------------------- */ - -#if defined(CONFIG_SERIAL_ATMEL) -static struct resource dbgu_resources[] = { - [0] = { - .start = AT91_VA_BASE_SYS + AT91_DBGU, - .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91_ID_SYS, - .end = AT91_ID_SYS, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data dbgu_data = { - .use_dma_tx = 0, - .use_dma_rx = 0, /* DBGU not capable of receive DMA */ - .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), -}; - -static struct platform_device at91rm9200_dbgu_device = { - .name = "atmel_usart", - .id = 0, - .dev = { - .platform_data = &dbgu_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = dbgu_resources, - .num_resources = ARRAY_SIZE(dbgu_resources), -}; - -static inline void configure_dbgu_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA30, 0); /* DRXD */ - at91_set_A_periph(AT91_PIN_PA31, 1); /* DTXD */ -} - -static struct resource uart0_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US0, - .end = AT91RM9200_BASE_US0 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US0, - .end = AT91RM9200_ID_US0, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart0_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart0_device = { - .name = "atmel_usart", - .id = 1, - .dev = { - .platform_data = &uart0_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart0_resources, - .num_resources = ARRAY_SIZE(uart0_resources), -}; - -static inline void configure_usart0_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA17, 1); /* TXD0 */ - at91_set_A_periph(AT91_PIN_PA18, 0); /* RXD0 */ - at91_set_A_periph(AT91_PIN_PA20, 0); /* CTS0 */ - - /* - * AT91RM9200 Errata #39 - RTS0 is not internally connected to PA21. - * We need to drive the pin manually. Default is off (RTS is active low). - */ - at91_set_gpio_output(AT91_PIN_PA21, 1); -} - -static struct resource uart1_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US1, - .end = AT91RM9200_BASE_US1 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US1, - .end = AT91RM9200_ID_US1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart1_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart1_device = { - .name = "atmel_usart", - .id = 2, - .dev = { - .platform_data = &uart1_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart1_resources, - .num_resources = ARRAY_SIZE(uart1_resources), -}; - -static inline void configure_usart1_pins(void) -{ - at91_set_A_periph(AT91_PIN_PB18, 0); /* RI1 */ - at91_set_A_periph(AT91_PIN_PB19, 0); /* DTR1 */ - at91_set_A_periph(AT91_PIN_PB20, 1); /* TXD1 */ - at91_set_A_periph(AT91_PIN_PB21, 0); /* RXD1 */ - at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD1 */ - at91_set_A_periph(AT91_PIN_PB24, 0); /* CTS1 */ - at91_set_A_periph(AT91_PIN_PB25, 0); /* DSR1 */ - at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS1 */ -} - -static struct resource uart2_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US2, - .end = AT91RM9200_BASE_US2 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US2, - .end = AT91RM9200_ID_US2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart2_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart2_device = { - .name = "atmel_usart", - .id = 3, - .dev = { - .platform_data = &uart2_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart2_resources, - .num_resources = ARRAY_SIZE(uart2_resources), -}; - -static inline void configure_usart2_pins(void) -{ - at91_set_A_periph(AT91_PIN_PA22, 0); /* RXD2 */ - at91_set_A_periph(AT91_PIN_PA23, 1); /* TXD2 */ -} - -static struct resource uart3_resources[] = { - [0] = { - .start = AT91RM9200_BASE_US3, - .end = AT91RM9200_BASE_US3 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = AT91RM9200_ID_US3, - .end = AT91RM9200_ID_US3, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct atmel_uart_data uart3_data = { - .use_dma_tx = 1, - .use_dma_rx = 1, -}; - -static struct platform_device at91rm9200_uart3_device = { - .name = "atmel_usart", - .id = 4, - .dev = { - .platform_data = &uart3_data, - .coherent_dma_mask = 0xffffffff, - }, - .resource = uart3_resources, - .num_resources = ARRAY_SIZE(uart3_resources), -}; - -static inline void configure_usart3_pins(void) -{ - at91_set_B_periph(AT91_PIN_PA5, 1); /* TXD3 */ - at91_set_B_periph(AT91_PIN_PA6, 0); /* RXD3 */ -} - -struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ -struct platform_device *atmel_default_console_device; /* the serial console device */ - -void __init at91_init_serial(struct at91_uart_config *config) -{ - int i; - - /* Fill in list of supported UARTs */ - for (i = 0; i < config->nr_tty; i++) { - switch (config->tty_map[i]) { - case 0: - configure_usart0_pins(); - at91_uarts[i] = &at91rm9200_uart0_device; - at91_clock_associate("usart0_clk", &at91rm9200_uart0_device.dev, "usart"); - break; - case 1: - configure_usart1_pins(); - at91_uarts[i] = &at91rm9200_uart1_device; - at91_clock_associate("usart1_clk", &at91rm9200_uart1_device.dev, "usart"); - break; - case 2: - configure_usart2_pins(); - at91_uarts[i] = &at91rm9200_uart2_device; - at91_clock_associate("usart2_clk", &at91rm9200_uart2_device.dev, "usart"); - break; - case 3: - configure_usart3_pins(); - at91_uarts[i] = &at91rm9200_uart3_device; - at91_clock_associate("usart3_clk", &at91rm9200_uart3_device.dev, "usart"); - break; - case 4: - configure_dbgu_pins(); - at91_uarts[i] = &at91rm9200_dbgu_device; - at91_clock_associate("mck", &at91rm9200_dbgu_device.dev, "usart"); - break; - default: - continue; - } - at91_uarts[i]->id = i; /* update ID number to mapped ID */ - } - - /* Set serial console device */ - if (config->console_tty < ATMEL_MAX_UART) - atmel_default_console_device = at91_uarts[config->console_tty]; - if (!atmel_default_console_device) - printk(KERN_INFO "AT91: No default serial console defined.\n"); -} - -void __init at91_add_device_serial(void) -{ - int i; - - for (i = 0; i < ATMEL_MAX_UART; i++) { - if (at91_uarts[i]) - platform_device_register(at91_uarts[i]); - } -} -#else -void __init at91_init_serial(struct at91_uart_config *config) {} -void __init at91_add_device_serial(void) {} -#endif - - -/* -------------------------------------------------------------------- */ - -/* - * These devices are always present and don't need any board-specific - * setup. - */ -static int __init at91_add_standard_devices(void) -{ - at91_add_device_rtc(); - at91_add_device_watchdog(); - return 0; -} - -arch_initcall(at91_add_standard_devices); -- cgit v1.2.3 From 1f4fd0a0d28fabf965815755f1a74ef91dfb5ca6 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 10:01:47 +0100 Subject: [ARM] 3946/1: AT91: at91_arch_reset and at91_extern_irq The external interrupt sources are different on the various AT91 processors. This patch introduces the global 'at91_extern_irq' variable that contains a bitset of the available external interrupt sources. The processor reset mechanism also differs on the various AT91 processors. This patch also adds a global 'at91_arch_reset' callback (from system.h) into the processor-specific code to perform the reset. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200.c | 17 +++++++++++++++++ arch/arm/mach-at91rm9200/generic.h | 3 +++ arch/arm/mach-at91rm9200/irq.c | 14 ++++++++++---- arch/arm/mach-at91rm9200/pm.c | 9 +-------- 4 files changed, 31 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index dcf6136fedf..0422593032f 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "generic.h" @@ -222,6 +223,16 @@ static struct at91_gpio_bank at91rm9200_gpio[] = { } }; +static void at91rm9200_reset(void) +{ + /* + * Perform a hardware reset with the use of the Watchdog timer. + */ + at91_sys_write(AT91_ST_WDMR, AT91_ST_RSTEN | AT91_ST_EXTEN | 1); + at91_sys_write(AT91_ST_CR, AT91_ST_WDRST); +} + + /* -------------------------------------------------------------------- * AT91RM9200 processor initialization * -------------------------------------------------------------------- */ @@ -230,6 +241,12 @@ void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks /* Map peripherals */ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); + at91_arch_reset = at91rm9200_reset; + at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1) + | (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3) + | (1 << AT91RM9200_ID_IRQ4) | (1 << AT91RM9200_ID_IRQ5) + | (1 << AT91RM9200_ID_IRQ6); + /* Init clock subsystem */ at91_clock_init(main_clock); diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index 694e411e285..fd98e353c5a 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -39,3 +39,6 @@ struct at91_gpio_bank { }; extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); extern void __init at91_gpio_irq_setup(void); + +extern void (*at91_arch_reset)(void); +extern int at91_extern_irq; diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91rm9200/irq.c index 3e488117ca9..2cea07a34a8 100644 --- a/arch/arm/mach-at91rm9200/irq.c +++ b/arch/arm/mach-at91rm9200/irq.c @@ -47,6 +47,10 @@ static void at91_aic_unmask_irq(unsigned int irq) at91_sys_write(AT91_AIC_IECR, 1 << irq); } +unsigned int at91_extern_irq; + +#define is_extern_irq(irq) ((1 << (irq)) & at91_extern_irq) + static int at91_aic_set_type(unsigned irq, unsigned type) { unsigned int smr, srctype; @@ -59,14 +63,16 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQT_LOW: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_LOW; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq == AT91_ID_FIQ) || is_extern_irq(irq)) /* only supported on external interrupts */ + srctype = AT91_AIC_SRCTYPE_FALLING; + else return -EINVAL; - srctype = AT91_AIC_SRCTYPE_FALLING; break; default: return -EINVAL; diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 32c95d8eaac..5e3b6e306f1 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -112,7 +112,6 @@ EXPORT_SYMBOL(at91_suspend_entering_slow_clock); static void (*slow_clock)(void); - static int at91_pm_enter(suspend_state_t state) { at91_gpio_suspend(); @@ -123,13 +122,7 @@ static int at91_pm_enter(suspend_state_t state) (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) - | (1 << AT91RM9200_ID_IRQ0) - | (1 << AT91RM9200_ID_IRQ1) - | (1 << AT91RM9200_ID_IRQ2) - | (1 << AT91RM9200_ID_IRQ3) - | (1 << AT91RM9200_ID_IRQ4) - | (1 << AT91RM9200_ID_IRQ5) - | (1 << AT91RM9200_ID_IRQ6)) + | (at91_extern_irq)) & at91_sys_read(AT91_AIC_IMR), state); -- cgit v1.2.3 From 62c1660d908c44663c63ad6c679f6afa1d33c5f6 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 12:27:38 +0100 Subject: [ARM] 3948/1: AT91: Initial support for AT91SAM9261 and AT91SAM9260 This patch adds the initial support for the newer Atmel AT91SAM9261 and AT91SAM9260 processors. The code is based on, and makes use of, the existing AT91RM9200 support. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 6 +- arch/arm/mach-at91rm9200/at91sam9260.c | 294 +++++++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/at91sam9261.c | 289 ++++++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/generic.h | 5 + 4 files changed, 591 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam9260.c create mode 100644 arch/arm/mach-at91rm9200/at91sam9261.c (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 568d8d76cde..40e89bf459f 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,10 +11,10 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += -obj-$(CONFIG_ARCH_AT91SAM9261) += +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o -# AT91RM9200 Board-specific support +# AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o obj-$(CONFIG_ARCH_AT91RM9200DK) += board-dk.o obj-$(CONFIG_MACH_AT91RM9200EK) += board-ek.o diff --git a/arch/arm/mach-at91rm9200/at91sam9260.c b/arch/arm/mach-at91rm9200/at91sam9260.c new file mode 100644 index 00000000000..203f073a53e --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9260.c @@ -0,0 +1,294 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9260.c + * + * Copyright (C) 2006 SAN People + * + * 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. + * + */ + +#include + +#include +#include +#include +#include + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9260_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), + .length = AT91SAM9260_SRAM0_SIZE, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, + .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), + .length = AT91SAM9260_SRAM1_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9260_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk adc_clk = { + .name = "adc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ADC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9260_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9260_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ether_clk = { + .name = "ether_clk", + .pmc_mask = 1 << AT91SAM9260_ID_EMAC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk isi_clk = { + .name = "isi_clk", + .pmc_mask = 1 << AT91SAM9260_ID_ISI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US3, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart4_clk = { + .name = "usart4_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US4, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart5_clk = { + .name = "usart5_clk", + .pmc_mask = 1 << AT91SAM9260_ID_US5, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &adc_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + // ssc + // tc0 .. tc2 + &ohci_clk, + ðer_clk, + &isi_clk, + &usart3_clk, + &usart4_clk, + &usart5_clk, + // tc3 .. tc5 + // irq0 .. irq2 +}; + +/* + * The two programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; + +static void __init at91sam9260_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clk_register(&pck0); + clk_register(&pck1); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9260_gpio[] = { + { + .id = AT91SAM9260_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9260_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9260_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9260_reset(void) +{ +#warning "Implement CPU reset" +} + + +/* -------------------------------------------------------------------- + * AT91SAM9260 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9260_initialize(unsigned long main_clock) +{ + /* Map peripherals */ + iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); + + at91_arch_reset = at91sam9260_reset; + at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) + | (1 << AT91SAM9260_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9260_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9260_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, /* Analog-to-Digital Converter */ + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller */ + 0, + 0, + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* Ethernet */ + 0, /* Image Sensor Interface */ + 6, /* USART 3 */ + 6, /* USART 4 */ + 6, /* USART 5 */ + 0, /* Timer Counter 3 */ + 0, /* Timer Counter 4 */ + 0, /* Timer Counter 5 */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9260_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91rm9200/at91sam9261.c b/arch/arm/mach-at91rm9200/at91sam9261.c new file mode 100644 index 00000000000..5a82f35da2e --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9261.c @@ -0,0 +1,289 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9261.c + * + * Copyright (C) 2005 SAN People + * + * 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. + * + */ + +#include + +#include +#include +#include +#include + +#include "generic.h" +#include "clock.h" + +static struct map_desc at91sam9261_io_desc[] __initdata = { + { + .virtual = AT91_VA_BASE_SYS, + .pfn = __phys_to_pfn(AT91_BASE_SYS), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_IO_VIRT_BASE - AT91SAM9261_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91SAM9261_SRAM_BASE), + .length = AT91SAM9261_SRAM_SIZE, + .type = MT_DEVICE, + }, +}; + +/* -------------------------------------------------------------------- + * Clocks + * -------------------------------------------------------------------- */ + +/* + * The peripheral clocks. + */ +static struct clk pioA_clk = { + .name = "pioA_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOA, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOB, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .pmc_mask = 1 << AT91SAM9261_ID_PIOC, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .pmc_mask = 1 << AT91SAM9261_ID_US2, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_MCI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk udc_clk = { + .name = "udc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UDP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .pmc_mask = 1 << AT91SAM9261_ID_TWI, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi0_clk = { + .name = "spi0_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI0, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk spi1_clk = { + .name = "spi1_clk", + .pmc_mask = 1 << AT91SAM9261_ID_SPI1, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .pmc_mask = 1 << AT91SAM9261_ID_UHP, + .type = CLK_TYPE_PERIPHERAL, +}; +static struct clk lcdc_clk = { + .name = "lcdc_clk", + .pmc_mask = 1 << AT91SAM9261_ID_LCDC, + .type = CLK_TYPE_PERIPHERAL, +}; + +static struct clk *periph_clocks[] __initdata = { + &pioA_clk, + &pioB_clk, + &pioC_clk, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi0_clk, + &spi1_clk, + // ssc 0 .. ssc2 + // tc0 .. tc2 + &ohci_clk, + &lcdc_clk, + // irq0 .. irq2 +}; + +/* + * The four programmable clocks. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .type = CLK_TYPE_PROGRAMMABLE, + .id = 3, +}; + +/* HClocks */ +static struct clk hck0 = { + .name = "hck0", + .pmc_mask = AT91_PMC_HCK0, + .type = CLK_TYPE_SYSTEM, + .id = 0, +}; +static struct clk hck1 = { + .name = "hck1", + .pmc_mask = AT91_PMC_HCK1, + .type = CLK_TYPE_SYSTEM, + .id = 1, +}; + +static void __init at91sam9261_register_clocks(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) + clk_register(periph_clocks[i]); + + clk_register(&pck0); + clk_register(&pck1); + clk_register(&pck2); + clk_register(&pck3); + + clk_register(&hck0); + clk_register(&hck1); +} + +/* -------------------------------------------------------------------- + * GPIO + * -------------------------------------------------------------------- */ + +static struct at91_gpio_bank at91sam9261_gpio[] = { + { + .id = AT91SAM9261_ID_PIOA, + .offset = AT91_PIOA, + .clock = &pioA_clk, + }, { + .id = AT91SAM9261_ID_PIOB, + .offset = AT91_PIOB, + .clock = &pioB_clk, + }, { + .id = AT91SAM9261_ID_PIOC, + .offset = AT91_PIOC, + .clock = &pioC_clk, + } +}; + +static void at91sam9261_reset(void) +{ +#warning "Implement CPU reset" +} + + +/* -------------------------------------------------------------------- + * AT91SAM9261 processor initialization + * -------------------------------------------------------------------- */ + +void __init at91sam9261_initialize(unsigned long main_clock) +{ + /* Map peripherals */ + iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc)); + + at91_arch_reset = at91sam9261_reset; + at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1) + | (1 << AT91SAM9261_ID_IRQ2); + + /* Init clock subsystem */ + at91_clock_init(main_clock); + + /* Register the processor-specific clocks */ + at91sam9261_register_clocks(); + + /* Register GPIO subsystem */ + at91_gpio_init(at91sam9261_gpio, 3); +} + +/* -------------------------------------------------------------------- + * Interrupt initialization + * -------------------------------------------------------------------- */ + +/* + * The default interrupt priority levels (0 = lowest, 7 = highest). + */ +static unsigned int at91sam9261_default_irq_priority[NR_AIC_IRQS] __initdata = { + 7, /* Advanced Interrupt Controller */ + 7, /* System Peripherals */ + 0, /* Parallel IO Controller A */ + 0, /* Parallel IO Controller B */ + 0, /* Parallel IO Controller C */ + 0, + 6, /* USART 0 */ + 6, /* USART 1 */ + 6, /* USART 2 */ + 0, /* Multimedia Card Interface */ + 4, /* USB Device Port */ + 0, /* Two-Wire Interface */ + 6, /* Serial Peripheral Interface 0 */ + 6, /* Serial Peripheral Interface 1 */ + 5, /* Serial Synchronous Controller 0 */ + 5, /* Serial Synchronous Controller 1 */ + 5, /* Serial Synchronous Controller 2 */ + 0, /* Timer Counter 0 */ + 0, /* Timer Counter 1 */ + 0, /* Timer Counter 2 */ + 3, /* USB Host port */ + 3, /* LCD Controller */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ + 0, /* Advanced Interrupt Controller */ +}; + +void __init at91sam9261_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +{ + if (!priority) + priority = at91sam9261_default_irq_priority; + + /* Initialize the AIC interrupt controller */ + at91_aic_init(priority); + + /* Enable GPIO interrupts */ + at91_gpio_irq_setup(); +} diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91rm9200/generic.h index fd98e353c5a..8c4d5a77d48 100644 --- a/arch/arm/mach-at91rm9200/generic.h +++ b/arch/arm/mach-at91rm9200/generic.h @@ -10,14 +10,19 @@ /* Processors */ extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); +extern void __init at91sam9260_initialize(unsigned long main_clock); +extern void __init at91sam9261_initialize(unsigned long main_clock); /* Interrupts */ extern void __init at91rm9200_init_interrupts(unsigned int priority[]); +extern void __init at91sam9260_init_interrupts(unsigned int priority[]); +extern void __init at91sam9261_init_interrupts(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; +extern struct sys_timer at91sam926x_timer; /* Clocks */ extern int __init at91_clock_init(unsigned long main_clock); -- cgit v1.2.3 From 55d8baee4a0b4709061104f7a56f53a310de76ac Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 17:16:43 +0100 Subject: [ARM] 3954/1: AT91: Update drivers for new headers This patch updates the drivers (and other files) which include the hardware headers. This fixes the breakage introduced in patches 3950/1 and 3951/1 (those patches were getting big). The AVR32 architecture uses the same serial driver and had its own copy of at91rm9200_pdc.h. Renamed it to at91_pdc.h Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200.c | 3 ++- arch/arm/mach-at91rm9200/at91rm9200_time.c | 2 ++ arch/arm/mach-at91rm9200/clock.c | 1 + arch/arm/mach-at91rm9200/gpio.c | 2 ++ arch/arm/mach-at91rm9200/pm.c | 2 ++ 5 files changed, 9 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0422593032f..0816a8d2e86 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -15,8 +15,9 @@ #include #include #include +#include +#include -#include #include "generic.h" #include "clock.h" diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91rm9200/at91rm9200_time.c index 07c9cea8961..8e9c049c8b7 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_time.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_time.c @@ -30,6 +30,8 @@ #include #include +#include + static unsigned long last_crtr; /* diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index a43b061a7c8..1e0000ceb34 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -28,6 +28,7 @@ #include #include +#include #include "clock.h" diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91rm9200/gpio.c index 7467d644f0a..e76422761db 100644 --- a/arch/arm/mach-at91rm9200/gpio.c +++ b/arch/arm/mach-at91rm9200/gpio.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include "generic.h" diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 5e3b6e306f1..5b775fac1c6 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include "generic.h" -- cgit v1.2.3 From 1a0ed732afdbd4b960a4b93f78fddc71b8076e61 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 09:04:47 +0100 Subject: [ARM] 3949/2: AT91: SAM9 timer driver Add support for the timer on the Atmel AT91SAM9261 and AT91SAM9260 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91sam926x_time.c | 114 ++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam926x_time.c (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 40e89bf459f..b8684ba60ce 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,8 +11,8 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o # AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o diff --git a/arch/arm/mach-at91rm9200/at91sam926x_time.c b/arch/arm/mach-at91rm9200/at91sam926x_time.c new file mode 100644 index 00000000000..99df5f6ee42 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam926x_time.c @@ -0,0 +1,114 @@ +/* + * linux/arch/arm/mach-at91rm9200/at91sam926x_time.c + * + * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France + * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + + +#define PIT_CPIV(x) ((x) & AT91_PIT_CPIV) +#define PIT_PICNT(x) (((x) & AT91_PIT_PICNT) >> 20) + +/* + * Returns number of microseconds since last timer interrupt. Note that interrupts + * will have been disabled by do_gettimeofday() + * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. + * 'tick' is usecs per jiffy (linux/timex.h). + */ +static unsigned long at91sam926x_gettimeoffset(void) +{ + unsigned long elapsed; + unsigned long t = at91_sys_read(AT91_PIT_PIIR); + + elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */ + + return (unsigned long)(elapsed * 1000000) / LATCH; +} + +/* + * IRQ handler for the timer. + */ +static irqreturn_t at91sam926x_timer_interrupt(int irq, void *dev_id) +{ + volatile long nr_ticks; + + if (at91_sys_read(AT91_PIT_SR) & AT91_PIT_PITS) { /* This is a shared interrupt */ + write_seqlock(&xtime_lock); + + /* Get number to ticks performed before interrupt and clear PIT interrupt */ + nr_ticks = PIT_PICNT(at91_sys_read(AT91_PIT_PIVR)); + do { + timer_tick(); + nr_ticks--; + } while (nr_ticks); + + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; + } else + return IRQ_NONE; /* not handled */ +} + +static struct irqaction at91sam926x_timer_irq = { + .name = "at91_tick", + .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER, + .handler = at91sam926x_timer_interrupt +}; + +void at91sam926x_timer_reset(void) +{ + /* Disable timer */ + at91_sys_write(AT91_PIT_MR, 0); + + /* Clear any pending interrupts */ + (void) at91_sys_read(AT91_PIT_PIVR); + + /* Set Period Interval timer and enable its interrupt */ + at91_sys_write(AT91_PIT_MR, (LATCH & AT91_PIT_PIV) | AT91_PIT_PITIEN | AT91_PIT_PITEN); +} + +/* + * Set up timer interrupt. + */ +void __init at91sam926x_timer_init(void) +{ + /* Initialize and enable the timer */ + at91sam926x_timer_reset(); + + /* Make IRQs happen for the system timer. */ + setup_irq(AT91_ID_SYS, &at91sam926x_timer_irq); +} + +#ifdef CONFIG_PM +static void at91sam926x_timer_suspend(void) +{ + /* Disable timer */ + at91_sys_write(AT91_PIT_MR, 0); +} +#else +#define at91sam926x_timer_suspend NULL +#endif + +struct sys_timer at91sam926x_timer = { + .init = at91sam926x_timer_init, + .offset = at91sam926x_gettimeoffset, + .suspend = at91sam926x_timer_suspend, + .resume = at91sam926x_timer_reset, +}; + -- cgit v1.2.3 From 86ad76bb2db7029343f681359c4b328fd8c36ae8 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 30 Nov 2006 16:45:01 +0100 Subject: [ARM] 3953/1: AT91: SAM9 platform devices This patch includes the pin initialization, resource definition and registration of the platform_devices for the SAM9260 and SAM9261 processors. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Makefile | 4 +- arch/arm/mach-at91rm9200/at91sam9260_devices.c | 866 +++++++++++++++++++++++++ arch/arm/mach-at91rm9200/at91sam9261_devices.c | 741 +++++++++++++++++++++ 3 files changed, 1609 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-at91rm9200/at91sam9260_devices.c create mode 100644 arch/arm/mach-at91rm9200/at91sam9261_devices.c (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index b8684ba60ce..6093c31e39a 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -11,8 +11,8 @@ obj-$(CONFIG_PM) += pm.o # CPU-specific support obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o +obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o +obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o # AT91RM9200 board-specific support obj-$(CONFIG_MACH_ONEARM) += board-1arm.o diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91rm9200/at91sam9260_devices.c new file mode 100644 index 00000000000..a6c596dc451 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9260_devices.c @@ -0,0 +1,866 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9260_devices.c + * + * Copyright (C) 2006 Atmel + * + * 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. + * + */ +#include +#include + +#include + +#include +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9260_UHP_BASE, + .end = AT91SAM9260_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UHP, + .end = AT91SAM9260_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_UDP, + .end = AT91SAM9260_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_UDP, + .end = AT91SAM9260_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally by USB device peripheral */ + + udc_data = *data; + platform_device_register(&at91_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * Ethernet + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) +static u64 eth_dmamask = 0xffffffffUL; +static struct eth_platform_data eth_data; + +static struct resource eth_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_EMAC, + .end = AT91SAM9260_BASE_EMAC + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_EMAC, + .end = AT91SAM9260_ID_EMAC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_eth_device = { + .name = "macb", + .id = -1, + .dev = { + .dma_mask = ð_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = ð_data, + }, + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), +}; + +void __init at91_add_device_eth(struct eth_platform_data *data) +{ + if (!data) + return; + + if (data->phy_irq_pin) { + at91_set_gpio_input(data->phy_irq_pin, 0); + at91_set_deglitch(data->phy_irq_pin, 1); + } + + /* Pins used for MII and RMII */ + at91_set_A_periph(AT91_PIN_PA19, 0); /* ETXCK_EREFCK */ + at91_set_A_periph(AT91_PIN_PA17, 0); /* ERXDV */ + at91_set_A_periph(AT91_PIN_PA14, 0); /* ERX0 */ + at91_set_A_periph(AT91_PIN_PA15, 0); /* ERX1 */ + at91_set_A_periph(AT91_PIN_PA18, 0); /* ERXER */ + at91_set_A_periph(AT91_PIN_PA16, 0); /* ETXEN */ + at91_set_A_periph(AT91_PIN_PA12, 0); /* ETX0 */ + at91_set_A_periph(AT91_PIN_PA13, 0); /* ETX1 */ + at91_set_A_periph(AT91_PIN_PA21, 0); /* EMDIO */ + at91_set_A_periph(AT91_PIN_PA20, 0); /* EMDC */ + + if (!data->is_rmii) { + at91_set_B_periph(AT91_PIN_PA28, 0); /* ECRS */ + at91_set_B_periph(AT91_PIN_PA29, 0); /* ECOL */ + at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */ + at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */ + at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */ + at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */ + at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */ + at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */ + } + + eth_data = *data; + platform_device_register(&at91sam9260_eth_device); +} +#else +void __init at91_add_device_eth(struct eth_platform_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_MCI, + .end = AT91SAM9260_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_MCI, + .end = AT91SAM9260_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_A_periph(AT91_PIN_PA8, 0); + + if (data->slot_b) { + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA3, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->wire4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } + } + + mmc_data = *data; + platform_device_register(&at91sam9260_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_8M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91sam9260_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + unsigned long csa, mode; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); + + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) + | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); + + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + nand_data = *data; + platform_device_register(&at91sam9260_nand_device); +} +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_TWI, + .end = AT91SAM9260_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_TWI, + .end = AT91SAM9260_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA23, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA23, 1); + + at91_set_A_periph(AT91_PIN_PA24, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA24, 1); + + platform_device_register(&at91sam9260_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI0, + .end = AT91SAM9260_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI0, + .end = AT91SAM9260_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PC11, AT91_PIN_PC16, AT91_PIN_PC17 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_SPI1, + .end = AT91SAM9260_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_SPI1, + .end = AT91SAM9260_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9260_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PC5, AT91_PIN_PC4, AT91_PIN_PC3 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */ + + at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk"); + platform_device_register(&at91sam9260_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB0, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB1, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* SPI1_SPCK */ + + at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk"); + platform_device_register(&at91sam9260_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91sam9260_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB14, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PB15, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US0, + .end = AT91SAM9260_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US0, + .end = AT91SAM9260_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB4, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PB5, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PB26, 0); /* RTS0 */ + at91_set_A_periph(AT91_PIN_PB27, 0); /* CTS0 */ + at91_set_A_periph(AT91_PIN_PB24, 0); /* DTR0 */ + at91_set_A_periph(AT91_PIN_PB22, 0); /* DSR0 */ + at91_set_A_periph(AT91_PIN_PB23, 0); /* DCD0 */ + at91_set_A_periph(AT91_PIN_PB25, 0); /* RI0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US1, + .end = AT91SAM9260_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US1, + .end = AT91SAM9260_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB6, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* RXD1 */ + at91_set_A_periph(AT91_PIN_PB28, 0); /* RTS1 */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* CTS1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US2, + .end = AT91SAM9260_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US2, + .end = AT91SAM9260_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB8, 1); /* TXD2 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* RXD2 */ +} + +static struct resource uart3_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US3, + .end = AT91SAM9260_BASE_US3 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US3, + .end = AT91SAM9260_ID_US3, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart3_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart3_device = { + .name = "atmel_usart", + .id = 4, + .dev = { + .platform_data = &uart3_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart3_resources, + .num_resources = ARRAY_SIZE(uart3_resources), +}; + +static inline void configure_usart3_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB10, 1); /* TXD3 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* RXD3 */ +} + +static struct resource uart4_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US4, + .end = AT91SAM9260_BASE_US4 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US4, + .end = AT91SAM9260_ID_US4, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart4_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart4_device = { + .name = "atmel_usart", + .id = 5, + .dev = { + .platform_data = &uart4_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart4_resources, + .num_resources = ARRAY_SIZE(uart4_resources), +}; + +static inline void configure_usart4_pins(void) +{ + at91_set_B_periph(AT91_PIN_PA31, 1); /* TXD4 */ + at91_set_B_periph(AT91_PIN_PA30, 0); /* RXD4 */ +} + +static struct resource uart5_resources[] = { + [0] = { + .start = AT91SAM9260_BASE_US5, + .end = AT91SAM9260_BASE_US5 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9260_ID_US5, + .end = AT91SAM9260_ID_US5, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart5_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9260_uart5_device = { + .name = "atmel_usart", + .id = 6, + .dev = { + .platform_data = &uart5_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart5_resources, + .num_resources = ARRAY_SIZE(uart5_resources), +}; + +static inline void configure_usart5_pins(void) +{ + at91_set_A_periph(AT91_PIN_PB12, 1); /* TXD5 */ + at91_set_A_periph(AT91_PIN_PB13, 0); /* RXD5 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91sam9260_uart0_device; + at91_clock_associate("usart0_clk", &at91sam9260_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91sam9260_uart1_device; + at91_clock_associate("usart1_clk", &at91sam9260_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91sam9260_uart2_device; + at91_clock_associate("usart2_clk", &at91sam9260_uart2_device.dev, "usart"); + break; + case 3: + configure_usart3_pins(); + at91_uarts[i] = &at91sam9260_uart3_device; + at91_clock_associate("usart3_clk", &at91sam9260_uart3_device.dev, "usart"); + break; + case 4: + configure_usart4_pins(); + at91_uarts[i] = &at91sam9260_uart4_device; + at91_clock_associate("usart4_clk", &at91sam9260_uart4_device.dev, "usart"); + break; + case 5: + configure_usart5_pins(); + at91_uarts[i] = &at91sam9260_uart5_device; + at91_clock_associate("usart5_clk", &at91sam9260_uart5_device.dev, "usart"); + break; + case 6: + configure_dbgu_pins(); + at91_uarts[i] = &at91sam9260_dbgu_device; + at91_clock_associate("mck", &at91sam9260_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + return 0; +} + +arch_initcall(at91_add_standard_devices); diff --git a/arch/arm/mach-at91rm9200/at91sam9261_devices.c b/arch/arm/mach-at91rm9200/at91sam9261_devices.c new file mode 100644 index 00000000000..ed1d79081b3 --- /dev/null +++ b/arch/arm/mach-at91rm9200/at91sam9261_devices.c @@ -0,0 +1,741 @@ +/* + * arch/arm/mach-at91rm9200/at91sam9261_devices.c + * + * Copyright (C) 2005 Thibaut VARENE + * Copyright (C) 2005 David Brownell + * + * 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. + * + */ +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "generic.h" + +#define SZ_512 0x00000200 +#define SZ_256 0x00000100 +#define SZ_16 0x00000010 + +/* -------------------------------------------------------------------- + * USB Host + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +static u64 ohci_dmamask = 0xffffffffUL; +static struct at91_usbh_data usbh_data; + +static struct resource usbh_resources[] = { + [0] = { + .start = AT91SAM9261_UHP_BASE, + .end = AT91SAM9261_UHP_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UHP, + .end = AT91SAM9261_ID_UHP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_usbh_device = { + .name = "at91_ohci", + .id = -1, + .dev = { + .dma_mask = &ohci_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &usbh_data, + }, + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), +}; + +void __init at91_add_device_usbh(struct at91_usbh_data *data) +{ + if (!data) + return; + + usbh_data = *data; + platform_device_register(&at91sam9261_usbh_device); +} +#else +void __init at91_add_device_usbh(struct at91_usbh_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * USB Device (Gadget) + * -------------------------------------------------------------------- */ + +#ifdef CONFIG_USB_GADGET_AT91 +static struct at91_udc_data udc_data; + +static struct resource udc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_UDP, + .end = AT91SAM9261_BASE_UDP + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_UDP, + .end = AT91SAM9261_ID_UDP, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_udc_device = { + .name = "at91_udc", + .id = -1, + .dev = { + .platform_data = &udc_data, + }, + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), +}; + +void __init at91_add_device_udc(struct at91_udc_data *data) +{ + unsigned long x; + + if (!data) + return; + + if (data->vbus_pin) { + at91_set_gpio_input(data->vbus_pin, 0); + at91_set_deglitch(data->vbus_pin, 1); + } + + /* Pullup pin is handled internally */ + x = at91_sys_read(AT91_MATRIX_USBPUCR); + at91_sys_write(AT91_MATRIX_USBPUCR, x | AT91_MATRIX_USBPUCR_PUON); + + udc_data = *data; + platform_device_register(&at91sam9261_udc_device); +} +#else +void __init at91_add_device_udc(struct at91_udc_data *data) {} +#endif + +/* -------------------------------------------------------------------- + * MMC / SD + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) +static u64 mmc_dmamask = 0xffffffffUL; +static struct at91_mmc_data mmc_data; + +static struct resource mmc_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_MCI, + .end = AT91SAM9261_BASE_MCI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_MCI, + .end = AT91SAM9261_ID_MCI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_mmc_device = { + .name = "at91_mci", + .id = -1, + .dev = { + .dma_mask = &mmc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &mmc_data, + }, + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), +}; + +void __init at91_add_device_mmc(struct at91_mmc_data *data) +{ + if (!data) + return; + + /* input/irq */ + if (data->det_pin) { + at91_set_gpio_input(data->det_pin, 1); + at91_set_deglitch(data->det_pin, 1); + } + if (data->wp_pin) + at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); + + /* CLK */ + at91_set_B_periph(AT91_PIN_PA2, 0); + + /* CMD */ + at91_set_B_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_B_periph(AT91_PIN_PA0, 1); + if (data->wire4) { + at91_set_B_periph(AT91_PIN_PA4, 1); + at91_set_B_periph(AT91_PIN_PA5, 1); + at91_set_B_periph(AT91_PIN_PA6, 1); + } + + mmc_data = *data; + platform_device_register(&at91sam9261_mmc_device); +} +#else +void __init at91_add_device_mmc(struct at91_mmc_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * NAND / SmartMedia + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) +static struct at91_nand_data nand_data; + +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { + { + .start = NAND_BASE, + .end = NAND_BASE + SZ_256M - 1, + .flags = IORESOURCE_MEM, + } +}; + +static struct platform_device at91_nand_device = { + .name = "at91_nand", + .id = -1, + .dev = { + .platform_data = &nand_data, + }, + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), +}; + +void __init at91_add_device_nand(struct at91_nand_data *data) +{ + unsigned long csa, mode; + + if (!data) + return; + + csa = at91_sys_read(AT91_MATRIX_EBICSA); + at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_CS3A_SMC); + + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) + | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0)); + + at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(2) | AT91_SMC_NCS_WRPULSE_(5) + | AT91_SMC_NRDPULSE_(2) | AT91_SMC_NCS_RDPULSE_(5)); + + at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(7) | AT91_SMC_NRDCYCLE_(7)); + + if (data->bus_width_16) + mode = AT91_SMC_DBW_16; + else + mode = AT91_SMC_DBW_8; + at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(1)); + + /* enable pin */ + if (data->enable_pin) + at91_set_gpio_output(data->enable_pin, 1); + + /* ready/busy pin */ + if (data->rdy_pin) + at91_set_gpio_input(data->rdy_pin, 1); + + /* card detect pin */ + if (data->det_pin) + at91_set_gpio_input(data->det_pin, 1); + + at91_set_A_periph(AT91_PIN_PC0, 0); /* NANDOE */ + at91_set_A_periph(AT91_PIN_PC1, 0); /* NANDWE */ + + nand_data = *data; + platform_device_register(&at91_nand_device); +} + +#else +void __init at91_add_device_nand(struct at91_nand_data *data) {} +#endif + + +/* -------------------------------------------------------------------- + * TWI (i2c) + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_TWI, + .end = AT91SAM9261_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_TWI, + .end = AT91SAM9261_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_twi_device = { + .name = "at91_i2c", + .id = -1, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), +}; + +void __init at91_add_device_i2c(void) +{ + /* pins used for TWI interface */ + at91_set_A_periph(AT91_PIN_PA7, 0); /* TWD */ + at91_set_multi_drive(AT91_PIN_PA7, 1); + + at91_set_A_periph(AT91_PIN_PA8, 0); /* TWCK */ + at91_set_multi_drive(AT91_PIN_PA8, 1); + + platform_device_register(&at91sam9261_twi_device); +} +#else +void __init at91_add_device_i2c(void) {} +#endif + + +/* -------------------------------------------------------------------- + * SPI + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) +static u64 spi_dmamask = 0xffffffffUL; + +static struct resource spi0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI0, + .end = AT91SAM9261_BASE_SPI0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI0, + .end = AT91SAM9261_ID_SPI0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi0_device = { + .name = "atmel_spi", + .id = 0, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi0_resources, + .num_resources = ARRAY_SIZE(spi0_resources), +}; + +static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; + +static struct resource spi1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_SPI1, + .end = AT91SAM9261_BASE_SPI1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_SPI1, + .end = AT91SAM9261_ID_SPI1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device at91sam9261_spi1_device = { + .name = "atmel_spi", + .id = 1, + .dev = { + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .resource = spi1_resources, + .num_resources = ARRAY_SIZE(spi1_resources), +}; + +static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB28, AT91_PIN_PA24, AT91_PIN_PA25, AT91_PIN_PA26 }; + +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) +{ + int i; + unsigned long cs_pin; + short enable_spi0 = 0; + short enable_spi1 = 0; + + /* Choose SPI chip-selects */ + for (i = 0; i < nr_devices; i++) { + if (devices[i].controller_data) + cs_pin = (unsigned long) devices[i].controller_data; + else if (devices[i].bus_num == 0) + cs_pin = spi0_standard_cs[devices[i].chip_select]; + else + cs_pin = spi1_standard_cs[devices[i].chip_select]; + + if (devices[i].bus_num == 0) + enable_spi0 = 1; + else + enable_spi1 = 1; + + /* enable chip-select pin */ + at91_set_gpio_output(cs_pin, 1); + + /* pass chip-select pin to driver */ + devices[i].controller_data = (void *) cs_pin; + } + + spi_register_board_info(devices, nr_devices); + + /* Configure SPI bus(es) */ + if (enable_spi0) { + at91_set_A_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */ + at91_set_A_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */ + at91_set_A_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */ + + at91_clock_associate("spi0_clk", &at91sam9261_spi0_device.dev, "spi_clk"); + platform_device_register(&at91sam9261_spi0_device); + } + if (enable_spi1) { + at91_set_A_periph(AT91_PIN_PB30, 0); /* SPI1_MISO */ + at91_set_A_periph(AT91_PIN_PB31, 0); /* SPI1_MOSI */ + at91_set_A_periph(AT91_PIN_PB29, 0); /* SPI1_SPCK */ + + at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk"); + platform_device_register(&at91sam9261_spi1_device); + } +} +#else +void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {} +#endif + + +/* -------------------------------------------------------------------- + * LCD Controller + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE) +static u64 lcdc_dmamask = 0xffffffffUL; +static struct at91fb_info lcdc_data; + +static struct resource lcdc_resources[] = { + [0] = { + .start = AT91SAM9261_LCDC_BASE, + .end = AT91SAM9261_LCDC_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_LCDC, + .end = AT91SAM9261_ID_LCDC, + .flags = IORESOURCE_IRQ, + }, +#if defined(CONFIG_FB_INTSRAM) + [2] = { + .start = AT91SAM9261_SRAM_BASE, + .end = AT91SAM9261_SRAM_BASE + AT91SAM9261_SRAM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +#endif +}; + +static struct platform_device at91_lcdc_device = { + .name = "at91-fb", + .id = 0, + .dev = { + .dma_mask = &lcdc_dmamask, + .coherent_dma_mask = 0xffffffff, + .platform_data = &lcdc_data, + }, + .resource = lcdc_resources, + .num_resources = ARRAY_SIZE(lcdc_resources), +}; + +void __init at91_add_device_lcdc(struct at91fb_info *data) +{ + if (!data) { + return; + } + + at91_set_A_periph(AT91_PIN_PB1, 0); /* LCDHSYNC */ + at91_set_A_periph(AT91_PIN_PB2, 0); /* LCDDOTCK */ + at91_set_A_periph(AT91_PIN_PB3, 0); /* LCDDEN */ + at91_set_A_periph(AT91_PIN_PB4, 0); /* LCDCC */ + at91_set_A_periph(AT91_PIN_PB7, 0); /* LCDD2 */ + at91_set_A_periph(AT91_PIN_PB8, 0); /* LCDD3 */ + at91_set_A_periph(AT91_PIN_PB9, 0); /* LCDD4 */ + at91_set_A_periph(AT91_PIN_PB10, 0); /* LCDD5 */ + at91_set_A_periph(AT91_PIN_PB11, 0); /* LCDD6 */ + at91_set_A_periph(AT91_PIN_PB12, 0); /* LCDD7 */ + at91_set_A_periph(AT91_PIN_PB15, 0); /* LCDD10 */ + at91_set_A_periph(AT91_PIN_PB16, 0); /* LCDD11 */ + at91_set_A_periph(AT91_PIN_PB17, 0); /* LCDD12 */ + at91_set_A_periph(AT91_PIN_PB18, 0); /* LCDD13 */ + at91_set_A_periph(AT91_PIN_PB19, 0); /* LCDD14 */ + at91_set_A_periph(AT91_PIN_PB20, 0); /* LCDD15 */ + at91_set_B_periph(AT91_PIN_PB23, 0); /* LCDD18 */ + at91_set_B_periph(AT91_PIN_PB24, 0); /* LCDD19 */ + at91_set_B_periph(AT91_PIN_PB25, 0); /* LCDD20 */ + at91_set_B_periph(AT91_PIN_PB26, 0); /* LCDD21 */ + at91_set_B_periph(AT91_PIN_PB27, 0); /* LCDD22 */ + at91_set_B_periph(AT91_PIN_PB28, 0); /* LCDD23 */ + + lcdc_data = *data; + platform_device_register(&at91_lcdc_device); +} +#else +void __init at91_add_device_lcdc(struct at91fb_info *data) {} +#endif + + +/* -------------------------------------------------------------------- + * LEDs + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_LEDS) +u8 at91_leds_cpu; +u8 at91_leds_timer; + +void __init at91_init_leds(u8 cpu_led, u8 timer_led) +{ + at91_leds_cpu = cpu_led; + at91_leds_timer = timer_led; +} +#else +void __init at91_init_leds(u8 cpu_led, u8 timer_led) {} +#endif + + +/* -------------------------------------------------------------------- + * UART + * -------------------------------------------------------------------- */ + +#if defined(CONFIG_SERIAL_ATMEL) +static struct resource dbgu_resources[] = { + [0] = { + .start = AT91_VA_BASE_SYS + AT91_DBGU, + .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91_ID_SYS, + .end = AT91_ID_SYS, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data dbgu_data = { + .use_dma_tx = 0, + .use_dma_rx = 0, /* DBGU not capable of receive DMA */ + .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU), +}; + +static struct platform_device at91sam9261_dbgu_device = { + .name = "atmel_usart", + .id = 0, + .dev = { + .platform_data = &dbgu_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = dbgu_resources, + .num_resources = ARRAY_SIZE(dbgu_resources), +}; + +static inline void configure_dbgu_pins(void) +{ + at91_set_A_periph(AT91_PIN_PA9, 0); /* DRXD */ + at91_set_A_periph(AT91_PIN_PA10, 1); /* DTXD */ +} + +static struct resource uart0_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US0, + .end = AT91SAM9261_BASE_US0 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US0, + .end = AT91SAM9261_ID_US0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart0_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart0_device = { + .name = "atmel_usart", + .id = 1, + .dev = { + .platform_data = &uart0_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart0_resources, + .num_resources = ARRAY_SIZE(uart0_resources), +}; + +static inline void configure_usart0_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC8, 1); /* TXD0 */ + at91_set_A_periph(AT91_PIN_PC9, 0); /* RXD0 */ + at91_set_A_periph(AT91_PIN_PC10, 0); /* RTS0 */ + at91_set_A_periph(AT91_PIN_PC11, 0); /* CTS0 */ +} + +static struct resource uart1_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US1, + .end = AT91SAM9261_BASE_US1 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US1, + .end = AT91SAM9261_ID_US1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart1_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart1_device = { + .name = "atmel_usart", + .id = 2, + .dev = { + .platform_data = &uart1_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart1_resources, + .num_resources = ARRAY_SIZE(uart1_resources), +}; + +static inline void configure_usart1_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC12, 1); /* TXD1 */ + at91_set_A_periph(AT91_PIN_PC13, 0); /* RXD1 */ +} + +static struct resource uart2_resources[] = { + [0] = { + .start = AT91SAM9261_BASE_US2, + .end = AT91SAM9261_BASE_US2 + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91SAM9261_ID_US2, + .end = AT91SAM9261_ID_US2, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct atmel_uart_data uart2_data = { + .use_dma_tx = 1, + .use_dma_rx = 1, +}; + +static struct platform_device at91sam9261_uart2_device = { + .name = "atmel_usart", + .id = 3, + .dev = { + .platform_data = &uart2_data, + .coherent_dma_mask = 0xffffffff, + }, + .resource = uart2_resources, + .num_resources = ARRAY_SIZE(uart2_resources), +}; + +static inline void configure_usart2_pins(void) +{ + at91_set_A_periph(AT91_PIN_PC15, 0); /* RXD2 */ + at91_set_A_periph(AT91_PIN_PC14, 1); /* TXD2 */ +} + +struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */ +struct platform_device *atmel_default_console_device; /* the serial console device */ + +void __init at91_init_serial(struct at91_uart_config *config) +{ + int i; + + /* Fill in list of supported UARTs */ + for (i = 0; i < config->nr_tty; i++) { + switch (config->tty_map[i]) { + case 0: + configure_usart0_pins(); + at91_uarts[i] = &at91sam9261_uart0_device; + at91_clock_associate("usart0_clk", &at91sam9261_uart0_device.dev, "usart"); + break; + case 1: + configure_usart1_pins(); + at91_uarts[i] = &at91sam9261_uart1_device; + at91_clock_associate("usart1_clk", &at91sam9261_uart1_device.dev, "usart"); + break; + case 2: + configure_usart2_pins(); + at91_uarts[i] = &at91sam9261_uart2_device; + at91_clock_associate("usart2_clk", &at91sam9261_uart2_device.dev, "usart"); + break; + case 3: + configure_dbgu_pins(); + at91_uarts[i] = &at91sam9261_dbgu_device; + at91_clock_associate("mck", &at91sam9261_dbgu_device.dev, "usart"); + break; + default: + continue; + } + at91_uarts[i]->id = i; /* update ID number to mapped ID */ + } + + /* Set serial console device */ + if (config->console_tty < ATMEL_MAX_UART) + atmel_default_console_device = at91_uarts[config->console_tty]; + if (!atmel_default_console_device) + printk(KERN_INFO "AT91: No default serial console defined.\n"); +} + +void __init at91_add_device_serial(void) +{ + int i; + + for (i = 0; i < ATMEL_MAX_UART; i++) { + if (at91_uarts[i]) + platform_device_register(at91_uarts[i]); + } +} +#else +void __init at91_init_serial(struct at91_uart_config *config) {} +void __init at91_add_device_serial(void) {} +#endif + + +/* -------------------------------------------------------------------- */ + +/* + * These devices are always present and don't need any board-specific + * setup. + */ +static int __init at91_add_standard_devices(void) +{ + return 0; +} + +arch_initcall(at91_add_standard_devices); -- cgit v1.2.3 From d100f25956e8626afeafbb38558ca8c58df1cb6b Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:15:04 +0100 Subject: [ARM] 3955/1: AT91: Clear timer interrupt when resuming Attached is a patch for at91rm9200_time.c which removes the 'BUG: soft lockup detected on CPU#0!' message when exiting suspended states. Patch from Savin Zlobec Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200_time.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91rm9200/at91rm9200_time.c index 8e9c049c8b7..b999e192a7e 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_time.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_time.c @@ -101,6 +101,9 @@ void at91rm9200_timer_reset(void) /* Set Period Interval timer */ at91_sys_write(AT91_ST_PIMR, LATCH); + /* Clear any pending interrupts */ + (void) at91_sys_read(AT91_ST_SR); + /* Enable Period Interval Timer interrupt */ at91_sys_write(AT91_ST_IER, AT91_ST_PITS); } -- cgit v1.2.3 From 330d741b0632960e7853a2cb3b2899e94e696f12 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:31:29 +0100 Subject: [ARM] 3956/1: AT91: Carmeva board update This patch updates the Carmeva board support: * Specify the MMC Write-protect and Detection pins. * Add configuration of SPI devices. Patch from Peer Georgi. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/carmeva_defconfig | 2 +- arch/arm/mach-at91rm9200/board-carmeva.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/carmeva_defconfig b/arch/arm/configs/carmeva_defconfig index d24ae8777c3..d392833b31f 100644 --- a/arch/arm/configs/carmeva_defconfig +++ b/arch/arm/configs/carmeva_defconfig @@ -474,7 +474,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -# CONFIG_AT91_RTC is not set +# CONFIG_AT91RM9200_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 98208740e7c..5cd68e6001e 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c @@ -65,7 +65,6 @@ static void __init carmeva_init_irq(void) at91rm9200_init_interrupts(NULL); } - static struct at91_eth_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -91,6 +90,31 @@ static struct at91_udc_data __initdata carmeva_udc_data = { static struct at91_mmc_data __initdata carmeva_mmc_data = { .is_b = 0, .wire4 = 1, + .det_pin = AT91_PIN_PB10, + .wp_pin = AT91_PIN_PC14, +}; + +static struct spi_board_info carmeva_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + }, + { /* User accessable spi - cs1 (250KHz) */ + .modalias = "spi-cs1", + .chip_select = 1, + .max_speed_hz = 250 * 1000, + }, + { /* User accessable spi - cs2 (1MHz) */ + .modalias = "spi-cs2", + .chip_select = 2, + .max_speed_hz = 1 * 1000 * 1000, + }, + { /* User accessable spi - cs3 (10MHz) */ + .modalias = "spi-cs3", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + }, }; static void __init carmeva_board_init(void) @@ -105,10 +129,10 @@ static void __init carmeva_board_init(void) at91_add_device_udc(&carmeva_udc_data); /* I2C */ at91_add_device_i2c(); + /* SPI */ + at91_add_device_spi(carmeva_spi_devices, ARRAY_SIZE(carmeva_spi_devices)); /* Compact Flash */ // at91_add_device_cf(&carmeva_cf_data); - /* SPI */ -// at91_add_device_spi(NULL, 0); /* MMC */ at91_add_device_mmc(&carmeva_mmc_data); } -- cgit v1.2.3 From fcc63716a5ee93ec3d1043890e38753d53313b80 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 10:55:15 +0100 Subject: [ARM] 3957/1: AT91: Physically mapped flash on DK and EK boards This patch converts the old CONFIG_MTD_PHYSMAP_ options to the new physmap API by creating a physmap platform device for the NOR flash found on the Atmel AT91RM9200-DK and AT91RM9200-EK boards. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/at91rm9200dk_defconfig | 10 ++++++---- arch/arm/configs/at91rm9200ek_defconfig | 10 ++++++---- arch/arm/mach-at91rm9200/board-dk.c | 28 ++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/board-ek.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index b43041476e0..1d79360f3eb 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig @@ -357,9 +357,9 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x10000000 -CONFIG_MTD_PHYSMAP_LEN=0x200000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_START=0 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 # CONFIG_MTD_ARM_INTEGRATOR is not set # CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_PLATRAM is not set @@ -585,7 +585,9 @@ CONFIG_AT91RM9200_WATCHDOG=y # CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_AT91_RTC=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AT91RM9200=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index d96fc8386e2..16120bca3cb 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig @@ -348,9 +348,9 @@ CONFIG_MTD_CFI_UTIL=y # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x10000000 -CONFIG_MTD_PHYSMAP_LEN=0x800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_START=0 +CONFIG_MTD_PHYSMAP_LEN=0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 # CONFIG_MTD_ARM_INTEGRATOR is not set # CONFIG_MTD_IMPA7 is not set # CONFIG_MTD_PLATRAM is not set @@ -566,7 +566,9 @@ CONFIG_AT91RM9200_WATCHDOG=y # CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -CONFIG_AT91_RTC=y +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AT91RM9200=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index c699f3984d4..314e1f769ea 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include "generic.h" @@ -145,6 +147,30 @@ static struct at91_nand_data __initdata dk_nand_data = { .partition_info = nand_partitions, }; +#define DK_FLASH_BASE AT91_CHIPSELECT_0 +#define DK_FLASH_SIZE 0x200000 + +static struct physmap_flash_data dk_flash_data = { + .width = 2, +}; + +static struct resource dk_flash_resource = { + .start = DK_FLASH_BASE, + .end = DK_FLASH_BASE + DK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device dk_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &dk_flash_data, + }, + .resource = &dk_flash_resource, + .num_resources = 1, +}; + + static void __init dk_board_init(void) { /* Serial */ @@ -172,6 +198,8 @@ static void __init dk_board_init(void) #endif /* NAND */ at91_add_device_nand(&dk_nand_data); + /* NOR Flash */ + platform_device_register(&dk_flash); /* VGA */ // dk_add_device_video(); } diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 830eb793217..9fcfa066635 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include #include +#include #include "generic.h" @@ -107,6 +109,30 @@ static struct spi_board_info ek_spi_devices[] = { #endif }; +#define EK_FLASH_BASE AT91_CHIPSELECT_0 +#define EK_FLASH_SIZE 0x200000 + +static struct physmap_flash_data ek_flash_data = { + .width = 2, +}; + +static struct resource ek_flash_resource = { + .start = EK_FLASH_BASE, + .end = EK_FLASH_BASE + EK_FLASH_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device ek_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &ek_flash_data, + }, + .resource = &ek_flash_resource, + .num_resources = 1, +}; + + static void __init ek_board_init(void) { /* Serial */ @@ -130,6 +156,8 @@ static void __init ek_board_init(void) at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ at91_add_device_mmc(&ek_mmc_data); #endif + /* NOR Flash */ + platform_device_register(&ek_flash); /* VGA */ // ek_add_device_video(); } -- cgit v1.2.3 From d481f86449ccd66314b700c78b3a79168df80d02 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 11:27:31 +0100 Subject: [ARM] 3959/1: AT91: Support for SAM9 USB and HCK clocks The bits used to select the USB clocks are different on the SAM9's. Add support for the HCK clocks on the AT91SAM9261. Patch from Patrice Vilchez & Nicolas Ferre Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/clock.c | 26 ++++++++++++++++++++++---- arch/arm/mach-at91rm9200/clock.h | 1 + arch/arm/mach-at91rm9200/pm.c | 13 ++++++++++--- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91rm9200/clock.c index 1e0000ceb34..4dee21fefe5 100644 --- a/arch/arm/mach-at91rm9200/clock.c +++ b/arch/arm/mach-at91rm9200/clock.c @@ -29,6 +29,7 @@ #include #include +#include #include "clock.h" @@ -42,6 +43,7 @@ #define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) #define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) #define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) +#define clk_is_sys(x) ((x)->type & CLK_TYPE_SYSTEM) static LIST_HEAD(clocks); @@ -115,13 +117,11 @@ static void pmc_sys_mode(struct clk *clk, int is_on) static struct clk udpck = { .name = "udpck", .parent = &pllb, - .pmc_mask = AT91_PMC_UDP, .mode = pmc_sys_mode, }; static struct clk uhpck = { .name = "uhpck", .parent = &pllb, - .pmc_mask = AT91_PMC_UHP, .mode = pmc_sys_mode, }; @@ -435,6 +435,12 @@ int __init clk_register(struct clk *clk) clk->mode = pmc_periph_mode; list_add_tail(&clk->node, &clocks); } + else if (clk_is_sys(clk)) { + clk->parent = &mck; + clk->mode = pmc_sys_mode; + + list_add_tail(&clk->node, &clocks); + } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS else if (clk_is_programmable(clk)) { clk->mode = pmc_sys_mode; @@ -587,9 +593,21 @@ int __init at91_clock_init(unsigned long main_clock) */ at91_pllb_usb_init = at91_pll_calc(main_clock, 48000000 * 2) | AT91_PMC_USB96M; pllb.rate_hz = at91_pll_rate(&pllb, main_clock, at91_pllb_usb_init); - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_UHP | AT91_PMC_UDP); + if (cpu_is_at91rm9200()) { + uhpck.pmc_mask = AT91RM9200_PMC_UHP; + udpck.pmc_mask = AT91RM9200_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP); + at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); + } else if (cpu_is_at91sam9260()) { + uhpck.pmc_mask = AT91SAM926x_PMC_UHP; + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP); + } else if (cpu_is_at91sam9261()) { + uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0); + udpck.pmc_mask = AT91SAM926x_PMC_UDP; + at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP); + } at91_sys_write(AT91_CKGR_PLLBR, 0); - at91_sys_write(AT91_PMC_SCER, AT91_PMC_MCKUDP); udpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); uhpck.rate_hz = at91_usb_rate(&pllb, pllb.rate_hz, at91_pllb_usb_init); diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91rm9200/clock.h index 0592e662ab3..b5c7a2eb2d1 100644 --- a/arch/arm/mach-at91rm9200/clock.h +++ b/arch/arm/mach-at91rm9200/clock.h @@ -10,6 +10,7 @@ #define CLK_TYPE_PLL 0x2 #define CLK_TYPE_PROGRAMMABLE 0x4 #define CLK_TYPE_PERIPHERAL 0x8 +#define CLK_TYPE_SYSTEM 0x10 struct clk { diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91rm9200/pm.c index 5b775fac1c6..67aa5572a3e 100644 --- a/arch/arm/mach-at91rm9200/pm.c +++ b/arch/arm/mach-at91rm9200/pm.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "generic.h" @@ -70,9 +71,15 @@ static int at91_pm_verify_clocks(void) scsr = at91_sys_read(AT91_PMC_SCSR); /* USB must not be using PLLB */ - if ((scsr & (AT91_PMC_UHP | AT91_PMC_UDP)) != 0) { - pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); - return 0; + if (cpu_is_at91rm9200()) { + if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { + pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); + return 0; + } + } else if (cpu_is_at91sam9260()) { +#warning "Check SAM9260 USB clocks" + } else if (cpu_is_at91sam9261()) { +#warning "Check SAM9261 USB clocks" } #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS -- cgit v1.2.3 From 05043d08045271eb5655308371dd285a852ef855 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 11:51:19 +0100 Subject: [ARM] 3960/1: AT91: Final SAM9 intergration patches. This patch includes a number of small changes for integrating the AT91SAM9261 and AT91SAM0260 support. * Can only select support for one AT91 processor at a time. * Remove most of the remaining static memory mapping for the AT91RM9200. * Reserve 1Mb of memory below the IO for mapping the internal SRAM and any custom board-specific devices (ie, FPGA). * The SAM9260 has more serial ports, so increase the maximum to 7. * Define the standard chipselect addresses, and define other addresses relative to those. * CLOCK_TICK_RATE is different on the SAM926x's. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/Kconfig | 6 ++++-- arch/arm/mach-at91rm9200/Makefile | 2 +- arch/arm/mach-at91rm9200/at91rm9200.c | 22 +--------------------- 3 files changed, 6 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 2f85e8693b1..8d443264789 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -2,7 +2,8 @@ if ARCH_AT91 menu "Atmel AT91 System-on-Chip" -comment "Atmel AT91 Processors" +choice + prompt "Atmel AT91 Processor" config ARCH_AT91RM9200 bool "AT91RM9200" @@ -13,6 +14,8 @@ config ARCH_AT91SAM9260 config ARCH_AT91SAM9261 bool "AT91SAM9261" +endchoice + # ---------------------------------------------------------- if ARCH_AT91RM9200 @@ -33,7 +36,6 @@ config ARCH_AT91RM9200DK Select this if you are using Atmel's AT91RM9200-DK Development board. (Discontinued) - config MACH_AT91RM9200EK bool "Atmel AT91RM9200-EK Evaluation Kit" depends on ARCH_AT91RM9200 diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 6093c31e39a..564ad6e4524 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -10,7 +10,7 @@ obj- := obj-$(CONFIG_PM) += pm.o # CPU-specific support -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.c +obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91rm9200/at91rm9200.c index 0816a8d2e86..a92e9a495b0 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/arch/arm/mach-at91rm9200/at91rm9200.c @@ -27,33 +27,13 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { .pfn = __phys_to_pfn(AT91_BASE_SYS), .length = SZ_4K, .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_SPI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), - .length = SZ_16K, - .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_EMAC, .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, }, { - .virtual = AT91_VA_BASE_TWI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_MCI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_UDP, - .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_SRAM_VIRT_BASE, + .virtual = AT91_IO_VIRT_BASE - AT91RM9200_SRAM_SIZE, .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), .length = AT91RM9200_SRAM_SIZE, .type = MT_DEVICE, -- cgit v1.2.3 From 5283304bdcb4af47c46280ac21100d037d31fcf0 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 1 Dec 2006 15:15:55 +0100 Subject: [ARM] 3964/1: ep93xx: add ads sphere support Add initial board support for the ADS Sphere board. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/configs/ep93xx_defconfig | 1 + arch/arm/mach-ep93xx/Kconfig | 6 +++ arch/arm/mach-ep93xx/Makefile | 1 + arch/arm/mach-ep93xx/adssphere.c | 91 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 arch/arm/mach-ep93xx/adssphere.c (limited to 'arch') diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 3b4802a849e..2c673446012 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig @@ -125,6 +125,7 @@ CONFIG_CRUNCH=y # # EP93xx Platforms # +CONFIG_MACH_ADSSPHERE=y CONFIG_MACH_EDB9302=y CONFIG_MACH_EDB9312=y CONFIG_MACH_EDB9315=y diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index e346b03cd92..fcc5e2500dc 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -9,6 +9,12 @@ config CRUNCH comment "EP93xx Platforms" +config MACH_ADSSPHERE + bool "Support ADS Sphere" + help + Say 'Y' here if you want your kernel to support the ADS + Sphere board. + config MACH_EDB9302 bool "Support Cirrus Logic EDB9302" help diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index c2eb18b530c..bd09cddbc52 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -6,6 +6,7 @@ obj-m := obj-n := obj- := +obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_EDB9302) += edb9302.o obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c new file mode 100644 index 00000000000..ac5d5818eb7 --- /dev/null +++ b/arch/arm/mach-ep93xx/adssphere.c @@ -0,0 +1,91 @@ +/* + * arch/arm/mach-ep93xx/adssphere.c + * ADS Sphere support. + * + * Copyright (C) 2006 Lennert Buytenhek + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct physmap_flash_data adssphere_flash_data = { + .width = 4, +}; + +static struct resource adssphere_flash_resource = { + .start = 0x60000000, + .end = 0x61ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device adssphere_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &adssphere_flash_data, + }, + .num_resources = 1, + .resource = &adssphere_flash_resource, +}; + +static struct ep93xx_eth_data adssphere_eth_data = { + .phy_id = 1, +}; + +static struct resource adssphere_eth_resource[] = { + { + .start = EP93XX_ETHERNET_PHYS_BASE, + .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_EP93XX_ETHERNET, + .end = IRQ_EP93XX_ETHERNET, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device adssphere_eth_device = { + .name = "ep93xx-eth", + .id = -1, + .dev = { + .platform_data = &adssphere_eth_data, + }, + .num_resources = 2, + .resource = adssphere_eth_resource, +}; + +static void __init adssphere_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&adssphere_flash); + + memcpy(adssphere_eth_data.dev_addr, + (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); + platform_device_register(&adssphere_eth_device); +} + +MACHINE_START(ADSSPHERE, "ADS Sphere board") + /* Maintainer: Lennert Buytenhek */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = adssphere_init_machine, +MACHINE_END -- cgit v1.2.3 From 2024c39dbba4d036f0b16daf530ad5f4416fb344 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 1 Dec 2006 16:02:40 +0100 Subject: [ARM] 3965/1: ixp2000: fix handling of pci master aborts The master abort check in ixp2000_pci_read_config() recently started failing due to the compiler optimising out the read access following the clearing of pci_master_aborts. Mark pci_master_aborts volatile to force the compiler to reload it on every use. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-ixp2000/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index d4bf1e1c003..5a09a90c08f 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -32,7 +32,7 @@ #include -static int pci_master_aborts = 0; +static volatile int pci_master_aborts = 0; static int clear_master_aborts(void); -- cgit v1.2.3 From b85a8914033d81077e8276df1956bf3307bb31bd Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:37:56 +0100 Subject: [ARM] 3962/1: AT91: Support for Atmel AT91SAM9260-EK board This patch adds support for the Atmel AT91SAM9260-EK board. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/at91sam9260ek_defconfig | 950 +++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/Makefile | 1 + arch/arm/mach-at91rm9200/board-sam9260ek.c | 201 ++++++ 3 files changed, 1152 insertions(+) create mode 100644 arch/arm/configs/at91sam9260ek_defconfig create mode 100644 arch/arm/mach-at91rm9200/board-sam9260ek.c (limited to 'arch') diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig new file mode 100644 index 00000000000..79049206dfa --- /dev/null +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -0,0 +1,950 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc6 +# Fri Nov 17 18:42:21 2006 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +CONFIG_ARCH_AT91SAM9260=y +# CONFIG_ARCH_AT91SAM9261 is not set + +# +# AT91SAM9260 Board Type +# +CONFIG_MACH_AT91SAM9260EK=y + +# +# AT91 Board Options +# +# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set + +# +# AT91 Feature Selections +# +# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +# CONFIG_NETDEVICES is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_ETH is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index 564ad6e4524..cd83c9fb3c7 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o obj-$(CONFIG_MACH_KAFA) += board-kafa.o # AT91SAM9260 board-specific support +obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o # AT91SAM9261 board-specific support diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91rm9200/board-sam9260ek.c new file mode 100644 index 00000000000..ffca9bdec37 --- /dev/null +++ b/arch/arm/mach-at91rm9200/board-sam9260ek.c @@ -0,0 +1,201 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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 +#include + +#include +#include +#include + +#include "generic.h" + + +/* + * Serial port configuration. + * 0 .. 5 = USART0 .. USART5 + * 6 = DBGU + */ +static struct at91_uart_config __initdata ek_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 3, + .tty_map = { 6, 0, 1, -1, -1, -1, -1 } /* ttyS0, ..., ttyS6 */ +}; + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9260_initialize(18432000); + + /* Setup the serial ports and console */ + at91_init_serial(&ek_uart_config); +} + +static void __init ek_init_irq(void) +{ + at91sam9260_init_interrupts(NULL); +} + + +/* + * USB Host port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + +/* + * USB Device port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PC5, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * SPI devices. + */ +static struct spi_board_info ek_spi_devices[] = { +#if !defined(CONFIG_MMC_AT91) + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 1, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#endif +#endif +#if defined(CONFIG_SND_AT73C213) + { /* AT73C213 DAC */ + .modalias = "snd_at73c213", + .chip_select = 0, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 1, + }, +#endif +}; + + +/* + * MACB Ethernet device + */ +static struct __initdata eth_platform_data ek_macb_data = { + .is_rmii = 1, +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = 256 * 1024, + }, + { + .name = "Partition 2", + .offset = 256 * 1024, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 21, + .cle = 22, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC13, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .slot_b = 1, + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* Ethernet */ + at91_add_device_eth(&ek_macb_data); + /* MMC */ + at91_add_device_mmc(&ek_mmc_data); +} + +MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END -- cgit v1.2.3 From 022cbd7376fcdf030fe821636f1c910c45a9356a Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:38:59 +0100 Subject: [ARM] 3961/2: AT91: Support for Atmel AT91SAM9261-EK board This patch adds support for the Atmel AT91SAM9261-EK board. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/configs/at91sam9261ek_defconfig | 1106 ++++++++++++++++++++++++++++ arch/arm/mach-at91rm9200/Makefile | 1 + arch/arm/mach-at91rm9200/board-sam9261ek.c | 259 +++++++ 3 files changed, 1366 insertions(+) create mode 100644 arch/arm/configs/at91sam9261ek_defconfig create mode 100644 arch/arm/mach-at91rm9200/board-sam9261ek.c (limited to 'arch') diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig new file mode 100644 index 00000000000..784ad7c0186 --- /dev/null +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -0,0 +1,1106 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc6 +# Fri Nov 17 18:00:38 2006 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +CONFIG_ARCH_AT91=y +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# Atmel AT91 System-on-Chip +# +# CONFIG_ARCH_AT91RM9200 is not set +# CONFIG_ARCH_AT91SAM9260 is not set +CONFIG_ARCH_AT91SAM9261=y + +# +# AT91SAM9261 Board Type +# +CONFIG_MACH_AT91SAM9261EK=y + +# +# AT91 Board Options +# +# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set + +# +# AT91 Feature Selections +# +# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_ARM926T=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_COPY_V4WB=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set + +# +# Bus support +# + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_LEDS is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +# CONFIG_MTD_CFI is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_IDS=y +# CONFIG_MTD_NAND_DISKONCHIP is not set +CONFIG_MTD_NAND_AT91=y +# CONFIG_MTD_NAND_NANDSIM is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_SMC91X is not set +CONFIG_DM9000=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +CONFIG_I2C_AT91=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_PCA is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_ARCH_HAS_EHCI is not set +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +CONFIG_USB_STORAGE_DEBUG=y +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_NET2280 is not set +# CONFIG_USB_GADGET_PXA2XX is not set +# CONFIG_USB_GADGET_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +# CONFIG_USB_GADGET_OMAP is not set +CONFIG_USB_GADGET_AT91=y +CONFIG_USB_AT91=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_DUALSPEED is not set +CONFIG_USB_ZERO=m +# CONFIG_USB_ETH is not set +CONFIG_USB_GADGETFS=m +CONFIG_USB_FILE_STORAGE=m +# CONFIG_USB_FILE_STORAGE_TEST is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_MIDI_GADGET is not set + +# +# MMC/SD Card support +# +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_AT91=m +# CONFIG_MMC_TIFM_SD is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=y +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FRAME_POINTER=y +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_WAITQ is not set +# CONFIG_DEBUG_ERRORS is not set +CONFIG_DEBUG_LL=y +# CONFIG_DEBUG_ICEDCC is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_PLIST=y diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91rm9200/Makefile index cd83c9fb3c7..cf777007847 100644 --- a/arch/arm/mach-at91rm9200/Makefile +++ b/arch/arm/mach-at91rm9200/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_MACH_KAFA) += board-kafa.o obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o # AT91SAM9261 board-specific support +obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o # LEDs support led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o diff --git a/arch/arm/mach-at91rm9200/board-sam9261ek.c b/arch/arm/mach-at91rm9200/board-sam9261ek.c new file mode 100644 index 00000000000..30b490d8886 --- /dev/null +++ b/arch/arm/mach-at91rm9200/board-sam9261ek.c @@ -0,0 +1,259 @@ +/* + * linux/arch/arm/mach-at91rm9200/board-ek.c + * + * Copyright (C) 2005 SAN People + * Copyright (C) 2006 Atmel + * + * 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 +#include +#include + +#include +#include +#include + +#include "generic.h" + + +/* + * Serial port configuration. + * 0 .. 2 = USART0 .. USART2 + * 3 = DBGU + */ +static struct at91_uart_config __initdata ek_uart_config = { + .console_tty = 0, /* ttyS0 */ + .nr_tty = 1, + .tty_map = { 3, -1, -1, -1 } /* ttyS0, ..., ttyS3 */ +}; + +static void __init ek_map_io(void) +{ + /* Initialize processor: 18.432 MHz crystal */ + at91sam9261_initialize(18432000); + + /* Setup the serial ports and console */ + at91_init_serial(&ek_uart_config); +} + +static void __init ek_init_irq(void) +{ + at91sam9261_init_interrupts(NULL); +} + + +/* + * DM9000 ethernet device + */ +#if defined(CONFIG_DM9000) +static struct resource at91sam9261_dm9000_resource[] = { + [0] = { + .start = AT91_CHIPSELECT_2, + .end = AT91_CHIPSELECT_2 + 3, + .flags = IORESOURCE_MEM + }, + [1] = { + .start = AT91_CHIPSELECT_2 + 0x44, + .end = AT91_CHIPSELECT_2 + 0xFF, + .flags = IORESOURCE_MEM + }, + [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, + .flags = IORESOURCE_IRQ + } +}; + +static struct dm9000_plat_data dm9000_platdata = { + .flags = DM9000_PLATF_16BITONLY, +}; + +static struct platform_device at91sam9261_dm9000_device = { + .name = "dm9000", + .id = 0, + .num_resources = ARRAY_SIZE(at91sam9261_dm9000_resource), + .resource = at91sam9261_dm9000_resource, + .dev = { + .platform_data = &dm9000_platdata, + } +}; + +static void __init ek_add_device_dm9000(void) +{ + /* + * Configure Chip-Select 2 on SMC for the DM9000. + * Note: These timings were calculated for MASTER_CLOCK = 100000000 + * according to the DM9000 timings. + */ + at91_sys_write(AT91_SMC_SETUP(2), AT91_SMC_NWESETUP_(2) | AT91_SMC_NCS_WRSETUP_(0) | AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(0)); + at91_sys_write(AT91_SMC_PULSE(2), AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(8) | AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(8)); + at91_sys_write(AT91_SMC_CYCLE(2), AT91_SMC_NWECYCLE_(16) | AT91_SMC_NRDCYCLE_(16)); + at91_sys_write(AT91_SMC_MODE(2), AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16 | AT91_SMC_TDF_(1)); + + /* Configure Reset signal as output */ + at91_set_gpio_output(AT91_PIN_PC10, 0); + + /* Configure Interrupt pin as input, no pull-up */ + at91_set_gpio_input(AT91_PIN_PC11, 0); + + platform_device_register(&at91sam9261_dm9000_device); +} +#else +static void __init ek_add_device_dm9000(void) {} +#endif /* CONFIG_DM9000 */ + + +/* + * USB Host Port + */ +static struct at91_usbh_data __initdata ek_usbh_data = { + .ports = 2, +}; + + +/* + * USB Device Port + */ +static struct at91_udc_data __initdata ek_udc_data = { + .vbus_pin = AT91_PIN_PB29, + .pullup_pin = 0, /* pull-up driven by UDC */ +}; + + +/* + * MCI (SD/MMC) + */ +static struct at91_mmc_data __initdata ek_mmc_data = { + .wire4 = 1, +// .det_pin = ... not connected +// .wp_pin = ... not connected +// .vcc_pin = ... not connected +}; + + +/* + * NAND flash + */ +static struct mtd_partition __initdata ek_nand_partition[] = { + { + .name = "Partition 1", + .offset = 0, + .size = 256 * 1024, + }, + { + .name = "Partition 2", + .offset = 256 * 1024 , + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct mtd_partition *nand_partitions(int size, int *num_partitions) +{ + *num_partitions = ARRAY_SIZE(ek_nand_partition); + return ek_nand_partition; +} + +static struct at91_nand_data __initdata ek_nand_data = { + .ale = 22, + .cle = 21, +// .det_pin = ... not connected + .rdy_pin = AT91_PIN_PC15, + .enable_pin = AT91_PIN_PC14, + .partition_info = nand_partitions, +#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16) + .bus_width_16 = 1, +#else + .bus_width_16 = 0, +#endif +}; + +/* + * SPI devices + */ +static struct spi_board_info ek_spi_devices[] = { + { /* DataFlash chip */ + .modalias = "mtd_dataflash", + .chip_select = 0, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD) + { /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */ + .modalias = "mtd_dataflash", + .chip_select = 3, + .max_speed_hz = 15 * 1000 * 1000, + .bus_num = 0, + }, +#elif defined(CONFIG_SND_AT73C213) + { /* AT73C213 DAC */ + .modalias = "snd_at73c213", + .chip_select = 3, + .max_speed_hz = 10 * 1000 * 1000, + .bus_num = 0, + }, +#endif +}; + + +static void __init ek_board_init(void) +{ + /* Serial */ + at91_add_device_serial(); + /* USB Host */ + at91_add_device_usbh(&ek_usbh_data); + /* USB Device */ + at91_add_device_udc(&ek_udc_data); + /* I2C */ + at91_add_device_i2c(); + /* NAND */ + at91_add_device_nand(&ek_nand_data); + /* DM9000 ethernet */ + ek_add_device_dm9000(); + + /* spi0 and mmc/sd share the same PIO pins */ +#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE) + /* SPI */ + at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); +#else + /* MMC */ + at91_add_device_mmc(&ek_mmc_data); +#endif +} + +MACHINE_START(AT91SAM9261EK, "Atmel AT91SAM9261-EK") + /* Maintainer: Atmel */ + .phys_io = AT91_BASE_SYS, + .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, + .boot_params = AT91_SDRAM_BASE + 0x100, + .timer = &at91sam926x_timer, + .map_io = ek_map_io, + .init_irq = ek_init_irq, + .init_machine = ek_board_init, +MACHINE_END -- cgit v1.2.3 From 58a0cd7887cd689ae42540dd12b3b3131abfbe6c Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 14:51:13 +0100 Subject: [ARM] 3963/1: AT91: Update configuration files A number of configuration file changes. These are mainly to replace references to ARCH_AT91RM9200 and ARCH_AT91SAM9261 with the common/generic ARCH_AT91. That way we don't need to mention every specific AT91 processor explicitly. Also adds the configuration option for AT91SAM9260-EK and AT91SAM9261-EK boards. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/Kconfig | 2 +- arch/arm/configs/csb637_defconfig | 2 +- arch/arm/configs/kb9202_defconfig | 2 +- arch/arm/mach-at91rm9200/Kconfig | 30 ++++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ce00c570459..43bd17bfc38 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -583,7 +583,7 @@ config LEDS ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ - ARCH_AT91RM9200 || MACH_TRIZEPS4 + ARCH_AT91 || MACH_TRIZEPS4 help If you say Y here, the LEDs on your machine will be used to provide useful information about your current system status. diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig index df8595ac031..abf33520b70 100644 --- a/arch/arm/configs/csb637_defconfig +++ b/arch/arm/configs/csb637_defconfig @@ -623,7 +623,7 @@ CONFIG_AT91RM9200_WATCHDOG=y # CONFIG_USBPCWATCHDOG is not set # CONFIG_NVRAM is not set CONFIG_RTC=y -# CONFIG_AT91_RTC is not set +# CONFIG_AT91RM9200_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/configs/kb9202_defconfig b/arch/arm/configs/kb9202_defconfig index b4cd4b41483..9ab0e0a66fd 100644 --- a/arch/arm/configs/kb9202_defconfig +++ b/arch/arm/configs/kb9202_defconfig @@ -437,7 +437,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # CONFIG_WATCHDOG is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set -# CONFIG_AT91_RTC is not set +# CONFIG_AT91RM9200_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91rm9200/Kconfig index 8d443264789..9f11db8af23 100644 --- a/arch/arm/mach-at91rm9200/Kconfig +++ b/arch/arm/mach-at91rm9200/Kconfig @@ -92,6 +92,13 @@ if ARCH_AT91SAM9260 comment "AT91SAM9260 Board Type" +config MACH_AT91SAM9260EK + bool "Atmel AT91SAM9260-EK Evaluation Kit" + depends on ARCH_AT91SAM9260 + help + Select this if you are using Atmel's AT91SAM9260-EK Evaluation Kit. + + endif # ---------------------------------------------------------- @@ -100,8 +107,31 @@ if ARCH_AT91SAM9261 comment "AT91SAM9261 Board Type" +config MACH_AT91SAM9261EK + bool "Atmel AT91SAM9261-EK Evaluation Kit" + depends on ARCH_AT91SAM9261 + help + Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit. + + endif +# ---------------------------------------------------------- + +comment "AT91 Board Options" + +config MTD_AT91_DATAFLASH_CARD + bool "Enable DataFlash Card support" + depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK) + help + Enable support for the DataFlash card. + +config MTD_NAND_AT91_BUSWIDTH_16 + bool "Enable 16-bit data bus interface to NAND flash" + depends on (MACH_AT91SAM9261EK || MACH_AT91SAM9260EK) + help + On AT91SAM926x boards both types of NAND flash can be present + (8 and 16 bit data bus width). # ---------------------------------------------------------- -- cgit v1.2.3 From 69c5eccd164200a17b5a24e594b37958d39d2933 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Fri, 1 Dec 2006 15:53:20 +0100 Subject: [ARM] 3966/1: AT91: RM9200 device data update This patch contains various updates the at91rm9200_devices.c file: * Consistent naming of resources and platform_devices. * PCMCIA/Compact Flash: Configuration of the memory controller moved out of the driver and into this file. * MMC: Enable the VCC pin (if one is configured) * MMC: Enable the internal pullups on the I/O pins. * NAND: Configuration of the memory controller moved out of the driver and into this file. * Added TWI/I2C resources. * The names of some of the CONFIG_ variables were changed. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/at91rm9200_devices.c | 158 ++++++++++++++++++-------- 1 file changed, 110 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91rm9200/at91rm9200_devices.c index 2b3a23605bf..4641b99db0e 100644 --- a/arch/arm/mach-at91rm9200/at91rm9200_devices.c +++ b/arch/arm/mach-at91rm9200/at91rm9200_devices.c @@ -15,9 +15,10 @@ #include -#include #include #include +#include +#include #include "generic.h" @@ -33,7 +34,7 @@ static u64 ohci_dmamask = 0xffffffffUL; static struct at91_usbh_data usbh_data; -static struct resource at91_usbh_resources[] = { +static struct resource usbh_resources[] = { [0] = { .start = AT91RM9200_UHP_BASE, .end = AT91RM9200_UHP_BASE + SZ_1M - 1, @@ -54,8 +55,8 @@ static struct platform_device at91rm9200_usbh_device = { .coherent_dma_mask = 0xffffffff, .platform_data = &usbh_data, }, - .resource = at91_usbh_resources, - .num_resources = ARRAY_SIZE(at91_usbh_resources), + .resource = usbh_resources, + .num_resources = ARRAY_SIZE(usbh_resources), }; void __init at91_add_device_usbh(struct at91_usbh_data *data) @@ -78,7 +79,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data) {} #ifdef CONFIG_USB_GADGET_AT91 static struct at91_udc_data udc_data; -static struct resource at91_udc_resources[] = { +static struct resource udc_resources[] = { [0] = { .start = AT91RM9200_BASE_UDP, .end = AT91RM9200_BASE_UDP + SZ_16K - 1, @@ -97,8 +98,8 @@ static struct platform_device at91rm9200_udc_device = { .dev = { .platform_data = &udc_data, }, - .resource = at91_udc_resources, - .num_resources = ARRAY_SIZE(at91_udc_resources), + .resource = udc_resources, + .num_resources = ARRAY_SIZE(udc_resources), }; void __init at91_add_device_udc(struct at91_udc_data *data) @@ -129,7 +130,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {} static u64 eth_dmamask = 0xffffffffUL; static struct at91_eth_data eth_data; -static struct resource at91_eth_resources[] = { +static struct resource eth_resources[] = { [0] = { .start = AT91_VA_BASE_EMAC, .end = AT91_VA_BASE_EMAC + SZ_16K - 1, @@ -150,8 +151,8 @@ static struct platform_device at91rm9200_eth_device = { .coherent_dma_mask = 0xffffffff, .platform_data = ð_data, }, - .resource = at91_eth_resources, - .num_resources = ARRAY_SIZE(at91_eth_resources), + .resource = eth_resources, + .num_resources = ARRAY_SIZE(eth_resources), }; void __init at91_add_device_eth(struct at91_eth_data *data) @@ -202,11 +203,13 @@ void __init at91_add_device_eth(struct at91_eth_data *data) {} #if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) static struct at91_cf_data cf_data; -static struct resource at91_cf_resources[] = { +#define CF_BASE AT91_CHIPSELECT_4 + +static struct resource cf_resources[] = { [0] = { - .start = AT91_CF_BASE, + .start = CF_BASE, /* ties up CS4, CS5 and CS6 */ - .end = AT91_CF_BASE + (0x30000000 - 1), + .end = CF_BASE + (0x30000000 - 1), .flags = IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT, }, }; @@ -217,15 +220,38 @@ static struct platform_device at91rm9200_cf_device = { .dev = { .platform_data = &cf_data, }, - .resource = at91_cf_resources, - .num_resources = ARRAY_SIZE(at91_cf_resources), + .resource = cf_resources, + .num_resources = ARRAY_SIZE(cf_resources), }; void __init at91_add_device_cf(struct at91_cf_data *data) { + unsigned int csa; + if (!data) return; + data->chipselect = 4; /* can only use EBI ChipSelect 4 */ + + /* CF takes over CS4, CS5, CS6 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); + + /* + * Static memory controller timing adjustments. + * REVISIT: these timings are in terms of MCK cycles, so + * when MCK changes (cpufreq etc) so must these values... + */ + at91_sys_write(AT91_SMC_CSR(4), + AT91_SMC_ACSS_STD + | AT91_SMC_DBW_16 + | AT91_SMC_BAT + | AT91_SMC_WSEN + | AT91_SMC_NWS_(32) /* wait states */ + | AT91_SMC_RWSETUP_(6) /* setup time */ + | AT91_SMC_RWHOLD_(4) /* hold time */ + ); + /* input/irq */ if (data->irq_pin) { at91_set_gpio_input(data->irq_pin, 1); @@ -245,6 +271,9 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */ at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */ + /* nWAIT is _not_ a default setting */ + at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ + cf_data = *data; platform_device_register(&at91rm9200_cf_device); } @@ -257,11 +286,11 @@ void __init at91_add_device_cf(struct at91_cf_data *data) {} * MMC / SD * -------------------------------------------------------------------- */ -#if defined(CONFIG_MMC_AT91RM9200) || defined(CONFIG_MMC_AT91RM9200_MODULE) +#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE) static u64 mmc_dmamask = 0xffffffffUL; static struct at91_mmc_data mmc_data; -static struct resource at91_mmc_resources[] = { +static struct resource mmc_resources[] = { [0] = { .start = AT91RM9200_BASE_MCI, .end = AT91RM9200_BASE_MCI + SZ_16K - 1, @@ -282,8 +311,8 @@ static struct platform_device at91rm9200_mmc_device = { .coherent_dma_mask = 0xffffffff, .platform_data = &mmc_data, }, - .resource = at91_mmc_resources, - .num_resources = ARRAY_SIZE(at91_mmc_resources), + .resource = mmc_resources, + .num_resources = ARRAY_SIZE(mmc_resources), }; void __init at91_add_device_mmc(struct at91_mmc_data *data) @@ -298,31 +327,33 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) } if (data->wp_pin) at91_set_gpio_input(data->wp_pin, 1); + if (data->vcc_pin) + at91_set_gpio_output(data->vcc_pin, 0); /* CLK */ at91_set_A_periph(AT91_PIN_PA27, 0); - if (data->is_b) { + if (data->slot_b) { /* CMD */ - at91_set_B_periph(AT91_PIN_PA8, 0); + at91_set_B_periph(AT91_PIN_PA8, 1); /* DAT0, maybe DAT1..DAT3 */ - at91_set_B_periph(AT91_PIN_PA9, 0); + at91_set_B_periph(AT91_PIN_PA9, 1); if (data->wire4) { - at91_set_B_periph(AT91_PIN_PA10, 0); - at91_set_B_periph(AT91_PIN_PA11, 0); - at91_set_B_periph(AT91_PIN_PA12, 0); + at91_set_B_periph(AT91_PIN_PA10, 1); + at91_set_B_periph(AT91_PIN_PA11, 1); + at91_set_B_periph(AT91_PIN_PA12, 1); } } else { /* CMD */ - at91_set_A_periph(AT91_PIN_PA28, 0); + at91_set_A_periph(AT91_PIN_PA28, 1); /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA29, 0); + at91_set_A_periph(AT91_PIN_PA29, 1); if (data->wire4) { - at91_set_B_periph(AT91_PIN_PB3, 0); - at91_set_B_periph(AT91_PIN_PB4, 0); - at91_set_B_periph(AT91_PIN_PB5, 0); + at91_set_B_periph(AT91_PIN_PB3, 1); + at91_set_B_periph(AT91_PIN_PB4, 1); + at91_set_B_periph(AT91_PIN_PB5, 1); } } @@ -341,29 +372,45 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data) {} #if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE) static struct at91_nand_data nand_data; -static struct resource at91_nand_resources[] = { +#define NAND_BASE AT91_CHIPSELECT_3 + +static struct resource nand_resources[] = { { - .start = AT91_SMARTMEDIA_BASE, - .end = AT91_SMARTMEDIA_BASE + SZ_8M - 1, + .start = NAND_BASE, + .end = NAND_BASE + SZ_8M - 1, .flags = IORESOURCE_MEM, } }; -static struct platform_device at91_nand_device = { +static struct platform_device at91rm9200_nand_device = { .name = "at91_nand", .id = -1, .dev = { .platform_data = &nand_data, }, - .resource = at91_nand_resources, - .num_resources = ARRAY_SIZE(at91_nand_resources), + .resource = nand_resources, + .num_resources = ARRAY_SIZE(nand_resources), }; void __init at91_add_device_nand(struct at91_nand_data *data) { + unsigned int csa; + if (!data) return; + /* enable the address range of CS3 */ + csa = at91_sys_read(AT91_EBI_CSA); + at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS3A_SMC_SMARTMEDIA); + + /* set the bus interface characteristics */ + at91_sys_write(AT91_SMC_CSR(3), AT91_SMC_ACSS_STD | AT91_SMC_DBW_8 | AT91_SMC_WSEN + | AT91_SMC_NWS_(5) + | AT91_SMC_TDF_(1) + | AT91_SMC_RWSETUP_(0) /* tDS Data Set up Time 30 - ns */ + | AT91_SMC_RWHOLD_(1) /* tDH Data Hold Time 20 - ns */ + ); + /* enable pin */ if (data->enable_pin) at91_set_gpio_output(data->enable_pin, 1); @@ -380,7 +427,7 @@ void __init at91_add_device_nand(struct at91_nand_data *data) at91_set_A_periph(AT91_PIN_PC3, 0); /* SMWE */ nand_data = *data; - platform_device_register(&at91_nand_device); + platform_device_register(&at91rm9200_nand_device); } #else void __init at91_add_device_nand(struct at91_nand_data *data) {} @@ -392,10 +439,25 @@ void __init at91_add_device_nand(struct at91_nand_data *data) {} * -------------------------------------------------------------------- */ #if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE) + +static struct resource twi_resources[] = { + [0] = { + .start = AT91RM9200_BASE_TWI, + .end = AT91RM9200_BASE_TWI + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = AT91RM9200_ID_TWI, + .end = AT91RM9200_ID_TWI, + .flags = IORESOURCE_IRQ, + }, +}; + static struct platform_device at91rm9200_twi_device = { .name = "at91_i2c", .id = -1, - .num_resources = 0, + .resource = twi_resources, + .num_resources = ARRAY_SIZE(twi_resources), }; void __init at91_add_device_i2c(void) @@ -421,7 +483,7 @@ void __init at91_add_device_i2c(void) {} #if defined(CONFIG_SPI_AT91) || defined(CONFIG_SPI_AT91_MODULE) || defined(CONFIG_AT91_SPI) || defined(CONFIG_AT91_SPI_MODULE) static u64 spi_dmamask = 0xffffffffUL; -static struct resource at91_spi_resources[] = { +static struct resource spi_resources[] = { [0] = { .start = AT91RM9200_BASE_SPI, .end = AT91RM9200_BASE_SPI + SZ_16K - 1, @@ -438,14 +500,14 @@ static struct platform_device at91rm9200_spi_device = { .name = "at91_spi", .id = 0, .dev = { - .dma_mask = &spi_dmamask, - .coherent_dma_mask = 0xffffffff, + .dma_mask = &spi_dmamask, + .coherent_dma_mask = 0xffffffff, }, - .resource = at91_spi_resources, - .num_resources = ARRAY_SIZE(at91_spi_resources), + .resource = spi_resources, + .num_resources = ARRAY_SIZE(spi_resources), }; -static const unsigned at91_spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; +static const unsigned spi_standard_cs[4] = { AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PA5, AT91_PIN_PA6 }; void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) { @@ -461,7 +523,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) if (devices[i].controller_data) cs_pin = (unsigned long) devices[i].controller_data; else - cs_pin = at91_spi_standard_cs[devices[i].chip_select]; + cs_pin = spi_standard_cs[devices[i].chip_select]; #ifdef CONFIG_SPI_AT91_MANUAL_CS at91_set_gpio_output(cs_pin, 1); @@ -474,7 +536,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) } spi_register_board_info(devices, nr_devices); - at91_clock_associate("spi0_clk", &at91rm9200_spi_device.dev, "spi"); + at91_clock_associate("spi_clk", &at91rm9200_spi_device.dev, "spi"); platform_device_register(&at91rm9200_spi_device); } #else @@ -486,7 +548,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) * RTC * -------------------------------------------------------------------- */ -#if defined(CONFIG_RTC_DRV_AT91) || defined(CONFIG_RTC_DRV_AT91_MODULE) +#if defined(CONFIG_RTC_DRV_AT91RM9200) || defined(CONFIG_RTC_DRV_AT91RM9200_MODULE) static struct platform_device at91rm9200_rtc_device = { .name = "at91_rtc", .id = -1, @@ -506,7 +568,7 @@ static void __init at91_add_device_rtc(void) {} * Watchdog * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91_WATCHDOG) || defined(CONFIG_AT91_WATCHDOG_MODULE) +#if defined(CONFIG_AT91RM9200_WATCHDOG) || defined(CONFIG_AT91RM9200_WATCHDOG_MODULE) static struct platform_device at91rm9200_wdt_device = { .name = "at91_wdt", .id = -1, -- cgit v1.2.3 From e520a36de2f7985df5ef2e84a9f6d2608ecc6f25 Mon Sep 17 00:00:00 2001 From: Milan Svoboda Date: Fri, 1 Dec 2006 11:36:41 +0100 Subject: [ARM] 3958/1: add platform device (pxa2xx-udc)to ixp4xx Create include/asm-arm/arch-ixp4xx/udc.h and add platfrom device ixp4xx_udc_device into arch/arm/mach-ixp4xx/common.c. This allows us to use pxa2xx-udc on the ixp4xx platfrom. Both pxa2xx and ixp4xx use the same device controller. Signed-off-by:Milan Svoboda Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 074c9652024..1cf3bde1a5d 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -286,6 +287,44 @@ struct sys_timer ixp4xx_timer = { .init = ixp4xx_timer_init, }; +static struct pxa2xx_udc_mach_info ixp4xx_udc_info; + +void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info) +{ + memcpy(&ixp4xx_udc_info, info, sizeof *info); +} + +static struct resource ixp4xx_udc_resources[] = { + [0] = { + .start = 0xc800b000, + .end = 0xc800bfff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IXP4XX_USB, + .end = IRQ_IXP4XX_USB, + .flags = IORESOURCE_IRQ, + }, +}; + +/* + * USB device controller. The IXP4xx uses the same controller as PXA2XX, + * so we just use the same device. + */ +static struct platform_device ixp4xx_udc_device = { + .name = "pxa2xx-udc", + .id = -1, + .num_resources = 2, + .resource = ixp4xx_udc_resources, + .dev = { + .platform_data = &ixp4xx_udc_info, + }, +}; + +static struct platform_device *ixp4xx_devices[] __initdata = { + &ixp4xx_udc_device, +}; + static struct resource ixp46x_i2c_resources[] = { [0] = { .start = 0xc8011000, @@ -321,6 +360,8 @@ void __init ixp4xx_sys_init(void) { ixp4xx_exp_bus_size = SZ_16M; + platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices)); + if (cpu_is_ixp46x()) { int region; -- cgit v1.2.3 From 368c73d4f689dae0807d0a2aa74c61fd2b9b075f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 4 Oct 2006 00:41:26 +0100 Subject: PCI: quirks: fix the festering mess that claims to handle IDE quirks The number of permutations of crap we do is amazing and almost all of it has the wrong effect in 2.6. At the heart of this is the PCI SFF magic which says that compatibility mode PCI IDE controllers use ISA IRQ routing and hard coded addresses not the BAR values. The old quirks variously clears them, sets them, adjusts them and then IDE ignores the result. In order to drive all this garbage out and to do it portably we need to handle the SFF rules directly and properly. Because we know the device BAR 0-3 are not used in compatibility mode we load them with the values that are implied (and indeed which many controllers actually thoughtfully put there in this mode anyway). This removes special cases in the IDE layer and libata which now knows that bar 0/1/2/3 always contain the correct address. It means our resource allocation map is accurate from boot, not "mostly accurate" after ide is loaded, and it shoots lots of code. There is also lots more code and magic constant knowledge to shoot once this is in and settled. Been in my test tree for a while both with drivers/ide and with libata. Wants some -mm shakedown in case I've missed something dumb or there are corner cases lurking. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/fixup.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index c1949ff38d6..cde1170b01a 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -74,52 +74,6 @@ static void __devinit pci_fixup_ncr53c810(struct pci_dev *d) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, pci_fixup_ncr53c810); -static void __devinit pci_fixup_ide_bases(struct pci_dev *d) -{ - int i; - - /* - * PCI IDE controllers use non-standard I/O port decoding, respect it. - */ - if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - DBG("PCI: IDE base address fixup for %s\n", pci_name(d)); - for(i=0; i<4; i++) { - struct resource *r = &d->resource[i]; - if ((r->start & ~0x80) == 0x374) { - r->start |= 2; - r->end = r->start; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); - -static void __devinit pci_fixup_ide_trash(struct pci_dev *d) -{ - int i; - - /* - * Runs the fixup only for the first IDE controller - * (Shai Fultheim - shai@ftcon.com) - */ - static int called = 0; - if (called) - return; - called = 1; - - /* - * There exist PCI IDE controllers which have utter garbage - * in first four base registers. Ignore that. - */ - DBG("PCI: IDE base address trash cleared for %s\n", pci_name(d)); - for(i=0; i<4; i++) - d->resource[i].start = d->resource[i].end = d->resource[i].flags = 0; -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, pci_fixup_ide_trash); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, pci_fixup_ide_trash); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_11, pci_fixup_ide_trash); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_9, pci_fixup_ide_trash); - static void __devinit pci_fixup_latency(struct pci_dev *d) { /* -- cgit v1.2.3 From 3efe2d84c8d909567c7976a7106114127b8c3470 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 10 Oct 2006 08:01:19 -0600 Subject: PCI: Use pci_generic_prep_mwi on ia64 The pci_generic_prep_mwi() code does everything that pcibios_prep_mwi() does on ia64. All we need to do is be sure that pci_cache_line_size is set appropriately, and we can delete pcibios_prep_mwi(). Using SMP_CACHE_BYTES as the default was wrong on uniprocessor machines as it is only 8 bytes. The default in the generic code of L1_CACHE_BYTES is at least as good. Signed-off-by: Matthew Wilcox Acked-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 71 +++++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 51 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index b30be7c48ba..4f774725346 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -738,75 +738,44 @@ int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size) return ret; } +/* It's defined in drivers/pci/pci.c */ +extern u8 pci_cache_line_size; + /** - * pci_cacheline_size - determine cacheline size for PCI devices - * @dev: void + * set_pci_cacheline_size - determine cacheline size for PCI devices * * We want to use the line-size of the outer-most cache. We assume * that this line-size is the same for all CPUs. * * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info(). - * - * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. */ -static unsigned long -pci_cacheline_size (void) +static void __init set_pci_cacheline_size(void) { u64 levels, unique_caches; s64 status; pal_cache_config_info_t cci; - static u8 cacheline_size; - - if (cacheline_size) - return cacheline_size; status = ia64_pal_cache_summary(&levels, &unique_caches); if (status != 0) { - printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n", - __FUNCTION__, status); - return SMP_CACHE_BYTES; + printk(KERN_ERR "%s: ia64_pal_cache_summary() failed " + "(status=%ld)\n", __FUNCTION__, status); + return; } - status = ia64_pal_cache_config_info(levels - 1, /* cache_type (data_or_unified)= */ 2, - &cci); + status = ia64_pal_cache_config_info(levels - 1, + /* cache_type (data_or_unified)= */ 2, &cci); if (status != 0) { - printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed (status=%ld)\n", - __FUNCTION__, status); - return SMP_CACHE_BYTES; + printk(KERN_ERR "%s: ia64_pal_cache_config_info() failed " + "(status=%ld)\n", __FUNCTION__, status); + return; } - cacheline_size = 1 << cci.pcci_line_size; - return cacheline_size; + pci_cache_line_size = (1 << cci.pcci_line_size) / 4; } -/** - * pcibios_prep_mwi - helper function for drivers/pci/pci.c:pci_set_mwi() - * @dev: the PCI device for which MWI is enabled - * - * For ia64, we can get the cacheline sizes from PAL. - * - * RETURNS: An appropriate -ERRNO error value on eror, or zero for success. - */ -int -pcibios_prep_mwi (struct pci_dev *dev) -{ - unsigned long desired_linesize, current_linesize; - int rc = 0; - u8 pci_linesize; - - desired_linesize = pci_cacheline_size(); - - pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_linesize); - current_linesize = 4 * pci_linesize; - if (desired_linesize != current_linesize) { - printk(KERN_WARNING "PCI: slot %s has incorrect PCI cache line size of %lu bytes,", - pci_name(dev), current_linesize); - if (current_linesize > desired_linesize) { - printk(" expected %lu bytes instead\n", desired_linesize); - rc = -EINVAL; - } else { - printk(" correcting to %lu\n", desired_linesize); - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, desired_linesize / 4); - } - } - return rc; +static int __init pcibios_init(void) +{ + set_pci_cacheline_size(); + return 0; } + +subsys_initcall(pcibios_init); -- cgit v1.2.3 From ebf5a24829def5d066922ceebde61dd57fdc6b1e Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 10 Oct 2006 08:01:20 -0600 Subject: PCI: Use pci_generic_prep_mwi on sparc64 The setting of the CACHE_LINE_SIZE register in sparc64's pci initialisation code isn't quite adequate as the device may have incompatible requirements. The generic code tests for this, so switch sparc64 over to using it. Since sparc64 has different L1 cache line size and PCI cache line size, it would need to override the generic code like i386 and ia64 do. We know what the cache line size is at compile time though, so introduce a new optional constant PCI_CACHE_LINE_BYTES. Signed-off-by: Matthew Wilcox Signed-off-by: David Miller Acked-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- arch/sparc64/kernel/pci.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index e02f01b644a..dfc41cd4bb5 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -646,13 +646,4 @@ int pci_domain_nr(struct pci_bus *pbus) } EXPORT_SYMBOL(pci_domain_nr); -int pcibios_prep_mwi(struct pci_dev *dev) -{ - /* We set correct PCI_CACHE_LINE_SIZE register values for every - * device probed on this platform. So there is nothing to check - * and this always succeeds. - */ - return 0; -} - #endif /* !(CONFIG_PCI) */ -- cgit v1.2.3 From e08cf02f32dff732b2be0c9755cf5eb676f88e48 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Tue, 10 Oct 2006 08:01:22 -0600 Subject: PCI: Delete unused extern in powermac/pci.c This file no longer uses pci_cache_line_size, so delete the declaration Signed-off-by: Matthew Wilcox Cc: Benjamin Herrenschmidt Acked-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- arch/powerpc/platforms/powermac/pci.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 9923adc5248..257dc906846 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -48,7 +48,6 @@ static struct pci_controller *u3_ht; static int has_second_ohare; #endif /* CONFIG_PPC64 */ -extern u8 pci_cache_line_size; extern int pcibios_assign_bus_offset; struct device_node *k2_skiplist[2]; -- cgit v1.2.3 From 8ea6091f500162e97687d7acf925f84202066b8d Mon Sep 17 00:00:00 2001 From: John Keller Date: Wed, 4 Oct 2006 16:49:25 -0500 Subject: Altix: Add initial ACPI IO support First phase in introducing ACPI support to SN. In this phase, when running with an ACPI capable PROM, the DSDT will define the root busses and all SN nodes (SGIHUB, SGITIO). An ACPI bus driver will be registered for the node devices, with the acpi_pci_root_driver being used for the root busses. An ACPI vendor descriptor is now used to pass platform specific information for both nodes and busses, eliminating the need for the current SAL calls. Also, with ACPI support, SN fixup code is no longer needed to initiate the PCI bus scans, as the acpi_pci_root_driver does that. However, to maintain backward compatibility with non-ACPI capable PROMs, none of the current 'fixup' code can been deleted, though much restructuring has been done. For example, the bulk of the code in io_common.c is relocated code that is now common regardless of what PROM is running, while io_acpi_init.c and io_init.c contain routines specific to an ACPI or non ACPI capable PROM respectively. A new pci bus fixup platform vector has been created to provide a hook for invoking platform specific bus fixup from pcibios_fixup_bus(). The size of io_space[] has been increased to support systems with large IO configurations. Signed-off-by: John Keller Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 4 +- arch/ia64/sn/kernel/Makefile | 5 +- arch/ia64/sn/kernel/io_acpi_init.c | 198 ++++++++++ arch/ia64/sn/kernel/io_common.c | 612 +++++++++++++++++++++++++++++++ arch/ia64/sn/kernel/io_init.c | 630 +++++--------------------------- arch/ia64/sn/kernel/iomv.c | 11 +- arch/ia64/sn/kernel/setup.c | 18 + arch/ia64/sn/kernel/tiocx.c | 2 +- arch/ia64/sn/pci/pcibr/pcibr_provider.c | 17 +- arch/ia64/sn/pci/tioce_provider.c | 18 - 10 files changed, 945 insertions(+), 570 deletions(-) create mode 100644 arch/ia64/sn/kernel/io_acpi_init.c create mode 100644 arch/ia64/sn/kernel/io_common.c (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 4f774725346..f4edfbf2713 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -469,10 +469,11 @@ pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) } } -static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) +void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES); } +EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources); static void __devinit pcibios_fixup_bridge_resources(struct pci_dev *dev) { @@ -493,6 +494,7 @@ pcibios_fixup_bus (struct pci_bus *b) } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); + platform_pci_fixup_bus(b); return; } diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile index 2d78f34dd76..0a59371d347 100644 --- a/arch/ia64/sn/kernel/Makefile +++ b/arch/ia64/sn/kernel/Makefile @@ -4,13 +4,14 @@ # License. See the file "COPYING" in the main directory of this archive # for more details. # -# Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All Rights Reserved. # CPPFLAGS += -I$(srctree)/arch/ia64/sn/include obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ - huberror.o io_init.o iomv.o klconflib.o pio_phys.o \ + huberror.o io_acpi_init.o io_common.o \ + io_init.o iomv.o klconflib.o pio_phys.o \ sn2/ obj-$(CONFIG_IA64_GENERIC) += machvec.o obj-$(CONFIG_SGI_TIOCX) += tiocx.o diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c new file mode 100644 index 00000000000..a9dc36901b1 --- /dev/null +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -0,0 +1,198 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "xtalk/hubdev.h" +#include + + +/* + * The code in this file will only be executed when running with + * a PROM that has ACPI IO support. (i.e., SN_ACPI_BASE_SUPPORT() == 1) + */ + + +/* + * This value must match the UUID the PROM uses + * (io/acpi/defblk.c) when building a vendor descriptor. + */ +struct acpi_vendor_uuid sn_uuid = { + .subtype = 0, + .data = { 0x2c, 0xc6, 0xa6, 0xfe, 0x9c, 0x44, 0xda, 0x11, + 0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 }, +}; + +/* + * Perform the early IO init in PROM. + */ +static s64 +sal_ioif_init(u64 *result) +{ + struct ia64_sal_retval isrv = {0,0,0,0}; + + SAL_CALL_NOLOCK(isrv, + SN_SAL_IOIF_INIT, 0, 0, 0, 0, 0, 0, 0); + *result = isrv.v0; + return isrv.status; +} + +/* + * sn_hubdev_add - The 'add' function of the acpi_sn_hubdev_driver. + * Called for every "SGIHUB" or "SGITIO" device defined + * in the ACPI namespace. + */ +static int __init +sn_hubdev_add(struct acpi_device *device) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + u64 addr; + struct hubdev_info *hubdev; + struct hubdev_info *hubdev_ptr; + int i; + u64 nasid; + struct acpi_resource *resource; + int ret = 0; + acpi_status status; + struct acpi_resource_vendor_typed *vendor; + extern void sn_common_hubdev_init(struct hubdev_info *); + + status = acpi_get_vendor_resource(device->handle, METHOD_NAME__CRS, + &sn_uuid, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR + "sn_hubdev_add: acpi_get_vendor_resource() failed: %d\n", + status); + return 1; + } + + resource = buffer.pointer; + vendor = &resource->data.vendor_typed; + if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != + sizeof(struct hubdev_info *)) { + printk(KERN_ERR + "sn_hubdev_add: Invalid vendor data length: %d\n", + vendor->byte_length); + ret = 1; + goto exit; + } + + memcpy(&addr, vendor->byte_data, sizeof(struct hubdev_info *)); + hubdev_ptr = __va((struct hubdev_info *) addr); + + nasid = hubdev_ptr->hdi_nasid; + i = nasid_to_cnodeid(nasid); + hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); + *hubdev = *hubdev_ptr; + sn_common_hubdev_init(hubdev); + +exit: + kfree(buffer.pointer); + return ret; +} + +/* + * sn_get_bussoft_ptr() - The pcibus_bussoft pointer is found in + * the ACPI Vendor resource for this bus. + */ +static struct pcibus_bussoft * +sn_get_bussoft_ptr(struct pci_bus *bus) +{ + u64 addr; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + acpi_handle handle; + struct pcibus_bussoft *prom_bussoft_ptr; + struct acpi_resource *resource; + acpi_status status; + struct acpi_resource_vendor_typed *vendor; + + + handle = PCI_CONTROLLER(bus)->acpi_handle; + status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS, + &sn_uuid, &buffer); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR "get_acpi_pcibus_ptr: " + "get_acpi_bussoft_info() failed: %d\n", + status); + return NULL; + } + resource = buffer.pointer; + vendor = &resource->data.vendor_typed; + + if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) != + sizeof(struct pcibus_bussoft *)) { + printk(KERN_ERR + "get_acpi_bussoft_ptr: Invalid vendor data " + "length %d\n", vendor->byte_length); + kfree(buffer.pointer); + return NULL; + } + memcpy(&addr, vendor->byte_data, sizeof(struct pcibus_bussoft *)); + prom_bussoft_ptr = __va((struct pcibus_bussoft *) addr); + kfree(buffer.pointer); + + return prom_bussoft_ptr; +} + +/* + * sn_acpi_bus_fixup + */ +void +sn_acpi_bus_fixup(struct pci_bus *bus) +{ + struct pci_dev *pci_dev = NULL; + struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); + + if (!bus->parent) { /* If root bus */ + prom_bussoft_ptr = sn_get_bussoft_ptr(bus); + if (prom_bussoft_ptr == NULL) { + printk(KERN_ERR + "sn_pci_fixup_bus: 0x%04x:0x%02x Unable to " + "obtain prom_bussoft_ptr\n", + pci_domain_nr(bus), bus->number); + return; + } + sn_common_bus_fixup(bus, prom_bussoft_ptr); + } + list_for_each_entry(pci_dev, &bus->devices, bus_list) { + sn_pci_fixup_slot(pci_dev); + } +} + +static struct acpi_driver acpi_sn_hubdev_driver = { + .name = "SGI HUBDEV Driver", + .ids = "SGIHUB,SGITIO", + .ops = { + .add = sn_hubdev_add, + }, +}; + + +/* + * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the + * nodes and root buses in the DSDT. As a result, bus scanning + * will be initiated by the Linux ACPI code. + */ + +void __init +sn_io_acpi_init(void) +{ + u64 result; + s64 status; + + acpi_bus_register_driver(&acpi_sn_hubdev_driver); + status = sal_ioif_init(&result); + if (status || result) + panic("sal_ioif_init failed: [%lx] %s\n", + status, ia64_sal_strerror(status)); +} diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c new file mode 100644 index 00000000000..12531de6754 --- /dev/null +++ b/arch/ia64/sn/kernel/io_common.c @@ -0,0 +1,612 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xtalk/hubdev.h" +#include "xtalk/xwidgetdev.h" +#include +#include +#include + +extern void sn_init_cpei_timer(void); +extern void register_sn_procfs(void); +extern void sn_acpi_bus_fixup(struct pci_bus *); +extern void sn_bus_fixup(struct pci_bus *); +extern void sn_acpi_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_more_slot_fixup(struct pci_dev *, struct pcidev_info *); +extern void sn_legacy_pci_window_fixup(struct pci_controller *, u64, u64); +extern void sn_io_acpi_init(void); +extern void sn_io_init(void); + + +static struct list_head sn_sysdata_list; + +/* sysdata list struct */ +struct sysdata_el { + struct list_head entry; + void *sysdata; +}; + +int sn_ioif_inited; /* SN I/O infrastructure initialized? */ + +struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ + +/* + * Hooks and struct for unsupported pci providers + */ + +static dma_addr_t +sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) +{ + return 0; +} + +static void +sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) +{ + return; +} + +static void * +sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) +{ + return NULL; +} + +static struct sn_pcibus_provider sn_pci_default_provider = { + .dma_map = sn_default_pci_map, + .dma_map_consistent = sn_default_pci_map, + .dma_unmap = sn_default_pci_unmap, + .bus_fixup = sn_default_pci_bus_fixup, +}; + +/* + * Retrieve the DMA Flush List given nasid, widget, and device. + * This list is needed to implement the WAR - Flush DMA data on PIO Reads. + */ +static inline u64 +sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, + u64 address) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, + (u64) nasid, (u64) widget_num, + (u64) device_num, (u64) address, 0, 0, 0); + return ret_stuff.status; +} + +/* + * Retrieve the pci device information given the bus and device|function number. + */ +static inline u64 +sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, + u64 sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, + (u64) segment, (u64) bus_number, (u64) devfn, + (u64) pci_dev, + sn_irq_info, 0, 0); + return ret_stuff.v0; +} + +/* + * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified + * device. + */ +inline struct pcidev_info * +sn_pcidev_info_get(struct pci_dev *dev) +{ + struct pcidev_info *pcidev; + + list_for_each_entry(pcidev, + &(SN_PLATFORM_DATA(dev)->pcidev_info), pdi_list) { + if (pcidev->pdi_linux_pcidev == dev) + return pcidev; + } + return NULL; +} + +/* Older PROM flush WAR + * + * 01/16/06 -- This war will be in place until a new official PROM is released. + * Additionally note that the struct sn_flush_device_war also has to be + * removed from arch/ia64/sn/include/xtalk/hubdev.h + */ +static u8 war_implemented = 0; + +static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, + struct sn_flush_device_common *common) +{ + struct sn_flush_device_war *war_list; + struct sn_flush_device_war *dev_entry; + struct ia64_sal_retval isrv = {0,0,0,0}; + + if (!war_implemented) { + printk(KERN_WARNING "PROM version < 4.50 -- implementing old " + "PROM flush WAR\n"); + war_implemented = 1; + } + + war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); + if (!war_list) + BUG(); + + SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, + nasid, widget, __pa(war_list), 0, 0, 0 ,0); + if (isrv.status) + panic("sn_device_fixup_war failed: %s\n", + ia64_sal_strerror(isrv.status)); + + dev_entry = war_list + device; + memcpy(common,dev_entry, sizeof(*common)); + kfree(war_list); + + return isrv.status; +} + +/* + * sn_common_hubdev_init() - This routine is called to initialize the HUB data + * structure for each node in the system. + */ +void __init +sn_common_hubdev_init(struct hubdev_info *hubdev) +{ + + struct sn_flush_device_kernel *sn_flush_device_kernel; + struct sn_flush_device_kernel *dev_entry; + s64 status; + int widget, device, size; + + /* Attach the error interrupt handlers */ + if (hubdev->hdi_nasid & 1) /* If TIO */ + ice_error_init(hubdev); + else + hub_error_init(hubdev); + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) + hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; + + if (!hubdev->hdi_flush_nasid_list.widget_p) + return; + + size = (HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *); + hubdev->hdi_flush_nasid_list.widget_p = + kzalloc(size, GFP_KERNEL); + if (!hubdev->hdi_flush_nasid_list.widget_p) + BUG(); + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { + size = DEV_PER_WIDGET * + sizeof(struct sn_flush_device_kernel); + sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); + if (!sn_flush_device_kernel) + BUG(); + + dev_entry = sn_flush_device_kernel; + for (device = 0; device < DEV_PER_WIDGET; + device++, dev_entry++) { + size = sizeof(struct sn_flush_device_common); + dev_entry->common = kzalloc(size, GFP_KERNEL); + if (!dev_entry->common) + BUG(); + if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST)) + status = sal_get_device_dmaflush_list( + hubdev->hdi_nasid, widget, device, + (u64)(dev_entry->common)); + else + status = sn_device_fixup_war(hubdev->hdi_nasid, + widget, device, + dev_entry->common); + if (status != SALRET_OK) + panic("SAL call failed: %s\n", + ia64_sal_strerror(status)); + + spin_lock_init(&dev_entry->sfdl_flush_lock); + } + + if (sn_flush_device_kernel) + hubdev->hdi_flush_nasid_list.widget_p[widget] = + sn_flush_device_kernel; + } +} + +void sn_pci_unfixup_slot(struct pci_dev *dev) +{ + struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; + + sn_irq_unfixup(dev); + pci_dev_put(host_pci_dev); + pci_dev_put(dev); +} + +/* + * sn_pci_fixup_slot() - This routine sets up a slot's resources consistent + * with the Linux PCI abstraction layer. Resources + * acquired from our PCI provider include PIO maps + * to BAR space and interrupt objects. + */ +void sn_pci_fixup_slot(struct pci_dev *dev) +{ + int segment = pci_domain_nr(dev->bus); + int status = 0; + struct pcibus_bussoft *bs; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct pcidev_info *pcidev_info; + struct sn_irq_info *sn_irq_info; + unsigned int bus_no, devfn; + + pci_dev_get(dev); /* for the sysdata pointer */ + pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); + if (!pcidev_info) + BUG(); /* Cannot afford to run out of memory */ + + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) + BUG(); /* Cannot afford to run out of memory */ + + /* Call to retrieve pci device information needed by kernel. */ + status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, + dev->devfn, + (u64) __pa(pcidev_info), + (u64) __pa(sn_irq_info)); + if (status) + BUG(); /* Cannot get platform pci device information */ + + /* Add pcidev_info to list in pci_controller.platform_data */ + list_add_tail(&pcidev_info->pdi_list, + &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); + + if (!SN_ACPI_BASE_SUPPORT()) + sn_more_slot_fixup(dev, pcidev_info); + + /* + * Using the PROMs values for the PCI host bus, get the Linux + * PCI host_pci_dev struct and set up host bus linkages + */ + + bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; + devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff; + host_pci_bus = pci_find_bus(segment, bus_no); + host_pci_dev = pci_get_slot(host_pci_bus, devfn); + + pcidev_info->host_pci_dev = host_pci_dev; + pcidev_info->pdi_linux_pcidev = dev; + pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev); + bs = SN_PCIBUS_BUSSOFT(dev->bus); + pcidev_info->pdi_pcibus_info = bs; + + if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { + SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; + } else { + SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider; + } + + /* Only set up IRQ stuff if this device has a host bus context */ + if (bs && sn_irq_info->irq_irq) { + pcidev_info->pdi_sn_irq_info = sn_irq_info; + dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq; + sn_irq_fixup(dev, sn_irq_info); + } else { + pcidev_info->pdi_sn_irq_info = NULL; + kfree(sn_irq_info); + } +} + +/* + * sn_common_bus_fixup - Perform platform specific bus fixup. + * Execute the ASIC specific fixup routine + * for this bus. + */ +void +sn_common_bus_fixup(struct pci_bus *bus, + struct pcibus_bussoft *prom_bussoft_ptr) +{ + int cnode; + struct pci_controller *controller; + struct hubdev_info *hubdev_info; + int nasid; + void *provider_soft; + struct sn_pcibus_provider *provider; + struct sn_platform_data *sn_platform_data; + + controller = PCI_CONTROLLER(bus); + /* + * Per-provider fixup. Copies the bus soft structure from prom + * to local area and links SN_PCIBUS_BUSSOFT(). + */ + + if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) { + printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d", + prom_bussoft_ptr->bs_asic_type); + return; + } + + if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) + return; /* no further fixup necessary */ + + provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; + if (provider == NULL) + panic("sn_common_bus_fixup: No provider registered for this asic type, %d", + prom_bussoft_ptr->bs_asic_type); + + if (provider->bus_fixup) + provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, + controller); + else + provider_soft = NULL; + + /* + * Generic bus fixup goes here. Don't reference prom_bussoft_ptr + * after this point. + */ + controller->platform_data = kzalloc(sizeof(struct sn_platform_data), + GFP_KERNEL); + if (controller->platform_data == NULL) + BUG(); + sn_platform_data = + (struct sn_platform_data *) controller->platform_data; + sn_platform_data->provider_soft = provider_soft; + INIT_LIST_HEAD(&((struct sn_platform_data *) + controller->platform_data)->pcidev_info); + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = + &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); + + /* + * If the node information we obtained during the fixup phase is + * invalid then set controller->node to -1 (undetermined) + */ + if (controller->node >= num_online_nodes()) { + struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); + + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" + "L_IO=%lx L_MEM=%lx BASE=%lx\n", + b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, + b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); + printk(KERN_WARNING "on node %d but only %d nodes online." + "Association set to undetermined.\n", + controller->node, num_online_nodes()); + controller->node = -1; + } +} + +void sn_bus_store_sysdata(struct pci_dev *dev) +{ + struct sysdata_el *element; + + element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); + if (!element) { + dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); + return; + } + element->sysdata = SN_PCIDEV_INFO(dev); + list_add(&element->entry, &sn_sysdata_list); +} + +void sn_bus_free_sysdata(void) +{ + struct sysdata_el *element; + struct list_head *list, *safe; + + list_for_each_safe(list, safe, &sn_sysdata_list) { + element = list_entry(list, struct sysdata_el, entry); + list_del(&element->entry); + list_del(&(((struct pcidev_info *) + (element->sysdata))->pdi_list)); + kfree(element->sysdata); + kfree(element); + } + return; +} + +/* + * hubdev_init_node() - Creates the HUB data structure and link them to it's + * own NODE specific data area. + */ +void hubdev_init_node(nodepda_t * npda, cnodeid_t node) +{ + struct hubdev_info *hubdev_info; + int size; + pg_data_t *pg; + + size = sizeof(struct hubdev_info); + + if (node >= num_online_nodes()) /* Headless/memless IO nodes */ + pg = NODE_DATA(0); + else + pg = NODE_DATA(node); + + hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); + + npda->pdinfo = (void *)hubdev_info; +} + +geoid_t +cnodeid_get_geoid(cnodeid_t cnode) +{ + struct hubdev_info *hubdev; + + hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + return hubdev->hdi_geoid; +} + +void sn_generate_path(struct pci_bus *pci_bus, char *address) +{ + nasid_t nasid; + cnodeid_t cnode; + geoid_t geoid; + moduleid_t moduleid; + u16 bricktype; + + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + geoid = cnodeid_get_geoid(cnode); + moduleid = geo_module(geoid); + + sprintf(address, "module_%c%c%c%c%.2d", + '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), + MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); + + /* Tollhouse requires slot id to be displayed */ + bricktype = MODULE_GET_BTYPE(moduleid); + if ((bricktype == L1_BRICKTYPE_191010) || + (bricktype == L1_BRICKTYPE_1932)) + sprintf(address, "%s^%d", address, geo_slot(geoid)); +} + +/* + * sn_pci_fixup_bus() - Perform SN specific setup of software structs + * (pcibus_bussoft, pcidev_info) and hardware + * registers, for the specified bus and devices under it. + */ +void __devinit +sn_pci_fixup_bus(struct pci_bus *bus) +{ + + if (SN_ACPI_BASE_SUPPORT()) + sn_acpi_bus_fixup(bus); + else + sn_bus_fixup(bus); +} + +/* + * sn_io_early_init - Perform early IO (and some non-IO) initialization. + * In particular, setup the sn_pci_provider[] array. + * This needs to be done prior to any bus scanning + * (acpi_scan_init()) in the ACPI case, as the SN + * bus fixup code will reference the array. + */ +static int __init +sn_io_early_init(void) +{ + int i; + + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) + return 0; + + /* + * prime sn_pci_provider[]. Individial provider init routines will + * override their respective default entries. + */ + + for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) + sn_pci_provider[i] = &sn_pci_default_provider; + + pcibr_init_provider(); + tioca_init_provider(); + tioce_init_provider(); + + /* + * This is needed to avoid bounce limit checks in the blk layer + */ + ia64_max_iommu_merge_mask = ~PAGE_MASK; + + sn_irq_lh_init(); + INIT_LIST_HEAD(&sn_sysdata_list); + sn_init_cpei_timer(); + +#ifdef CONFIG_PROC_FS + register_sn_procfs(); +#endif + + printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", + acpi_gbl_DSDT->oem_revision); + if (SN_ACPI_BASE_SUPPORT()) + sn_io_acpi_init(); + else + sn_io_init(); + return 0; +} + +arch_initcall(sn_io_early_init); + +/* + * sn_io_late_init() - Perform any final platform specific IO initialization. + */ + +int __init +sn_io_late_init(void) +{ + struct pci_bus *bus; + struct pcibus_bussoft *bussoft; + cnodeid_t cnode; + nasid_t nasid; + cnodeid_t near_cnode; + + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) + return 0; + + /* + * Setup closest node in pci_controller->node for + * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using + * info from the PROM). + */ + bus = NULL; + while ((bus = pci_find_next_bus(bus)) != NULL) { + bussoft = SN_PCIBUS_BUSSOFT(bus); + nasid = NASID_GET(bussoft->bs_base); + cnode = nasid_to_cnodeid(nasid); + if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) || + (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE)) { + /* TIO PCI Bridge: find nearest node with CPUs */ + int e = sn_hwperf_get_nearest_node(cnode, NULL, + &near_cnode); + if (e < 0) { + near_cnode = (cnodeid_t)-1; /* use any node */ + printk(KERN_WARNING "pcibr_bus_fixup: failed " + "to find near node with CPUs to TIO " + "node %d, err=%d\n", cnode, e); + } + PCI_CONTROLLER(bus)->node = near_cnode; + } else if (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC) { + PCI_CONTROLLER(bus)->node = cnode; + } + } + + sn_ioif_inited = 1; /* SN I/O infrastructure now initialized */ + + return 0; +} + +fs_initcall(sn_io_late_init); + +EXPORT_SYMBOL(sn_pci_fixup_slot); +EXPORT_SYMBOL(sn_pci_unfixup_slot); +EXPORT_SYMBOL(sn_bus_store_sysdata); +EXPORT_SYMBOL(sn_bus_free_sysdata); +EXPORT_SYMBOL(sn_generate_path); + diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index dc09a6a28a3..990224a4412 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -3,103 +3,28 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. */ -#include -#include #include #include -#include -#include #include -#include #include -#include +#include #include #include -#include #include -#include -#include #include "xtalk/hubdev.h" -#include "xtalk/xwidgetdev.h" - - -extern void sn_init_cpei_timer(void); -extern void register_sn_procfs(void); - -static struct list_head sn_sysdata_list; - -/* sysdata list struct */ -struct sysdata_el { - struct list_head entry; - void *sysdata; -}; - -struct slab_info { - struct hubdev_info hubdev; -}; - -struct brick { - moduleid_t id; /* Module ID of this module */ - struct slab_info slab_info[MAX_SLABS + 1]; -}; - -int sn_ioif_inited; /* SN I/O infrastructure initialized? */ - -struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ - -static int max_segment_number; /* Default highest segment number */ -static int max_pcibus_number = 255; /* Default highest pci bus number */ /* - * Hooks and struct for unsupported pci providers + * The code in this file will only be executed when running with + * a PROM that does _not_ have base ACPI IO support. + * (i.e., SN_ACPI_BASE_SUPPORT() == 0) */ -static dma_addr_t -sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) -{ - return 0; -} - -static void -sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) -{ - return; -} - -static void * -sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) -{ - return NULL; -} - -static struct sn_pcibus_provider sn_pci_default_provider = { - .dma_map = sn_default_pci_map, - .dma_map_consistent = sn_default_pci_map, - .dma_unmap = sn_default_pci_unmap, - .bus_fixup = sn_default_pci_bus_fixup, -}; - -/* - * Retrieve the DMA Flush List given nasid, widget, and device. - * This list is needed to implement the WAR - Flush DMA data on PIO Reads. - */ -static inline u64 -sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, - u64 address) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; +static int max_segment_number; /* Default highest segment number */ +static int max_pcibus_number = 255; /* Default highest pci bus number */ - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, - (u64) nasid, (u64) widget_num, - (u64) device_num, (u64) address, 0, 0, 0); - return ret_stuff.status; -} /* * Retrieve the hub device info structure for the given nasid. @@ -131,93 +56,20 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) return ret_stuff.v0; } -/* - * Retrieve the pci device information given the bus and device|function number. - */ -static inline u64 -sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, - u64 sn_irq_info) -{ - struct ia64_sal_retval ret_stuff; - ret_stuff.status = 0; - ret_stuff.v0 = 0; - - SAL_CALL_NOLOCK(ret_stuff, - (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, - (u64) segment, (u64) bus_number, (u64) devfn, - (u64) pci_dev, - sn_irq_info, 0, 0); - return ret_stuff.v0; -} - -/* - * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified - * device. - */ -inline struct pcidev_info * -sn_pcidev_info_get(struct pci_dev *dev) -{ - struct pcidev_info *pcidev; - - list_for_each_entry(pcidev, - &(SN_PCI_CONTROLLER(dev)->pcidev_info), pdi_list) { - if (pcidev->pdi_linux_pcidev == dev) { - return pcidev; - } - } - return NULL; -} - -/* Older PROM flush WAR - * - * 01/16/06 -- This war will be in place until a new official PROM is released. - * Additionally note that the struct sn_flush_device_war also has to be - * removed from arch/ia64/sn/include/xtalk/hubdev.h - */ -static u8 war_implemented = 0; - -static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, - struct sn_flush_device_common *common) -{ - struct sn_flush_device_war *war_list; - struct sn_flush_device_war *dev_entry; - struct ia64_sal_retval isrv = {0,0,0,0}; - - if (!war_implemented) { - printk(KERN_WARNING "PROM version < 4.50 -- implementing old " - "PROM flush WAR\n"); - war_implemented = 1; - } - - war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); - if (!war_list) - BUG(); - - SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, - nasid, widget, __pa(war_list), 0, 0, 0 ,0); - if (isrv.status) - panic("sn_device_fixup_war failed: %s\n", - ia64_sal_strerror(isrv.status)); - - dev_entry = war_list + device; - memcpy(common,dev_entry, sizeof(*common)); - kfree(war_list); - - return isrv.status; -} /* - * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for - * each node in the system. + * sn_fixup_ionodes() - This routine initializes the HUB data structure for + * each node in the system. This function is only + * executed when running with a non-ACPI capable PROM. */ static void __init sn_fixup_ionodes(void) { - struct sn_flush_device_kernel *sn_flush_device_kernel; - struct sn_flush_device_kernel *dev_entry; + struct hubdev_info *hubdev; u64 status; u64 nasid; - int i, widget, device, size; + int i; + extern void sn_common_hubdev_init(struct hubdev_info *); /* * Get SGI Specific HUB chipset information. @@ -240,70 +92,47 @@ static void __init sn_fixup_ionodes(void) max_segment_number = hubdev->max_segment_number; max_pcibus_number = hubdev->max_pcibus_number; } + sn_common_hubdev_init(hubdev); + } +} - /* Attach the error interrupt handlers */ - if (nasid & 1) - ice_error_init(hubdev); - else - hub_error_init(hubdev); - - for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) - hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; - - if (!hubdev->hdi_flush_nasid_list.widget_p) - continue; - - size = (HUB_WIDGET_ID_MAX + 1) * - sizeof(struct sn_flush_device_kernel *); - hubdev->hdi_flush_nasid_list.widget_p = - kzalloc(size, GFP_KERNEL); - if (!hubdev->hdi_flush_nasid_list.widget_p) +/* + * sn_pci_legacy_window_fixup - Create PCI controller windows for + * legacy IO and MEM space. This needs to + * be done here, as the PROM does not have + * ACPI support defining the root buses + * and their resources (_CRS), + */ +static void +sn_legacy_pci_window_fixup(struct pci_controller *controller, + u64 legacy_io, u64 legacy_mem) +{ + controller->window = kcalloc(2, sizeof(struct pci_window), + GFP_KERNEL); + if (controller->window == NULL) BUG(); - - for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { - size = DEV_PER_WIDGET * - sizeof(struct sn_flush_device_kernel); - sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); - if (!sn_flush_device_kernel) - BUG(); - - dev_entry = sn_flush_device_kernel; - for (device = 0; device < DEV_PER_WIDGET; - device++,dev_entry++) { - size = sizeof(struct sn_flush_device_common); - dev_entry->common = kzalloc(size, GFP_KERNEL); - if (!dev_entry->common) - BUG(); - - if (sn_prom_feature_available( - PRF_DEVICE_FLUSH_LIST)) - status = sal_get_device_dmaflush_list( - nasid, widget, device, - (u64)(dev_entry->common)); - else - status = sn_device_fixup_war(nasid, - widget, device, - dev_entry->common); - if (status != SALRET_OK) - panic("SAL call failed: %s\n", - ia64_sal_strerror(status)); - - spin_lock_init(&dev_entry->sfdl_flush_lock); - } - - if (sn_flush_device_kernel) - hubdev->hdi_flush_nasid_list.widget_p[widget] = - sn_flush_device_kernel; - } - } + controller->window[0].offset = legacy_io; + controller->window[0].resource.name = "legacy_io"; + controller->window[0].resource.flags = IORESOURCE_IO; + controller->window[0].resource.start = legacy_io; + controller->window[0].resource.end = + controller->window[0].resource.start + 0xffff; + controller->window[0].resource.parent = &ioport_resource; + controller->window[1].offset = legacy_mem; + controller->window[1].resource.name = "legacy_mem"; + controller->window[1].resource.flags = IORESOURCE_MEM; + controller->window[1].resource.start = legacy_mem; + controller->window[1].resource.end = + controller->window[1].resource.start + (1024 * 1024) - 1; + controller->window[1].resource.parent = &iomem_resource; + controller->windows = 2; } /* * sn_pci_window_fixup() - Create a pci_window for each device resource. - * Until ACPI support is added, we need this code - * to setup pci_windows for use by - * pcibios_bus_to_resource(), - * pcibios_resource_to_bus(), etc. + * It will setup pci_windows for use by + * pcibios_bus_to_resource(), pcibios_resource_to_bus(), + * etc. */ static void sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, @@ -342,60 +171,22 @@ sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, controller->window = new_window; } -void sn_pci_unfixup_slot(struct pci_dev *dev) -{ - struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; - - sn_irq_unfixup(dev); - pci_dev_put(host_pci_dev); - pci_dev_put(dev); -} - /* - * sn_pci_fixup_slot() - This routine sets up a slot's resources - * consistent with the Linux PCI abstraction layer. Resources acquired - * from our PCI provider include PIO maps to BAR space and interrupt - * objects. + * sn_more_slot_fixup() - We are not running with an ACPI capable PROM, + * and need to convert the pci_dev->resource + * 'start' and 'end' addresses to mapped addresses, + * and setup the pci_controller->window array entries. */ -void sn_pci_fixup_slot(struct pci_dev *dev) +void +sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) { unsigned int count = 0; int idx; - int segment = pci_domain_nr(dev->bus); - int status = 0; - struct pcibus_bussoft *bs; - struct pci_bus *host_pci_bus; - struct pci_dev *host_pci_dev; - struct pcidev_info *pcidev_info; s64 pci_addrs[PCI_ROM_RESOURCE + 1]; - struct sn_irq_info *sn_irq_info; - unsigned long size; - unsigned int bus_no, devfn; - - pci_dev_get(dev); /* for the sysdata pointer */ - pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); - if (!pcidev_info) - BUG(); /* Cannot afford to run out of memory */ - - sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); - if (!sn_irq_info) - BUG(); /* Cannot afford to run out of memory */ - - /* Call to retrieve pci device information needed by kernel. */ - status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, - dev->devfn, - (u64) __pa(pcidev_info), - (u64) __pa(sn_irq_info)); - if (status) - BUG(); /* Cannot get platform pci device information */ - - /* Add pcidev_info to list in sn_pci_controller struct */ - list_add_tail(&pcidev_info->pdi_list, - &(SN_PCI_CONTROLLER(dev->bus)->pcidev_info)); + unsigned long addr, end, size, start; /* Copy over PIO Mapped Addresses */ for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { - unsigned long start, end, addr; if (!pcidev_info->pdi_pio_mapped_addr[idx]) { pci_addrs[idx] = -1; @@ -425,54 +216,19 @@ void sn_pci_fixup_slot(struct pci_dev *dev) */ if (count > 0) sn_pci_window_fixup(dev, count, pci_addrs); - - /* - * Using the PROMs values for the PCI host bus, get the Linux - * PCI host_pci_dev struct and set up host bus linkages - */ - - bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; - devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff; - host_pci_bus = pci_find_bus(segment, bus_no); - host_pci_dev = pci_get_slot(host_pci_bus, devfn); - - pcidev_info->host_pci_dev = host_pci_dev; - pcidev_info->pdi_linux_pcidev = dev; - pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev); - bs = SN_PCIBUS_BUSSOFT(dev->bus); - pcidev_info->pdi_pcibus_info = bs; - - if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { - SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; - } else { - SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider; - } - - /* Only set up IRQ stuff if this device has a host bus context */ - if (bs && sn_irq_info->irq_irq) { - pcidev_info->pdi_sn_irq_info = sn_irq_info; - dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq; - sn_irq_fixup(dev, sn_irq_info); - } else { - pcidev_info->pdi_sn_irq_info = NULL; - kfree(sn_irq_info); - } } /* * sn_pci_controller_fixup() - This routine sets up a bus's resources - * consistent with the Linux PCI abstraction layer. + * consistent with the Linux PCI abstraction layer. */ -void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) +static void +sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) { - int status; - int nasid, cnode; + s64 status = 0; struct pci_controller *controller; - struct sn_pci_controller *sn_controller; struct pcibus_bussoft *prom_bussoft_ptr; - struct hubdev_info *hubdev_info; - void *provider_soft; - struct sn_pcibus_provider *provider; + status = sal_get_pcibus_info((u64) segment, (u64) busnum, (u64) ia64_tpa(&prom_bussoft_ptr)); @@ -480,261 +236,77 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) return; /*bus # does not exist */ prom_bussoft_ptr = __va(prom_bussoft_ptr); - /* Allocate a sn_pci_controller, which has a pci_controller struct - * as the first member. - */ - sn_controller = kzalloc(sizeof(struct sn_pci_controller), GFP_KERNEL); - if (!sn_controller) + controller = kzalloc(sizeof(*controller), GFP_KERNEL); + if (!controller) BUG(); - INIT_LIST_HEAD(&sn_controller->pcidev_info); - controller = &sn_controller->pci_controller; controller->segment = segment; - if (bus == NULL) { - bus = pci_scan_bus(busnum, &pci_root_ops, controller); - if (bus == NULL) - goto error_return; /* error, or bus already scanned */ - bus->sysdata = NULL; - } - - if (bus->sysdata) - goto error_return; /* sysdata already alloc'd */ - /* - * Per-provider fixup. Copies the contents from prom to local - * area and links SN_PCIBUS_BUSSOFT(). + * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup(). + * (platform_data will be overwritten later in sn_common_bus_fixup()) */ + controller->platform_data = prom_bussoft_ptr; - if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) - goto error_return; /* unsupported asic type */ - - if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) - goto error_return; /* no further fixup necessary */ - - provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; - if (provider == NULL) - goto error_return; /* no provider registerd for this asic */ + bus = pci_scan_bus(busnum, &pci_root_ops, controller); + if (bus == NULL) + goto error_return; /* error, or bus already scanned */ bus->sysdata = controller; - if (provider->bus_fixup) - provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); - else - provider_soft = NULL; - - if (provider_soft == NULL) { - /* fixup failed or not applicable */ - bus->sysdata = NULL; - goto error_return; - } - - /* - * Setup pci_windows for legacy IO and MEM space. - * (Temporary until ACPI support is in place.) - */ - controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL); - if (controller->window == NULL) - BUG(); - controller->window[0].offset = prom_bussoft_ptr->bs_legacy_io; - controller->window[0].resource.name = "legacy_io"; - controller->window[0].resource.flags = IORESOURCE_IO; - controller->window[0].resource.start = prom_bussoft_ptr->bs_legacy_io; - controller->window[0].resource.end = - controller->window[0].resource.start + 0xffff; - controller->window[0].resource.parent = &ioport_resource; - controller->window[1].offset = prom_bussoft_ptr->bs_legacy_mem; - controller->window[1].resource.name = "legacy_mem"; - controller->window[1].resource.flags = IORESOURCE_MEM; - controller->window[1].resource.start = prom_bussoft_ptr->bs_legacy_mem; - controller->window[1].resource.end = - controller->window[1].resource.start + (1024 * 1024) - 1; - controller->window[1].resource.parent = &iomem_resource; - controller->windows = 2; - - /* - * Generic bus fixup goes here. Don't reference prom_bussoft_ptr - * after this point. - */ - - PCI_CONTROLLER(bus)->platform_data = provider_soft; - nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); - cnode = nasid_to_cnodeid(nasid); - hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); - SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = - &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); - /* - * If the node information we obtained during the fixup phase is invalid - * then set controller->node to -1 (undetermined) - */ - if (controller->node >= num_online_nodes()) { - struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); - - printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" - "L_IO=%lx L_MEM=%lx BASE=%lx\n", - b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, - b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); - printk(KERN_WARNING "on node %d but only %d nodes online." - "Association set to undetermined.\n", - controller->node, num_online_nodes()); - controller->node = -1; - } return; error_return: - kfree(sn_controller); + kfree(controller); return; } -void sn_bus_store_sysdata(struct pci_dev *dev) +/* + * sn_bus_fixup + */ +void +sn_bus_fixup(struct pci_bus *bus) { - struct sysdata_el *element; - - element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); - if (!element) { - dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); - return; - } - element->sysdata = SN_PCIDEV_INFO(dev); - list_add(&element->entry, &sn_sysdata_list); -} + struct pci_dev *pci_dev = NULL; + struct pcibus_bussoft *prom_bussoft_ptr; + extern void sn_common_bus_fixup(struct pci_bus *, + struct pcibus_bussoft *); + + + if (!bus->parent) { /* If root bus */ + prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data; + if (prom_bussoft_ptr == NULL) { + printk(KERN_ERR + "sn_bus_fixup: 0x%04x:0x%02x Unable to " + "obtain prom_bussoft_ptr\n", + pci_domain_nr(bus), bus->number); + return; + } + sn_common_bus_fixup(bus, prom_bussoft_ptr); + sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), + prom_bussoft_ptr->bs_legacy_io, + prom_bussoft_ptr->bs_legacy_mem); + } + list_for_each_entry(pci_dev, &bus->devices, bus_list) { + sn_pci_fixup_slot(pci_dev); + } -void sn_bus_free_sysdata(void) -{ - struct sysdata_el *element; - struct list_head *list, *safe; - - list_for_each_safe(list, safe, &sn_sysdata_list) { - element = list_entry(list, struct sysdata_el, entry); - list_del(&element->entry); - list_del(&(((struct pcidev_info *) - (element->sysdata))->pdi_list)); - kfree(element->sysdata); - kfree(element); - } - return; } /* - * Ugly hack to get PCI setup until we have a proper ACPI namespace. + * sn_io_init - PROM does not have ACPI support to define nodes or root buses, + * so we need to do things the hard way, including initiating the + * bus scanning ourselves. */ -#define PCI_BUSES_TO_SCAN 256 - -static int __init sn_pci_init(void) +void __init sn_io_init(void) { int i, j; - struct pci_dev *pci_dev = NULL; - - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) - return 0; - - /* - * prime sn_pci_provider[]. Individial provider init routines will - * override their respective default entries. - */ - - for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) - sn_pci_provider[i] = &sn_pci_default_provider; - pcibr_init_provider(); - tioca_init_provider(); - tioce_init_provider(); - - /* - * This is needed to avoid bounce limit checks in the blk layer - */ - ia64_max_iommu_merge_mask = ~PAGE_MASK; sn_fixup_ionodes(); - sn_irq_lh_init(); - INIT_LIST_HEAD(&sn_sysdata_list); - sn_init_cpei_timer(); - -#ifdef CONFIG_PROC_FS - register_sn_procfs(); -#endif /* busses are not known yet ... */ for (i = 0; i <= max_segment_number; i++) for (j = 0; j <= max_pcibus_number; j++) sn_pci_controller_fixup(i, j, NULL); - - /* - * Generic Linux PCI Layer has created the pci_bus and pci_dev - * structures - time for us to add our SN PLatform specific - * information. - */ - - while ((pci_dev = - pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) - sn_pci_fixup_slot(pci_dev); - - sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ - - return 0; -} - -/* - * hubdev_init_node() - Creates the HUB data structure and link them to it's - * own NODE specific data area. - */ -void hubdev_init_node(nodepda_t * npda, cnodeid_t node) -{ - struct hubdev_info *hubdev_info; - int size; - pg_data_t *pg; - - size = sizeof(struct hubdev_info); - - if (node >= num_online_nodes()) /* Headless/memless IO nodes */ - pg = NODE_DATA(0); - else - pg = NODE_DATA(node); - - hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); - - npda->pdinfo = (void *)hubdev_info; } - -geoid_t -cnodeid_get_geoid(cnodeid_t cnode) -{ - struct hubdev_info *hubdev; - - hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); - return hubdev->hdi_geoid; -} - -void sn_generate_path(struct pci_bus *pci_bus, char *address) -{ - nasid_t nasid; - cnodeid_t cnode; - geoid_t geoid; - moduleid_t moduleid; - u16 bricktype; - - nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); - cnode = nasid_to_cnodeid(nasid); - geoid = cnodeid_get_geoid(cnode); - moduleid = geo_module(geoid); - - sprintf(address, "module_%c%c%c%c%.2d", - '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), - '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), - '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), - MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); - - /* Tollhouse requires slot id to be displayed */ - bricktype = MODULE_GET_BTYPE(moduleid); - if ((bricktype == L1_BRICKTYPE_191010) || - (bricktype == L1_BRICKTYPE_1932)) - sprintf(address, "%s^%d", address, geo_slot(geoid)); -} - -subsys_initcall(sn_pci_init); -EXPORT_SYMBOL(sn_pci_fixup_slot); -EXPORT_SYMBOL(sn_pci_unfixup_slot); -EXPORT_SYMBOL(sn_pci_controller_fixup); -EXPORT_SYMBOL(sn_bus_store_sysdata); -EXPORT_SYMBOL(sn_bus_free_sysdata); -EXPORT_SYMBOL(sn_generate_path); diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c index 7ce3cdad627..4aa4f301d56 100644 --- a/arch/ia64/sn/kernel/iomv.c +++ b/arch/ia64/sn/kernel/iomv.c @@ -3,10 +3,11 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2000-2003, 2006 Silicon Graphics, Inc. All rights reserved. */ #include +#include #include #include #include @@ -15,6 +16,7 @@ #include #include #include +#include #define IS_LEGACY_VGA_IOPORT(p) \ (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) @@ -31,11 +33,14 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { if (IS_LEGACY_VGA_IOPORT(port)) - port += vga_console_iobase; + return (__ia64_mk_io_addr(port)); /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; - return ((void *)(port | __IA64_UNCACHED_OFFSET)); + if (SN_ACPI_BASE_SUPPORT()) + return (__ia64_mk_io_addr(port)); + else + return ((void *)(port | __IA64_UNCACHED_OFFSET)); } else { /* but the simulator uses them... */ unsigned long addr; diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 7a2d824c5ce..1d009f93244 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -388,6 +388,14 @@ void __init sn_setup(char **cmdline_p) ia64_sn_plat_set_error_handling_features(); // obsolete ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); + /* + * Note: The calls to notify the PROM of ACPI and PCI Segment + * support must be done prior to acpi_load_tables(), as + * an ACPI capable PROM will rebuild the DSDT as result + * of the call. + */ + ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE); + ia64_sn_set_os_feature(OSF_ACPI_ENABLE); #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) @@ -413,6 +421,16 @@ void __init sn_setup(char **cmdline_p) if (! vga_console_membase) sn_scan_pcdp(); + /* + * Setup legacy IO space. + * vga_console_iobase maps to PCI IO Space address 0 on the + * bus containing the VGA console. + */ + if (vga_console_iobase) { + io_space[0].mmio_base = vga_console_iobase; + io_space[0].sparse = 0; + } + if (vga_console_membase) { /* usable vga ... make tty0 the preferred default console */ if (!strstr(*cmdline_p, "console=")) diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index feaf1a6e810..493380b2c05 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -552,7 +552,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -subsys_initcall(tiocx_init); +fs_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index 27dd7df0f44..6846dc9b432 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001-2004 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 2001-2004, 2006 Silicon Graphics, Inc. All rights reserved. */ #include @@ -109,7 +109,6 @@ void * pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { int nasid, cnode, j; - cnodeid_t near_cnode; struct hubdev_info *hubdev_info; struct pcibus_info *soft; struct sn_flush_device_kernel *sn_flush_device_kernel; @@ -186,20 +185,6 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont return NULL; } - if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) { - /* TIO PCI Bridge: find nearest node with CPUs */ - int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode); - - if (e < 0) { - near_cnode = (cnodeid_t)-1; /* use any node */ - printk(KERN_WARNING "pcibr_bus_fixup: failed to find " - "near node with CPUs to TIO node %d, err=%d\n", - cnode, e); - } - controller->node = near_cnode; - } - else - controller->node = cnode; return soft; } diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c index 46e16dcf597..35f854fb612 100644 --- a/arch/ia64/sn/pci/tioce_provider.c +++ b/arch/ia64/sn/pci/tioce_provider.c @@ -15,7 +15,6 @@ #include #include #include -#include /* * 1/26/2006 @@ -990,8 +989,6 @@ tioce_target_interrupt(struct sn_irq_info *sn_irq_info) static void * tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller) { - int my_nasid; - cnodeid_t my_cnode, mem_cnode; struct tioce_common *tioce_common; struct tioce_kernel *tioce_kern; struct tioce __iomem *tioce_mmr; @@ -1035,21 +1032,6 @@ tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont tioce_common->ce_pcibus.bs_persist_segment, tioce_common->ce_pcibus.bs_persist_busnum); - /* - * identify closest nasid for memory allocations - */ - - my_nasid = NASID_GET(tioce_common->ce_pcibus.bs_base); - my_cnode = nasid_to_cnodeid(my_nasid); - - if (sn_hwperf_get_nearest_node(my_cnode, &mem_cnode, NULL) < 0) { - printk(KERN_WARNING "tioce_bus_fixup: failed to find " - "closest node with MEM to TIO node %d\n", my_cnode); - mem_cnode = (cnodeid_t)-1; /* use any node */ - } - - controller->node = mem_cnode; - return tioce_common; } -- cgit v1.2.3 From a2302c68d923537436b1114aa207787c1a31bd50 Mon Sep 17 00:00:00 2001 From: John Keller Date: Wed, 4 Oct 2006 16:49:52 -0500 Subject: Altix: Initial ACPI support - ROM shadowing. Support a shadowed ROM when running with an ACPI capable PROM. Define a new dev.resource flag IORESOURCE_ROM_BIOS_COPY to describe the case of a BIOS shadowed ROM, which can then be used to avoid pci_map_rom() making an unneeded call to pci_enable_rom(). Signed-off-by: John Keller Signed-off-by: Greg Kroah-Hartman --- arch/ia64/sn/kernel/io_acpi_init.c | 33 +++++++++++++++++++++++++++++++++ arch/ia64/sn/kernel/io_common.c | 5 +++-- arch/ia64/sn/kernel/io_init.c | 3 +++ 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c index a9dc36901b1..99d7f278612 100644 --- a/arch/ia64/sn/kernel/io_acpi_init.c +++ b/arch/ia64/sn/kernel/io_acpi_init.c @@ -169,6 +169,39 @@ sn_acpi_bus_fixup(struct pci_bus *bus) } } +/* + * sn_acpi_slot_fixup - Perform any SN specific slot fixup. + * At present there does not appear to be + * any generic way to handle a ROM image + * that has been shadowed by the PROM, so + * we pass a pointer to it within the + * pcidev_info structure. + */ + +void +sn_acpi_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) +{ + void __iomem *addr; + size_t size; + + if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) { + /* + * A valid ROM image exists and has been shadowed by the + * PROM. Setup the pci_dev ROM resource to point to + * the shadowed copy. + */ + size = dev->resource[PCI_ROM_RESOURCE].end - + dev->resource[PCI_ROM_RESOURCE].start; + addr = + ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE], + size); + dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr; + dev->resource[PCI_ROM_RESOURCE].end = + (unsigned long) addr + size; + dev->resource[PCI_ROM_RESOURCE].flags |= IORESOURCE_ROM_BIOS_COPY; + } +} + static struct acpi_driver acpi_sn_hubdev_driver = { .name = "SGI HUBDEV Driver", .ids = "SGIHUB,SGITIO", diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c index 12531de6754..d4dd8f4b6b8 100644 --- a/arch/ia64/sn/kernel/io_common.c +++ b/arch/ia64/sn/kernel/io_common.c @@ -286,9 +286,10 @@ void sn_pci_fixup_slot(struct pci_dev *dev) list_add_tail(&pcidev_info->pdi_list, &(SN_PLATFORM_DATA(dev->bus)->pcidev_info)); - if (!SN_ACPI_BASE_SUPPORT()) + if (SN_ACPI_BASE_SUPPORT()) + sn_acpi_slot_fixup(dev, pcidev_info); + else sn_more_slot_fixup(dev, pcidev_info); - /* * Using the PROMs values for the PCI host bus, get the Linux * PCI host_pci_dev struct and set up host bus linkages diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 990224a4412..9ad843e0383 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -210,6 +210,9 @@ sn_more_slot_fixup(struct pci_dev *dev, struct pcidev_info *pcidev_info) dev->resource[idx].parent = &ioport_resource; else dev->resource[idx].parent = &iomem_resource; + /* If ROM, mark as shadowed in PROM */ + if (idx == PCI_ROM_RESOURCE) + dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY; } /* Create a pci_window in the pci_controller struct for * each device resource. -- cgit v1.2.3 From 7edab2f0876ff6a38e10a88c9aca20180aad307c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 17 Oct 2006 10:17:58 -0700 Subject: pci/i386: style cleanups Mostly CodingStyle cleanups for arch/i386/pci/i386.c: - fit in 80 columns; - use a #defined value instead of an inline constant; Also change one resource_size_t (DBG) printk from %08lx to %lx since it can be more than 32 bits (more than 8 hexits). Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/i386.c | 64 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 98580292f0d..43005f04442 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -104,16 +104,24 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) /* Depth-First Search on bus tree */ list_for_each_entry(bus, bus_list, node) { if ((dev = bus->self)) { - for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { + for (idx = PCI_BRIDGE_RESOURCES; + idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; if (!r->flags) continue; pr = pci_find_parent_resource(dev, r); - if (!r->start || !pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); - /* Something is wrong with the region. - Invalidate the resource to prevent child - resource allocations in this range. */ + if (!r->start || !pr || + request_resource(pr, r) < 0) { + printk(KERN_ERR "PCI: Cannot allocate " + "resource region %d " + "of bridge %s\n", + idx, pci_name(dev)); + /* + * Something is wrong with the region. + * Invalidate the resource to prevent + * child resource allocations in this + * range. + */ r->flags = 0; } } @@ -131,7 +139,7 @@ static void __init pcibios_allocate_resources(int pass) for_each_pci_dev(dev) { pci_read_config_word(dev, PCI_COMMAND, &command); - for(idx = 0; idx < 6; idx++) { + for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { r = &dev->resource[idx]; if (r->parent) /* Already allocated */ continue; @@ -142,11 +150,15 @@ static void __init pcibios_allocate_resources(int pass) else disabled = !(command & PCI_COMMAND_MEMORY); if (pass == disabled) { - DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n", + DBG("PCI: Resource %08lx-%08lx " + "(f=%lx, d=%d, p=%d)\n", r->start, r->end, r->flags, disabled, pass); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { - printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev)); + printk(KERN_ERR "PCI: Cannot allocate " + "resource region %d " + "of device %s\n", + idx, pci_name(dev)); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; @@ -156,12 +168,16 @@ static void __init pcibios_allocate_resources(int pass) if (!pass) { r = &dev->resource[PCI_ROM_RESOURCE]; if (r->flags & IORESOURCE_ROM_ENABLE) { - /* Turn the ROM off, leave the resource region, but keep it unregistered. */ + /* Turn the ROM off, leave the resource region, + * but keep it unregistered. */ u32 reg; - DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); + DBG("PCI: Switching off ROM of %s\n", + pci_name(dev)); r->flags &= ~IORESOURCE_ROM_ENABLE; - pci_read_config_dword(dev, dev->rom_base_reg, ®); - pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE); + pci_read_config_dword(dev, + dev->rom_base_reg, ®); + pci_write_config_dword(dev, dev->rom_base_reg, + reg & ~PCI_ROM_ADDRESS_ENABLE); } } } @@ -173,9 +189,11 @@ static int __init pcibios_assign_resources(void) struct resource *r, *pr; if (!(pci_probe & PCI_ASSIGN_ROMS)) { - /* Try to use BIOS settings for ROMs, otherwise let - pci_assign_unassigned_resources() allocate the new - addresses. */ + /* + * Try to use BIOS settings for ROMs, otherwise let + * pci_assign_unassigned_resources() allocate the new + * addresses. + */ for_each_pci_dev(dev) { r = &dev->resource[PCI_ROM_RESOURCE]; if (!r->flags || !r->start) @@ -215,9 +233,9 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { + for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { /* Only set up the requested stuff */ - if (!(mask & (1<resource[idx]; @@ -227,7 +245,9 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) (!(r->flags & IORESOURCE_ROM_ENABLE))) continue; if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -236,7 +256,8 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; } if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; @@ -258,7 +279,8 @@ void pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); + printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } -- cgit v1.2.3 From 039d09a845209122c5193e650ab2d8b3c849ca7c Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Tue, 17 Oct 2006 10:02:50 +0530 Subject: PCI: arch/i386/kernel/pci-dma.c: ioremap balanced with iounmap ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Tested (compilation only): - using allmodconfig - making sure the files are compiling without any warning/error due to new changes Signed-off-by: Amol Lad Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/pci-dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c index 25fe6685393..5c8c6ef1fc5 100644 --- a/arch/i386/kernel/pci-dma.c +++ b/arch/i386/kernel/pci-dma.c @@ -75,7 +75,7 @@ EXPORT_SYMBOL(dma_free_coherent); int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, dma_addr_t device_addr, size_t size, int flags) { - void __iomem *mem_base; + void __iomem *mem_base = NULL; int pages = size >> PAGE_SHIFT; int bitmap_size = (pages + 31)/32; @@ -114,6 +114,8 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, free1_out: kfree(dev->dma_mem->bitmap); out: + if (mem_base) + iounmap(mem_base); return 0; } EXPORT_SYMBOL(dma_declare_coherent_memory); -- cgit v1.2.3 From 3b59d52d8c7925e7a9a396f2e31a66eb060c6c37 Mon Sep 17 00:00:00 2001 From: Jason Gaston Date: Wed, 22 Nov 2006 15:15:08 -0800 Subject: PCI: irq: irq and pci_ids patch for Intel ICH9 This updated patch adds the Intel ICH9 LPC and SMBus Controller DID's. Signed-off-by: Jason Gaston Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/irq.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 69163998ade..e65551cd821 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -543,6 +543,12 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH8_2: case PCI_DEVICE_ID_INTEL_ICH8_3: case PCI_DEVICE_ID_INTEL_ICH8_4: + case PCI_DEVICE_ID_INTEL_ICH9_0: + case PCI_DEVICE_ID_INTEL_ICH9_1: + case PCI_DEVICE_ID_INTEL_ICH9_2: + case PCI_DEVICE_ID_INTEL_ICH9_3: + case PCI_DEVICE_ID_INTEL_ICH9_4: + case PCI_DEVICE_ID_INTEL_ICH9_5: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; -- cgit v1.2.3 From 2b290da053608692ea206507d993b70c39d2cdea Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 16 Nov 2006 13:16:23 +0100 Subject: PCI: make arch/i386/pci/common.c:pci_bf_sort static This patch makes the needlessly global pci_bf_sort static. Signed-off-by: Adrian Bunk Acked-by: Matt Domsch Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index cdfcf971098..53ca6e89798 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -20,7 +20,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF; -int pci_bf_sort; +static int pci_bf_sort; int pci_routeirq; int pcibios_last_bus = -1; unsigned long pirq_table_addr; -- cgit v1.2.3 From a271aaf15f492d202def1b34e447107b60fe4ece Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Aug 2006 22:19:37 -0700 Subject: Driver core: convert msr code to use struct device Converts from using struct "class_device" to "struct device" making everything show up properly in /sys/devices/ with symlinks from the /sys/class directory. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/msr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index d535cdbbfd2..a773f776c9e 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -239,14 +239,14 @@ static struct file_operations msr_fops = { .open = msr_open, }; -static int msr_class_device_create(int i) +static int msr_device_create(int i) { int err = 0; - struct class_device *class_err; + struct device *dev; - class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); - if (IS_ERR(class_err)) - err = PTR_ERR(class_err); + dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); + if (IS_ERR(dev)) + err = PTR_ERR(dev); return err; } @@ -258,10 +258,10 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, switch (action) { case CPU_ONLINE: - msr_class_device_create(cpu); + msr_device_create(cpu); break; case CPU_DEAD: - class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); + device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); break; } return NOTIFY_OK; @@ -290,7 +290,7 @@ static int __init msr_init(void) goto out_chrdev; } for_each_online_cpu(i) { - err = msr_class_device_create(i); + err = msr_device_create(i); if (err != 0) goto out_class; } @@ -302,7 +302,7 @@ static int __init msr_init(void) out_class: i = 0; for_each_online_cpu(i) - class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); + device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); class_destroy(msr_class); out_chrdev: unregister_chrdev(MSR_MAJOR, "cpu/msr"); @@ -314,7 +314,7 @@ static void __exit msr_exit(void) { int cpu = 0; for_each_online_cpu(cpu) - class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); + device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); class_destroy(msr_class); unregister_chrdev(MSR_MAJOR, "cpu/msr"); unregister_hotcpu_notifier(&msr_class_cpu_notifier); -- cgit v1.2.3 From 07accdc18e014cad945013886ee34e09f859f88a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 7 Aug 2006 22:19:37 -0700 Subject: Driver core: convert cpuid code to use struct device Converts from using struct "class_device" to "struct device" making everything show up properly in /sys/devices/ with symlinks from the /sys/class directory. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/cpuid.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index fde8bea85ce..ab0c327e79d 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -156,14 +156,14 @@ static struct file_operations cpuid_fops = { .open = cpuid_open, }; -static int cpuid_class_device_create(int i) +static int cpuid_device_create(int i) { int err = 0; - struct class_device *class_err; + struct device *dev; - class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i); - if (IS_ERR(class_err)) - err = PTR_ERR(class_err); + dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i); + if (IS_ERR(dev)) + err = PTR_ERR(dev); return err; } @@ -174,10 +174,10 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac switch (action) { case CPU_ONLINE: - cpuid_class_device_create(cpu); + cpuid_device_create(cpu); break; case CPU_DEAD: - class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); + device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); break; } return NOTIFY_OK; @@ -206,7 +206,7 @@ static int __init cpuid_init(void) goto out_chrdev; } for_each_online_cpu(i) { - err = cpuid_class_device_create(i); + err = cpuid_device_create(i); if (err != 0) goto out_class; } @@ -218,7 +218,7 @@ static int __init cpuid_init(void) out_class: i = 0; for_each_online_cpu(i) { - class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); + device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i)); } class_destroy(cpuid_class); out_chrdev: @@ -232,7 +232,7 @@ static void __exit cpuid_exit(void) int cpu = 0; for_each_online_cpu(cpu) - class_device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); + device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu)); class_destroy(cpuid_class); unregister_chrdev(CPUID_MAJOR, "cpu/cpuid"); unregister_hotcpu_notifier(&cpuid_class_cpu_notifier); -- cgit v1.2.3 From 0e5fdca7622eb950f42f97a1970670e00a739175 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 2 Dec 2006 00:03:47 +0100 Subject: [ARM] 3971/1: xsc3: get rid of L_PTE_COHERENT Merge L_PTE_COHERENT with L_PTE_SHARED and free up a L_PTE_* bit. Signed-off-by: Lennert Buytenhek Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 2 +- arch/arm/mm/proc-xsc3.S | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index f866bf6b97d..445bc3b951e 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -265,7 +265,7 @@ static void __init build_mem_type_table(void) if (arch_is_coherent()) { if (cpu_is_xsc3()) { mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; + mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; } } diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index c4d778a8619..85c3523d0a9 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -371,8 +371,10 @@ ENTRY(cpu_xsc3_switch_mm) ENTRY(cpu_xsc3_set_pte) str r1, [r0], #-2048 @ linux version - bic r2, r1, #0xdf0 @ Keep C, B, coherency bits + bic r2, r1, #0xff0 @ Keep C, B bits orr r2, r2, #PTE_TYPE_EXT @ extended page + tst r1, #L_PTE_SHARED @ Shared? + orrne r2, r2, #0x200 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY -- cgit v1.2.3 From f5236225a3858b505221a59233af1f1158be9139 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 1 Dec 2006 19:31:42 +0100 Subject: [ARM] 3967/1: xsc3: make branch predication configurable on xsc3 Remove BTB_ENABLE from proc-xsc3.S On some early revisions of xsc3 enabling the branch target buffer can cause crashes, see erratum #42. Cc: Lennert Buytenhek Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/mm/Kconfig | 2 +- arch/arm/mm/proc-xsc3.S | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c0bfb8212b7..efebd605028 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -580,7 +580,7 @@ config CPU_CACHE_ROUND_ROBIN config CPU_BPREDICT_DISABLE bool "Disable branch prediction" - depends on CPU_ARM1020 || CPU_V6 + depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 help Say Y here to disable branch prediction. If unsure, say N. diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index 85c3523d0a9..1ef564d0957 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S @@ -56,11 +56,6 @@ */ #define L2_CACHE_ENABLE 1 -/* - * Enable the Branch Target Buffer (can cause crashes, see erratum #42.) - */ -#define BTB_ENABLE 0 - /* * This macro is used to wait for a CP15 write and is needed * when we have to ensure that the last operation to the co-pro @@ -434,9 +429,7 @@ __xsc3_setup: mrc p15, 0, r0, c1, c0, 0 @ get control register bic r0, r0, r5 @ .... .... .... ..A. orr r0, r0, r6 @ .... .... .... .C.M -#if BTB_ENABLE orr r0, r0, #0x00000800 @ ..VI Z..S .... .... -#endif #if L2_CACHE_ENABLE orr r0, r0, #0x04000000 @ L2 enable #endif -- cgit v1.2.3 From 7bdd21cef9e5dbc3d3a718c55bb3d0da024644da Mon Sep 17 00:00:00 2001 From: Len Brown Date: Sat, 2 Dec 2006 02:27:46 -0500 Subject: Revert "ACPI: SCI interrupt source override" This reverts commit 281ea49b0c294649a6de47a6f8fbe5611137726b, which broke ACPI Interrupt source overrides that move the SCI from one IRQ in PIC mode to another in IOAPIC mode. If the SCI shared an interrupt line with another device, this would result in a "irq 18: nobody cared" type failure. http://bugzilla.kernel.org/show_bug.cgi?id=7601 Signed-off-by: Len Brown --- arch/i386/kernel/acpi/boot.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index d12fb97a533..c8f96cff07c 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -333,7 +333,7 @@ acpi_parse_ioapic(acpi_table_entry_header * header, const unsigned long end) /* * Parse Interrupt Source Override for the ACPI SCI */ -static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigger) +static void acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger) { if (trigger == 0) /* compatible SCI trigger is level */ trigger = 3; @@ -353,13 +353,13 @@ static void acpi_sci_ioapic_setup(u32 bus_irq, u32 gsi, u16 polarity, u16 trigge * If GSI is < 16, this will update its flags, * else it will create a new mp_irqs[] entry. */ - mp_override_legacy_irq(bus_irq, polarity, trigger, gsi); + mp_override_legacy_irq(gsi, polarity, trigger, gsi); /* * stash over-ride to indicate we've been here * and for later update of acpi_fadt */ - acpi_sci_override_gsi = bus_irq; + acpi_sci_override_gsi = gsi; return; } @@ -377,7 +377,7 @@ acpi_parse_int_src_ovr(acpi_table_entry_header * header, acpi_table_print_madt_entry(header); if (intsrc->bus_irq == acpi_fadt.sci_int) { - acpi_sci_ioapic_setup(intsrc->bus_irq, intsrc->global_irq, + acpi_sci_ioapic_setup(intsrc->global_irq, intsrc->flags.polarity, intsrc->flags.trigger); return 0; @@ -880,7 +880,7 @@ static int __init acpi_parse_madt_ioapic_entries(void) * pretend we got one so we can set the SCI flags. */ if (!acpi_sci_override_gsi) - acpi_sci_ioapic_setup(acpi_fadt.sci_int, acpi_fadt.sci_int, 0, 0); + acpi_sci_ioapic_setup(acpi_fadt.sci_int, 0, 0); /* Fill in identity legacy mapings where no override */ mp_config_acpi_legacy_irqs(); -- cgit v1.2.3 From 3277c39f8d706afb6fefc02f49563a73bbd405b9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:13:53 -0800 Subject: [NET]: Kill direct includes of asm/checksum.h Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/frv/lib/checksum.c | 1 - arch/sh/kernel/sh_ksyms.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c index 20e7dfc474e..2581a960d58 100644 --- a/arch/frv/lib/checksum.c +++ b/arch/frv/lib/checksum.c @@ -32,7 +32,6 @@ of the assembly has to go. */ #include -#include #include static inline unsigned short from32to16(unsigned long x) diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 9daad70bc30..8a2fd19dc9e 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -18,7 +18,6 @@ #include #include #include -#include extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); extern struct hw_interrupt_type no_irq_type; -- cgit v1.2.3 From 9be259aae5264511fe0a8b5e3d6711e0fd1d55df Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:14:53 -0800 Subject: [NET]: Alpha checksum annotations and cleanups. * sanitize prototypes and annotate * kill useless access_ok() in csum_partial_copy_from_user() (the only caller checks it already). * do_csum_partial_copy_from_user() is not needed now * replace htons(len) with len << 8 - they are the same wrt checksums on little-endian. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/alpha/lib/checksum.c | 37 +++++++++++++++++-------------------- arch/alpha/lib/csum_partial_copy.c | 31 +++++++++---------------------- 2 files changed, 26 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c index 89044e6385f..ab3761c437a 100644 --- a/arch/alpha/lib/checksum.c +++ b/arch/alpha/lib/checksum.c @@ -41,28 +41,25 @@ static inline unsigned short from64to16(unsigned long x) * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented. */ -unsigned short int csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, - unsigned int sum) + __wsum sum) { - return ~from64to16(saddr + daddr + sum + - ((unsigned long) ntohs(len) << 16) + - ((unsigned long) proto << 8)); + return (__force __sum16)~from64to16( + (__force u64)saddr + (__force u64)daddr + + (__force u64)sum + ((len + proto) << 8)); } -unsigned int csum_tcpudp_nofold(unsigned long saddr, - unsigned long daddr, +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, - unsigned int sum) + __wsum sum) { unsigned long result; - result = (saddr + daddr + sum + - ((unsigned long) ntohs(len) << 16) + - ((unsigned long) proto << 8)); + result = (__force u64)saddr + (__force u64)daddr + + (__force u64)sum + ((len + proto) << 8); /* Fold down to 32-bits so we don't lose in the typedef-less network stack. */ @@ -70,7 +67,7 @@ unsigned int csum_tcpudp_nofold(unsigned long saddr, result = (result & 0xffffffff) + (result >> 32); /* 33 to 32 */ result = (result & 0xffffffff) + (result >> 32); - return result; + return (__force __wsum)result; } /* @@ -146,9 +143,9 @@ out: * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) { - return ~do_csum(iph,ihl*4); + return (__force __sum16)~do_csum(iph,ihl*4); } /* @@ -163,15 +160,15 @@ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned long result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; + result += (__force u32)sum; /* 32+c bits -> 32 bits */ result = (result & 0xffffffff) + (result >> 32); - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -180,7 +177,7 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~from64to16(do_csum(buff,len)); + return (__force __sum16)~from64to16(do_csum(buff,len)); } diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c index a37948f3037..4ca75c74ce9 100644 --- a/arch/alpha/lib/csum_partial_copy.c +++ b/arch/alpha/lib/csum_partial_copy.c @@ -329,11 +329,11 @@ csum_partial_cfu_unaligned(const unsigned long __user * src, return checksum; } -static unsigned int -do_csum_partial_copy_from_user(const char __user *src, char *dst, int len, - unsigned int sum, int *errp) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *errp) { - unsigned long checksum = (unsigned) sum; + unsigned long checksum = (__force u32) sum; unsigned long soff = 7 & (unsigned long) src; unsigned long doff = 7 & (unsigned long) dst; @@ -367,25 +367,12 @@ do_csum_partial_copy_from_user(const char __user *src, char *dst, int len, } checksum = from64to16 (checksum); } - return checksum; -} - -unsigned int -csum_partial_copy_from_user(const char __user *src, char *dst, int len, - unsigned int sum, int *errp) -{ - if (!access_ok(VERIFY_READ, src, len)) { - *errp = -EFAULT; - memset(dst, 0, len); - return sum; - } - - return do_csum_partial_copy_from_user(src, dst, len, sum, errp); + return (__force __wsum)checksum; } -unsigned int -csum_partial_copy_nocheck(const char __user *src, char *dst, int len, - unsigned int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { - return do_csum_partial_copy_from_user(src, dst, len, sum, NULL); + return csum_partial_copy_from_user((__force const void __user *)src, + dst, len, sum, NULL); } -- cgit v1.2.3 From 3532010bcf7699f2ce9a2baab58b4b9a5426d97e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:15:19 -0800 Subject: [NET]: Cris checksum annotations and cleanups. * sanitize prototypes and annotate * kill cast-as-lvalue abuses in csum_partial() * usual ntohs-equals-shift for checksum purposes Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/cris/arch-v10/lib/old_checksum.c | 62 ++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v10/lib/old_checksum.c b/arch/cris/arch-v10/lib/old_checksum.c index 22a6f0aa9ce..497634a6482 100644 --- a/arch/cris/arch-v10/lib/old_checksum.c +++ b/arch/cris/arch-v10/lib/old_checksum.c @@ -47,39 +47,41 @@ #include -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +__wsum csum_partial(const void *p, int len, __wsum __sum) { - /* - * Experiments with ethernet and slip connections show that buff - * is aligned on either a 2-byte or 4-byte boundary. - */ - const unsigned char *endMarker = buff + len; - const unsigned char *marker = endMarker - (len % 16); + u32 sum = (__force u32)__sum; + const u16 *buff = p; + /* + * Experiments with ethernet and slip connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. + */ + const void *endMarker = p + len; + const void *marker = endMarker - (len % 16); #if 0 - if((int)buff & 0x3) - printk("unaligned buff %p\n", buff); - __delay(900); /* extra delay of 90 us to test performance hit */ + if((int)buff & 0x3) + printk("unaligned buff %p\n", buff); + __delay(900); /* extra delay of 90 us to test performance hit */ #endif - BITON; - while (buff < marker) { - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - sum += *((unsigned short *)buff)++; - } - marker = endMarker - (len % 2); - while(buff < marker) { - sum += *((unsigned short *)buff)++; - } - if(endMarker - buff > 0) { - sum += *buff; /* add extra byte seperately */ - } - BITOFF; - return(sum); + BITON; + while (buff < marker) { + sum += *buff++; + sum += *buff++; + sum += *buff++; + sum += *buff++; + sum += *buff++; + sum += *buff++; + sum += *buff++; + sum += *buff++; + } + marker = endMarker - (len % 2); + while (buff < marker) + sum += *buff++; + + if (endMarker > buff) + sum += *(const u8 *)buff; /* add extra byte seperately */ + + BITOFF; + return (__force __wsum)sum; } EXPORT_SYMBOL(csum_partial); -- cgit v1.2.3 From 8042c44b8a6171ed75b7dd6a224df18d993f6094 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:15:40 -0800 Subject: [NET]: FRV checksum annotations. * sanitize prototypes and annotate * collapse csum_partial_copy Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/frv/lib/checksum.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/frv/lib/checksum.c b/arch/frv/lib/checksum.c index 2581a960d58..44e16d59bc1 100644 --- a/arch/frv/lib/checksum.c +++ b/arch/frv/lib/checksum.c @@ -104,15 +104,15 @@ out: * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned int result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; - if (sum > result) + result += (__force u32)sum; + if ((__force u32)sum > result) result += 1; - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -121,9 +121,9 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(const unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff, len); + return (__force __sum16)~do_csum(buff, len); } EXPORT_SYMBOL(ip_compute_csum); @@ -131,9 +131,9 @@ EXPORT_SYMBOL(ip_compute_csum); /* * copy from fs while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_from_user(const char __user *src, char *dst, - int len, int sum, int *csum_err) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) { int rem; @@ -156,11 +156,11 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); /* * copy from ds while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy(const char *src, char *dst, int len, int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); } -EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(csum_partial_copy_nocheck); -- cgit v1.2.3 From db521083bcb75505e9c3e21cbabe8274ee0daea6 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:16:07 -0800 Subject: [NET]: H8300 checksum annotations and cleanups. * sanitize prototypes and annotate * collapse csum_partial_copy NB: csum_partial() is almost certainly still buggy. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/h8300/kernel/h8300_ksyms.c | 2 +- arch/h8300/lib/checksum.c | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c index 9b4be053de3..d1b15267ac8 100644 --- a/arch/h8300/kernel/h8300_ksyms.c +++ b/arch/h8300/kernel/h8300_ksyms.c @@ -39,7 +39,7 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); /* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(csum_partial_copy_nocheck); /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff --git a/arch/h8300/lib/checksum.c b/arch/h8300/lib/checksum.c index 5aa688d9242..bdc5b032acd 100644 --- a/arch/h8300/lib/checksum.c +++ b/arch/h8300/lib/checksum.c @@ -96,9 +96,9 @@ out: * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) { - return ~do_csum(iph,ihl*4); + return (__force __sum16)~do_csum(iph,ihl*4); } /* @@ -113,15 +113,19 @@ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +/* + * Egads... That thing apparently assumes that *all* checksums it ever sees will + * be folded. Very likely a bug. + */ +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned int result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; + result += (__force u32)sum; /* 16+c bits -> 16 bits */ result = (result & 0xffff) + (result >> 16); - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -130,20 +134,21 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(const unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff,len); + return (__force __sum16)~do_csum(buff,len); } /* * copy from fs while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *csum_err) { if (csum_err) *csum_err = 0; - memcpy(dst, src, len); + memcpy(dst, (__force const void *)src, len); return csum_partial(dst, len, sum); } @@ -151,8 +156,8 @@ csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *c * copy from ds while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy(const char *src, char *dst, int len, int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); -- cgit v1.2.3 From 322529961e3b3e64fdf1a3e46a45294456c91acf Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:16:30 -0800 Subject: [NET]: IA64 checksum annotations and cleanups. * sanitize prototypes, annotate * ntohs -> shift in checksum calculations * kill access_ok() in csum_partial_copy_from_user * collapse do_csum_partial_copy_from_user Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/ia64/lib/checksum.c | 38 ++++++++++++++++++-------------------- arch/ia64/lib/csum_partial_copy.c | 31 +++++++++---------------------- 2 files changed, 27 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/ia64/lib/checksum.c b/arch/ia64/lib/checksum.c index beb11721d9f..4411d9baeb2 100644 --- a/arch/ia64/lib/checksum.c +++ b/arch/ia64/lib/checksum.c @@ -33,32 +33,32 @@ from64to16 (unsigned long x) * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented. */ -unsigned short int -csum_tcpudp_magic (unsigned long saddr, unsigned long daddr, unsigned short len, - unsigned short proto, unsigned int sum) +__sum16 +csum_tcpudp_magic (__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { - return ~from64to16(saddr + daddr + sum + ((unsigned long) ntohs(len) << 16) + - ((unsigned long) proto << 8)); + return (__force __sum16)~from64to16( + (__force u64)saddr + (__force u64)daddr + + (__force u64)sum + ((len + proto) << 8)); } EXPORT_SYMBOL(csum_tcpudp_magic); -unsigned int -csum_tcpudp_nofold (unsigned long saddr, unsigned long daddr, unsigned short len, - unsigned short proto, unsigned int sum) +__wsum +csum_tcpudp_nofold (__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { unsigned long result; - result = (saddr + daddr + sum + - ((unsigned long) ntohs(len) << 16) + - ((unsigned long) proto << 8)); + result = (__force u64)saddr + (__force u64)daddr + + (__force u64)sum + ((len + proto) << 8); /* Fold down to 32-bits so we don't lose in the typedef-less network stack. */ /* 64 to 33 */ result = (result & 0xffffffff) + (result >> 32); /* 33 to 32 */ result = (result & 0xffffffff) + (result >> 32); - return result; + return (__force __wsum)result; } extern unsigned long do_csum (const unsigned char *, long); @@ -75,16 +75,15 @@ extern unsigned long do_csum (const unsigned char *, long); * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int -csum_partial (const unsigned char * buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { - unsigned long result = do_csum(buff, len); + u64 result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; + result += (__force u32)sum; /* 32+c bits -> 32 bits */ result = (result & 0xffffffff) + (result >> 32); - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -93,10 +92,9 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short -ip_compute_csum (unsigned char * buff, int len) +__sum16 ip_compute_csum (const void *buff, int len) { - return ~do_csum(buff,len); + return (__force __sum16)~do_csum(buff,len); } EXPORT_SYMBOL(ip_compute_csum); diff --git a/arch/ia64/lib/csum_partial_copy.c b/arch/ia64/lib/csum_partial_copy.c index 36866e8a5d2..503dfe6d145 100644 --- a/arch/ia64/lib/csum_partial_copy.c +++ b/arch/ia64/lib/csum_partial_copy.c @@ -104,9 +104,9 @@ out: */ extern unsigned long do_csum(const unsigned char *, long); -static unsigned int -do_csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst, - int len, unsigned int psum, int *errp) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum psum, int *errp) { unsigned long result; @@ -122,30 +122,17 @@ do_csum_partial_copy_from_user (const unsigned char __user *src, unsigned char * result = do_csum(dst, len); /* add in old sum, and carry.. */ - result += psum; + result += (__force u32)psum; /* 32+c bits -> 32 bits */ result = (result & 0xffffffff) + (result >> 32); - return result; -} - -unsigned int -csum_partial_copy_from_user (const unsigned char __user *src, unsigned char *dst, - int len, unsigned int sum, int *errp) -{ - if (!access_ok(VERIFY_READ, src, len)) { - *errp = -EFAULT; - memset(dst, 0, len); - return sum; - } - - return do_csum_partial_copy_from_user(src, dst, len, sum, errp); + return (__force __wsum)result; } -unsigned int -csum_partial_copy_nocheck(const unsigned char __user *src, unsigned char *dst, - int len, unsigned int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { - return do_csum_partial_copy_from_user(src, dst, len, sum, NULL); + return csum_partial_copy_from_user((__force const void __user *)src, + dst, len, sum, NULL); } EXPORT_SYMBOL(csum_partial_copy_nocheck); -- cgit v1.2.3 From 85d20dee20f0958df1615e73698f6b0c525812f7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:16:55 -0800 Subject: [NET]: M32R checksum annotations and cleanups. * sanitize prototypes, annotate * ntohs -> shift in checksum calculations in l-e case * kill shift-by-16 in checksum calculations Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/m32r/lib/csum_partial_copy.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c index 3d5f0614585..5596f3df833 100644 --- a/arch/m32r/lib/csum_partial_copy.c +++ b/arch/m32r/lib/csum_partial_copy.c @@ -27,9 +27,8 @@ /* * Copy while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_nocheck (const unsigned char *src, unsigned char *dst, - int len, unsigned int sum) +__wsum +csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) { sum = csum_partial(src, len, sum); memcpy(dst, src, len); @@ -42,10 +41,9 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -unsigned int -csum_partial_copy_from_user (const unsigned char __user *src, - unsigned char *dst, - int len, unsigned int sum, int *err_ptr) +__wsum +csum_partial_copy_from_user (const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) { int missing; -- cgit v1.2.3 From 2061acaaae0e165f0104ec9d327a02addbcabd62 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:17:19 -0800 Subject: [NET]: M68K checksum annotations and cleanups. * sanitize prototypes, annotate Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/m68k/lib/checksum.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c index cb13c6e3cca..aed3be29e06 100644 --- a/arch/m68k/lib/checksum.c +++ b/arch/m68k/lib/checksum.c @@ -39,8 +39,7 @@ * computes a partial checksum, e.g. for TCP/UDP fragments */ -unsigned int -csum_partial (const unsigned char *buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned long tmp1, tmp2; /* @@ -133,9 +132,9 @@ EXPORT_SYMBOL(csum_partial); * copy from user space while checksumming, with exception handling. */ -unsigned int -csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, - int len, int sum, int *csum_err) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) { /* * GCC doesn't like more than 10 operands for the asm @@ -325,8 +324,8 @@ csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, * copy from kernel space while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { unsigned long tmp1, tmp2; __asm__("movel %2,%4\n\t" -- cgit v1.2.3 From 59ed05a7e891d694a43df96ac613f7e8e164eb95 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:17:56 -0800 Subject: [NET]: M68Knommu checksum annotations and cleanups. * sanitize prototypes, annotated * collapsed csum_partial_copy() Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/m68knommu/kernel/m68k_ksyms.c | 2 +- arch/m68knommu/lib/checksum.c | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c index 1e62150f358..25327c9eadd 100644 --- a/arch/m68knommu/kernel/m68k_ksyms.c +++ b/arch/m68knommu/kernel/m68k_ksyms.c @@ -38,7 +38,7 @@ EXPORT_SYMBOL(ip_fast_csum); EXPORT_SYMBOL(kernel_thread); /* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(csum_partial_copy_nocheck); /* The following are special because they're not called explicitly (the C compiler generates them). Fortunately, diff --git a/arch/m68knommu/lib/checksum.c b/arch/m68knommu/lib/checksum.c index 7bec6fdee34..269d83bfbbe 100644 --- a/arch/m68knommu/lib/checksum.c +++ b/arch/m68knommu/lib/checksum.c @@ -96,9 +96,9 @@ out: * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) { - return ~do_csum(iph,ihl*4); + return (__force __sum16)~do_csum(iph,ihl*4); } /* @@ -113,15 +113,15 @@ unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned int result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; - if (sum > result) + result += (__force u32)sum; + if ((__force u32)sum > result) result += 1; - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -130,21 +130,21 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(const unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff,len); + return (__force __sum16)~do_csum(buff,len); } /* * copy from fs while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, - int len, int sum, int *csum_err) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *csum_err) { if (csum_err) *csum_err = 0; - memcpy(dst, src, len); + memcpy(dst, (__force const void *)src, len); return csum_partial(dst, len, sum); } @@ -152,8 +152,8 @@ csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, * copy from ds while checksumming, otherwise like csum_partial */ -unsigned int -csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); -- cgit v1.2.3 From 8e3d8433d8c22ca6c42cba4a67d300c39aae7822 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:18:18 -0800 Subject: [NET]: MIPS checksum annotations and cleanups. * sanitize prototypes, annotate * kill shift-by-16 in checksum calculations * htons->shift in l-e checksum calculations Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/mips/lib/csum_partial_copy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c index 6e9f366f961..1720f2ceeea 100644 --- a/arch/mips/lib/csum_partial_copy.c +++ b/arch/mips/lib/csum_partial_copy.c @@ -16,8 +16,8 @@ /* * copy while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy_nocheck(const unsigned char *src, - unsigned char *dst, int len, unsigned int sum) +__wsum csum_partial_copy_nocheck(const void *src, + void *dst, int len, __wsum sum) { /* * It's 2:30 am and I don't feel like doing it real ... @@ -33,8 +33,8 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -unsigned int csum_partial_copy_from_user (const unsigned char __user *src, - unsigned char *dst, int len, unsigned int sum, int *err_ptr) +__wsum csum_partial_copy_from_user (const void __user *src, + void *dst, int len, __wsum sum, int *err_ptr) { int missing; -- cgit v1.2.3 From 7814e4b6d6ce59071887600a8659641ba3d30a43 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:18:39 -0800 Subject: [NET]: PARISC checksum annotations and cleanups. * sanitized prototypes, annotated * kill shift-by-16 in checksum calculation Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/parisc/lib/checksum.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c index 8a1e08068e7..462696d30d3 100644 --- a/arch/parisc/lib/checksum.c +++ b/arch/parisc/lib/checksum.c @@ -101,11 +101,14 @@ out: /* * computes a partial checksum, e.g. for TCP/UDP fragments */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +/* + * why bother folding? + */ +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned int result = do_csum(buff, len); addc(result, sum); - return from32to16(result); + return (__force __wsum)from32to16(result); } EXPORT_SYMBOL(csum_partial); @@ -113,8 +116,8 @@ EXPORT_SYMBOL(csum_partial); /* * copy while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, - int len, unsigned int sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) { /* * It's 2:30 am and I don't feel like doing it real ... @@ -131,9 +134,9 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck); * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -unsigned int csum_partial_copy_from_user(const unsigned char __user *src, - unsigned char *dst, int len, - unsigned int sum, int *err_ptr) +__wsum csum_partial_copy_from_user(const void __user *src, + void *dst, int len, + __wsum sum, int *err_ptr) { int missing; -- cgit v1.2.3 From c459dd90f0de00db1ca1328482214019f6ca292f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:19:01 -0800 Subject: [NET]: SH64 checksum annotations and cleanups. * sanitize prototypes, annotate * collapse csum_partial_copy * kill csum_partial_copy_fromuser * ntohs->shift in checksum calculation Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sh64/kernel/sh_ksyms.c | 2 +- arch/sh64/lib/c-checksum.c | 49 ++++++++++++++++----------------------------- 2 files changed, 18 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index 4b2df7247b5..7aa4b4f7bc5 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c @@ -38,7 +38,7 @@ EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(kernel_thread); /* Networking helper routines. */ -EXPORT_SYMBOL(csum_partial_copy); +EXPORT_SYMBOL(csum_partial_copy_nocheck); EXPORT_SYMBOL(strstr); diff --git a/arch/sh64/lib/c-checksum.c b/arch/sh64/lib/c-checksum.c index 0e8a742abf8..4b2676380de 100644 --- a/arch/sh64/lib/c-checksum.c +++ b/arch/sh64/lib/c-checksum.c @@ -118,24 +118,24 @@ static unsigned long do_csum(const unsigned char *buff, int len) /* computes the checksum of a memory block at buff, length len, and adds in "sum" (32-bit) */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned long long result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; + result += (__force u32)sum; /* 32+c bits -> 32 bits */ result = (result & 0xffffffff) + (result >> 32); pr_debug("csum_partial, buff %p len %d sum 0x%x result=0x%016Lx\n", buff, len, sum, result); - return result; + return (__force __wsum)result; } /* Copy while checksumming, otherwise like csum_partial. */ -unsigned int -csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, unsigned int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { sum = csum_partial(src, len, sum); memcpy(dst, src, len); @@ -145,9 +145,9 @@ csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, unsigne /* Copy from userspace and compute checksum. If we catch an exception then zero the rest of the buffer. */ -unsigned int -csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, - unsigned int sum, int *err_ptr) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, + __wsum sum, int *err_ptr) { int missing; @@ -166,9 +166,9 @@ csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int le } /* Copy to userspace and compute checksum. */ -unsigned int +__wsum csum_partial_copy_to_user(const unsigned char *src, unsigned char *dst, int len, - unsigned int sum, int *err_ptr) + __wsum sum, int *err_ptr) { sum = csum_partial(src, len, sum); @@ -182,28 +182,24 @@ csum_partial_copy_to_user(const unsigned char *src, unsigned char *dst, int len, * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) { pr_debug("ip_fast_csum %p,%d\n", iph, ihl); - return ~do_csum(iph, ihl * 4); + return (__force __sum16)~do_csum(iph, ihl * 4); } -unsigned int csum_tcpudp_nofold(unsigned long saddr, - unsigned long daddr, +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, - unsigned short proto, unsigned int sum) + unsigned short proto, __wsum sum) { unsigned long long result; pr_debug("ntohs(0x%x)=0x%x\n", 0xdead, ntohs(0xdead)); pr_debug("htons(0x%x)=0x%x\n", 0xdead, htons(0xdead)); - result = ((unsigned long long) saddr + - (unsigned long long) daddr + - (unsigned long long) sum + - ((unsigned long long) ntohs(len) << 16) + - ((unsigned long long) proto << 8)); + result = (__force u64) saddr + (__force u64) daddr + + (__force u64) sum + ((len + proto) << 8); /* Fold down to 32-bits so we don't loose in the typedef-less network stack. */ @@ -215,16 +211,5 @@ unsigned int csum_tcpudp_nofold(unsigned long saddr, pr_debug("%s saddr %x daddr %x len %x proto %x sum %x result %08Lx\n", __FUNCTION__, saddr, daddr, len, proto, sum, result); - return result; -} - -// Post SIM: -unsigned int -csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum) -{ - // unsigned dummy; - pr_debug("csum_partial_copy_nocheck src %p dst %p len %d\n", src, dst, - len); - - return csum_partial_copy(src, dst, len, sum); + return (__wsum)result; } -- cgit v1.2.3 From abf419b809bed2333267e4b23dd2b3b4f10da88c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:19:22 -0800 Subject: [NET]: UML checksum annotations and cleanups. * sanitize prototypes, annotate * kill csum_partial_copy_fromuser * kill shift-by-16 in checksum calculations * ntohs->shift in checksum calculations Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/um/include/sysdep-i386/checksum.h | 74 +++++++++++++------------------- arch/um/include/sysdep-x86_64/checksum.h | 47 ++++++++++---------- 2 files changed, 53 insertions(+), 68 deletions(-) (limited to 'arch') diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 052bb061a97..0cb4645cbeb 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h @@ -20,8 +20,7 @@ * * it's best to have buff aligned on a 32-bit boundary */ -unsigned int csum_partial(const unsigned char * buff, int len, - unsigned int sum); +__wsum csum_partial(const void *buff, int len, __wsum sum); /* * Note: when you get a NULL pointer exception here this means someone @@ -32,8 +31,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, */ static __inline__ -unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, - int len, int sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); @@ -48,27 +47,17 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * */ static __inline__ -unsigned int csum_partial_copy_from_user(const unsigned char __user *src, - unsigned char *dst, - int len, int sum, int *err_ptr) +__wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) { - if(copy_from_user(dst, src, len)){ + if (copy_from_user(dst, src, len)) { *err_ptr = -EFAULT; - return(-1); + return (__force __wsum)-1; } return csum_partial(dst, len, sum); } -/* - * These are the old (and unsafe) way of doing checksums, a warning message - * will be printed if they are used and an exception occurs. - * - * these functions should go away after some time. - */ - -#define csum_partial_copy_fromuser csum_partial_copy_from_user - /* * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. @@ -76,8 +65,7 @@ unsigned int csum_partial_copy_from_user(const unsigned char __user *src, * By Jorge Cwik , adapted for linux by * Arnt Gulbrandsen. */ -static inline unsigned short ip_fast_csum(unsigned char * iph, - unsigned int ihl) +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { unsigned int sum; @@ -105,29 +93,29 @@ static inline unsigned short ip_fast_csum(unsigned char * iph, : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl) : "memory"); - return sum; + return (__force __sum16)sum; } /* * Fold a partial checksum */ -static inline unsigned int csum_fold(unsigned int sum) +static inline __sum16 csum_fold(__wsum sum) { __asm__( "addl %1, %0 ;\n" "adcl $0xffff, %0 ;\n" : "=r" (sum) - : "r" (sum << 16), "0" (sum & 0xffff0000) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) ); - return (~sum) >> 16; + return (__force __sum16)(~(__force u32)sum >> 16); } -static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, - unsigned long daddr, +static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, - unsigned int sum) + __wsum sum) { __asm__( "addl %1, %0 ;\n" @@ -135,7 +123,7 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, "adcl %3, %0 ;\n" "adcl $0, %0 ;\n" : "=r" (sum) - : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum)); + : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); return sum; } @@ -143,11 +131,10 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ -static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, - unsigned int sum) + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -157,17 +144,16 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, * in icmp.c */ -static inline unsigned short ip_compute_csum(unsigned char * buff, int len) +static inline __sum16 ip_compute_csum(const void *buff, int len) { return csum_fold (csum_partial(buff, len, 0)); } #define _HAVE_ARCH_IPV6_CSUM -static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, - struct in6_addr *daddr, - __u32 len, - unsigned short proto, - unsigned int sum) +static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, + __wsum sum) { __asm__( "addl 0(%1), %0 ;\n" @@ -192,14 +178,14 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, - unsigned char __user *dst, - int len, int sum, int *err_ptr) +static __inline__ __wsum csum_and_copy_to_user(const void *src, + void __user *dst, + int len, __wsum sum, int *err_ptr) { - if (access_ok(VERIFY_WRITE, dst, len)){ - if(copy_to_user(dst, src, len)){ + if (access_ok(VERIFY_WRITE, dst, len)) { + if (copy_to_user(dst, src, len)) { *err_ptr = -EFAULT; - return(-1); + return (__force __wsum)-1; } return csum_partial(src, len, sum); @@ -208,7 +194,7 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, if (len) *err_ptr = -EFAULT; - return -1; /* invalid checksum */ + return (__force __wsum)-1; /* invalid checksum */ } #endif diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h index ea97005af69..a5be9031ea8 100644 --- a/arch/um/include/sysdep-x86_64/checksum.h +++ b/arch/um/include/sysdep-x86_64/checksum.h @@ -9,8 +9,7 @@ #include "linux/in6.h" #include "asm/uaccess.h" -extern unsigned csum_partial(const unsigned char *buff, unsigned len, - unsigned sum); +extern __wsum csum_partial(const void *buff, int len, __wsum sum); /* * Note: when you get a NULL pointer exception here this means someone @@ -21,21 +20,21 @@ extern unsigned csum_partial(const unsigned char *buff, unsigned len, */ static __inline__ -unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, - int len, int sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) { memcpy(dst, src, len); return(csum_partial(dst, len, sum)); } static __inline__ -unsigned int csum_partial_copy_from_user(const unsigned char *src, - unsigned char *dst, int len, int sum, +__wsum csum_partial_copy_from_user(const void __user *src, + void *dst, int len, __wsum sum, int *err_ptr) { - if(copy_from_user(dst, src, len)){ + if (copy_from_user(dst, src, len)) { *err_ptr = -EFAULT; - return(-1); + return (__force __wsum)-1; } return csum_partial(dst, len, sum); } @@ -48,15 +47,16 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, * the last step before putting a checksum into a packet. * Make sure not to mix with 64bit checksums. */ -static inline unsigned int csum_fold(unsigned int sum) +static inline __sum16 csum_fold(__wsum sum) { __asm__( " addl %1,%0\n" " adcl $0xffff,%0" : "=r" (sum) - : "r" (sum << 16), "0" (sum & 0xffff0000) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) ); - return (~sum) >> 16; + return (__force __sum16)(~(__force u32)sum >> 16); } /** @@ -70,28 +70,27 @@ static inline unsigned int csum_fold(unsigned int sum) * Returns the pseudo header checksum the input data. Result is * 32bit unfolded. */ -static inline unsigned long -csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len, - unsigned short proto, unsigned int sum) +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { asm(" addl %1, %0\n" " adcl %2, %0\n" " adcl %3, %0\n" " adcl $0, %0\n" : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum)); - return sum; + : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); + return sum; } /* * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ -static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, - unsigned long daddr, - unsigned short len, - unsigned short proto, - unsigned int sum) +static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, + __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -101,7 +100,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, * iph: ipv4 header * ihl: length of header / 4 */ -static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { unsigned int sum; @@ -128,7 +127,7 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl) : "memory"); - return(sum); + return (__force __sum16)sum; } static inline unsigned add32_with_carry(unsigned a, unsigned b) @@ -140,6 +139,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b) return a; } -extern unsigned short ip_compute_csum(unsigned char * buff, int len); +extern __sum16 ip_compute_csum(const void *buff, int len); #endif -- cgit v1.2.3 From 9d3d41955845939cb41b87affb039db0bae03b65 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:19:44 -0800 Subject: [NET]: V850 checksum annotations and cleanups. * sanitize prototypes, annotate * collapse csum_partial_copy * usual ntohs->shift Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/v850/kernel/v850_ksyms.c | 2 +- arch/v850/lib/checksum.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/v850/kernel/v850_ksyms.c b/arch/v850/kernel/v850_ksyms.c index 67bc48e57c6..93575fdc874 100644 --- a/arch/v850/kernel/v850_ksyms.c +++ b/arch/v850/kernel/v850_ksyms.c @@ -24,7 +24,7 @@ EXPORT_SYMBOL (kernel_thread); EXPORT_SYMBOL (__bug); /* Networking helper routines. */ -EXPORT_SYMBOL (csum_partial_copy); +EXPORT_SYMBOL (csum_partial_copy_nocheck); EXPORT_SYMBOL (csum_partial_copy_from_user); EXPORT_SYMBOL (ip_compute_csum); EXPORT_SYMBOL (ip_fast_csum); diff --git a/arch/v850/lib/checksum.c b/arch/v850/lib/checksum.c index fa587263307..042158dfe17 100644 --- a/arch/v850/lib/checksum.c +++ b/arch/v850/lib/checksum.c @@ -88,32 +88,32 @@ out: * This is a version of ip_compute_csum() optimized for IP headers, * which always checksum on 4 octet boundaries. */ -unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl) +__sum16 ip_fast_csum(const void *iph, unsigned int ihl) { - return ~do_csum(iph,ihl*4); + return (__force __sum16)~do_csum(iph,ihl*4); } /* * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(const unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { - return ~do_csum(buff,len); + return (__force __sum16)~do_csum(buff,len); } /* * computes a partial checksum, e.g. for TCP/UDP fragments */ -unsigned int csum_partial(const unsigned char *buff, int len, unsigned int sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { unsigned int result = do_csum(buff, len); /* add in old sum, and carry.. */ - result += sum; - if(sum > result) + result += (__force u32)sum; + if ((__force u32)sum > result) result += 1; - return result; + return (__force __wsum)result; } EXPORT_SYMBOL(csum_partial); @@ -121,8 +121,8 @@ EXPORT_SYMBOL(csum_partial); /* * copy while checksumming, otherwise like csum_partial */ -unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, - int len, unsigned int sum) +__wsum csum_partial_copy_nocheck(const void *src, void *dst, + int len, __wsum sum) { /* * It's 2:30 am and I don't feel like doing it real ... @@ -138,9 +138,9 @@ unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. */ -unsigned int csum_partial_copy_from_user (const unsigned char *src, - unsigned char *dst, - int len, unsigned int sum, +__wsum csum_partial_copy_from_user (const void *src, + void *dst, + int len, __wsum sum, int *err_ptr) { int missing; -- cgit v1.2.3 From a4f89fb7c072b8592b296c2ba216269c0c96db43 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:20:08 -0800 Subject: [NET]: X86_64 checksum annotations and cleanups. * sanitize prototypes, annotate * usual ntohs->shift Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/x86_64/lib/csum-partial.c | 7 ++++--- arch/x86_64/lib/csum-wrappers.c | 37 +++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/lib/csum-partial.c b/arch/x86_64/lib/csum-partial.c index c493735218d..06ae630de82 100644 --- a/arch/x86_64/lib/csum-partial.c +++ b/arch/x86_64/lib/csum-partial.c @@ -132,9 +132,10 @@ static __force_inline unsigned do_csum(const unsigned char *buff, unsigned len) * * it's best to have buff aligned on a 64-bit boundary */ -unsigned csum_partial(const unsigned char *buff, unsigned len, unsigned sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { - return add32_with_carry(do_csum(buff, len), sum); + return (__force __wsum)add32_with_carry(do_csum(buff, len), + (__force u32)sum); } EXPORT_SYMBOL(csum_partial); @@ -143,7 +144,7 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { return csum_fold(csum_partial(buff,len,0)); } diff --git a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c index b1320ec5842..fd42a4a095f 100644 --- a/arch/x86_64/lib/csum-wrappers.c +++ b/arch/x86_64/lib/csum-wrappers.c @@ -18,9 +18,9 @@ * Returns an 32bit unfolded checksum of the buffer. * src and dst are best aligned to 64bits. */ -unsigned int -csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, - int len, unsigned int isum, int *errp) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum isum, int *errp) { might_sleep(); *errp = 0; @@ -34,17 +34,19 @@ csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, if (unlikely((unsigned long)src & 6)) { while (((unsigned long)src & 6) && len >= 2) { __u16 val16; - *errp = __get_user(val16, (__u16 __user *)src); + *errp = __get_user(val16, (const __u16 __user *)src); if (*errp) return isum; *(__u16 *)dst = val16; - isum = add32_with_carry(isum, val16); + isum = (__force __wsum)add32_with_carry( + (__force unsigned)isum, val16); src += 2; dst += 2; len -= 2; } } - isum = csum_partial_copy_generic((__force void *)src,dst,len,isum,errp,NULL); + isum = csum_partial_copy_generic((__force const void *)src, + dst, len, isum, errp, NULL); if (likely(*errp == 0)) return isum; } @@ -66,9 +68,9 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); * Returns an 32bit unfolded checksum of the buffer. * src and dst are best aligned to 64bits. */ -unsigned int -csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst, - int len, unsigned int isum, int *errp) +__wsum +csum_partial_copy_to_user(const void *src, void __user *dst, + int len, __wsum isum, int *errp) { might_sleep(); if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { @@ -79,7 +81,8 @@ csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst, if (unlikely((unsigned long)dst & 6)) { while (((unsigned long)dst & 6) && len >= 2) { __u16 val16 = *(__u16 *)src; - isum = add32_with_carry(isum, val16); + isum = (__force __wsum)add32_with_carry( + (__force unsigned)isum, val16); *errp = __put_user(val16, (__u16 __user *)dst); if (*errp) return isum; @@ -104,19 +107,21 @@ EXPORT_SYMBOL(csum_partial_copy_to_user); * * Returns an 32bit unfolded checksum of the buffer. */ -unsigned int -csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL); } EXPORT_SYMBOL(csum_partial_copy_nocheck); -unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, - __u32 len, unsigned short proto, unsigned int sum) +__sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) { __u64 rest, sum64; - rest = (__u64)htonl(len) + (__u64)htons(proto) + (__u64)sum; + rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) + + (__force __u64)sum; asm(" addq (%[saddr]),%[sum]\n" " adcq 8(%[saddr]),%[sum]\n" " adcq (%[daddr]),%[sum]\n" @@ -124,7 +129,7 @@ unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, " adcq $0,%[sum]\n" : [sum] "=r" (sum64) : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr)); - return csum_fold(add32_with_carry(sum64 & 0xffffffff, sum64>>32)); + return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32)); } EXPORT_SYMBOL(csum_ipv6_magic); -- cgit v1.2.3 From afe4b25e7d9260d85fccb2d13c9933a987bdfc8a Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 3 Dec 2006 18:51:14 +0100 Subject: [ARM] 3881/4: xscale: clean up cp0/cp1 handling XScale cores either have a DSP coprocessor (which contains a single 40 bit accumulator register), or an iWMMXt coprocessor (which contains eight 64 bit registers.) Because of the small amount of state in the DSP coprocessor, access to the DSP coprocessor (CP0) is always enabled, and DSP context switching is done unconditionally on every task switch. Access to the iWMMXt coprocessor (CP0/CP1) is enabled only when an iWMMXt instruction is first issued, and iWMMXt context switching is done lazily. CONFIG_IWMMXT is supposed to mean 'the cpu we will be running on will have iWMMXt support', but boards are supposed to select this config symbol by hand, and at least one pxa27x board doesn't get this right, so on that board, proc-xscale.S will incorrectly assume that we have a DSP coprocessor, enable CP0 on boot, and we will then only save the first iWMMXt register (wR0) on context switches, which is Bad. This patch redefines CONFIG_IWMMXT as 'the cpu we will be running on might have iWMMXt support, and we will enable iWMMXt context switching if it does.' This means that with this patch, running a CONFIG_IWMMXT=n kernel on an iWMMXt-capable CPU will no longer potentially corrupt iWMMXt state over context switches, and running a CONFIG_IWMMXT=y kernel on a non-iWMMXt capable CPU will still do DSP context save/restore. These changes should make iWMMXt work on PXA3xx, and as a side effect, enable proper acc0 save/restore on non-iWMMXt capable xsc3 cores such as IOP13xx and IXP23xx (which will not have CONFIG_CPU_XSCALE defined), as well as setting and using HWCAP_IWMMXT properly. Signed-off-by: Lennert Buytenhek Acked-by: Dan Williams Signed-off-by: Russell King --- arch/arm/Kconfig | 8 ++ arch/arm/kernel/Makefile | 4 +- arch/arm/kernel/entry-armv.S | 9 -- arch/arm/kernel/iwmmxt-notifier.c | 63 -------------- arch/arm/kernel/setup.c | 3 - arch/arm/kernel/xscale-cp0.c | 179 ++++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/Kconfig | 8 -- arch/arm/mach-pxa/pm.c | 3 +- arch/arm/mm/proc-xscale.S | 9 +- 9 files changed, 194 insertions(+), 92 deletions(-) delete mode 100644 arch/arm/kernel/iwmmxt-notifier.c create mode 100644 arch/arm/kernel/xscale-cp0.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ce00c570459..7be67ef4b84 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -374,6 +374,14 @@ config PLAT_IOP source arch/arm/mm/Kconfig +config IWMMXT + bool "Enable iWMMXt support" + depends CPU_XSCALE || CPU_XSC3 + default y if PXA27x + help + Enable support for iWMMXt context switching at run time if + running on a CPU that supports it. + # bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER config XSCALE_PMU bool diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 1320a0efca7..ab06a86e85d 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -24,7 +24,9 @@ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 -obj-$(CONFIG_IWMMXT) += iwmmxt.o iwmmxt-notifier.o +obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o +obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o +obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt ifneq ($(CONFIG_ARCH_EBSA110),y) diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index bd623b73445..2db42b18f53 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -589,10 +589,6 @@ ENTRY(__switch_to) strex r5, r4, [ip] @ Clear exclusive monitor #endif #endif -#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) - mra r4, r5, acc0 - stmia ip, {r4, r5} -#endif #if defined(CONFIG_HAS_TLS_REG) mcr p15, 0, r3, c13, c0, 3 @ set TLS register #elif !defined(CONFIG_TLS_REG_EMUL) @@ -601,11 +597,6 @@ ENTRY(__switch_to) #endif #ifdef CONFIG_MMU mcr p15, 0, r6, c3, c0, 0 @ Set domain register -#endif -#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT) - add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra - ldmib r4, {r4, r5} - mar acc0, r4, r5 #endif mov r5, r0 add r4, r2, #TI_CPU_SAVE diff --git a/arch/arm/kernel/iwmmxt-notifier.c b/arch/arm/kernel/iwmmxt-notifier.c deleted file mode 100644 index 0d1a1db4006..00000000000 --- a/arch/arm/kernel/iwmmxt-notifier.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * linux/arch/arm/kernel/iwmmxt-notifier.c - * - * XScale iWMMXt (Concan) context switching and handling - * - * Initial code: - * Copyright (c) 2003, Intel Corporation - * - * Full lazy switching support, optimizations and more, by Nicolas Pitre - * Copyright (c) 2003-2004, MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) -{ - struct thread_info *thread = t; - - switch (cmd) { - case THREAD_NOTIFY_FLUSH: - /* - * flush_thread() zeroes thread->fpstate, so no need - * to do anything here. - * - * FALLTHROUGH: Ensure we don't try to overwrite our newly - * initialised state information on the first fault. - */ - - case THREAD_NOTIFY_RELEASE: - iwmmxt_task_release(thread); - break; - - case THREAD_NOTIFY_SWITCH: - iwmmxt_task_switch(thread); - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block iwmmxt_notifier_block = { - .notifier_call = iwmmxt_do, -}; - -static int __init iwmmxt_init(void) -{ - thread_register_notifier(&iwmmxt_notifier_block); - - return 0; -} - -late_initcall(iwmmxt_init); diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 29efc9f8205..6f12d2686aa 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -357,9 +357,6 @@ static void __init setup_processor(void) #ifndef CONFIG_VFP elf_hwcap &= ~HWCAP_VFP; #endif -#ifndef CONFIG_IWMMXT - elf_hwcap &= ~HWCAP_IWMMXT; -#endif cpu_proc_init(); } diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c new file mode 100644 index 00000000000..180000bfdc8 --- /dev/null +++ b/arch/arm/kernel/xscale-cp0.c @@ -0,0 +1,179 @@ +/* + * linux/arch/arm/kernel/xscale-cp0.c + * + * XScale DSP and iWMMXt coprocessor context switching and handling + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void dsp_save_state(u32 *state) +{ + __asm__ __volatile__ ( + "mrrc p0, 0, %0, %1, c0\n" + : "=r" (state[0]), "=r" (state[1])); +} + +static inline void dsp_load_state(u32 *state) +{ + __asm__ __volatile__ ( + "mcrr p0, 0, %0, %1, c0\n" + : : "r" (state[0]), "r" (state[1])); +} + +static int dsp_do(struct notifier_block *self, unsigned long cmd, void *t) +{ + struct thread_info *thread = t; + + switch (cmd) { + case THREAD_NOTIFY_FLUSH: + thread->cpu_context.extra[0] = 0; + thread->cpu_context.extra[1] = 0; + break; + + case THREAD_NOTIFY_SWITCH: + dsp_save_state(current_thread_info()->cpu_context.extra); + dsp_load_state(thread->cpu_context.extra); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block dsp_notifier_block = { + .notifier_call = dsp_do, +}; + + +#ifdef CONFIG_IWMMXT +static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) +{ + struct thread_info *thread = t; + + switch (cmd) { + case THREAD_NOTIFY_FLUSH: + /* + * flush_thread() zeroes thread->fpstate, so no need + * to do anything here. + * + * FALLTHROUGH: Ensure we don't try to overwrite our newly + * initialised state information on the first fault. + */ + + case THREAD_NOTIFY_RELEASE: + iwmmxt_task_release(thread); + break; + + case THREAD_NOTIFY_SWITCH: + iwmmxt_task_switch(thread); + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block iwmmxt_notifier_block = { + .notifier_call = iwmmxt_do, +}; +#endif + + +static u32 __init xscale_cp_access_read(void) +{ + u32 value; + + __asm__ __volatile__ ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + : "=r" (value)); + + return value; +} + +static void __init xscale_cp_access_write(u32 value) +{ + u32 temp; + + __asm__ __volatile__ ( + "mcr p15, 0, %1, c15, c1, 0\n\t" + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4\n\t" + : "=r" (temp) : "r" (value)); +} + +/* + * Detect whether we have a MAC coprocessor (40 bit register) or an + * iWMMXt coprocessor (64 bit registers) by loading 00000100:00000000 + * into a coprocessor register and reading it back, and checking + * whether the upper word survived intact. + */ +static int __init cpu_has_iwmmxt(void) +{ + u32 lo; + u32 hi; + + /* + * This sequence is interpreted by the DSP coprocessor as: + * mar acc0, %2, %3 + * mra %0, %1, acc0 + * + * And by the iWMMXt coprocessor as: + * tmcrr wR0, %2, %3 + * tmrrc %0, %1, wR0 + */ + __asm__ __volatile__ ( + "mcrr p0, 0, %2, %3, c0\n" + "mrrc p0, 0, %0, %1, c0\n" + : "=r" (lo), "=r" (hi) + : "r" (0), "r" (0x100)); + + return !!hi; +} + + +/* + * If we detect that the CPU has iWMMXt (and CONFIG_IWMMXT=y), we + * disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy + * switch code handle iWMMXt context switching. If on the other + * hand the CPU has a DSP coprocessor, we keep access to CP0 enabled + * all the time, and save/restore acc0 on context switch in non-lazy + * fashion. + */ +static int __init xscale_cp0_init(void) +{ + u32 cp_access; + + cp_access = xscale_cp_access_read() & ~3; + xscale_cp_access_write(cp_access | 1); + + if (cpu_has_iwmmxt()) { +#ifndef CONFIG_IWMMXT + printk(KERN_WARNING "CAUTION: XScale iWMMXt coprocessor " + "detected, but kernel support is missing.\n"); +#else + printk(KERN_INFO "XScale iWMMXt coprocessor detected.\n"); + elf_hwcap |= HWCAP_IWMMXT; + thread_register_notifier(&iwmmxt_notifier_block); +#endif + } else { + printk(KERN_INFO "XScale DSP coprocessor detected.\n"); + thread_register_notifier(&dsp_notifier_block); + cp_access |= 1; + } + + xscale_cp_access_write(cp_access); + + return 0; +} + +late_initcall(xscale_cp0_init); diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 03d07cae26c..9e3d0bdcba0 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -13,12 +13,10 @@ config ARCH_LUBBOCK config MACH_LOGICPD_PXA270 bool "LogicPD PXA270 Card Engine Development Platform" select PXA27x - select IWMMXT config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform" select PXA27x - select IWMMXT config ARCH_PXA_IDP bool "Accelent Xscale IDP" @@ -53,7 +51,6 @@ config PXA_SHARPSL_25x config PXA_SHARPSL_27x bool "Sharp PXA270 models (SL-Cxx00)" select PXA27x - select IWMMXT endchoice @@ -129,11 +126,6 @@ config PXA27x help Select code specific to PXA27x variants -config IWMMXT - bool - help - Enable support for iWMMXt - config PXA_SHARP_C7xx bool select PXA_SSP diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 2112c414f0e..b4d8276d605 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -83,7 +83,8 @@ int pxa_pm_enter(suspend_state_t state) #ifdef CONFIG_IWMMXT /* force any iWMMXt context to ram **/ - iwmmxt_task_disable(NULL); + if (elf_hwcap & HWCAP_IWMMXT) + iwmmxt_task_disable(NULL); #endif /* preserve current time */ diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 906e9de7f83..cc1004b3e51 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S @@ -491,12 +491,7 @@ __xscale_setup: mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs -#ifdef CONFIG_IWMMXT - mov r0, #0 @ initially disallow access to CP0/CP1 -#else - mov r0, #1 @ Allow access to CP0 -#endif - orr r0, r0, #1 << 6 @ cp6 for IOP3xx and Bulverde + mov r0, #1 << 6 @ cp6 for IOP3xx and Bulverde orr r0, r0, #1 << 13 @ Its undefined whether this mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes @@ -909,7 +904,7 @@ __pxa270_proc_info: b __xscale_setup .long cpu_arch_name .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_IWMMXT + .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP .long cpu_pxa270_name .long xscale_processor_functions .long v4wbi_tlb_fns -- cgit v1.2.3 From f90bb153b1493719d18b4529a46ebfe43220ea6c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:51 +1100 Subject: [POWERPC] Make pci_read_irq_line the default This patch reworks the way IRQs are fixed up on PCI for arch powerpc. It makes pci_read_irq_line() called by default in the PCI code for devices that are probed, and add an optional per-device fixup in ppc_md for platforms that really need to correct what they obtain from pci_read_irq_line(). It also removes ppc_md.irq_bus_setup which was only used by pSeries and should not be needed anymore. I've also removed the pSeries s7a workaround as it can't work with the current interrupt code anyway. I'm trying to get one of these machines working so I can test a proper fix for that problem. I also haven't updated the old-style fixup code from 85xx_cds.c because it's actually buggy :) It assigns pci_dev->irq hard coded numbers which is no good with the new IRQ mapping code. It should at least use irq_create_mapping(NULL, hard_coded_number); and possibly also set_irq_type() to set them as level low. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 10 +++++ arch/powerpc/kernel/pci_64.c | 8 +++- arch/powerpc/platforms/82xx/mpc82xx_ads.c | 13 ------- arch/powerpc/platforms/83xx/mpc834x_itx.c | 3 -- arch/powerpc/platforms/83xx/mpc834x_sys.c | 3 -- arch/powerpc/platforms/83xx/mpc83xx.h | 1 - arch/powerpc/platforms/83xx/pci.c | 9 ----- arch/powerpc/platforms/85xx/mpc85xx_ads.c | 11 ------ arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | 10 ----- arch/powerpc/platforms/cell/setup.c | 9 ----- arch/powerpc/platforms/chrp/chrp.h | 1 - arch/powerpc/platforms/chrp/pci.c | 9 ----- arch/powerpc/platforms/chrp/setup.c | 1 - arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 16 +++----- arch/powerpc/platforms/maple/maple.h | 2 +- arch/powerpc/platforms/maple/pci.c | 47 +++++++++-------------- arch/powerpc/platforms/maple/setup.c | 2 +- arch/powerpc/platforms/pasemi/pasemi.h | 1 - arch/powerpc/platforms/pasemi/pci.c | 8 ---- arch/powerpc/platforms/pasemi/setup.c | 1 - arch/powerpc/platforms/powermac/pci.c | 35 +++++++---------- arch/powerpc/platforms/powermac/pmac.h | 2 +- arch/powerpc/platforms/powermac/setup.c | 2 +- arch/powerpc/platforms/pseries/pci.c | 35 ----------------- arch/powerpc/platforms/pseries/setup.c | 1 - 25 files changed, 58 insertions(+), 182 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 0d9ff72e285..853ecef8178 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -1338,6 +1339,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) struct pci_controller *hose = (struct pci_controller *) bus->sysdata; unsigned long io_offset; struct resource *res; + struct pci_dev *dev; int i; io_offset = (unsigned long)hose->io_base_virt - isa_io_base; @@ -1390,8 +1392,16 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) } } + /* Platform specific bus fixups */ if (ppc_md.pcibios_fixup_bus) ppc_md.pcibios_fixup_bus(bus); + + /* Read default IRQs and fixup if necessary */ + list_for_each_entry(dev, &bus->devices, bus_list) { + pci_read_irq_line(dev); + if (ppc_md.pci_irq_fixup) + ppc_md.pci_irq_fixup(dev); + } } char __init *pcibios_setup(char *str) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 80ae9ea15cd..9a6bb80a8cd 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -1215,8 +1215,12 @@ static void __devinit do_bus_setup(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) ppc_md.iommu_dev_setup(dev); - if (ppc_md.irq_bus_setup) - ppc_md.irq_bus_setup(bus); + /* Read default IRQs and fixup if necessary */ + list_for_each_entry(dev, &bus->devices, bus_list) { + pci_read_irq_line(dev); + if (ppc_md.pci_irq_fixup) + ppc_md.pci_irq_fixup(dev); + } } void __devinit pcibios_fixup_bus(struct pci_bus *bus) diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c index bb9acbb9817..ea880f1f0dc 100644 --- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c +++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c @@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } -static void -__init mpc82xx_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) { - pci_read_irq_line(dev); - } -} - void __init add_bridge(struct device_node *np) { int len; @@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arch(void) add_bridge(np); of_node_put(np); - ppc_md.pci_map_irq = NULL; - ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup; - ppc_md.pcibios_fixup_bus = NULL; #endif #ifdef CONFIG_ROOT_NFS diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c index e2bcaaf6b32..314c42ac604 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_itx.c +++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c @@ -118,7 +118,4 @@ define_machine(mpc834x_itx) { .time_init = mpc83xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup = mpc83xx_pcibios_fixup, -#endif }; diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c index 677196187a4..80b735a414d 100644 --- a/arch/powerpc/platforms/83xx/mpc834x_sys.c +++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c @@ -137,7 +137,4 @@ define_machine(mpc834x_sys) { .time_init = mpc83xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, -#ifdef CONFIG_PCI - .pcibios_fixup = mpc83xx_pcibios_fixup, -#endif }; diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h index 2c82bca9bfb..01cae106912 100644 --- a/arch/powerpc/platforms/83xx/mpc83xx.h +++ b/arch/powerpc/platforms/83xx/mpc83xx.h @@ -11,7 +11,6 @@ extern int add_bridge(struct device_node *dev); extern int mpc83xx_exclude_device(u_char bus, u_char devfn); -extern void mpc83xx_pcibios_fixup(void); extern void mpc83xx_restart(char *cmd); extern long mpc83xx_time_init(void); diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c index 4557ac5255c..9c365055514 100644 --- a/arch/powerpc/platforms/83xx/pci.c +++ b/arch/powerpc/platforms/83xx/pci.c @@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } -void __init mpc83xx_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - /* map all the PCI irqs */ - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - int __init add_bridge(struct device_node *dev) { int len; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c index d3e669d69c7..bda2e55e6c4 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_char devfn) else return PCIBIOS_SUCCESSFUL; } - -void __init -mpc85xx_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} #endif /* CONFIG_PCI */ #ifdef CONFIG_CPM2 @@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arch(void) #ifdef CONFIG_PCI for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - - ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 1a1c226ad4d..f4dd5f2f8a2 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) } -void __init mpc86xx_hpcn_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - - /* * Called very early, device-tree isn't unflattened */ @@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) { .setup_arch = mpc86xx_hpcn_setup_arch, .init_IRQ = mpc86xx_hpcn_init_irq, .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, - .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup, .get_irq = mpic_get_irq, .restart = mpc86xx_restart, .time_init = mpc86xx_time_init, diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 22c228a49c3..1944bb413f0 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -80,14 +80,6 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } -static void __init cell_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - static void __init cell_init_irq(void) { iic_init_IRQ(); @@ -180,7 +172,6 @@ define_machine(cell) { .check_legacy_ioport = cell_check_legacy_ioport, .progress = cell_progress, .init_IRQ = cell_init_irq, - .pcibios_fixup = cell_pcibios_fixup, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 996c28744e9..63f0aee4c15 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h @@ -9,4 +9,3 @@ extern long chrp_time_init(void); extern void chrp_find_bridges(void); extern void chrp_event_scan(unsigned long); -extern void chrp_pcibios_fixup(void); diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 0f4340506c7..ddb4a116ea8 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c @@ -156,15 +156,6 @@ hydra_init(void) return 1; } -void __init -chrp_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - #define PRG_CL_RESET_VALID 0x00010000 static void __init diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 49b8dabcbc9..e6807d6d75b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -600,7 +600,6 @@ define_machine(chrp) { .init = chrp_init2, .show_cpuinfo = chrp_show_cpuinfo, .init_IRQ = chrp_init_IRQ, - .pcibios_fixup = chrp_pcibios_fixup, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt, diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index bdb475c65cb..c6113c39009 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -89,7 +89,7 @@ u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) /* * Scans the interrupt map for pci device */ -void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) +void __devinit mpc7448_hpc2_fixup_irq(struct pci_dev *dev) { struct pci_controller *hose; struct device_node *node; @@ -117,19 +117,13 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) pin = 1; pin--; dev->irq = interrupt[slot*4*7 + pin*7 + 5]; + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); } /* temporary pci irq map fixup*/ -void __init mpc7448_hpc2_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - for_each_pci_dev(dev) { - mpc7448_hpc2_fixup_irq(dev); - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - } -} - static void __init mpc7448_hpc2_setup_arch(void) { struct device_node *cpu; @@ -300,7 +294,7 @@ define_machine(mpc7448_hpc2){ .init_IRQ = mpc7448_hpc2_init_IRQ, .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, .get_irq = mpic_get_irq, - .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, + .pci_irq_fixup = mpc7448_hpc2_fixup_irq, .restart = mpc7448_hpc2_restart, .calibrate_decr = generic_calibrate_decr, .machine_check_exception= mpc7448_machine_check_exception, diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h index 0657c579b84..c6911ddc479 100644 --- a/arch/powerpc/platforms/maple/maple.h +++ b/arch/powerpc/platforms/maple/maple.h @@ -8,5 +8,5 @@ extern void maple_get_rtc_time(struct rtc_time *tm); extern unsigned long maple_get_boot_time(void); extern void maple_calibrate_decr(void); extern void maple_pci_init(void); -extern void maple_pcibios_fixup(void); +extern void maple_pci_irq_fixup(struct pci_dev *dev); extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel); diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 63b4d1bff35..3a32deda765 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -502,38 +502,29 @@ static int __init add_bridge(struct device_node *dev) } -void __init maple_pcibios_fixup(void) +void __devinit maple_pci_irq_fixup(struct pci_dev *dev) { - struct pci_dev *dev = NULL; - - DBG(" -> maple_pcibios_fixup\n"); - - for_each_pci_dev(dev) { - /* Fixup IRQ for PCIe host */ - if (u4_pcie != NULL && dev->bus->number == 0 && - pci_bus_to_host(dev->bus) == u4_pcie) { - printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n"); - dev->irq = irq_create_mapping(NULL, 1); - if (dev->irq != NO_IRQ) - set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); - continue; - } - - /* Hide AMD8111 IDE interrupt when in legacy mode so - * the driver calls pci_get_legacy_ide_irq() - */ - if (dev->vendor == PCI_VENDOR_ID_AMD && - dev->device == PCI_DEVICE_ID_AMD_8111_IDE && - (dev->class & 5) != 5) { - dev->irq = NO_IRQ; - continue; - } + DBG(" -> maple_pci_irq_fixup\n"); + + /* Fixup IRQ for PCIe host */ + if (u4_pcie != NULL && dev->bus->number == 0 && + pci_bus_to_host(dev->bus) == u4_pcie) { + printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n"); + dev->irq = irq_create_mapping(NULL, 1); + if (dev->irq != NO_IRQ) + set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); + } - /* For all others, map the interrupt from the device-tree */ - pci_read_irq_line(dev); + /* Hide AMD8111 IDE interrupt when in legacy mode so + * the driver calls pci_get_legacy_ide_irq() + */ + if (dev->vendor == PCI_VENDOR_ID_AMD && + dev->device == PCI_DEVICE_ID_AMD_8111_IDE && + (dev->class & 5) != 5) { + dev->irq = NO_IRQ; } - DBG(" <- maple_pcibios_fixup\n"); + DBG(" <- maple_pci_irq_fixup\n"); } static void __init maple_fixup_phb_resources(void) diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index fe6b9bff61b..094989d50ba 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -312,7 +312,7 @@ define_machine(maple_md) { .setup_arch = maple_setup_arch, .init_early = maple_init_early, .init_IRQ = maple_init_IRQ, - .pcibios_fixup = maple_pcibios_fixup, + .pci_irq_fixup = maple_pci_irq_fixup, .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, .restart = maple_restart, .power_off = maple_power_off, diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h index fd71d72736b..51c2a2397ec 100644 --- a/arch/powerpc/platforms/pasemi/pasemi.h +++ b/arch/powerpc/platforms/pasemi/pasemi.h @@ -3,6 +3,5 @@ extern unsigned long pas_get_boot_time(void); extern void pas_pci_init(void); -extern void pas_pcibios_fixup(void); #endif /* _PASEMI_PASEMI_H */ diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index 39020c1fa13..faa618e0404 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c @@ -148,14 +148,6 @@ static int __init add_bridge(struct device_node *dev) } -void __init pas_pcibios_fixup(void) -{ - struct pci_dev *dev = NULL; - - for_each_pci_dev(dev) - pci_read_irq_line(dev); -} - static void __init pas_fixup_phb_resources(void) { struct pci_controller *hose, *tmp; diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 106896c3b60..eb2457567f8 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -176,7 +176,6 @@ define_machine(pas) { .init_early = pas_init_early, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, - .pcibios_fixup = pas_pcibios_fixup, .restart = pas_restart, .power_off = pas_power_off, .halt = pas_halt, diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 257dc906846..f42475b27c1 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c @@ -984,30 +984,23 @@ static int __init add_bridge(struct device_node *dev) return 0; } -void __init pmac_pcibios_fixup(void) +void __devinit pmac_pci_irq_fixup(struct pci_dev *dev) { - struct pci_dev* dev = NULL; - - for_each_pci_dev(dev) { - /* Read interrupt from the device-tree */ - pci_read_irq_line(dev); - #ifdef CONFIG_PPC32 - /* Fixup interrupt for the modem/ethernet combo controller. - * on machines with a second ohare chip. - * The number in the device tree (27) is bogus (correct for - * the ethernet-only board but not the combo ethernet/modem - * board). The real interrupt is 28 on the second controller - * -> 28+32 = 60. - */ - if (has_second_ohare && - dev->vendor == PCI_VENDOR_ID_DEC && - dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { - dev->irq = irq_create_mapping(NULL, 60); - set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); - } -#endif /* CONFIG_PPC32 */ + /* Fixup interrupt for the modem/ethernet combo controller. + * on machines with a second ohare chip. + * The number in the device tree (27) is bogus (correct for + * the ethernet-only board but not the combo ethernet/modem + * board). The real interrupt is 28 on the second controller + * -> 28+32 = 60. + */ + if (has_second_ohare && + dev->vendor == PCI_VENDOR_ID_DEC && + dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { + dev->irq = irq_create_mapping(NULL, 60); + set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); } +#endif /* CONFIG_PPC32 */ } #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h index 94e7b24b840..6e090a7dea8 100644 --- a/arch/powerpc/platforms/powermac/pmac.h +++ b/arch/powerpc/platforms/powermac/pmac.h @@ -20,7 +20,7 @@ extern void pmac_get_rtc_time(struct rtc_time *); extern int pmac_set_rtc_time(struct rtc_time *); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); -extern void pmac_pcibios_fixup(void); +extern void pmac_pci_irq_fixup(struct pci_dev *); extern void pmac_pci_init(void); extern unsigned long pmac_ide_get_base(int index); extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index cb1c342061e..805791d76fd 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -727,7 +727,7 @@ define_machine(powermac) { .show_cpuinfo = pmac_show_cpuinfo, .init_IRQ = pmac_pic_init, .get_irq = NULL, /* changed later */ - .pcibios_fixup = pmac_pcibios_fixup, + .pci_irq_fixup = pmac_pci_irq_fixup, .restart = pmac_restart, .power_off = pmac_power_off, .halt = pmac_halt, diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 410a6bcc4ca..715db5c8990 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -29,8 +29,6 @@ #include #include -static int __devinitdata s7a_workaround = -1; - #if 0 void pcibios_name_device(struct pci_dev *dev) { @@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev *dev) DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); #endif -static void __devinit check_s7a(void) -{ - struct device_node *root; - const char *model; - - s7a_workaround = 0; - root = of_find_node_by_path("/"); - if (root) { - model = get_property(root, "model", NULL); - if (model && !strcmp(model, "IBM,7013-S7A")) - s7a_workaround = 1; - of_node_put(root); - } -} - -void __devinit pSeries_irq_bus_setup(struct pci_bus *bus) -{ - struct pci_dev *dev; - - if (s7a_workaround < 0) - check_s7a(); - list_for_each_entry(dev, &bus->devices, bus_list) { - pci_read_irq_line(dev); - if (s7a_workaround) { - if (dev->irq > 16) { - dev->irq -= 3; - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, - dev->irq); - } - } - } -} - static void __init pSeries_request_regions(void) { if (!isa_io_base) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 89a8119f988..a8f3812aa38 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -553,7 +553,6 @@ define_machine(pseries) { .log_error = pSeries_log_error, .pcibios_fixup = pSeries_final_fixup, .pci_probe_mode = pSeries_pci_probe_mode, - .irq_bus_setup = pSeries_irq_bus_setup, .restart = rtas_restart, .power_off = rtas_power_off, .halt = rtas_halt, -- cgit v1.2.3 From 69108cf00679716bcab58acb3135390654c5bb99 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:52 +1100 Subject: [POWERPC] Remove ppc_md.pci_map_irq & ppc_swizzle for ARCH=powerpc These were inherited from ARCH=ppc, but are not needed since parsing of interrupts should be done via the of_* functions (who can do swizzling). If we ever need to do non-standard swizzling on bridges without a device-node, then we might add back a slightly different version of ppc_md.pci_swizzle but for now, that is not the case. I removed the couple of calls for these in 83xx. If that breaks something, then there is a problem with the device-tree on these. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 23 ----------------------- arch/powerpc/platforms/83xx/mpc832x_mds.c | 2 -- arch/powerpc/platforms/83xx/mpc8360e_pb.c | 2 -- 3 files changed, 27 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 853ecef8178..d32cd500d8b 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -1283,10 +1283,6 @@ pcibios_init(void) if (pci_assign_all_buses && have_of) pcibios_make_OF_bus_map(); - /* Do machine dependent PCI interrupt routing */ - if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) - pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); - /* Call machine dependent fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); @@ -1309,25 +1305,6 @@ pcibios_init(void) subsys_initcall(pcibios_init); -unsigned char __init -common_swizzle(struct pci_dev *dev, unsigned char *pinp) -{ - struct pci_controller *hose = dev->sysdata; - - if (dev->bus->number != hose->first_busno) { - u8 pin = *pinp; - do { - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - /* Move up the chain of bridges. */ - dev = dev->bus->self; - } while (dev->bus->self); - *pinp = pin; - - /* The slot is the idsel of the last bridge. */ - } - return PCI_SLOT(dev->devfn); -} - unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, unsigned long start, unsigned long size) { diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c index a43ac71ab74..f58c9780b66 100644 --- a/arch/powerpc/platforms/83xx/mpc832x_mds.c +++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c @@ -97,8 +97,6 @@ static void __init mpc832x_sys_setup_arch(void) #ifdef CONFIG_PCI for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - - ppc_md.pci_swizzle = common_swizzle; ppc_md.pci_exclude_device = mpc83xx_exclude_device; #endif diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c index 1a523c81c06..7bfd47ad723 100644 --- a/arch/powerpc/platforms/83xx/mpc8360e_pb.c +++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c @@ -102,8 +102,6 @@ static void __init mpc8360_sys_setup_arch(void) #ifdef CONFIG_PCI for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - - ppc_md.pci_swizzle = common_swizzle; ppc_md.pci_exclude_device = mpc83xx_exclude_device; #endif -- cgit v1.2.3 From 4c75a6f441cdd1c69a6c173bc7944e12c2ba6f84 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:53 +1100 Subject: [POWERPC] Generic DCR infrastructure This patch adds new dcr_map/dcr_read/dcr_write accessors for DCRs that can be used by drivers to transparently address either native DCRs or memory mapped DCRs. The implementation for memory mapped DCRs is done after the binding being currently worked on for SLOF and the Axon chipset. This patch enables it for the cell native platform Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 16 +++++ arch/powerpc/kernel/Makefile | 1 + arch/powerpc/sysdev/Makefile | 3 +- arch/powerpc/sysdev/dcr-low.S | 39 ++++++++++++ arch/powerpc/sysdev/dcr.c | 137 ++++++++++++++++++++++++++++++++++++++++++ arch/ppc/Kconfig | 11 ++++ 6 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/sysdev/dcr-low.S create mode 100644 arch/powerpc/sysdev/dcr.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 96316c86610..0e564d30fc4 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -160,9 +160,11 @@ config PPC_86xx config 40x bool "AMCC 40x" + select PPC_DCR_NATIVE config 44x bool "AMCC 44x" + select PPC_DCR_NATIVE config 8xx bool "Freescale 8xx" @@ -208,6 +210,19 @@ config PPC_FPU bool default y if PPC64 +config PPC_DCR_NATIVE + bool + default n + +config PPC_DCR_MMIO + bool + default n + +config PPC_DCR + bool + depends on PPC_DCR_NATIVE || PPC_DCR_MMIO + default y + config BOOKE bool depends on E200 || E500 @@ -453,6 +468,7 @@ config PPC_CELL config PPC_CELL_NATIVE bool select PPC_CELL + select PPC_DCR_MMIO default n config PPC_IBM_CELL_BLADE diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index d8240ce2212..f34d158b962 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o + module-$(CONFIG_PPC64) += module_64.o obj-$(CONFIG_MODULES) += $(module-y) diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 5b87f7b42a1..8ba11ab5e61 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -5,8 +5,7 @@ endif obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_MPC106) += grackle.o -obj-$(CONFIG_BOOKE) += dcr.o -obj-$(CONFIG_40x) += dcr.o +obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S new file mode 100644 index 00000000000..2078f39e2f1 --- /dev/null +++ b/arch/powerpc/sysdev/dcr-low.S @@ -0,0 +1,39 @@ +/* + * "Indirect" DCR access + * + * Copyright (c) 2004 Eugene Surovegin + * + * 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. + */ + +#include +#include + +#define DCR_ACCESS_PROLOG(table) \ + rlwinm r3,r3,4,18,27; \ + lis r5,table@h; \ + ori r5,r5,table@l; \ + add r3,r3,r5; \ + mtctr r3; \ + bctr + +_GLOBAL(__mfdcr) + DCR_ACCESS_PROLOG(__mfdcr_table) + +_GLOBAL(__mtdcr) + DCR_ACCESS_PROLOG(__mtdcr_table) + +__mfdcr_table: + mfdcr r3,0; blr +__mtdcr_table: + mtdcr 0,r4; blr + +dcr = 1 + .rept 1023 + mfdcr r3,dcr; blr + mtdcr dcr,r4; blr + dcr = dcr + 1 + .endr diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c new file mode 100644 index 00000000000..dffeeaeca1d --- /dev/null +++ b/arch/powerpc/sysdev/dcr.c @@ -0,0 +1,137 @@ +/* + * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. + * + * + * 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 + */ + +#undef DEBUG + +#include +#include +#include + +unsigned int dcr_resource_start(struct device_node *np, unsigned int index) +{ + unsigned int ds; + const u32 *dr = get_property(np, "dcr-reg", &ds); + + if (dr == NULL || ds & 1 || index >= (ds / 8)) + return 0; + + return dr[index * 2]; +} + +unsigned int dcr_resource_len(struct device_node *np, unsigned int index) +{ + unsigned int ds; + const u32 *dr = get_property(np, "dcr-reg", &ds); + + if (dr == NULL || ds & 1 || index >= (ds / 8)) + return 0; + + return dr[index * 2 + 1]; +} + +#ifndef CONFIG_PPC_DCR_NATIVE + +static struct device_node * find_dcr_parent(struct device_node * node) +{ + struct device_node *par, *tmp; + const u32 *p; + + for (par = of_node_get(node); par;) { + if (get_property(par, "dcr-controller", NULL)) + break; + p = get_property(par, "dcr-parent", NULL); + tmp = par; + if (p == NULL) + par = of_get_parent(par); + else + par = of_find_node_by_phandle(*p); + of_node_put(tmp); + } + return par; +} + +u64 of_translate_dcr_address(struct device_node *dev, + unsigned int dcr_n, + unsigned int *out_stride) +{ + struct device_node *dp; + const u32 *p; + unsigned int stride; + u64 ret; + + dp = find_dcr_parent(dev); + if (dp == NULL) + return OF_BAD_ADDR; + + /* Stride is not properly defined yet, default to 0x10 for Axon */ + p = get_property(dp, "dcr-mmio-stride", NULL); + stride = (p == NULL) ? 0x10 : *p; + + /* XXX FIXME: Which property name is to use of the 2 following ? */ + p = get_property(dp, "dcr-mmio-range", NULL); + if (p == NULL) + p = get_property(dp, "dcr-mmio-space", NULL); + if (p == NULL) + return OF_BAD_ADDR; + + /* Maybe could do some better range checking here */ + ret = of_translate_address(dp, p); + if (ret != OF_BAD_ADDR) + ret += (u64)(stride) * (u64)dcr_n; + if (out_stride) + *out_stride = stride; + return ret; +} + +dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n, + unsigned int dcr_c) +{ + dcr_host_t ret = { .token = NULL, .stride = 0 }; + u64 addr; + + pr_debug("dcr_map(%s, 0x%x, 0x%x)\n", + dev->full_name, dcr_n, dcr_c); + + addr = of_translate_dcr_address(dev, dcr_n, &ret.stride); + pr_debug("translates to addr: 0x%lx, stride: 0x%x\n", + addr, ret.stride); + if (addr == OF_BAD_ADDR) + return ret; + pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride); + ret.token = ioremap(addr, dcr_c * ret.stride); + if (ret.token == NULL) + return ret; + pr_debug("mapped at 0x%p -> base is 0x%p\n", + ret.token, ret.token - dcr_n * ret.stride); + ret.token -= dcr_n * ret.stride; + return ret; +} + +void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c) +{ + dcr_host_t h = host; + + if (h.token == NULL) + return; + h.token -= dcr_n * h.stride; + iounmap(h.token); + h.token = NULL; +} + +#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */ diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index ef018e25fb0..edf71a4ecc9 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -77,9 +77,11 @@ config 6xx config 40x bool "40x" + select PPC_DCR_NATIVE config 44x bool "44x" + select PPC_DCR_NATIVE config 8xx bool "8xx" @@ -95,6 +97,15 @@ endchoice config PPC_FPU bool +config PPC_DCR_NATIVE + bool + default n + +config PPC_DCR + bool + depends on PPC_DCR_NATIVE + default y + config BOOKE bool depends on E200 || E500 -- cgit v1.2.3 From fbf0274e43b7e17ee740fee2d693932be093d56d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:55 +1100 Subject: [POWERPC] Support for DCR based MPIC This patch implements support for DCR based MPIC implementations. Such implementations have the MPIC_USES_DCR flag set and don't use the phys_addr argument of mpic_alloc (they require a valid dcr mapping in the device node) This version of the patch can use a little bif of cleanup still (I can probably consolidate rb->dbase/doff, at least once I'm sure on how the hardware is actually supposed to work vs. possible simulator issues) and it should be possible to build a DCR-only version of the driver. I need to cleanup a bit the CONFIG_* handling for that and probably introduce CONFIG_MPIC_MMIO and CONFIG_MPIC_DCR. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 136 +++++++++++++++++++++++++++++++++------------ 1 file changed, 100 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index ba4833f57d4..909306ca04f 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -147,33 +147,51 @@ static u32 mpic_infos[][MPIC_IDX_END] = { */ -static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, - unsigned int reg) +static inline u32 _mpic_read(enum mpic_reg_type type, + struct mpic_reg_bank *rb, + unsigned int reg) { - if (be) - return in_be32(base + (reg >> 2)); - else - return in_le32(base + (reg >> 2)); + switch(type) { +#ifdef CONFIG_PPC_DCR + case mpic_access_dcr: + return dcr_read(rb->dhost, + rb->dbase + reg + rb->doff); +#endif + case mpic_access_mmio_be: + return in_be32(rb->base + (reg >> 2)); + case mpic_access_mmio_le: + default: + return in_le32(rb->base + (reg >> 2)); + } } -static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, - unsigned int reg, u32 value) +static inline void _mpic_write(enum mpic_reg_type type, + struct mpic_reg_bank *rb, + unsigned int reg, u32 value) { - if (be) - out_be32(base + (reg >> 2), value); - else - out_le32(base + (reg >> 2), value); + switch(type) { +#ifdef CONFIG_PPC_DCR + case mpic_access_dcr: + return dcr_write(rb->dhost, + rb->dbase + reg + rb->doff, value); +#endif + case mpic_access_mmio_be: + return out_be32(rb->base + (reg >> 2), value); + case mpic_access_mmio_le: + default: + return out_le32(rb->base + (reg >> 2), value); + } } static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) { - unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; + enum mpic_reg_type type = mpic->reg_type; unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + (ipi * MPIC_INFO(GREG_IPI_STRIDE)); - if (mpic->flags & MPIC_BROKEN_IPI) - be = !be; - return _mpic_read(be, mpic->gregs, offset); + if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le) + type = mpic_access_mmio_be; + return _mpic_read(type, &mpic->gregs, offset); } static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) @@ -181,7 +199,7 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + (ipi * MPIC_INFO(GREG_IPI_STRIDE)); - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); + _mpic_write(mpic->reg_type, &mpic->gregs, offset, value); } static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) @@ -190,8 +208,7 @@ static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) if (mpic->flags & MPIC_PRIMARY) cpu = hard_smp_processor_id(); - return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, - mpic->cpuregs[cpu], reg); + return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg); } static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) @@ -201,7 +218,7 @@ static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 valu if (mpic->flags & MPIC_PRIMARY) cpu = hard_smp_processor_id(); - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value); + _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value); } static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) @@ -209,7 +226,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne unsigned int isu = src_no >> mpic->isu_shift; unsigned int idx = src_no & mpic->isu_mask; - return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], + return _mpic_read(mpic->reg_type, &mpic->isus[isu], reg + (idx * MPIC_INFO(IRQ_STRIDE))); } @@ -219,12 +236,12 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, unsigned int isu = src_no >> mpic->isu_shift; unsigned int idx = src_no & mpic->isu_mask; - _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], + _mpic_write(mpic->reg_type, &mpic->isus[isu], reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); } -#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) -#define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v)) +#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r)) +#define mpic_write(b,r,v) _mpic_write(mpic->reg_type,&(b),(r),(v)) #define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) #define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) #define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) @@ -238,6 +255,38 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no, */ +static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr, + struct mpic_reg_bank *rb, unsigned int offset, + unsigned int size) +{ + rb->base = ioremap(phys_addr + offset, size); + BUG_ON(rb->base == NULL); +} + +#ifdef CONFIG_PPC_DCR +static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, + unsigned int offset, unsigned int size) +{ + rb->dbase = mpic->dcr_base; + rb->doff = offset; + rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size); + BUG_ON(!DCR_MAP_OK(rb->dhost)); +} + +static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr, + struct mpic_reg_bank *rb, unsigned int offset, + unsigned int size) +{ + if (mpic->flags & MPIC_USES_DCR) + _mpic_map_dcr(mpic, rb, offset, size); + else + _mpic_map_mmio(mpic, phys_addr, rb, offset, size); +} +#else /* CONFIG_PPC_DCR */ +#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) +#endif /* !CONFIG_PPC_DCR */ + + /* Check if we have one of those nice broken MPICs with a flipped endian on * reads from IPI registers @@ -883,6 +932,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, if (flags & MPIC_PRIMARY) mpic->hc_ht_irq.set_affinity = mpic_set_affinity; #endif /* CONFIG_MPIC_BROKEN_U3 */ + #ifdef CONFIG_SMP mpic->hc_ipi = mpic_ipi_chip; mpic->hc_ipi.typename = name; @@ -897,11 +947,26 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; #endif + /* default register type */ + mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ? + mpic_access_mmio_be : mpic_access_mmio_le; + +#ifdef CONFIG_PPC_DCR + if (mpic->flags & MPIC_USES_DCR) { + const u32 *dbasep; + BUG_ON(mpic->of_node == NULL); + dbasep = get_property(mpic->of_node, "dcr-reg", NULL); + BUG_ON(dbasep == NULL); + mpic->dcr_base = *dbasep; + mpic->reg_type = mpic_access_dcr; + } +#else + BUG_ON (mpic->flags & MPIC_USES_DCR); +#endif /* CONFIG_PPC_DCR */ + /* Map the global registers */ - mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); - mpic->tmregs = mpic->gregs + - ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2); - BUG_ON(mpic->gregs == NULL); + mpic_map(mpic, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); + mpic_map(mpic, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); /* Reset */ if (flags & MPIC_WANTS_RESET) { @@ -926,17 +991,16 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + - i * MPIC_INFO(CPU_STRIDE), 0x1000); - BUG_ON(mpic->cpuregs[i] == NULL); + mpic_map(mpic, phys_addr, &mpic->cpuregs[i], + MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), + 0x1000); } /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), - MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); - BUG_ON(mpic->isus[0] == NULL); + mpic_map(mpic, phys_addr, &mpic->isus[0], + MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); mpic->isu_mask = (1 << mpic->isu_shift) - 1; @@ -979,8 +1043,8 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic->isus[isu_num] = ioremap(phys_addr, - MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); + mpic_map(mpic, phys_addr, &mpic->isus[isu_num], 0, + MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; } -- cgit v1.2.3 From a959ff56bbf07954ea4fa1cf72f99a38795eadb3 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:56 +1100 Subject: [POWERPC] Improve MPIC driver auto-configuration from DT This patch applies on top of the MPIC DCR support. It makes the MPIC driver capable of a lot more auto-configuration based on the device-tree, for example, it can retreive it's own physical address if not passed as an argument, find out if it's DCR or MMIO mapped, and set the BIG_ENDIAN flag automatically in the presence of a "big-endian" property in the device-tree node. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/mpic.c | 50 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 909306ca04f..411480d5c62 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -894,7 +894,7 @@ static struct irq_host_ops mpic_host_ops = { */ struct mpic * __init mpic_alloc(struct device_node *node, - unsigned long phys_addr, + phys_addr_t phys_addr, unsigned int flags, unsigned int isu_size, unsigned int irq_count, @@ -904,6 +904,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, u32 reg; const char *vers; int i; + u64 paddr = phys_addr; mpic = alloc_bootmem(sizeof(struct mpic)); if (mpic == NULL) @@ -943,6 +944,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->irq_count = irq_count; mpic->num_sources = 0; /* so far */ + /* Check for "big-endian" in device-tree */ + if (node && get_property(node, "big-endian", NULL) != NULL) + mpic->flags |= MPIC_BIG_ENDIAN; + + #ifdef CONFIG_MPIC_WEIRD mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; #endif @@ -951,11 +957,17 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ? mpic_access_mmio_be : mpic_access_mmio_le; + /* If no physical address is passed in, a device-node is mandatory */ + BUG_ON(paddr == 0 && node == NULL); + + /* If no physical address passed in, check if it's dcr based */ + if (paddr == 0 && get_property(node, "dcr-reg", NULL) != NULL) + mpic->flags |= MPIC_USES_DCR; + #ifdef CONFIG_PPC_DCR if (mpic->flags & MPIC_USES_DCR) { const u32 *dbasep; - BUG_ON(mpic->of_node == NULL); - dbasep = get_property(mpic->of_node, "dcr-reg", NULL); + dbasep = get_property(node, "dcr-reg", NULL); BUG_ON(dbasep == NULL); mpic->dcr_base = *dbasep; mpic->reg_type = mpic_access_dcr; @@ -964,9 +976,20 @@ struct mpic * __init mpic_alloc(struct device_node *node, BUG_ON (mpic->flags & MPIC_USES_DCR); #endif /* CONFIG_PPC_DCR */ + /* If the MPIC is not DCR based, and no physical address was passed + * in, try to obtain one + */ + if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) { + const u32 *reg; + reg = get_property(node, "reg", NULL); + BUG_ON(reg == NULL); + paddr = of_translate_address(node, reg); + BUG_ON(paddr == OF_BAD_ADDR); + } + /* Map the global registers */ - mpic_map(mpic, phys_addr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); - mpic_map(mpic, phys_addr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); + mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); /* Reset */ if (flags & MPIC_WANTS_RESET) { @@ -991,7 +1014,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Map the per-CPU registers */ for (i = 0; i < mpic->num_cpus; i++) { - mpic_map(mpic, phys_addr, &mpic->cpuregs[i], + mpic_map(mpic, paddr, &mpic->cpuregs[i], MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), 0x1000); } @@ -999,7 +1022,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, /* Initialize main ISU if none provided */ if (mpic->isu_size == 0) { mpic->isu_size = mpic->num_sources; - mpic_map(mpic, phys_addr, &mpic->isus[0], + mpic_map(mpic, paddr, &mpic->isus[0], MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); } mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); @@ -1020,10 +1043,11 @@ struct mpic * __init mpic_alloc(struct device_node *node, vers = ""; break; } - printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n", - name, vers, phys_addr, mpic->num_cpus); - printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size, - mpic->isu_shift, mpic->isu_mask); + printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx," + " max %d CPUs\n", + name, vers, (unsigned long long)paddr, mpic->num_cpus); + printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", + mpic->isu_size, mpic->isu_shift, mpic->isu_mask); mpic->next = mpics; mpics = mpic; @@ -1037,13 +1061,13 @@ struct mpic * __init mpic_alloc(struct device_node *node, } void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, - unsigned long phys_addr) + phys_addr_t paddr) { unsigned int isu_first = isu_num * mpic->isu_size; BUG_ON(isu_num >= MPIC_MAX_ISU); - mpic_map(mpic, phys_addr, &mpic->isus[isu_num], 0, + mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); if ((isu_first + mpic->isu_size) > mpic->num_sources) mpic->num_sources = isu_first + mpic->isu_size; -- cgit v1.2.3 From 21fb5a1d9f554970c680b801ba32184bc7c34aa0 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:58 +1100 Subject: [POWERPC] Native cell support for MPIC in southbridge Add support for southbridges using the MPIC interrupt controller to the native cell platforms. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + arch/powerpc/platforms/cell/setup.c | 44 +++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 0e564d30fc4..65588a6bd2f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -469,6 +469,7 @@ config PPC_CELL_NATIVE bool select PPC_CELL select PPC_DCR_MMIO + select MPIC default n config PPC_IBM_CELL_BLADE diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 1944bb413f0..13f628def36 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "interrupt.h" #include "iommu.h" @@ -80,10 +81,53 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } +static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) +{ + struct mpic *mpic = desc->handler_data; + unsigned int virq; + + virq = mpic_get_one_irq(mpic); + if (virq != NO_IRQ) + generic_handle_irq(virq); + desc->chip->eoi(irq); +} + +static void __init mpic_init_IRQ(void) +{ + struct device_node *dn; + struct mpic *mpic; + unsigned int virq; + + for (dn = NULL; + (dn = of_find_node_by_name(dn, "interrupt-controller"));) { + if (!device_is_compatible(dn, "CBEA,platform-open-pic")) + continue; + + /* The MPIC driver will get everything it needs from the + * device-tree, just pass 0 to all arguments + */ + mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC "); + if (mpic == NULL) + continue; + mpic_init(mpic); + + virq = irq_of_parse_and_map(dn, 0); + if (virq == NO_IRQ) + continue; + + printk(KERN_INFO "%s : hooking up to IRQ %d\n", + dn->full_name, virq); + set_irq_data(virq, mpic); + set_irq_chained_handler(virq, cell_mpic_cascade); + } +} + + static void __init cell_init_irq(void) { iic_init_IRQ(); spider_init_IRQ(); + mpic_init_IRQ(); } static void __init cell_setup_arch(void) -- cgit v1.2.3 From 7eebde700fe6fd6573e80bd8e5ed82b4ae705575 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:24:59 +1100 Subject: [POWERPC] Souped-up of_platform_device support This patch first splits of_device.c and of_platform.c, the later containing the bits relative to of_platform_device's. On the "breaks" side of things, drivers uisng of_platform_device(s) need to include asm/of_platform.h now and of_(un)register_driver is now of_(un)register_platform_driver. In addition to a few utility functions to locate of_platform_device(s), the main new addition is of_platform_bus_probe() which allows the platform code to trigger an automatic creation of of_platform_devices for a whole tree of devices. The function acts based on the type of the various "parent" devices encountered from a provided root, using either a default known list of bus types that can be "probed" or a passed-in list. It will only register devices on busses matching that list, which mean that typically, it will not register PCI devices, as expected (since they will be picked up by the PCI layer). This will be used by Cell platforms using 4xx-type IOs in the Axon bridge and can be used by any embedded-type device as well. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/of_device.c | 172 +++------------ arch/powerpc/kernel/of_platform.c | 372 ++++++++++++++++++++++++++++++++ arch/powerpc/platforms/powermac/setup.c | 1 + 4 files changed, 401 insertions(+), 146 deletions(-) create mode 100644 arch/powerpc/kernel/of_platform.c (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f34d158b962..04fdbe568d7 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_PPC_970_NAP) += idle_power4.o -obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o +obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o procfs-$(CONFIG_PPC64) := proc_ppc64.o obj-$(CONFIG_PROC_FS) += $(procfs-y) rtaspci-$(CONFIG_PPC64) := rtas_pci.o diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 397c83eda20..5c653986afa 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -9,30 +9,26 @@ #include /** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure + * of_match_node - Tell if an device_node has a matching of_match structure * @ids: array of of device match structures to search in - * @dev: the of device structure to match against + * @node: the of device structure to match against * - * Used by a driver to check whether an of_device present in the - * system is in its list of supported devices. + * Low level utility function used by device matching. */ -const struct of_device_id *of_match_device(const struct of_device_id *matches, - const struct of_device *dev) +const struct of_device_id *of_match_node(const struct of_device_id *matches, + const struct device_node *node) { - if (!dev->node) - return NULL; while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) - match &= dev->node->name - && !strcmp(matches->name, dev->node->name); + match &= node->name + && !strcmp(matches->name, node->name); if (matches->type[0]) - match &= dev->node->type - && !strcmp(matches->type, dev->node->type); + match &= node->type + && !strcmp(matches->type, node->type); if (matches->compatible[0]) - match &= device_is_compatible(dev->node, - matches->compatible); + match &= device_is_compatible(node, + matches->compatible); if (match) return matches; matches++; @@ -40,16 +36,21 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, return NULL; } -static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +/** + * of_match_device - Tell if an of_device structure has a matching + * of_match structure + * @ids: array of of device match structures to search in + * @dev: the of device structure to match against + * + * Used by a driver to check whether an of_device present in the + * system is in its list of supported devices. + */ +const struct of_device_id *of_match_device(const struct of_device_id *matches, + const struct of_device *dev) { - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_device_id * matches = of_drv->match_table; - - if (!matches) - return 0; - - return of_match_device(matches, of_dev) != NULL; + if (!dev->node) + return NULL; + return of_match_node(matches, dev->node); } struct of_device *of_dev_get(struct of_device *dev) @@ -71,96 +72,8 @@ void of_dev_put(struct of_device *dev) put_device(&dev->dev); } - -static int of_device_probe(struct device *dev) -{ - int error = -ENODEV; - struct of_platform_driver *drv; - struct of_device *of_dev; - const struct of_device_id *match; - - drv = to_of_platform_driver(dev->driver); - of_dev = to_of_device(dev); - - if (!drv->probe) - return error; - - of_dev_get(of_dev); - - match = of_match_device(drv->match_table, of_dev); - if (match) - error = drv->probe(of_dev, match); - if (error) - of_dev_put(of_dev); - - return error; -} - -static int of_device_remove(struct device *dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - - if (dev->driver && drv->remove) - drv->remove(of_dev); - return 0; -} - -static int of_device_suspend(struct device *dev, pm_message_t state) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->suspend) - error = drv->suspend(of_dev, state); - return error; -} - -static int of_device_resume(struct device * dev) -{ - struct of_device * of_dev = to_of_device(dev); - struct of_platform_driver * drv = to_of_platform_driver(dev->driver); - int error = 0; - - if (dev->driver && drv->resume) - error = drv->resume(of_dev); - return error; -} - -struct bus_type of_platform_bus_type = { - .name = "of_platform", - .match = of_platform_bus_match, - .probe = of_device_probe, - .remove = of_device_remove, - .suspend = of_device_suspend, - .resume = of_device_resume, -}; - -static int __init of_bus_driver_init(void) -{ - return bus_register(&of_platform_bus_type); -} - -postcore_initcall(of_bus_driver_init); - -int of_register_driver(struct of_platform_driver *drv) -{ - /* initialize common driver fields */ - drv->driver.name = drv->name; - drv->driver.bus = &of_platform_bus_type; - - /* register with core */ - return driver_register(&drv->driver); -} - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} - - -static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t dev_show_devspec(struct device *dev, + struct device_attribute *attr, char *buf) { struct of_device *ofdev; @@ -208,41 +121,10 @@ void of_device_unregister(struct of_device *ofdev) device_unregister(&ofdev->dev); } -struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -{ - struct of_device *dev; - - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->node = of_node_get(np); - dev->dma_mask = 0xffffffffUL; - dev->dev.dma_mask = &dev->dma_mask; - dev->dev.parent = parent; - dev->dev.bus = &of_platform_bus_type; - dev->dev.release = of_release_dev; - - strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); - - if (of_device_register(dev) != 0) { - kfree(dev); - return NULL; - } - - return dev; -} EXPORT_SYMBOL(of_match_device); -EXPORT_SYMBOL(of_platform_bus_type); -EXPORT_SYMBOL(of_register_driver); -EXPORT_SYMBOL(of_unregister_driver); EXPORT_SYMBOL(of_device_register); EXPORT_SYMBOL(of_device_unregister); EXPORT_SYMBOL(of_dev_get); EXPORT_SYMBOL(of_dev_put); -EXPORT_SYMBOL(of_platform_device_create); EXPORT_SYMBOL(of_release_dev); diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c new file mode 100644 index 00000000000..25850ade8e6 --- /dev/null +++ b/arch/powerpc/kernel/of_platform.c @@ -0,0 +1,372 @@ +/* + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. + * + * + * 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. + * + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +/* + * The list of OF IDs below is used for matching bus types in the + * system whose devices are to be exposed as of_platform_devices. + * + * This is the default list valid for most platforms. This file provides + * functions who can take an explicit list if necessary though + * + * The search is always performed recursively looking for children of + * the provided device_node and recursively if such a children matches + * a bus type in the list + */ + +static struct of_device_id of_default_bus_ids[] = { + { .type = "soc", }, + { .compatible = "soc", }, + { .type = "spider", }, + { .type = "axon", }, + { .type = "plb5", }, + { .type = "plb4", }, + { .type = "opb", }, + {}, +}; + +/* + * + * OF platform device type definition & base infrastructure + * + */ + +static int of_platform_bus_match(struct device *dev, struct device_driver *drv) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * of_drv = to_of_platform_driver(drv); + const struct of_device_id * matches = of_drv->match_table; + + if (!matches) + return 0; + + return of_match_device(matches, of_dev) != NULL; +} + +static int of_platform_device_probe(struct device *dev) +{ + int error = -ENODEV; + struct of_platform_driver *drv; + struct of_device *of_dev; + const struct of_device_id *match; + + drv = to_of_platform_driver(dev->driver); + of_dev = to_of_device(dev); + + if (!drv->probe) + return error; + + of_dev_get(of_dev); + + match = of_match_device(drv->match_table, of_dev); + if (match) + error = drv->probe(of_dev, match); + if (error) + of_dev_put(of_dev); + + return error; +} + +static int of_platform_device_remove(struct device *dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + + if (dev->driver && drv->remove) + drv->remove(of_dev); + return 0; +} + +static int of_platform_device_suspend(struct device *dev, pm_message_t state) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->suspend) + error = drv->suspend(of_dev, state); + return error; +} + +static int of_platform_device_resume(struct device * dev) +{ + struct of_device * of_dev = to_of_device(dev); + struct of_platform_driver * drv = to_of_platform_driver(dev->driver); + int error = 0; + + if (dev->driver && drv->resume) + error = drv->resume(of_dev); + return error; +} + +struct bus_type of_platform_bus_type = { + .name = "of_platform", + .match = of_platform_bus_match, + .probe = of_platform_device_probe, + .remove = of_platform_device_remove, + .suspend = of_platform_device_suspend, + .resume = of_platform_device_resume, +}; +EXPORT_SYMBOL(of_platform_bus_type); + +static int __init of_bus_driver_init(void) +{ + return bus_register(&of_platform_bus_type); +} + +postcore_initcall(of_bus_driver_init); + +int of_register_platform_driver(struct of_platform_driver *drv) +{ + /* initialize common driver fields */ + drv->driver.name = drv->name; + drv->driver.bus = &of_platform_bus_type; + + /* register with core */ + return driver_register(&drv->driver); +} +EXPORT_SYMBOL(of_register_platform_driver); + +void of_unregister_platform_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(of_unregister_platform_driver); + +static void of_platform_make_bus_id(struct of_device *dev) +{ + struct device_node *node = dev->node; + char *name = dev->dev.bus_id; + const u32 *reg; + u64 addr; + + /* + * If it's a DCR based device, use 'd' for native DCRs + * and 'D' for MMIO DCRs. + */ +#ifdef CONFIG_PPC_DCR + reg = get_property(node, "dcr-reg", NULL); + if (reg) { +#ifdef CONFIG_PPC_DCR_NATIVE + snprintf(name, BUS_ID_SIZE, "d%x.%s", + *reg, node->name); +#else /* CONFIG_PPC_DCR_NATIVE */ + addr = of_translate_dcr_address(node, *reg, NULL); + if (addr != OF_BAD_ADDR) { + snprintf(name, BUS_ID_SIZE, + "D%llx.%s", (unsigned long long)addr, + node->name); + return; + } +#endif /* !CONFIG_PPC_DCR_NATIVE */ + } +#endif /* CONFIG_PPC_DCR */ + + /* + * For MMIO, get the physical address + */ + reg = get_property(node, "reg", NULL); + if (reg) { + addr = of_translate_address(node, reg); + if (addr != OF_BAD_ADDR) { + snprintf(name, BUS_ID_SIZE, + "%llx.%s", (unsigned long long)addr, + node->name); + return; + } + } + + /* + * No BusID, use the node name and pray + */ + snprintf(name, BUS_ID_SIZE, "%s", node->name); +} + +struct of_device* of_platform_device_create(struct device_node *np, + const char *bus_id, + struct device *parent) +{ + struct of_device *dev; + + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof(*dev)); + + dev->node = of_node_get(np); + dev->dma_mask = 0xffffffffUL; + dev->dev.dma_mask = &dev->dma_mask; + dev->dev.parent = parent; + dev->dev.bus = &of_platform_bus_type; + dev->dev.release = of_release_dev; + + if (bus_id) + strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); + else + of_platform_make_bus_id(dev); + + if (of_device_register(dev) != 0) { + kfree(dev); + return NULL; + } + + return dev; +} +EXPORT_SYMBOL(of_platform_device_create); + + + +/** + * of_platform_bus_create - Create an OF device for a bus node and all its + * children. Optionally recursively instanciate matching busses. + * @bus: device node of the bus to instanciate + * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to + * disallow recursive creation of child busses + */ +static int of_platform_bus_create(struct device_node *bus, + struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + for (child = NULL; (child = of_get_next_child(bus, child)); ) { + pr_debug(" create child: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else if (!of_match_node(matches, child)) + continue; + if (rc == 0) { + pr_debug(" and sub busses\n"); + rc = of_platform_bus_create(child, matches, &dev->dev); + } if (rc) { + of_node_put(child); + break; + } + } + return rc; +} + +/** + * of_platform_bus_probe - Probe the device-tree for platform busses + * @root: parent of the first level to probe or NULL for the root of the tree + * @matches: match table, NULL to use the default + * @parent: parent to hook devices from, NULL for toplevel + * + * Note that children of the provided root are not instanciated as devices + * unless the specified root itself matches the bus list and is not NULL. + */ + +int of_platform_bus_probe(struct device_node *root, + struct of_device_id *matches, + struct device *parent) +{ + struct device_node *child; + struct of_device *dev; + int rc = 0; + + if (matches == NULL) + matches = of_default_bus_ids; + if (matches == OF_NO_DEEP_PROBE) + return -EINVAL; + if (root == NULL) + root = of_find_node_by_path("/"); + else + of_node_get(root); + + pr_debug("of_platform_bus_probe()\n"); + pr_debug(" starting at: %s\n", root->full_name); + + /* Do a self check of bus type, if there's a match, create + * children + */ + if (of_match_node(matches, root)) { + pr_debug(" root match, create all sub devices\n"); + dev = of_platform_device_create(root, NULL, parent); + if (dev == NULL) { + rc = -ENOMEM; + goto bail; + } + pr_debug(" create all sub busses\n"); + rc = of_platform_bus_create(root, matches, &dev->dev); + goto bail; + } + for (child = NULL; (child = of_get_next_child(root, child)); ) { + if (!of_match_node(matches, child)) + continue; + + pr_debug(" match: %s\n", child->full_name); + dev = of_platform_device_create(child, NULL, parent); + if (dev == NULL) + rc = -ENOMEM; + else + rc = of_platform_bus_create(child, matches, &dev->dev); + if (rc) { + of_node_put(child); + break; + } + } + bail: + of_node_put(root); + return rc; +} +EXPORT_SYMBOL(of_platform_bus_probe); + +static int of_dev_node_match(struct device *dev, void *data) +{ + return to_of_device(dev)->node == data; +} + +struct of_device *of_find_device_by_node(struct device_node *np) +{ + struct device *dev; + + dev = bus_find_device(&of_platform_bus_type, + NULL, np, of_dev_node_match); + if (dev) + return to_of_device(dev); + return NULL; +} +EXPORT_SYMBOL(of_find_device_by_node); + +static int of_dev_phandle_match(struct device *dev, void *data) +{ + phandle *ph = data; + return to_of_device(dev)->node->linux_phandle == *ph; +} + +struct of_device *of_find_device_by_phandle(phandle ph) +{ + struct device *dev; + + dev = bus_find_device(&of_platform_bus_type, + NULL, &ph, of_dev_phandle_match); + if (dev) + return to_of_device(dev); + return NULL; +} +EXPORT_SYMBOL(of_find_device_by_phandle); diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 805791d76fd..4ec6a5a65f3 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From 96289b07eb319ab3f64db3f0d981970aa1d60a60 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:00 +1100 Subject: [POWERPC] Hook of_platform_bus_probe with cell Hook up of_platform_bus_probe with the cell platform in order to publish the non-PCI devices in the device-tree of cell blades as of_platform_device(s) Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/setup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 13f628def36..d704bc19a64 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -51,6 +51,7 @@ #include #include #include +#include #include "interrupt.h" #include "iommu.h" @@ -81,6 +82,14 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } +static int __init cell_publish_devices(void) +{ + if (machine_is(cell)) + of_platform_bus_probe(NULL, NULL, NULL); + return 0; +} +device_initcall(cell_publish_devices); + static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) { struct mpic *mpic = desc->handler_data; -- cgit v1.2.3 From f6a570333e554b48ad589e7137c77c57809eee81 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 18 Oct 2006 01:47:25 -0400 Subject: [PATCH] severing module.h->sched.h Signed-off-by: Al Viro --- arch/i386/kernel/alternative.c | 1 + arch/i386/kernel/cpu/mcheck/therm_throt.c | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 583c238e17f..535f9794fba 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index 2d8703b7ce6..bad8b442070 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* How long to wait between reporting thermal events */ -- cgit v1.2.3 From 914e26379decf1fd984b22e51fd2e4209b7a7f1b Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 18 Oct 2006 13:55:46 -0400 Subject: [PATCH] severing fs.h, radix-tree.h -> sched.h Signed-off-by: Al Viro --- arch/i386/kernel/acpi/cstate.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c index 20563e52c62..4664b55f623 100644 --- a/arch/i386/kernel/acpi/cstate.c +++ b/arch/i386/kernel/acpi/cstate.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 12d04eef927bf61328af2c7cbe756c96f98ac3bf Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:02 +1100 Subject: [POWERPC] Refactor 64 bits DMA operations This patch completely refactors DMA operations for 64 bits powerpc. 32 bits is untouched for now. We use the new dev_archdata structure to add the dma operations pointer and associated data to struct device. While at it, we also add the OF node pointer and numa node. In the future, we might want to look into merging that with pci_dn as well. The old vio, pci-iommu and pci-direct DMA ops are gone. They are now replaced by a set of generic iommu and direct DMA ops (non PCI specific) that can be used by bus types. The toplevel implementation is now inline. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 3 +- arch/powerpc/kernel/dma_64.c | 240 ++++++++++++++++------------- arch/powerpc/kernel/ibmebus.c | 6 +- arch/powerpc/kernel/iommu.c | 6 +- arch/powerpc/kernel/of_platform.c | 9 +- arch/powerpc/kernel/pci_64.c | 26 +++- arch/powerpc/kernel/pci_direct_iommu.c | 98 ------------ arch/powerpc/kernel/pci_iommu.c | 164 -------------------- arch/powerpc/kernel/setup_64.c | 1 + arch/powerpc/kernel/vio.c | 94 +++-------- arch/powerpc/platforms/cell/iommu.c | 21 +-- arch/powerpc/platforms/iseries/iommu.c | 12 +- arch/powerpc/platforms/iseries/pci.c | 2 +- arch/powerpc/platforms/pasemi/setup.c | 16 +- arch/powerpc/platforms/pseries/iommu.c | 90 +++++------ arch/powerpc/platforms/pseries/pci_dlpar.c | 4 +- arch/powerpc/sysdev/dart_iommu.c | 31 ++-- 17 files changed, 271 insertions(+), 552 deletions(-) delete mode 100644 arch/powerpc/kernel/pci_direct_iommu.c delete mode 100644 arch/powerpc/kernel/pci_iommu.c (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 04fdbe568d7..eba8d118e21 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -62,8 +62,7 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o module-$(CONFIG_PPC64) += module_64.o obj-$(CONFIG_MODULES) += $(module-y) -pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ - pci_direct_iommu.o iomap.o +pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o iomap.o pci32-$(CONFIG_PPC32) := pci_32.o obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) kexec-$(CONFIG_PPC64) := machine_kexec_64.o diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 6c168f6ea14..4e655119978 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -1,151 +1,185 @@ /* - * Copyright (C) 2004 IBM Corporation + * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation * - * Implements the generic device dma API for ppc64. Handles - * the pci and vio busses + * Provide default implementations of the DMA mapping callbacks for + * directly mapped busses and busses using the iommu infrastructure */ #include #include -/* Include the busses we support */ -#include -#include -#include -#include #include +#include +#include -static struct dma_mapping_ops *get_dma_ops(struct device *dev) -{ -#ifdef CONFIG_PCI - if (dev->bus == &pci_bus_type) - return &pci_dma_ops; -#endif -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return &vio_dma_ops; -#endif -#ifdef CONFIG_IBMEBUS - if (dev->bus == &ibmebus_bus_type) - return &ibmebus_dma_ops; -#endif - return NULL; -} +/* + * Generic iommu implementation + */ -int dma_supported(struct device *dev, u64 mask) +static inline unsigned long device_to_mask(struct device *dev) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + if (dev->dma_mask && *dev->dma_mask) + return *dev->dma_mask; + /* Assume devices without mask can take 32 bit addresses */ + return 0xfffffffful; +} - BUG_ON(!dma_ops); - return dma_ops->dma_supported(dev, mask); +/* Allocates a contiguous real buffer and creates mappings over it. + * Returns the virtual address of the buffer and sets dma_handle + * to the dma address (mapping) of the first page. + */ +static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + return iommu_alloc_coherent(dev->archdata.dma_data, size, dma_handle, + device_to_mask(dev), flag, + dev->archdata.numa_node); } -EXPORT_SYMBOL(dma_supported); -int dma_set_mask(struct device *dev, u64 dma_mask) +static void dma_iommu_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) { -#ifdef CONFIG_PCI - if (dev->bus == &pci_bus_type) - return pci_set_dma_mask(to_pci_dev(dev), dma_mask); -#endif -#ifdef CONFIG_IBMVIO - if (dev->bus == &vio_bus_type) - return -EIO; -#endif /* CONFIG_IBMVIO */ -#ifdef CONFIG_IBMEBUS - if (dev->bus == &ibmebus_bus_type) - return -EIO; -#endif - BUG(); - return 0; + iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle); } -EXPORT_SYMBOL(dma_set_mask); -void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) +/* Creates TCEs for a user provided buffer. The user buffer must be + * contiguous real kernel storage (not vmalloc). The address of the buffer + * passed here is the kernel (virtual) address of the buffer. The buffer + * need not be page aligned, the dma_addr_t returned will point to the same + * byte within the page as vaddr. + */ +static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr, + size_t size, + enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops->alloc_coherent(dev, size, dma_handle, flag); + return iommu_map_single(dev->archdata.dma_data, vaddr, size, + device_to_mask(dev), direction); } -EXPORT_SYMBOL(dma_alloc_coherent); -void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) + +static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle, + size_t size, + enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction); +} - BUG_ON(!dma_ops); - dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); +static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction) +{ + return iommu_map_sg(dev->archdata.dma_data, sglist, nelems, + device_to_mask(dev), direction); } -EXPORT_SYMBOL(dma_free_coherent); -dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, - enum dma_data_direction direction) +static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, + int nelems, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - return dma_ops->map_single(dev, cpu_addr, size, direction); + iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction); } -EXPORT_SYMBOL(dma_map_single); -void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) +/* We support DMA to/from any memory page via the iommu */ +static int dma_iommu_dma_supported(struct device *dev, u64 mask) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops->unmap_single(dev, dma_addr, size, direction); + struct iommu_table *tbl = dev->archdata.dma_data; + + if (!tbl || tbl->it_offset > mask) { + printk(KERN_INFO + "Warning: IOMMU offset too big for device mask\n"); + if (tbl) + printk(KERN_INFO + "mask: 0x%08lx, table offset: 0x%08lx\n", + mask, tbl->it_offset); + else + printk(KERN_INFO "mask: 0x%08lx, table unavailable\n", + mask); + return 0; + } else + return 1; } -EXPORT_SYMBOL(dma_unmap_single); -dma_addr_t dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction direction) -{ - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); +struct dma_mapping_ops dma_iommu_ops = { + .alloc_coherent = dma_iommu_alloc_coherent, + .free_coherent = dma_iommu_free_coherent, + .map_single = dma_iommu_map_single, + .unmap_single = dma_iommu_unmap_single, + .map_sg = dma_iommu_map_sg, + .unmap_sg = dma_iommu_unmap_sg, + .dma_supported = dma_iommu_dma_supported, +}; +EXPORT_SYMBOL(dma_iommu_ops); - BUG_ON(!dma_ops); +/* + * Generic direct DMA implementation + */ - return dma_ops->map_single(dev, page_address(page) + offset, size, - direction); +static void *dma_direct_alloc_coherent(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t flag) +{ + void *ret; + + /* TODO: Maybe use the numa node here too ? */ + ret = (void *)__get_free_pages(flag, get_order(size)); + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_abs(ret); + } + return ret; } -EXPORT_SYMBOL(dma_map_page); -void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, - enum dma_data_direction direction) +static void dma_direct_free_coherent(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma_handle) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + free_pages((unsigned long)vaddr, get_order(size)); +} - BUG_ON(!dma_ops); +static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, + size_t size, + enum dma_data_direction direction) +{ + return virt_to_abs(ptr); +} - dma_ops->unmap_single(dev, dma_address, size, direction); +static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, + size_t size, + enum dma_data_direction direction) +{ } -EXPORT_SYMBOL(dma_unmap_page); -int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, - enum dma_data_direction direction) +static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); + int i; - BUG_ON(!dma_ops); + for (i = 0; i < nents; i++, sg++) { + sg->dma_address = page_to_phys(sg->page) + sg->offset; + sg->dma_length = sg->length; + } - return dma_ops->map_sg(dev, sg, nents, direction); + return nents; } -EXPORT_SYMBOL(dma_map_sg); -void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, - enum dma_data_direction direction) +static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg, + int nents, enum dma_data_direction direction) { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); +} - dma_ops->unmap_sg(dev, sg, nhwentries, direction); +static int dma_direct_dma_supported(struct device *dev, u64 mask) +{ + /* Could be improved to check for memory though it better be + * done via some global so platforms can set the limit in case + * they have limited DMA windows + */ + return mask >= DMA_32BIT_MASK; } -EXPORT_SYMBOL(dma_unmap_sg); + +struct dma_mapping_ops dma_direct_ops = { + .alloc_coherent = dma_direct_alloc_coherent, + .free_coherent = dma_direct_free_coherent, + .map_single = dma_direct_map_single, + .unmap_single = dma_direct_unmap_single, + .map_sg = dma_direct_map_sg, + .unmap_sg = dma_direct_unmap_sg, + .dma_supported = dma_direct_dma_supported, +}; +EXPORT_SYMBOL(dma_direct_ops); diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 39db7a3affe..8e515797de6 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -112,7 +112,7 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask) return 1; } -struct dma_mapping_ops ibmebus_dma_ops = { +static struct dma_mapping_ops ibmebus_dma_ops = { .alloc_coherent = ibmebus_alloc_coherent, .free_coherent = ibmebus_free_coherent, .map_single = ibmebus_map_single, @@ -176,6 +176,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_common( dev->ofdev.dev.bus = &ibmebus_bus_type; dev->ofdev.dev.release = ibmebus_dev_release; + dev->ofdev.dev.archdata.of_node = dev->ofdev.node; + dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops; + dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node); + /* An ibmebusdev is based on a of_device. We have to change the * bus type to use our own DMA mapping operations. */ diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ba6b7256084..95edad4faf2 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -258,9 +258,9 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, spin_unlock_irqrestore(&(tbl->it_lock), flags); } -int iommu_map_sg(struct device *dev, struct iommu_table *tbl, - struct scatterlist *sglist, int nelems, - unsigned long mask, enum dma_data_direction direction) +int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist, + int nelems, unsigned long mask, + enum dma_data_direction direction) { dma_addr_t dma_next = 0, dma_addr; unsigned long flags; diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 25850ade8e6..7a0e77af7c9 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -22,7 +22,7 @@ #include #include #include - +#include /* * The list of OF IDs below is used for matching bus types in the @@ -221,6 +221,13 @@ struct of_device* of_platform_device_create(struct device_node *np, dev->dev.parent = parent; dev->dev.bus = &of_platform_bus_type; dev->dev.release = of_release_dev; + dev->dev.archdata.of_node = np; + dev->dev.archdata.numa_node = of_node_to_nid(np); + + /* We do not fill the DMA ops for platform devices by default. + * This is currently the responsibility of the platform code + * to do such, possibly using a device notifier + */ if (bus_id) strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 9a6bb80a8cd..88b78484b94 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -61,7 +61,7 @@ void iSeries_pcibios_init(void); LIST_HEAD(hose_list); -struct dma_mapping_ops pci_dma_ops; +struct dma_mapping_ops *pci_dma_ops; EXPORT_SYMBOL(pci_dma_ops); int global_phb_number; /* Global phb counter */ @@ -1205,15 +1205,35 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, } EXPORT_SYMBOL(pcibios_fixup_device_resources); +void __devinit pcibios_setup_new_device(struct pci_dev *dev) +{ + struct dev_archdata *sd = &dev->dev.archdata; + + sd->of_node = pci_device_to_OF_node(dev); + + DBG("PCI device %s OF node: %s\n", pci_name(dev), + sd->of_node ? sd->of_node->full_name : ""); + + sd->dma_ops = pci_dma_ops; +#ifdef CONFIG_NUMA + sd->numa_node = pcibus_to_node(dev->bus); +#else + sd->numa_node = -1; +#endif + if (ppc_md.pci_dma_dev_setup) + ppc_md.pci_dma_dev_setup(dev); +} +EXPORT_SYMBOL(pcibios_setup_new_device); static void __devinit do_bus_setup(struct pci_bus *bus) { struct pci_dev *dev; - ppc_md.iommu_bus_setup(bus); + if (ppc_md.pci_dma_bus_setup) + ppc_md.pci_dma_bus_setup(bus); list_for_each_entry(dev, &bus->devices, bus_list) - ppc_md.iommu_dev_setup(dev); + pcibios_setup_new_device(dev); /* Read default IRQs and fixup if necessary */ list_for_each_entry(dev, &bus->devices, bus_list) { diff --git a/arch/powerpc/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c deleted file mode 100644 index 72ce082ce73..00000000000 --- a/arch/powerpc/kernel/pci_direct_iommu.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Support for DMA from PCI devices to main memory on - * machines without an iommu or with directly addressable - * RAM (typically a pmac with 2Gb of RAM or less) - * - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - void *ret; - - ret = (void *)__get_free_pages(flag, get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_abs(ret); - } - return ret; -} - -static void pci_direct_free_coherent(struct device *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} - -static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr, - size_t size, enum dma_data_direction direction) -{ - return virt_to_abs(ptr); -} - -static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ - int i; - - for (i = 0; i < nents; i++, sg++) { - sg->dma_address = page_to_phys(sg->page) + sg->offset; - sg->dma_length = sg->length; - } - - return nents; -} - -static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ -} - -static int pci_direct_dma_supported(struct device *dev, u64 mask) -{ - return mask < 0x100000000ull; -} - -static struct dma_mapping_ops pci_direct_ops = { - .alloc_coherent = pci_direct_alloc_coherent, - .free_coherent = pci_direct_free_coherent, - .map_single = pci_direct_map_single, - .unmap_single = pci_direct_unmap_single, - .map_sg = pci_direct_map_sg, - .unmap_sg = pci_direct_unmap_sg, - .dma_supported = pci_direct_dma_supported, -}; - -void __init pci_direct_iommu_init(void) -{ - pci_dma_ops = pci_direct_ops; -} diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c deleted file mode 100644 index 0688b2534ac..00000000000 --- a/arch/powerpc/kernel/pci_iommu.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation - * - * Rewrite, cleanup, new allocation schemes: - * Copyright (C) 2004 Olof Johansson, IBM Corporation - * - * Dynamic DMA mapping support, platform-independent parts. - * - * 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 -#include -#include - -/* - * We can use ->sysdata directly and avoid the extra work in - * pci_device_to_OF_node since ->sysdata will have been initialised - * in the iommu init code for all devices. - */ -#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata)) - -static inline struct iommu_table *device_to_table(struct device *hwdev) -{ - struct pci_dev *pdev; - - if (!hwdev) { - pdev = ppc64_isabridge_dev; - if (!pdev) - return NULL; - } else - pdev = to_pci_dev(hwdev); - - return PCI_DN(PCI_GET_DN(pdev))->iommu_table; -} - - -static inline unsigned long device_to_mask(struct device *hwdev) -{ - struct pci_dev *pdev; - - if (!hwdev) { - pdev = ppc64_isabridge_dev; - if (!pdev) /* This is the best guess we can do */ - return 0xfffffffful; - } else - pdev = to_pci_dev(hwdev); - - if (pdev->dma_mask) - return pdev->dma_mask; - - /* Assume devices without mask can take 32 bit addresses */ - return 0xfffffffful; -} - - -/* Allocates a contiguous real buffer and creates mappings over it. - * Returns the virtual address of the buffer and sets dma_handle - * to the dma address (mapping) of the first page. - */ -static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle, - device_to_mask(hwdev), flag, - pcibus_to_node(to_pci_dev(hwdev)->bus)); -} - -static void pci_iommu_free_coherent(struct device *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle); -} - -/* Creates TCEs for a user provided buffer. The user buffer must be - * contiguous real kernel storage (not vmalloc). The address of the buffer - * passed here is the kernel (virtual) address of the buffer. The buffer - * need not be page aligned, the dma_addr_t returned will point to the same - * byte within the page as vaddr. - */ -static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, - size_t size, enum dma_data_direction direction) -{ - return iommu_map_single(device_to_table(hwdev), vaddr, size, - device_to_mask(hwdev), direction); -} - - -static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) -{ - iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction); -} - - -static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) -{ - return iommu_map_sg(pdev, device_to_table(pdev), sglist, - nelems, device_to_mask(pdev), direction); -} - -static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) -{ - iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction); -} - -/* We support DMA to/from any memory page via the iommu */ -static int pci_iommu_dma_supported(struct device *dev, u64 mask) -{ - struct iommu_table *tbl = device_to_table(dev); - - if (!tbl || tbl->it_offset > mask) { - printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n"); - if (tbl) - printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n", - mask, tbl->it_offset); - else - printk(KERN_INFO "mask: 0x%08lx, table unavailable\n", - mask); - return 0; - } else - return 1; -} - -struct dma_mapping_ops pci_iommu_ops = { - .alloc_coherent = pci_iommu_alloc_coherent, - .free_coherent = pci_iommu_free_coherent, - .map_single = pci_iommu_map_single, - .unmap_single = pci_iommu_unmap_single, - .map_sg = pci_iommu_map_sg, - .unmap_sg = pci_iommu_unmap_sg, - .dma_supported = pci_iommu_dma_supported, -}; - -void pci_iommu_init(void) -{ - pci_dma_ops = pci_iommu_ops; -} diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index b0f1c82df99..f7ad64acf47 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index ed007878d1b..a80f8f1d2e5 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) struct iommu_table *tbl; unsigned long offset, size; - dma_window = get_property(dev->dev.platform_data, - "ibm,my-dma-window", NULL); + dma_window = 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.platform_data, dma_window, - &tbl->it_index, &offset, &size); + 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; @@ -117,7 +117,8 @@ static const struct vio_device_id *vio_match_device( { while (ids->type[0] != '\0') { if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && - device_is_compatible(dev->dev.platform_data, ids->compat)) + device_is_compatible(dev->dev.archdata.of_node, + ids->compat)) return ids; ids++; } @@ -198,9 +199,9 @@ EXPORT_SYMBOL(vio_unregister_driver); /* vio_dev refcount hit 0 */ static void __devinit vio_dev_release(struct device *dev) { - if (dev->platform_data) { - /* XXX free TCE table */ - of_node_put(dev->platform_data); + if (dev->archdata.of_node) { + /* XXX should free TCE table */ + of_node_put(dev->archdata.of_node); } kfree(to_vio_dev(dev)); } @@ -210,7 +211,7 @@ static void __devinit vio_dev_release(struct device *dev) * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in - * of_node (dev.platform_data) and adds it to the list of virtual devices. + * of_node and adds it to the list of virtual devices. * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ @@ -240,8 +241,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) if (viodev == NULL) return NULL; - viodev->dev.platform_data = of_node_get(of_node); - viodev->irq = irq_of_parse_and_map(of_node, 0); snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); @@ -254,7 +253,10 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) if (unit_address != NULL) viodev->unit_address = *unit_address; } - viodev->iommu_table = vio_build_iommu_table(viodev); + viodev->dev.archdata.of_node = of_node_get(of_node); + viodev->dev.archdata.dma_ops = &dma_iommu_ops; + viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev); + viodev->dev.archdata.numa_node = of_node_to_nid(of_node); /* init generic 'struct device' fields: */ viodev->dev.parent = &vio_bus_device.dev; @@ -285,10 +287,11 @@ static int __init vio_bus_init(void) #ifdef CONFIG_PPC_ISERIES if (firmware_has_feature(FW_FEATURE_ISERIES)) { iommu_vio_init(); - vio_bus_device.iommu_table = &vio_iommu_table; + vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops; + vio_bus_device.dev.archdata.dma_data = &vio_iommu_table; iSeries_vio_dev = &vio_bus_device.dev; } -#endif +#endif /* CONFIG_PPC_ISERIES */ err = bus_register(&vio_bus_type); if (err) { @@ -336,7 +339,7 @@ static ssize_t name_show(struct device *dev, static ssize_t devspec_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct device_node *of_node = dev->platform_data; + struct device_node *of_node = dev->archdata.of_node; return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); } @@ -353,62 +356,6 @@ void __devinit vio_unregister_device(struct vio_dev *viodev) } EXPORT_SYMBOL(vio_unregister_device); -static dma_addr_t vio_map_single(struct device *dev, void *vaddr, - size_t size, enum dma_data_direction direction) -{ - return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size, - ~0ul, direction); -} - -static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) -{ - iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size, - direction); -} - -static int vio_map_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) -{ - return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist, - nelems, ~0ul, direction); -} - -static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist, - int nelems, enum dma_data_direction direction) -{ - iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction); -} - -static void *vio_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, - dma_handle, ~0ul, flag, -1); -} - -static void vio_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr, - dma_handle); -} - -static int vio_dma_supported(struct device *dev, u64 mask) -{ - return 1; -} - -struct dma_mapping_ops vio_dma_ops = { - .alloc_coherent = vio_alloc_coherent, - .free_coherent = vio_free_coherent, - .map_single = vio_map_single, - .unmap_single = vio_unmap_single, - .map_sg = vio_map_sg, - .unmap_sg = vio_unmap_sg, - .dma_supported = vio_dma_supported, -}; - static int vio_bus_match(struct device *dev, struct device_driver *drv) { const struct vio_dev *vio_dev = to_vio_dev(dev); @@ -422,13 +369,14 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { const struct vio_dev *vio_dev = to_vio_dev(dev); - struct device_node *dn = dev->platform_data; + struct device_node *dn; const char *cp; int length; if (!num_envp) return -ENOMEM; + dn = dev->archdata.of_node; if (!dn) return -ENODEV; cp = get_property(dn, "compatible", &length); @@ -465,7 +413,7 @@ struct bus_type vio_bus_type = { */ const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) { - return get_property(vdev->dev.platform_data, which, length); + return get_property(vdev->dev.archdata.of_node, which, length); } EXPORT_SYMBOL(vio_get_attribute); diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index aca4c3db0dd..0e6ab8a55ef 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -255,9 +255,6 @@ static void enable_mapping(void __iomem *base, void __iomem *mmio_base) set_iost_origin(mmio_base); } -static void iommu_dev_setup_null(struct pci_dev *d) { } -static void iommu_bus_setup_null(struct pci_bus *b) { } - struct cell_iommu { unsigned long base; unsigned long mmio_base; @@ -306,12 +303,15 @@ static void cell_do_map_iommu(struct cell_iommu *iommu, } } -static void iommu_devnode_setup(struct device_node *d) +static void pci_dma_cell_bus_setup(struct pci_bus *b) { const unsigned int *ioid; unsigned long map_start, map_size, token; const unsigned long *dma_window; struct cell_iommu *iommu; + struct device_node *d; + + d = pci_bus_to_OF_node(b); ioid = get_property(d, "ioid", NULL); if (!ioid) @@ -330,12 +330,6 @@ static void iommu_devnode_setup(struct device_node *d) cell_do_map_iommu(iommu, *ioid, map_start, map_size); } -static void iommu_bus_setup(struct pci_bus *b) -{ - struct device_node *d = (struct device_node *)b->sysdata; - iommu_devnode_setup(d); -} - static int cell_map_iommu_hardcoded(int num_nodes) { @@ -499,16 +493,13 @@ void cell_init_iommu(void) if (setup_bus) { pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__); - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup; + ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup; } else { pr_debug("%s: IOMMU mapping activated, " "no device action necessary\n", __FUNCTION__); /* Direct I/O, IOMMU off */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; } } - pci_dma_ops = cell_iommu_ops; + pci_dma_ops = &cell_iommu_ops; } diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 218817d13c5..ee0a4e42e4f 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -168,7 +169,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) } -void iommu_devnode_init_iSeries(struct device_node *dn) +void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn) { struct iommu_table *tbl; struct pci_dn *pdn = PCI_DN(dn); @@ -186,19 +187,14 @@ void iommu_devnode_init_iSeries(struct device_node *dn) pdn->iommu_table = iommu_init_table(tbl, -1); else kfree(tbl); + pdev->dev.archdata.dma_data = pdn->iommu_table; } #endif -static void iommu_dev_setup_iSeries(struct pci_dev *dev) { } -static void iommu_bus_setup_iSeries(struct pci_bus *bus) { } - void iommu_init_early_iSeries(void) { ppc_md.tce_build = tce_build_iSeries; ppc_md.tce_free = tce_free_iSeries; - ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; - ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries; - - pci_iommu_init(); + pci_dma_ops = &dma_iommu_ops; } diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 4aa165e010d..a90ae42a7bc 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -253,7 +253,7 @@ void __init iSeries_pci_final_fixup(void) PCI_DN(node)->pcidev = pdev; allocate_device_bars(pdev); iSeries_Device_Information(pdev, DeviceCount); - iommu_devnode_init_iSeries(node); + iommu_devnode_init_iSeries(pdev, node); } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index eb2457567f8..89d6e295dbf 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,9 @@ void __init pas_setup_arch(void) /* Setup SMP callback */ smp_ops = &pas_smp_ops; #endif + /* no iommu yet */ + pci_dma_ops = &dma_direct_ops; + /* Lookup PCI hosts */ pas_pci_init(); @@ -81,17 +85,6 @@ void __init pas_setup_arch(void) printk(KERN_DEBUG "Using default idle loop\n"); } -static void iommu_dev_setup_null(struct pci_dev *dev) { } -static void iommu_bus_setup_null(struct pci_bus *bus) { } - -static void __init pas_init_early(void) -{ - /* No iommu code yet */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - pci_direct_iommu_init(); -} - /* No legacy IO on our parts */ static int pas_check_legacy_ioport(unsigned int baseport) { @@ -173,7 +166,6 @@ define_machine(pas) { .name = "PA Semi PA6T-1682M", .probe = pas_probe, .setup_arch = pas_setup_arch, - .init_early = pas_init_early, .init_IRQ = pas_init_IRQ, .get_irq = mpic_get_irq, .restart = pas_restart, diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 556c279a789..3c95392f4f4 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -309,7 +309,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, tbl->it_size = size >> IOMMU_PAGE_SHIFT; } -static void iommu_bus_setup_pSeries(struct pci_bus *bus) +static void pci_dma_bus_setup_pSeries(struct pci_bus *bus) { struct device_node *dn; struct iommu_table *tbl; @@ -318,10 +318,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) struct pci_dn *pci; int children; - DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self); - dn = pci_bus_to_OF_node(bus); - pci = PCI_DN(dn); + + DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name); if (bus->self) { /* This is not a root bus, any setup will be done for the @@ -329,6 +328,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) */ return; } + pci = PCI_DN(dn); /* Check if the ISA bus on the system is under * this PHB. @@ -390,17 +390,17 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) } -static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) +static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) { struct iommu_table *tbl; struct device_node *dn, *pdn; struct pci_dn *ppci; const void *dma_window = NULL; - DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); - dn = pci_bus_to_OF_node(bus); + DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name); + /* Find nearest ibm,dma-window, walking up the device tree */ for (pdn = dn; pdn != NULL; pdn = pdn->parent) { dma_window = get_property(pdn, "ibm,dma-window", NULL); @@ -409,11 +409,15 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) } if (dma_window == NULL) { - DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); + DBG(" no ibm,dma-window property !\n"); return; } ppci = PCI_DN(pdn); + + DBG(" parent is %s, iommu_table: 0x%p\n", + pdn->full_name, ppci->iommu_table); + if (!ppci->iommu_table) { /* Bussubno hasn't been copied yet. * Do it now because iommu_table_setparms_lpar needs it. @@ -427,6 +431,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); + DBG(" created table: %p\n", ppci->iommu_table); } if (pdn != dn) @@ -434,27 +439,27 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) } -static void iommu_dev_setup_pSeries(struct pci_dev *dev) +static void pci_dma_dev_setup_pSeries(struct pci_dev *dev) { - struct device_node *dn, *mydn; + struct device_node *dn; struct iommu_table *tbl; - DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); + DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev)); - mydn = dn = pci_device_to_OF_node(dev); + dn = dev->dev.archdata.of_node; /* If we're the direct child of a root bus, then we need to allocate * an iommu table ourselves. The bus setup code should have setup * the window sizes already. */ if (!dev->bus->self) { + struct pci_controller *phb = PCI_DN(dn)->phb; + DBG(" --> first child, no bridge. Allocating iommu table.\n"); tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - PCI_DN(dn)->phb->node); - iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); - PCI_DN(dn)->iommu_table = iommu_init_table(tbl, - PCI_DN(dn)->phb->node); - + phb->node); + iommu_table_setparms(phb, dn, tbl); + dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node); return; } @@ -465,11 +470,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; - if (dn && PCI_DN(dn)) { - PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; - } else { - DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); - } + if (dn && PCI_DN(dn)) + dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table; + else + printk(KERN_WARNING "iommu: Device %s has no iommu table\n", + pci_name(dev)); } static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) @@ -495,13 +500,15 @@ static struct notifier_block iommu_reconfig_nb = { .notifier_call = iommu_reconfig_notifier, }; -static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) +static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) { struct device_node *pdn, *dn; struct iommu_table *tbl; const void *dma_window = NULL; struct pci_dn *pci; + DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev)); + /* dev setup for LPAR is a little tricky, since the device tree might * contain the dma-window properties per-device and not neccesarily * for the bus. So we need to search upwards in the tree until we @@ -509,9 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) * already allocated. */ dn = pci_device_to_OF_node(dev); - - DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n", - dev, pci_name(dev), dn->full_name); + DBG(" node is %s\n", dn->full_name); for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { @@ -520,16 +525,17 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) break; } + DBG(" parent is %s\n", pdn->full_name); + /* Check for parent == NULL so we don't try to setup the empty EADS * slots on POWER4 machines. */ if (dma_window == NULL || pdn->parent == NULL) { - DBG("No dma window for device, linking to parent\n"); - PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; + DBG(" no dma window for device, linking to parent\n"); + dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table; return; - } else { - DBG("Found DMA window, allocating table\n"); } + DBG(" found DMA window, table: %p\n", pci->iommu_table); pci = PCI_DN(pdn); if (!pci->iommu_table) { @@ -542,24 +548,20 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); pci->iommu_table = iommu_init_table(tbl, pci->phb->node); + DBG(" created table: %p\n", pci->iommu_table); } - if (pdn != dn) - PCI_DN(dn)->iommu_table = pci->iommu_table; + dev->dev.archdata.dma_data = pci->iommu_table; } -static void iommu_bus_setup_null(struct pci_bus *b) { } -static void iommu_dev_setup_null(struct pci_dev *d) { } - /* These are called very early. */ void iommu_init_early_pSeries(void) { if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { /* Direct I/O, IOMMU off */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - pci_direct_iommu_init(); - + ppc_md.pci_dma_dev_setup = NULL; + ppc_md.pci_dma_bus_setup = NULL; + pci_dma_ops = &dma_direct_ops; return; } @@ -572,19 +574,19 @@ void iommu_init_early_pSeries(void) ppc_md.tce_free = tce_free_pSeriesLP; } ppc_md.tce_get = tce_get_pSeriesLP; - ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; - ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP; + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; ppc_md.tce_get = tce_get_pseries; - ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; - ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries; + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries; } pSeries_reconfig_notifier_register(&iommu_reconfig_nb); - pci_iommu_init(); + pci_dma_ops = &dma_iommu_ops; } diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index 6bfacc21708..bb0cb5c5b56 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) if (list_empty(&dev->global_list)) { int i; - /* Need to setup IOMMU tables */ - ppc_md.iommu_dev_setup(dev); + /* Fill device archdata and setup iommu table */ + pcibios_setup_new_device(dev); if(fix_bus) pcibios_fixup_device_resources(dev, bus); diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 572b7846cc7..ac784bb5728 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -289,24 +289,15 @@ static void iommu_table_dart_setup(void) set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); } -static void iommu_dev_setup_dart(struct pci_dev *dev) +static void pci_dma_dev_setup_dart(struct pci_dev *dev) { - struct device_node *dn; - /* We only have one iommu table on the mac for now, which makes * things simple. Setup all PCI devices to point to this table - * - * We must use pci_device_to_OF_node() to make sure that - * we get the real "final" pointer to the device in the - * pci_dev sysdata and not the temporary PHB one */ - dn = pci_device_to_OF_node(dev); - - if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_dart; + dev->dev.archdata.dma_data = &iommu_table_dart; } -static void iommu_bus_setup_dart(struct pci_bus *bus) +static void pci_dma_bus_setup_dart(struct pci_bus *bus) { struct device_node *dn; @@ -321,9 +312,6 @@ static void iommu_bus_setup_dart(struct pci_bus *bus) PCI_DN(dn)->iommu_table = &iommu_table_dart; } -static void iommu_dev_setup_null(struct pci_dev *dev) { } -static void iommu_bus_setup_null(struct pci_bus *bus) { } - void iommu_init_early_dart(void) { struct device_node *dn; @@ -344,22 +332,21 @@ void iommu_init_early_dart(void) /* Initialize the DART HW */ if (dart_init(dn) == 0) { - ppc_md.iommu_dev_setup = iommu_dev_setup_dart; - ppc_md.iommu_bus_setup = iommu_bus_setup_dart; + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart; + ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart; /* Setup pci_dma ops */ - pci_iommu_init(); - + pci_dma_ops = &dma_iommu_ops; return; } bail: /* If init failed, use direct iommu and null setup functions */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; + ppc_md.pci_dma_dev_setup = NULL; + ppc_md.pci_dma_bus_setup = NULL; /* Setup pci_dma ops */ - pci_direct_iommu_init(); + pci_dma_ops = &dma_direct_ops; } -- cgit v1.2.3 From 868108784ccf0add6ac593bfbc2eb5a0804af48d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:04 +1100 Subject: [POWERPC] Add DMA ops support for of_platform_device to Cell This patch adds a bus device notifier to the of_platform bus type on cell to setup the DMA operations for of_platform_devices. We currently use the PCI operations as Cell use a special version of them that happens to be suitable for our needs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/setup.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index d704bc19a64..b39753f16d4 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -82,10 +83,41 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } +static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct device *dev = data; + + if (action != BUS_NOTIFY_ADD_DEVICE) + return 0; + + /* For now, we just use the PCI DMA ops for everything, though + * we'll need something better when we have a real iommu + * implementation. + */ + dev->archdata.dma_ops = pci_dma_ops; + + return 0; +} + +static struct notifier_block cell_of_bus_notifier = { + .notifier_call = cell_of_bus_notify +}; + + static int __init cell_publish_devices(void) { - if (machine_is(cell)) - of_platform_bus_probe(NULL, NULL, NULL); + if (!machine_is(cell)) + return 0; + + /* Register callbacks on OF platform device addition/removal + * to handle linking them to the right DMA operations + */ + bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); + + /* Publish OF platform devices for southbridge IOs */ + of_platform_bus_probe(NULL, NULL, NULL); + return 0; } device_initcall(cell_publish_devices); @@ -154,7 +186,6 @@ static void __init cell_setup_arch(void) #ifdef CONFIG_SMP smp_init_cell(); #endif - /* init to some ~sane value until calibrate_delay() runs */ loops_per_jiffy = 50000000; -- cgit v1.2.3 From e557a1c96c82f4d1a91b5c2e2e0275b5999c297d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:05 +1100 Subject: [POWERPC] Resolve the parent address of a PCI bus range When parsing the OF "ranges" properties of PCI host busses to determine the mapping of a PCI bus, we need to translate the "parent" address using the prom_parse.c routines in order to obtain a CPU physical address. This wasn't necessary while PCI busses were always at the root of the device-tree but this is no longer the case on Cell where they can be anywhere in the tree. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_64.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 88b78484b94..5ffab8787b9 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -967,11 +967,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, res = NULL; pci_space = ranges[0]; pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; - - cpu_phys_addr = ranges[3]; - if (na >= 2) - cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4]; - + cpu_phys_addr = of_translate_address(dev, &ranges[3]); size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; ranges += np; if (size == 0) -- cgit v1.2.3 From 6506e7102fd57b138979f131d751014462181202 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:06 +1100 Subject: [POWERPC] Resolve the BUID for RTAS PCI config space accesses The BUID is the first entry of a PCI host bridge "reg" property. Now that PCI busses can be anywhere in the device-tree, we need to fully translate the value there to a CPU physical address before we can use it with RTAS. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/rtas_pci.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index b4a0de79c06..2576e12d725 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -231,32 +231,13 @@ void __init init_pci_config_tokens (void) unsigned long __devinit get_phb_buid (struct device_node *phb) { - int addr_cells; - const unsigned int *buid_vals; - unsigned int len; - unsigned long buid; - - if (ibm_read_pci_config == -1) return 0; + struct resource r; - /* PHB's will always be children of the root node, - * or so it is promised by the current firmware. */ - if (phb->parent == NULL) + if (ibm_read_pci_config == -1) return 0; - if (phb->parent->parent) - return 0; - - buid_vals = get_property(phb, "reg", &len); - if (buid_vals == NULL) + if (of_address_to_resource(phb, 0, &r)) return 0; - - addr_cells = prom_n_addr_cells(phb); - if (addr_cells == 1) { - buid = (unsigned long) buid_vals[0]; - } else { - buid = (((unsigned long)buid_vals[0]) << 32UL) | - (((unsigned long)buid_vals[1]) & 0xffffffff); - } - return buid; + return r.start; } static int phb_set_bus_ranges(struct device_node *dev, -- cgit v1.2.3 From 803d4573e60bc890d7fbc040ad1c18c2dc7f8279 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:07 +1100 Subject: [POWERPC] Add "parent" struct device for PCI host bridges Add a "parent" struct device to our PCI host bridge data structure so that PCI can be rooted off another device in sysfs. Note that arch/ppc doesn't use it, only arch/powerpc, though it's available for both 32 and 64 bits. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 5 ++++- arch/powerpc/kernel/pci_64.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index d32cd500d8b..0ad101a5fc5 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -1269,7 +1269,10 @@ pcibios_init(void) if (pci_assign_all_buses) hose->first_busno = next_busno; hose->last_busno = 0xff; - bus = pci_scan_bus(hose->first_busno, hose->ops, hose); + bus = pci_scan_bus_parented(hose->parent, hose->first_busno, + hose->ops, hose); + if (bus) + pci_bus_add_devices(bus); hose->last_busno = bus->subordinate; if (pci_assign_all_buses || next_busno <= hose->last_busno) next_busno = hose->last_busno + pcibios_assign_bus_offset; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 5ffab8787b9..74e580d25c1 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -513,7 +513,7 @@ void __devinit scan_phb(struct pci_controller *hose) DBG("Scanning PHB %s\n", node ? node->full_name : ""); - bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); + bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); if (bus == NULL) { printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", hose->global_number); -- cgit v1.2.3 From 4c9d2800be5dfabf26acdeb401cbabe9edc1dcf2 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:08 +1100 Subject: [POWERPC] Generic OF platform driver for PCI host bridges. When enabled in Kconfig, it will pick up any of_platform_device matching it's match list (currently type "pci", "pcix", "pcie", or "ht" and setup a PHB for it. Platform must provide a ppc_md.pci_setup_phb() for it to work (for doing the necessary initialisations specific to a given PHB like setting up the config space ops). It's currently only available on 64 bits as the 32 bits PCI code can't quite cope with it in it's current form. I will fix that later. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 6 ++ arch/powerpc/kernel/of_platform.c | 103 +++++++++++++++++++++++++++++ arch/powerpc/kernel/pci_64.c | 9 +++ arch/powerpc/kernel/rtas_pci.c | 7 +- arch/powerpc/platforms/cell/setup.c | 1 + arch/powerpc/platforms/pseries/pci_dlpar.c | 2 +- 6 files changed, 124 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 65588a6bd2f..3d26ba7ad76 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -223,6 +223,11 @@ config PPC_DCR depends on PPC_DCR_NATIVE || PPC_DCR_MMIO default y +config PPC_OF_PLATFORM_PCI + bool + depends on PPC64 # not supported on 32 bits yet + default n + config BOOKE bool depends on E200 || E500 @@ -469,6 +474,7 @@ config PPC_CELL_NATIVE bool select PPC_CELL select PPC_DCR_MMIO + select PPC_OF_PLATFORM_PCI select MPIC default n diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 7a0e77af7c9..6029543c1b5 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. * + * and Arnd Bergmann, IBM Corp. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -17,12 +18,15 @@ #include #include #include +#include #include #include #include #include #include +#include +#include /* * The list of OF IDs below is used for matching bus types in the @@ -377,3 +381,102 @@ struct of_device *of_find_device_by_phandle(phandle ph) return NULL; } EXPORT_SYMBOL(of_find_device_by_phandle); + + +#ifdef CONFIG_PPC_OF_PLATFORM_PCI + +/* The probing of PCI controllers from of_platform is currently + * 64 bits only, mostly due to gratuitous differences between + * the 32 and 64 bits PCI code on PowerPC and the 32 bits one + * lacking some bits needed here. + */ + +static int __devinit of_pci_phb_probe(struct of_device *dev, + const struct of_device_id *match) +{ + struct pci_controller *phb; + + /* Check if we can do that ... */ + if (ppc_md.pci_setup_phb == NULL) + return -ENODEV; + + printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); + + /* Alloc and setup PHB data structure */ + phb = pcibios_alloc_controller(dev->node); + if (!phb) + return -ENODEV; + + /* Setup parent in sysfs */ + phb->parent = &dev->dev; + + /* Setup the PHB using arch provided callback */ + if (ppc_md.pci_setup_phb(phb)) { + pcibios_free_controller(phb); + return -ENODEV; + } + + /* Process "ranges" property */ + pci_process_bridge_OF_ranges(phb, dev->node, 0); + + /* Setup IO space. + * This will not work properly for ISA IOs, something needs to be done + * about it if we ever generalize that way of probing PCI brigdes + */ + pci_setup_phb_io_dynamic(phb, 0); + + /* Init pci_dn data structures */ + pci_devs_phb_init_dynamic(phb); + + /* Register devices with EEH */ +#ifdef CONFIG_EEH + if (dev->node->child) + eeh_add_device_tree_early(dev->node); +#endif /* CONFIG_EEH */ + + /* Scan the bus */ + scan_phb(phb); + + /* Claim resources. This might need some rework as well depending + * wether we are doing probe-only or not, like assigning unassigned + * resources etc... + */ + pcibios_claim_one_bus(phb->bus); + + /* Finish EEH setup */ +#ifdef CONFIG_EEH + eeh_add_device_tree_late(phb->bus); +#endif + + /* Add probed PCI devices to the device model */ + pci_bus_add_devices(phb->bus); + + return 0; +} + +static struct of_device_id of_pci_phb_ids[] = { + { .type = "pci", }, + { .type = "pcix", }, + { .type = "pcie", }, + { .type = "pciex", }, + { .type = "ht", }, + {} +}; + +static struct of_platform_driver of_pci_phb_driver = { + .name = "of-pci", + .match_table = of_pci_phb_ids, + .probe = of_pci_phb_probe, + .driver = { + .multithread_probe = 1, + }, +}; + +static __init int of_pci_phb_init(void) +{ + return of_register_platform_driver(&of_pci_phb_driver); +} + +device_initcall(of_pci_phb_init); + +#endif /* CONFIG_PPC_OF_PLATFORM_PCI */ diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 74e580d25c1..d800e19ea56 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -210,6 +210,10 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev) void pcibios_free_controller(struct pci_controller *phb) { + spin_lock(&hose_spinlock); + list_del(&phb->list_node); + spin_unlock(&hose_spinlock); + if (phb->is_dynamic) kfree(phb); } @@ -1242,6 +1246,11 @@ static void __devinit do_bus_setup(struct pci_bus *bus) void __devinit pcibios_fixup_bus(struct pci_bus *bus) { struct pci_dev *dev = bus->self; + struct device_node *np; + + np = pci_bus_to_OF_node(bus); + + DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : ""); if (dev && pci_probe_only && (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 2576e12d725..03cacc25a0a 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -257,8 +257,10 @@ static int phb_set_bus_ranges(struct device_node *dev, return 0; } -int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) +int __devinit rtas_setup_phb(struct pci_controller *phb) { + struct device_node *dev = phb->arch_data; + if (is_python(dev)) python_countermeasures(dev); @@ -290,7 +292,7 @@ unsigned long __init find_and_init_phbs(void) phb = pcibios_alloc_controller(node); if (!phb) continue; - setup_phb(node, phb); + rtas_setup_phb(phb); pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); index++; @@ -362,7 +364,6 @@ int pcibios_remove_root_bus(struct pci_controller *phb) } } - list_del(&phb->list_node); pcibios_free_controller(phb); return 0; diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index b39753f16d4..7e18420166c 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -256,6 +256,7 @@ define_machine(cell) { .check_legacy_ioport = cell_check_legacy_ioport, .progress = cell_progress, .init_IRQ = cell_init_irq, + .pci_setup_phb = rtas_setup_phb, #ifdef CONFIG_KEXEC .machine_kexec = default_machine_kexec, .machine_kexec_prepare = default_machine_kexec_prepare, diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index bb0cb5c5b56..ac56b868913 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -195,7 +195,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) phb = pcibios_alloc_controller(dn); if (!phb) return NULL; - setup_phb(dn, phb); + rtas_setup_phb(phb); pci_process_bridge_OF_ranges(phb, dn, 0); pci_setup_phb_io_dynamic(phb, primary); -- cgit v1.2.3 From d03f387eb321189bc2ba278b6ca82f1a45cf19d6 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:09 +1100 Subject: [POWERPC] Cell fixup DMA offset for new southbridge This patch makes the Cell DMA code work on both the Spider and the Axon south bridges by turning cell_dma_valid into a variable instead of a constant. This is a temporary patch until we have full iommu support. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/iommu.c | 14 +++++++++++--- arch/powerpc/platforms/cell/iommu.h | 8 +++++--- 2 files changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 0e6ab8a55ef..e3ea5311476 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -46,6 +46,8 @@ #include "iommu.h" +static dma_addr_t cell_dma_valid = SPIDER_DMA_VALID; + static inline unsigned long get_iopt_entry(unsigned long real_address, unsigned long ioid, unsigned long prot) @@ -423,7 +425,7 @@ static void *cell_alloc_coherent(struct device *hwdev, size_t size, ret = (void *)__get_free_pages(flag, get_order(size)); if (ret != NULL) { memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) | CELL_DMA_VALID; + *dma_handle = virt_to_abs(ret) | cell_dma_valid; } return ret; } @@ -437,7 +439,7 @@ static void cell_free_coherent(struct device *hwdev, size_t size, static dma_addr_t cell_map_single(struct device *hwdev, void *ptr, size_t size, enum dma_data_direction direction) { - return virt_to_abs(ptr) | CELL_DMA_VALID; + return virt_to_abs(ptr) | cell_dma_valid; } static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr, @@ -452,7 +454,7 @@ static int cell_map_sg(struct device *hwdev, struct scatterlist *sg, for (i = 0; i < nents; i++, sg++) { sg->dma_address = (page_to_phys(sg->page) + sg->offset) - | CELL_DMA_VALID; + | cell_dma_valid; sg->dma_length = sg->length; } @@ -483,6 +485,12 @@ void cell_init_iommu(void) { int setup_bus = 0; + /* If we have an Axon bridge, clear the DMA valid mask. This is fairly + * hackish but will work well enough until we have proper iommu code. + */ + if (of_find_node_by_name(NULL, "axon")) + cell_dma_valid = 0; + if (of_find_node_by_path("/mambo")) { pr_info("Not using iommu on systemsim\n"); } else { diff --git a/arch/powerpc/platforms/cell/iommu.h b/arch/powerpc/platforms/cell/iommu.h index 490d77abfe8..2a9ab95604a 100644 --- a/arch/powerpc/platforms/cell/iommu.h +++ b/arch/powerpc/platforms/cell/iommu.h @@ -53,9 +53,11 @@ enum { IOC_ST_ORIGIN = 0x918, IOC_CONF = 0x930, - /* The high bit needs to be set on every DMA address, - only 2GB are addressable */ - CELL_DMA_VALID = 0x80000000, + /* The high bit needs to be set on every DMA address when using + * a spider bridge and only 2GB are addressable with the current + * iommu code. + */ + SPIDER_DMA_VALID = 0x80000000, CELL_DMA_MASK = 0x7fffffff, }; -- cgit v1.2.3 From 4cb3cee03d558fd457cb58f56c80a2a09a66110c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:10 +1100 Subject: [POWERPC] Allow hooking of PCI MMIO & PIO accessors on 64 bits This patch reworks the way iSeries hooks on PCI IO operations (both MMIO and PIO) and provides a generic way for other platforms to do so (we have need to do that for various other platforms). While reworking the IO ops, I ended up doing some spring cleaning in io.h and eeh.h which I might want to split into 2 or 3 patches (among others, eeh.h had a lot of useless stuff in it). A side effect is that EEH for PIO should work now (it used to pass IO ports down to the eeh address check functions which is bogus). Also, new are MMIO "repeat" ops, which other archs like ARM already had, and that we have too now: readsb, readsw, readsl, writesb, writesw, writesl. In the long run, I might also make EEH use the hooks instead of wrapping at the toplevel, which would make things even cleaner and relegate EEH completely in platforms/iseries, but we have to measure the performance impact there (though it's really only on MMIO reads) Since I also need to hook on ioremap, I shuffled the functions a bit there. I introduced ioremap_flags() to use by drivers who want to pass explicit flags to ioremap (and it can be hooked). The old __ioremap() is still there as a low level and cannot be hooked, thus drivers who use it should migrate unless they know they want the low level version. The patch "arch provides generic iomap missing accessors" (should be number 4 in this series) is a pre-requisite to provide full iomap API support with this patch. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 10 + arch/powerpc/kernel/Makefile | 6 +- arch/powerpc/kernel/io.c | 18 +- arch/powerpc/kernel/pci_64.c | 2 +- arch/powerpc/kernel/setup_64.c | 7 + arch/powerpc/mm/pgtable_64.c | 46 ++-- arch/powerpc/platforms/iseries/pci.c | 370 ++++++++++++++------------------- arch/powerpc/platforms/iseries/setup.c | 12 ++ 8 files changed, 224 insertions(+), 247 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3d26ba7ad76..3e89d9d3493 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -394,6 +394,7 @@ config PPC_PSERIES config PPC_ISERIES bool "IBM Legacy iSeries" depends on PPC_MULTIPLATFORM && PPC64 + select PPC_INDIRECT_IO config PPC_CHRP bool "Common Hardware Reference Platform (CHRP) based machines" @@ -548,6 +549,15 @@ config PPC_970_NAP bool default n +config PPC_INDIRECT_IO + bool + select GENERIC_IOMAP + default n + +config GENERIC_IOMAP + bool + default n + source "drivers/cpufreq/Kconfig" config CPU_FREQ_PMAC diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index eba8d118e21..600954df07a 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -62,7 +62,7 @@ obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o module-$(CONFIG_PPC64) += module_64.o obj-$(CONFIG_MODULES) += $(module-y) -pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o iomap.o +pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci32-$(CONFIG_PPC32) := pci_32.o obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) kexec-$(CONFIG_PPC64) := machine_kexec_64.o @@ -71,6 +71,10 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y) obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o +ifneq ($(CONFIG_PPC_INDIRECT_IO),y) +pci64-$(CONFIG_PPC64) += iomap.o +endif + ifeq ($(CONFIG_PPC_ISERIES),y) $(obj)/head_64.o: $(obj)/lparmap.s AFLAGS_head_64.o += -I$(obj) diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c index e98180686b3..c1aa07524c2 100644 --- a/arch/powerpc/kernel/io.c +++ b/arch/powerpc/kernel/io.c @@ -25,13 +25,11 @@ #include #include -void _insb(volatile u8 __iomem *port, void *buf, long count) +void _insb(const volatile u8 __iomem *port, void *buf, long count) { u8 *tbuf = buf; u8 tmp; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); @@ -48,8 +46,6 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count) { const u8 *tbuf = buf; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); @@ -60,13 +56,11 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count) } EXPORT_SYMBOL(_outsb); -void _insw_ns(volatile u16 __iomem *port, void *buf, long count) +void _insw_ns(const volatile u16 __iomem *port, void *buf, long count) { u16 *tbuf = buf; u16 tmp; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); @@ -83,8 +77,6 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count) { const u16 *tbuf = buf; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); @@ -95,13 +87,11 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count) } EXPORT_SYMBOL(_outsw_ns); -void _insl_ns(volatile u32 __iomem *port, void *buf, long count) +void _insl_ns(const volatile u32 __iomem *port, void *buf, long count) { u32 *tbuf = buf; u32 tmp; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); @@ -118,8 +108,6 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count) { const u32 *tbuf = buf; - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - if (unlikely(count <= 0)) return; asm volatile("sync"); diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index d800e19ea56..afee470de92 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -1137,7 +1137,7 @@ int unmap_bus_range(struct pci_bus *bus) if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) return 1; - if (iounmap_explicit((void __iomem *) start_virt, size)) + if (__iounmap_explicit((void __iomem *) start_virt, size)) return 1; return 0; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index f7ad64acf47..f602a53b1b7 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -599,3 +599,10 @@ void __init setup_per_cpu_areas(void) } } #endif + + +#ifdef CONFIG_PPC_INDIRECT_IO +struct ppc_pci_io ppc_pci_io; +EXPORT_SYMBOL(ppc_pci_io); +#endif /* CONFIG_PPC_INDIRECT_IO */ + diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index ac64f4aaa50..e9b21846ccb 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -129,22 +129,12 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, return (void __iomem *) (ea + (addr & ~PAGE_MASK)); } - -void __iomem * -ioremap(unsigned long addr, unsigned long size) -{ - return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED); -} - void __iomem * __ioremap(unsigned long addr, unsigned long size, unsigned long flags) { unsigned long pa, ea; void __iomem *ret; - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return (void __iomem *)addr; - /* * Choose an address to map it to. * Once the imalloc system is running, we use it. @@ -178,6 +168,25 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size, return ret; } + +void __iomem * ioremap(unsigned long addr, unsigned long size) +{ + unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED; + + if (ppc_md.ioremap) + return ppc_md.ioremap(addr, size, flags); + return __ioremap(addr, size, flags); +} + +void __iomem * ioremap_flags(unsigned long addr, unsigned long size, + unsigned long flags) +{ + if (ppc_md.ioremap) + return ppc_md.ioremap(addr, size, flags); + return __ioremap(addr, size, flags); +} + + #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) int __ioremap_explicit(unsigned long pa, unsigned long ea, @@ -235,13 +244,10 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, * * XXX what about calls before mem_init_done (ie python_countermeasures()) */ -void iounmap(volatile void __iomem *token) +void __iounmap(void __iomem *token) { void *addr; - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return; - if (!mem_init_done) return; @@ -250,6 +256,14 @@ void iounmap(volatile void __iomem *token) im_free(addr); } +void iounmap(void __iomem *token) +{ + if (ppc_md.iounmap) + ppc_md.iounmap(token); + else + __iounmap(token); +} + static int iounmap_subset_regions(unsigned long addr, unsigned long size) { struct vm_struct *area; @@ -268,7 +282,7 @@ static int iounmap_subset_regions(unsigned long addr, unsigned long size) return 0; } -int iounmap_explicit(volatile void __iomem *start, unsigned long size) +int __iounmap_explicit(void __iomem *start, unsigned long size) { struct vm_struct *area; unsigned long addr; @@ -303,8 +317,10 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size) } EXPORT_SYMBOL(ioremap); +EXPORT_SYMBOL(ioremap_flags); EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(__iounmap); void __iomem * reserve_phb_iospace(unsigned long size) { diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index a90ae42a7bc..4a06d9c3498 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -155,53 +155,6 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, Error_Text, Bus, SubBus, AgentId, HvRc); } -/* - * iSeries_pcibios_init - * - * Description: - * This function checks for all possible system PCI host bridges that connect - * PCI buses. The system hypervisor is queried as to the guest partition - * ownership status. A pci_controller is built for any bus which is partially - * owned or fully owned by this guest partition. - */ -void iSeries_pcibios_init(void) -{ - struct pci_controller *phb; - struct device_node *root = of_find_node_by_path("/"); - struct device_node *node = NULL; - - if (root == NULL) { - printk(KERN_CRIT "iSeries_pcibios_init: can't find root " - "of device tree\n"); - return; - } - while ((node = of_get_next_child(root, node)) != NULL) { - HvBusNumber bus; - const u32 *busp; - - if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) - continue; - - busp = get_property(node, "bus-range", NULL); - if (busp == NULL) - continue; - bus = *busp; - printk("bus %d appears to exist\n", bus); - phb = pcibios_alloc_controller(node); - if (phb == NULL) - continue; - - phb->pci_mem_offset = phb->local_number = bus; - phb->first_busno = bus; - phb->last_busno = bus; - phb->ops = &iSeries_pci_ops; - } - - of_node_put(root); - - pci_devs_phb_init(); -} - /* * iSeries_pci_final_fixup(void) */ @@ -438,11 +391,7 @@ static inline struct device_node *xlate_iomm_address( /* * Read MM I/O Instructions for the iSeries * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal - * else, data is returned in big Endian format. - * - * iSeries_Read_Byte = Read Byte ( 8 bit) - * iSeries_Read_Word = Read Word (16 bit) - * iSeries_Read_Long = Read Long (32 bit) + * else, data is returned in Big Endian format. */ static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) { @@ -462,14 +411,15 @@ static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) num_printed = 0; } if (num_printed++ < 10) - printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress); + printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", + IoAddress); return 0xff; } do { HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); - return (u8)ret.value; + return ret.value; } static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) @@ -490,7 +440,8 @@ static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) num_printed = 0; } if (num_printed++ < 10) - printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress); + printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", + IoAddress); return 0xffff; } do { @@ -498,7 +449,7 @@ static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) BarOffset, 0); } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); - return swab16((u16)ret.value); + return ret.value; } static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) @@ -519,7 +470,8 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) num_printed = 0; } if (num_printed++ < 10) - printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress); + printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", + IoAddress); return 0xffffffff; } do { @@ -527,15 +479,12 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) BarOffset, 0); } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); - return swab32((u32)ret.value); + return ret.value; } /* * Write MM I/O Instructions for the iSeries * - * iSeries_Write_Byte = Write Byte (8 bit) - * iSeries_Write_Word = Write Word(16 bit) - * iSeries_Write_Long = Write Long(32 bit) */ static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) { @@ -581,11 +530,12 @@ static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) num_printed = 0; } if (num_printed++ < 10) - printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress); + printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", + IoAddress); return; } do { - rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); + rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0); } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); } @@ -607,231 +557,221 @@ static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) num_printed = 0; } if (num_printed++ < 10) - printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress); + printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", + IoAddress); return; } do { - rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); + rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0); } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); } -extern unsigned char __raw_readb(const volatile void __iomem *addr) +static u8 iseries_readb(const volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return *(volatile unsigned char __force *)addr; + return iSeries_Read_Byte(addr); } -EXPORT_SYMBOL(__raw_readb); -extern unsigned short __raw_readw(const volatile void __iomem *addr) +static u16 iseries_readw(const volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return *(volatile unsigned short __force *)addr; + return le16_to_cpu(iSeries_Read_Word(addr)); } -EXPORT_SYMBOL(__raw_readw); -extern unsigned int __raw_readl(const volatile void __iomem *addr) +static u32 iseries_readl(const volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return *(volatile unsigned int __force *)addr; + return le32_to_cpu(iSeries_Read_Long(addr)); } -EXPORT_SYMBOL(__raw_readl); -extern unsigned long __raw_readq(const volatile void __iomem *addr) +static u16 iseries_readw_be(const volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return *(volatile unsigned long __force *)addr; + return iSeries_Read_Word(addr); } -EXPORT_SYMBOL(__raw_readq); -extern void __raw_writeb(unsigned char v, volatile void __iomem *addr) +static u32 iseries_readl_be(const volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - *(volatile unsigned char __force *)addr = v; + return iSeries_Read_Long(addr); } -EXPORT_SYMBOL(__raw_writeb); -extern void __raw_writew(unsigned short v, volatile void __iomem *addr) +static void iseries_writeb(u8 data, volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - *(volatile unsigned short __force *)addr = v; + iSeries_Write_Byte(data, addr); } -EXPORT_SYMBOL(__raw_writew); -extern void __raw_writel(unsigned int v, volatile void __iomem *addr) +static void iseries_writew(u16 data, volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - *(volatile unsigned int __force *)addr = v; + iSeries_Write_Word(cpu_to_le16(data), addr); } -EXPORT_SYMBOL(__raw_writel); -extern void __raw_writeq(unsigned long v, volatile void __iomem *addr) +static void iseries_writel(u32 data, volatile void __iomem *addr) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - *(volatile unsigned long __force *)addr = v; + iSeries_Write_Long(cpu_to_le32(data), addr); } -EXPORT_SYMBOL(__raw_writeq); -int in_8(const volatile unsigned char __iomem *addr) +static void iseries_writew_be(u16 data, volatile void __iomem *addr) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return iSeries_Read_Byte(addr); - return __in_8(addr); + iSeries_Write_Word(data, addr); } -EXPORT_SYMBOL(in_8); -void out_8(volatile unsigned char __iomem *addr, int val) +static void iseries_writel_be(u32 data, volatile void __iomem *addr) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - iSeries_Write_Byte(val, addr); - else - __out_8(addr, val); + iSeries_Write_Long(data, addr); } -EXPORT_SYMBOL(out_8); -int in_le16(const volatile unsigned short __iomem *addr) +static void iseries_readsb(const volatile void __iomem *addr, void *buf, + unsigned long count) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return iSeries_Read_Word(addr); - return __in_le16(addr); + u8 *dst = buf; + while(count-- > 0) + *(dst++) = iSeries_Read_Byte(addr); } -EXPORT_SYMBOL(in_le16); -int in_be16(const volatile unsigned short __iomem *addr) +static void iseries_readsw(const volatile void __iomem *addr, void *buf, + unsigned long count) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return __in_be16(addr); + u16 *dst = buf; + while(count-- > 0) + *(dst++) = iSeries_Read_Word(addr); } -EXPORT_SYMBOL(in_be16); -void out_le16(volatile unsigned short __iomem *addr, int val) +static void iseries_readsl(const volatile void __iomem *addr, void *buf, + unsigned long count) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - iSeries_Write_Word(val, addr); - else - __out_le16(addr, val); + u32 *dst = buf; + while(count-- > 0) + *(dst++) = iSeries_Read_Long(addr); } -EXPORT_SYMBOL(out_le16); -void out_be16(volatile unsigned short __iomem *addr, int val) +static void iseries_writesb(volatile void __iomem *addr, const void *buf, + unsigned long count) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - __out_be16(addr, val); + const u8 *src = buf; + while(count-- > 0) + iSeries_Write_Byte(*(src++), addr); } -EXPORT_SYMBOL(out_be16); -unsigned in_le32(const volatile unsigned __iomem *addr) +static void iseries_writesw(volatile void __iomem *addr, const void *buf, + unsigned long count) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - return iSeries_Read_Long(addr); - return __in_le32(addr); + const u16 *src = buf; + while(count-- > 0) + iSeries_Write_Word(*(src++), addr); } -EXPORT_SYMBOL(in_le32); -unsigned in_be32(const volatile unsigned __iomem *addr) +static void iseries_writesl(volatile void __iomem *addr, const void *buf, + unsigned long count) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - return __in_be32(addr); + const u32 *src = buf; + while(count-- > 0) + iSeries_Write_Long(*(src++), addr); } -EXPORT_SYMBOL(in_be32); -void out_le32(volatile unsigned __iomem *addr, int val) +static void iseries_memset_io(volatile void __iomem *addr, int c, + unsigned long n) { - if (firmware_has_feature(FW_FEATURE_ISERIES)) - iSeries_Write_Long(val, addr); - else - __out_le32(addr, val); -} -EXPORT_SYMBOL(out_le32); + volatile char __iomem *d = addr; -void out_be32(volatile unsigned __iomem *addr, int val) -{ - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - - __out_be32(addr, val); + while (n-- > 0) + iSeries_Write_Byte(c, d++); } -EXPORT_SYMBOL(out_be32); -unsigned long in_le64(const volatile unsigned long __iomem *addr) +static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src, + unsigned long n) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + char *d = dest; + const volatile char __iomem *s = src; - return __in_le64(addr); + while (n-- > 0) + *d++ = iSeries_Read_Byte(s++); } -EXPORT_SYMBOL(in_le64); -unsigned long in_be64(const volatile unsigned long __iomem *addr) +static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src, + unsigned long n) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + const char *s = src; + volatile char __iomem *d = dest; - return __in_be64(addr); + while (n-- > 0) + iSeries_Write_Byte(*s++, d++); } -EXPORT_SYMBOL(in_be64); - -void out_le64(volatile unsigned long __iomem *addr, unsigned long val) -{ - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); - __out_le64(addr, val); -} -EXPORT_SYMBOL(out_le64); +/* We only set MMIO ops. The default PIO ops will be default + * to the MMIO ops + pci_io_base which is 0 on iSeries as + * expected so both should work. + * + * Note that we don't implement the readq/writeq versions as + * I don't know of an HV call for doing so. Thus, the default + * operation will be used instead, which will fault a the value + * return by iSeries for MMIO addresses always hits a non mapped + * area. This is as good as the BUG() we used to have there. + */ +static struct ppc_pci_io __initdata iseries_pci_io = { + .readb = iseries_readb, + .readw = iseries_readw, + .readl = iseries_readl, + .readw_be = iseries_readw_be, + .readl_be = iseries_readl_be, + .writeb = iseries_writeb, + .writew = iseries_writew, + .writel = iseries_writel, + .writew_be = iseries_writew_be, + .writel_be = iseries_writel_be, + .readsb = iseries_readsb, + .readsw = iseries_readsw, + .readsl = iseries_readsl, + .writesb = iseries_writesb, + .writesw = iseries_writesw, + .writesl = iseries_writesl, + .memset_io = iseries_memset_io, + .memcpy_fromio = iseries_memcpy_fromio, + .memcpy_toio = iseries_memcpy_toio, +}; -void out_be64(volatile unsigned long __iomem *addr, unsigned long val) +/* + * iSeries_pcibios_init + * + * Description: + * This function checks for all possible system PCI host bridges that connect + * PCI buses. The system hypervisor is queried as to the guest partition + * ownership status. A pci_controller is built for any bus which is partially + * owned or fully owned by this guest partition. + */ +void __init iSeries_pcibios_init(void) { - BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); + struct pci_controller *phb; + struct device_node *root = of_find_node_by_path("/"); + struct device_node *node = NULL; - __out_be64(addr, val); -} -EXPORT_SYMBOL(out_be64); + /* Install IO hooks */ + ppc_pci_io = iseries_pci_io; -void memset_io(volatile void __iomem *addr, int c, unsigned long n) -{ - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - volatile char __iomem *d = addr; + if (root == NULL) { + printk(KERN_CRIT "iSeries_pcibios_init: can't find root " + "of device tree\n"); + return; + } + while ((node = of_get_next_child(root, node)) != NULL) { + HvBusNumber bus; + const u32 *busp; - while (n-- > 0) { - iSeries_Write_Byte(c, d++); - } - } else - eeh_memset_io(addr, c, n); -} -EXPORT_SYMBOL(memset_io); + if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) + continue; -void memcpy_fromio(void *dest, const volatile void __iomem *src, - unsigned long n) -{ - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - char *d = dest; - const volatile char __iomem *s = src; + busp = get_property(node, "bus-range", NULL); + if (busp == NULL) + continue; + bus = *busp; + printk("bus %d appears to exist\n", bus); + phb = pcibios_alloc_controller(node); + if (phb == NULL) + continue; - while (n-- > 0) { - *d++ = iSeries_Read_Byte(s++); - } - } else - eeh_memcpy_fromio(dest, src, n); -} -EXPORT_SYMBOL(memcpy_fromio); + phb->pci_mem_offset = phb->local_number = bus; + phb->first_busno = bus; + phb->last_busno = bus; + phb->ops = &iSeries_pci_ops; + } -void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) -{ - if (firmware_has_feature(FW_FEATURE_ISERIES)) { - const char *s = src; - volatile char __iomem *d = dest; + of_node_put(root); - while (n-- > 0) { - iSeries_Write_Byte(*s++, d++); - } - } else - eeh_memcpy_toio(dest, src, n); + pci_devs_phb_init(); } -EXPORT_SYMBOL(memcpy_toio); + diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index cd8965ec9dd..2f16d9330cf 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -617,6 +617,16 @@ static void iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif +static void __iomem *iseries_ioremap(unsigned long address, unsigned long size, + unsigned long flags) +{ + return (void __iomem *)address; +} + +static void iseries_iounmap(void __iomem *token) +{ +} + /* * iSeries has no legacy IO, anything calling this function has to * fail or bad things will happen @@ -655,6 +665,8 @@ define_machine(iseries) { .progress = iSeries_progress, .probe = iseries_probe, .check_legacy_ioport = iseries_check_legacy_ioport, + .ioremap = iseries_ioremap, + .iounmap = iseries_iounmap, /* XXX Implement enable_pmcs for iSeries */ }; -- cgit v1.2.3 From 014da7ff47b559e5f0ae3e044b73f0359c08153d Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:12 +1100 Subject: [POWERPC] Cell "Spider" MMIO workarounds This patch implements a workaround for a Spider PCI host bridge bug where it doesn't enforce some of the PCI ordering rules unless some manual manipulation of a special register is done. In order to be fully compliant with the PCI spec, I do this on every MMIO read operation. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + arch/powerpc/platforms/cell/Makefile | 4 +- arch/powerpc/platforms/cell/io-workarounds.c | 346 +++++++++++++++++++++++++++ 3 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/platforms/cell/io-workarounds.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3e89d9d3493..9547aacc319 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -476,6 +476,7 @@ config PPC_CELL_NATIVE select PPC_CELL select PPC_DCR_MMIO select PPC_OF_PLATFORM_PCI + select PPC_INDIRECT_IO select MPIC default n diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 0f31db7a50a..62c011e8092 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ - cbe_regs.o spider-pic.o pervasive.o \ - pmu.o + cbe_regs.o spider-pic.o \ + pervasive.o pmu.o io-workarounds.o obj-$(CONFIG_CBE_RAS) += ras.o obj-$(CONFIG_CBE_THERM) += cbe_thermal.o diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c new file mode 100644 index 00000000000..580d4259591 --- /dev/null +++ b/arch/powerpc/platforms/cell/io-workarounds.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2006 Benjamin Herrenschmidt + * IBM, Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include + + +#define SPIDER_PCI_REG_BASE 0xd000 +#define SPIDER_PCI_VCI_CNTL_STAT 0x0110 +#define SPIDER_PCI_DUMMY_READ 0x0810 +#define SPIDER_PCI_DUMMY_READ_BASE 0x0814 + +/* Undefine that to re-enable bogus prefetch + * + * Without that workaround, the chip will do bogus prefetch past + * page boundary from system memory. This setting will disable that, + * though the documentation is unclear as to the consequences of doing + * so, either purely performances, or possible misbehaviour... It's not + * clear wether the chip can handle unaligned accesses at all without + * prefetching enabled. + * + * For now, things appear to be behaving properly with that prefetching + * disabled and IDE, possibly because IDE isn't doing any unaligned + * access. + */ +#define SPIDER_DISABLE_PREFETCH + +#define MAX_SPIDERS 2 + +static struct spider_pci_bus { + void __iomem *regs; + unsigned long mmio_start; + unsigned long mmio_end; + unsigned long pio_vstart; + unsigned long pio_vend; +} spider_pci_busses[MAX_SPIDERS]; +static int spider_pci_count; + +static struct spider_pci_bus *spider_pci_find(unsigned long vaddr, + unsigned long paddr) +{ + int i; + + for (i = 0; i < spider_pci_count; i++) { + struct spider_pci_bus *bus = &spider_pci_busses[i]; + if (paddr && paddr >= bus->mmio_start && paddr < bus->mmio_end) + return bus; + if (vaddr && vaddr >= bus->pio_vstart && vaddr < bus->pio_vend) + return bus; + } + return NULL; +} + +static void spider_io_flush(const volatile void __iomem *addr) +{ + struct spider_pci_bus *bus; + int token; + + /* Get platform token (set by ioremap) from address */ + token = PCI_GET_ADDR_TOKEN(addr); + + /* Fast path if we have a non-0 token, it indicates which bus we + * are on. + * + * If the token is 0, that means either the the ioremap was done + * before we initialized this layer, or it's a PIO operation. We + * fallback to a low path in this case. Hopefully, internal devices + * which are ioremap'ed early should use in_XX/out_XX functions + * instead of the PCI ones and thus not suffer from the slowdown. + * + * Also note that currently, the workaround will not work for areas + * that are not mapped with PTEs (bolted in the hash table). This + * is the case for ioremaps done very early at boot (before + * mem_init_done) and includes the mapping of the ISA IO space. + * + * Fortunately, none of the affected devices is expected to do DMA + * and thus there should be no problem in practice. + * + * In order to improve performances, we only do the PTE search for + * addresses falling in the PHB IO space area. That means it will + * not work for hotplug'ed PHBs but those don't exist with Spider. + */ + if (token && token <= spider_pci_count) + bus = &spider_pci_busses[token - 1]; + else { + unsigned long vaddr, paddr; + pte_t *ptep; + + /* Fixup physical address */ + vaddr = (unsigned long)PCI_FIX_ADDR(addr); + + /* Check if it's in allowed range for PIO */ + if (vaddr < PHBS_IO_BASE || vaddr >= IMALLOC_BASE) + return; + + /* Try to find a PTE. If not, clear the paddr, we'll do + * a vaddr only lookup (PIO only) + */ + ptep = find_linux_pte(init_mm.pgd, vaddr); + if (ptep == NULL) + paddr = 0; + else + paddr = pte_pfn(*ptep) << PAGE_SHIFT; + + bus = spider_pci_find(vaddr, paddr); + if (bus == NULL) + return; + } + + /* Now do the workaround + */ + (void)in_be32(bus->regs + SPIDER_PCI_DUMMY_READ); +} + +static u8 spider_readb(const volatile void __iomem *addr) +{ + u8 val = __do_readb(addr); + spider_io_flush(addr); + return val; +} + +static u16 spider_readw(const volatile void __iomem *addr) +{ + u16 val = __do_readw(addr); + spider_io_flush(addr); + return val; +} + +static u32 spider_readl(const volatile void __iomem *addr) +{ + u32 val = __do_readl(addr); + spider_io_flush(addr); + return val; +} + +static u64 spider_readq(const volatile void __iomem *addr) +{ + u64 val = __do_readq(addr); + spider_io_flush(addr); + return val; +} + +static u16 spider_readw_be(const volatile void __iomem *addr) +{ + u16 val = __do_readw_be(addr); + spider_io_flush(addr); + return val; +} + +static u32 spider_readl_be(const volatile void __iomem *addr) +{ + u32 val = __do_readl_be(addr); + spider_io_flush(addr); + return val; +} + +static u64 spider_readq_be(const volatile void __iomem *addr) +{ + u64 val = __do_readq_be(addr); + spider_io_flush(addr); + return val; +} + +static void spider_readsb(const volatile void __iomem *addr, void *buf, + unsigned long count) +{ + __do_readsb(addr, buf, count); + spider_io_flush(addr); +} + +static void spider_readsw(const volatile void __iomem *addr, void *buf, + unsigned long count) +{ + __do_readsw(addr, buf, count); + spider_io_flush(addr); +} + +static void spider_readsl(const volatile void __iomem *addr, void *buf, + unsigned long count) +{ + __do_readsl(addr, buf, count); + spider_io_flush(addr); +} + +static void spider_memcpy_fromio(void *dest, const volatile void __iomem *src, + unsigned long n) +{ + __do_memcpy_fromio(dest, src, n); + spider_io_flush(src); +} + + +static void __iomem * spider_ioremap(unsigned long addr, unsigned long size, + unsigned long flags) +{ + struct spider_pci_bus *bus; + void __iomem *res = __ioremap(addr, size, flags); + int busno; + + pr_debug("spider_ioremap(0x%lx, 0x%lx, 0x%lx) -> 0x%p\n", + addr, size, flags, res); + + bus = spider_pci_find(0, addr); + if (bus != NULL) { + busno = bus - spider_pci_busses; + pr_debug(" found bus %d, setting token\n", busno); + PCI_SET_ADDR_TOKEN(res, busno + 1); + } + pr_debug(" result=0x%p\n", res); + + return res; +} + +static void __init spider_pci_setup_chip(struct spider_pci_bus *bus) +{ +#ifdef SPIDER_DISABLE_PREFETCH + u32 val = in_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT); + pr_debug(" PVCI_Control_Status was 0x%08x\n", val); + out_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8); +#endif + + /* Configure the dummy address for the workaround */ + out_be32(bus->regs + SPIDER_PCI_DUMMY_READ_BASE, 0x80000000); +} + +static void __init spider_pci_add_one(struct pci_controller *phb) +{ + struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count]; + struct device_node *np = phb->arch_data; + struct resource rsrc; + void __iomem *regs; + + if (spider_pci_count >= MAX_SPIDERS) { + printk(KERN_ERR "Too many spider bridges, workarounds" + " disabled for %s\n", np->full_name); + return; + } + + /* Get the registers for the beast */ + if (of_address_to_resource(np, 0, &rsrc)) { + printk(KERN_ERR "Failed to get registers for spider %s" + " workarounds disabled\n", np->full_name); + return; + } + + /* Mask out some useless bits in there to get to the base of the + * spider chip + */ + rsrc.start &= ~0xfffffffful; + + /* Map them */ + regs = ioremap(rsrc.start + SPIDER_PCI_REG_BASE, 0x1000); + if (regs == NULL) { + printk(KERN_ERR "Failed to map registers for spider %s" + " workarounds disabled\n", np->full_name); + return; + } + + spider_pci_count++; + + /* We assume spiders only have one MMIO resource */ + bus->mmio_start = phb->mem_resources[0].start; + bus->mmio_end = phb->mem_resources[0].end + 1; + + bus->pio_vstart = (unsigned long)phb->io_base_virt; + bus->pio_vend = bus->pio_vstart + phb->pci_io_size; + + bus->regs = regs; + + printk(KERN_INFO "PCI: Spider MMIO workaround for %s\n",np->full_name); + + pr_debug(" mmio (P) = 0x%016lx..0x%016lx\n", + bus->mmio_start, bus->mmio_end); + pr_debug(" pio (V) = 0x%016lx..0x%016lx\n", + bus->pio_vstart, bus->pio_vend); + pr_debug(" regs (P) = 0x%016lx (V) = 0x%p\n", + rsrc.start + SPIDER_PCI_REG_BASE, bus->regs); + + spider_pci_setup_chip(bus); +} + +static struct ppc_pci_io __initdata spider_pci_io = { + .readb = spider_readb, + .readw = spider_readw, + .readl = spider_readl, + .readq = spider_readq, + .readw_be = spider_readw_be, + .readl_be = spider_readl_be, + .readq_be = spider_readq_be, + .readsb = spider_readsb, + .readsw = spider_readsw, + .readsl = spider_readsl, + .memcpy_fromio = spider_memcpy_fromio, +}; + +static int __init spider_pci_workaround_init(void) +{ + struct pci_controller *phb; + + if (!machine_is(cell)) + return 0; + + /* Find spider bridges. We assume they have been all probed + * in setup_arch(). If that was to change, we would need to + * update this code to cope with dynamically added busses + */ + list_for_each_entry(phb, &hose_list, list_node) { + struct device_node *np = phb->arch_data; + const char *model = get_property(np, "model", NULL); + + /* If no model property or name isn't exactly "pci", skip */ + if (model == NULL || strcmp(np->name, "pci")) + continue; + /* If model is not "Spider", skip */ + if (strcmp(model, "Spider")) + continue; + spider_pci_add_one(phb); + } + + /* No Spider PCI found, exit */ + if (spider_pci_count == 0) + return 0; + + /* Setup IO callbacks. We only setup MMIO reads. PIO reads will + * fallback to MMIO reads (though without a token, thus slower) + */ + ppc_pci_io = spider_pci_io; + + /* Setup ioremap callback */ + ppc_md.ioremap = spider_ioremap; + + return 0; +} +arch_initcall(spider_pci_workaround_init); -- cgit v1.2.3 From 92b20c40dcca2d441f367da57e7665cce15c492a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:14 +1100 Subject: [POWERPC] Add an optional offset to direct DMA on 64 bits This patch adds an optional global offset that can be added to DMA addresses when using the direct DMA operations. That brings it a step closer to the 32 bits direct DMA operations, and makes it useable on Cell when the MMU is disabled and we are using a spider southbridge. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/dma_64.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 4e655119978..1d1dc76606a 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -111,7 +111,11 @@ EXPORT_SYMBOL(dma_iommu_ops); /* * Generic direct DMA implementation + * + * This implementation supports a global offset that can be applied if + * the address at which memory is visible to devices is not 0. */ +unsigned long dma_direct_offset; static void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) @@ -122,7 +126,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size, ret = (void *)__get_free_pages(flag, get_order(size)); if (ret != NULL) { memset(ret, 0, size); - *dma_handle = virt_to_abs(ret); + *dma_handle = virt_to_abs(ret) | dma_direct_offset; } return ret; } @@ -137,7 +141,7 @@ static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr, size_t size, enum dma_data_direction direction) { - return virt_to_abs(ptr); + return virt_to_abs(ptr) | dma_direct_offset; } static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, @@ -152,7 +156,8 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, int i; for (i = 0; i < nents; i++, sg++) { - sg->dma_address = page_to_phys(sg->page) + sg->offset; + sg->dma_address = (page_to_phys(sg->page) + sg->offset) | + dma_direct_offset; sg->dma_length = sg->length; } -- cgit v1.2.3 From c80d9133e99de1af607314107910a2a1645efb17 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:16 +1100 Subject: [POWERPC] Make direct DMA use node local allocations This patch makes dma_alloc_coherent() use node local allocation when using the direct DMA ops. The node is obtained from the new device extension. If no such extension is present, the current node is used. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/dma_64.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c index 1d1dc76606a..7b0e754383c 100644 --- a/arch/powerpc/kernel/dma_64.c +++ b/arch/powerpc/kernel/dma_64.c @@ -120,14 +120,18 @@ unsigned long dma_direct_offset; static void *dma_direct_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { + struct page *page; void *ret; + int node = dev->archdata.numa_node; /* TODO: Maybe use the numa node here too ? */ - ret = (void *)__get_free_pages(flag, get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) | dma_direct_offset; - } + page = alloc_pages_node(node, flag, get_order(size)); + if (page == NULL) + return NULL; + ret = page_address(page); + memset(ret, 0, size); + *dma_handle = virt_to_abs(ret) | dma_direct_offset; + return ret; } -- cgit v1.2.3 From acfd946a1aaffdec346c2864f596d4d92125d1ad Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:17 +1100 Subject: [POWERPC] Make cell use direct DMA ops Now that the direct DMA ops supports an offset, we use that instead of defining our own. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/iommu.c | 79 +++---------------------------------- 1 file changed, 6 insertions(+), 73 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index e3ea5311476..6a97fe1319d 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -46,8 +46,6 @@ #include "iommu.h" -static dma_addr_t cell_dma_valid = SPIDER_DMA_VALID; - static inline unsigned long get_iopt_entry(unsigned long real_address, unsigned long ioid, unsigned long prot) @@ -417,83 +415,18 @@ static int cell_map_iommu(void) return 1; } -static void *cell_alloc_coherent(struct device *hwdev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - void *ret; - - ret = (void *)__get_free_pages(flag, get_order(size)); - if (ret != NULL) { - memset(ret, 0, size); - *dma_handle = virt_to_abs(ret) | cell_dma_valid; - } - return ret; -} - -static void cell_free_coherent(struct device *hwdev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - free_pages((unsigned long)vaddr, get_order(size)); -} - -static dma_addr_t cell_map_single(struct device *hwdev, void *ptr, - size_t size, enum dma_data_direction direction) -{ - return virt_to_abs(ptr) | cell_dma_valid; -} - -static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static int cell_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ - int i; - - for (i = 0; i < nents; i++, sg++) { - sg->dma_address = (page_to_phys(sg->page) + sg->offset) - | cell_dma_valid; - sg->dma_length = sg->length; - } - - return nents; -} - -static void cell_unmap_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ -} - -static int cell_dma_supported(struct device *dev, u64 mask) -{ - return mask < 0x100000000ull; -} - -static struct dma_mapping_ops cell_iommu_ops = { - .alloc_coherent = cell_alloc_coherent, - .free_coherent = cell_free_coherent, - .map_single = cell_map_single, - .unmap_single = cell_unmap_single, - .map_sg = cell_map_sg, - .unmap_sg = cell_unmap_sg, - .dma_supported = cell_dma_supported, -}; - void cell_init_iommu(void) { int setup_bus = 0; - /* If we have an Axon bridge, clear the DMA valid mask. This is fairly - * hackish but will work well enough until we have proper iommu code. - */ - if (of_find_node_by_name(NULL, "axon")) - cell_dma_valid = 0; - if (of_find_node_by_path("/mambo")) { pr_info("Not using iommu on systemsim\n"); } else { + /* If we don't have an Axon bridge, we assume we have a + * spider which requires a DMA offset + */ + if (of_find_node_by_name(NULL, "axon") == NULL) + dma_direct_offset = SPIDER_DMA_VALID; if (!(of_chosen && get_property(of_chosen, "linux,iommu-off", NULL))) @@ -509,5 +442,5 @@ void cell_init_iommu(void) } } - pci_dma_ops = &cell_iommu_ops; + pci_dma_ops = &dma_direct_ops; } -- cgit v1.2.3 From 165785e5c0be3ad43e8b8eadfbd25e92c2cd002a Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Sat, 11 Nov 2006 17:25:18 +1100 Subject: [POWERPC] Cell iommu support This patch adds full cell iommu support (and iommu disabled mode). It implements mapping/unmapping of iommu pages on demand using the standard powerpc iommu framework. It also supports running with iommu disabled for machines with less than 2GB of memory. (The default is off in that case, though it can be forced on with the kernel command line option iommu=force). Signed-off-by: Jeremy Kerr Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 14 +- arch/powerpc/platforms/cell/iommu.c | 1005 +++++++++++++++++++++++------------ arch/powerpc/platforms/cell/iommu.h | 67 --- arch/powerpc/platforms/cell/setup.c | 43 -- arch/powerpc/sysdev/dart_iommu.c | 3 - 5 files changed, 660 insertions(+), 472 deletions(-) delete mode 100644 arch/powerpc/platforms/cell/iommu.h (limited to 'arch') diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index b91761639d9..8671eb634a9 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -173,8 +173,8 @@ static unsigned long __initdata dt_string_start, dt_string_end; static unsigned long __initdata prom_initrd_start, prom_initrd_end; #ifdef CONFIG_PPC64 -static int __initdata iommu_force_on; -static int __initdata ppc64_iommu_off; +static int __initdata prom_iommu_force_on; +static int __initdata prom_iommu_off; static unsigned long __initdata prom_tce_alloc_start; static unsigned long __initdata prom_tce_alloc_end; #endif @@ -582,9 +582,9 @@ static void __init early_cmdline_parse(void) while (*opt && *opt == ' ') opt++; if (!strncmp(opt, RELOC("off"), 3)) - RELOC(ppc64_iommu_off) = 1; + RELOC(prom_iommu_off) = 1; else if (!strncmp(opt, RELOC("force"), 5)) - RELOC(iommu_force_on) = 1; + RELOC(prom_iommu_force_on) = 1; } #endif } @@ -1167,7 +1167,7 @@ static void __init prom_initialize_tce_table(void) u64 local_alloc_top, local_alloc_bottom; u64 i; - if (RELOC(ppc64_iommu_off)) + if (RELOC(prom_iommu_off)) return; prom_debug("starting prom_initialize_tce_table\n"); @@ -2283,11 +2283,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, * Fill in some infos for use by the kernel later on */ #ifdef CONFIG_PPC64 - if (RELOC(ppc64_iommu_off)) + if (RELOC(prom_iommu_off)) prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", NULL, 0); - if (RELOC(iommu_force_on)) + if (RELOC(prom_iommu_force_on)) prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on", NULL, 0); diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index 6a97fe1319d..b43466ba809 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c @@ -1,446 +1,747 @@ /* * IOMMU implementation for Cell Broadband Processor Architecture - * We just establish a linear mapping at boot by setting all the - * IOPT cache entries in the CPU. - * The mapping functions should be identical to pci_direct_iommu, - * except for the handling of the high order bit that is required - * by the Spider bridge. These should be split into a separate - * file at the point where we get a different bridge chip. * - * Copyright (C) 2005 IBM Deutschland Entwicklung GmbH, - * Arnd Bergmann + * (C) Copyright IBM Corporation 2006 * - * Based on linear mapping - * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org) + * Author: Jeremy Kerr * - * 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 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef DEBUG #include -#include -#include -#include #include -#include -#include -#include -#include -#include +#include +#include -#include -#include -#include #include -#include +#include #include -#include -#include -#include -#include +#include #include +#include +#include -#include "iommu.h" +#include "cbe_regs.h" +#include "interrupt.h" -static inline unsigned long -get_iopt_entry(unsigned long real_address, unsigned long ioid, - unsigned long prot) -{ - return (prot & IOPT_PROT_MASK) - | (IOPT_COHERENT) - | (IOPT_ORDER_VC) - | (real_address & IOPT_RPN_MASK) - | (ioid & IOPT_IOID_MASK); -} +/* Define CELL_IOMMU_REAL_UNMAP to actually unmap non-used pages + * instead of leaving them mapped to some dummy page. This can be + * enabled once the appropriate workarounds for spider bugs have + * been enabled + */ +#define CELL_IOMMU_REAL_UNMAP + +/* Define CELL_IOMMU_STRICT_PROTECTION to enforce protection of + * IO PTEs based on the transfer direction. That can be enabled + * once spider-net has been fixed to pass the correct direction + * to the DMA mapping functions + */ +#define CELL_IOMMU_STRICT_PROTECTION + + +#define NR_IOMMUS 2 + +/* IOC mmap registers */ +#define IOC_Reg_Size 0x2000 + +#define IOC_IOPT_CacheInvd 0x908 +#define IOC_IOPT_CacheInvd_NE_Mask 0xffe0000000000000ul +#define IOC_IOPT_CacheInvd_IOPTE_Mask 0x000003fffffffff8ul +#define IOC_IOPT_CacheInvd_Busy 0x0000000000000001ul + +#define IOC_IOST_Origin 0x918 +#define IOC_IOST_Origin_E 0x8000000000000000ul +#define IOC_IOST_Origin_HW 0x0000000000000800ul +#define IOC_IOST_Origin_HL 0x0000000000000400ul + +#define IOC_IO_ExcpStat 0x920 +#define IOC_IO_ExcpStat_V 0x8000000000000000ul +#define IOC_IO_ExcpStat_SPF_Mask 0x6000000000000000ul +#define IOC_IO_ExcpStat_SPF_S 0x6000000000000000ul +#define IOC_IO_ExcpStat_SPF_P 0x4000000000000000ul +#define IOC_IO_ExcpStat_ADDR_Mask 0x00000007fffff000ul +#define IOC_IO_ExcpStat_RW_Mask 0x0000000000000800ul +#define IOC_IO_ExcpStat_IOID_Mask 0x00000000000007fful + +#define IOC_IO_ExcpMask 0x928 +#define IOC_IO_ExcpMask_SFE 0x4000000000000000ul +#define IOC_IO_ExcpMask_PFE 0x2000000000000000ul + +#define IOC_IOCmd_Offset 0x1000 + +#define IOC_IOCmd_Cfg 0xc00 +#define IOC_IOCmd_Cfg_TE 0x0000800000000000ul + + +/* Segment table entries */ +#define IOSTE_V 0x8000000000000000ul /* valid */ +#define IOSTE_H 0x4000000000000000ul /* cache hint */ +#define IOSTE_PT_Base_RPN_Mask 0x3ffffffffffff000ul /* base RPN of IOPT */ +#define IOSTE_NPPT_Mask 0x0000000000000fe0ul /* no. pages in IOPT */ +#define IOSTE_PS_Mask 0x0000000000000007ul /* page size */ +#define IOSTE_PS_4K 0x0000000000000001ul /* - 4kB */ +#define IOSTE_PS_64K 0x0000000000000003ul /* - 64kB */ +#define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */ +#define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */ + +/* Page table entries */ +#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */ +#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */ +#define IOPTE_M 0x2000000000000000ul /* coherency required */ +#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */ +#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */ +#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */ +#define IOPTE_H 0x0000000000000800ul /* cache hint */ +#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */ + + +/* IOMMU sizing */ +#define IO_SEGMENT_SHIFT 28 +#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT) + +/* The high bit needs to be set on every DMA address */ +#define SPIDER_DMA_OFFSET 0x80000000ul + +struct iommu_window { + struct list_head list; + struct cbe_iommu *iommu; + unsigned long offset; + unsigned long size; + unsigned long pte_offset; + unsigned int ioid; + struct iommu_table table; +}; -typedef struct { - unsigned long val; -} ioste; +#define NAMESIZE 8 +struct cbe_iommu { + int nid; + char name[NAMESIZE]; + void __iomem *xlate_regs; + void __iomem *cmd_regs; + unsigned long *stab; + unsigned long *ptab; + void *pad_page; + struct list_head windows; +}; -static inline ioste -mk_ioste(unsigned long val) -{ - ioste ioste = { .val = val, }; - return ioste; -} +/* Static array of iommus, one per node + * each contains a list of windows, keyed from dma_window property + * - on bus setup, look for a matching window, or create one + * - on dev setup, assign iommu_table ptr + */ +static struct cbe_iommu iommus[NR_IOMMUS]; +static int cbe_nr_iommus; -static inline ioste -get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_size) +static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte, + long n_ptes) { - unsigned long ps; - unsigned long iostep; - unsigned long nnpt; - unsigned long shift; - - switch (page_size) { - case 0x1000000: - ps = IOST_PS_16M; - nnpt = 0; /* one page per segment */ - shift = 5; /* segment has 16 iopt entries */ - break; - - case 0x100000: - ps = IOST_PS_1M; - nnpt = 0; /* one page per segment */ - shift = 1; /* segment has 256 iopt entries */ - break; - - case 0x10000: - ps = IOST_PS_64K; - nnpt = 0x07; /* 8 pages per io page table */ - shift = 0; /* all entries are used */ - break; - - case 0x1000: - ps = IOST_PS_4K; - nnpt = 0x7f; /* 128 pages per io page table */ - shift = 0; /* all entries are used */ - break; - - default: /* not a known compile time constant */ - { - /* BUILD_BUG_ON() is not usable here */ - extern void __get_iost_entry_bad_page_size(void); - __get_iost_entry_bad_page_size(); - } - break; - } + unsigned long *reg, val; + long n; - iostep = iopt_base + - /* need 8 bytes per iopte */ - (((io_address / page_size * 8) - /* align io page tables on 4k page boundaries */ - << shift) - /* nnpt+1 pages go into each iopt */ - & ~(nnpt << 12)); - - nnpt++; /* this seems to work, but the documentation is not clear - about wether we put nnpt or nnpt-1 into the ioste bits. - In theory, this can't work for 4k pages. */ - return mk_ioste(IOST_VALID_MASK - | (iostep & IOST_PT_BASE_MASK) - | ((nnpt << 5) & IOST_NNPT_MASK) - | (ps & IOST_PS_MASK)); -} + reg = iommu->xlate_regs + IOC_IOPT_CacheInvd; -/* compute the address of an io pte */ -static inline unsigned long -get_ioptep(ioste iost_entry, unsigned long io_address) -{ - unsigned long iopt_base; - unsigned long page_size; - unsigned long page_number; - unsigned long iopt_offset; - - iopt_base = iost_entry.val & IOST_PT_BASE_MASK; - page_size = iost_entry.val & IOST_PS_MASK; - - /* decode page size to compute page number */ - page_number = (io_address & 0x0fffffff) >> (10 + 2 * page_size); - /* page number is an offset into the io page table */ - iopt_offset = (page_number << 3) & 0x7fff8ul; - return iopt_base + iopt_offset; -} + while (n_ptes > 0) { + /* we can invalidate up to 1 << 11 PTEs at once */ + n = min(n_ptes, 1l << 11); + val = (((n /*- 1*/) << 53) & IOC_IOPT_CacheInvd_NE_Mask) + | (__pa(pte) & IOC_IOPT_CacheInvd_IOPTE_Mask) + | IOC_IOPT_CacheInvd_Busy; -/* compute the tag field of the iopt cache entry */ -static inline unsigned long -get_ioc_tag(ioste iost_entry, unsigned long io_address) -{ - unsigned long iopte = get_ioptep(iost_entry, io_address); + out_be64(reg, val); + while (in_be64(reg) & IOC_IOPT_CacheInvd_Busy) + ; - return IOPT_VALID_MASK - | ((iopte & 0x00000000000000ff8ul) >> 3) - | ((iopte & 0x0000003fffffc0000ul) >> 9); + n_ptes -= n; + pte += n; + } } -/* compute the hashed 6 bit index for the 4-way associative pte cache */ -static inline unsigned long -get_ioc_hash(ioste iost_entry, unsigned long io_address) +static void tce_build_cell(struct iommu_table *tbl, long index, long npages, + unsigned long uaddr, enum dma_data_direction direction) { - unsigned long iopte = get_ioptep(iost_entry, io_address); - - return ((iopte & 0x000000000000001f8ul) >> 3) - ^ ((iopte & 0x00000000000020000ul) >> 17) - ^ ((iopte & 0x00000000000010000ul) >> 15) - ^ ((iopte & 0x00000000000008000ul) >> 13) - ^ ((iopte & 0x00000000000004000ul) >> 11) - ^ ((iopte & 0x00000000000002000ul) >> 9) - ^ ((iopte & 0x00000000000001000ul) >> 7); + int i; + unsigned long *io_pte, base_pte; + struct iommu_window *window = + container_of(tbl, struct iommu_window, table); + + /* implementing proper protection causes problems with the spidernet + * driver - check mapping directions later, but allow read & write by + * default for now.*/ +#ifdef CELL_IOMMU_STRICT_PROTECTION + /* to avoid referencing a global, we use a trick here to setup the + * protection bit. "prot" is setup to be 3 fields of 4 bits apprended + * together for each of the 3 supported direction values. It is then + * shifted left so that the fields matching the desired direction + * lands on the appropriate bits, and other bits are masked out. + */ + const unsigned long prot = 0xc48; + base_pte = + ((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R)) + | IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask); +#else + base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | + (window->ioid & IOPTE_IOID_Mask); +#endif + + io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); + + for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE) + io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask); + + mb(); + + invalidate_tce_cache(window->iommu, io_pte, npages); + + pr_debug("tce_build_cell(index=%lx,n=%lx,dir=%d,base_pte=%lx)\n", + index, npages, direction, base_pte); } -/* same as above, but pretend that we have a simpler 1-way associative - pte cache with an 8 bit index */ -static inline unsigned long -get_ioc_hash_1way(ioste iost_entry, unsigned long io_address) +static void tce_free_cell(struct iommu_table *tbl, long index, long npages) { - unsigned long iopte = get_ioptep(iost_entry, io_address); - - return ((iopte & 0x000000000000001f8ul) >> 3) - ^ ((iopte & 0x00000000000020000ul) >> 17) - ^ ((iopte & 0x00000000000010000ul) >> 15) - ^ ((iopte & 0x00000000000008000ul) >> 13) - ^ ((iopte & 0x00000000000004000ul) >> 11) - ^ ((iopte & 0x00000000000002000ul) >> 9) - ^ ((iopte & 0x00000000000001000ul) >> 7) - ^ ((iopte & 0x0000000000000c000ul) >> 8); -} -static inline ioste -get_iost_cache(void __iomem *base, unsigned long index) -{ - unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR); - return mk_ioste(in_be64(&p[index])); -} + int i; + unsigned long *io_pte, pte; + struct iommu_window *window = + container_of(tbl, struct iommu_window, table); -static inline void -set_iost_cache(void __iomem *base, unsigned long index, ioste ste) -{ - unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR); - pr_debug("ioste %02lx was %016lx, store %016lx", index, - get_iost_cache(base, index).val, ste.val); - out_be64(&p[index], ste.val); - pr_debug(" now %016lx\n", get_iost_cache(base, index).val); -} + pr_debug("tce_free_cell(index=%lx,n=%lx)\n", index, npages); -static inline unsigned long -get_iopt_cache(void __iomem *base, unsigned long index, unsigned long *tag) -{ - unsigned long __iomem *tags = (void *)(base + IOC_PT_CACHE_DIR); - unsigned long __iomem *p = (void *)(base + IOC_PT_CACHE_REG); +#ifdef CELL_IOMMU_REAL_UNMAP + pte = 0; +#else + /* spider bridge does PCI reads after freeing - insert a mapping + * to a scratch page instead of an invalid entry */ + pte = IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | __pa(window->iommu->pad_page) + | (window->ioid & IOPTE_IOID_Mask); +#endif - *tag = tags[index]; - rmb(); - return *p; -} + io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset); -static inline void -set_iopt_cache(void __iomem *base, unsigned long index, - unsigned long tag, unsigned long val) -{ - unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR; - unsigned long __iomem *p = base + IOC_PT_CACHE_REG; + for (i = 0; i < npages; i++) + io_pte[i] = pte; + + mb(); - out_be64(p, val); - out_be64(&tags[index], tag); + invalidate_tce_cache(window->iommu, io_pte, npages); } -static inline void -set_iost_origin(void __iomem *base) +static irqreturn_t ioc_interrupt(int irq, void *data) { - unsigned long __iomem *p = base + IOC_ST_ORIGIN; - unsigned long origin = IOSTO_ENABLE | IOSTO_SW; - - pr_debug("iost_origin %016lx, now %016lx\n", in_be64(p), origin); - out_be64(p, origin); + unsigned long stat; + struct cbe_iommu *iommu = data; + + stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat); + + /* Might want to rate limit it */ + printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat); + printk(KERN_ERR " V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n", + !!(stat & IOC_IO_ExcpStat_V), + (stat & IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ', + (stat & IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ', + (stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write", + (unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask)); + printk(KERN_ERR " page=0x%016lx\n", + stat & IOC_IO_ExcpStat_ADDR_Mask); + + /* clear interrupt */ + stat &= ~IOC_IO_ExcpStat_V; + out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, stat); + + return IRQ_HANDLED; } -static inline void -set_iocmd_config(void __iomem *base) +static int cell_iommu_find_ioc(int nid, unsigned long *base) { - unsigned long __iomem *p = base + 0xc00; - unsigned long conf; + struct device_node *np; + struct resource r; + + *base = 0; + + /* First look for new style /be nodes */ + for_each_node_by_name(np, "ioc") { + if (of_node_to_nid(np) != nid) + continue; + if (of_address_to_resource(np, 0, &r)) { + printk(KERN_ERR "iommu: can't get address for %s\n", + np->full_name); + continue; + } + *base = r.start; + of_node_put(np); + return 0; + } + + /* Ok, let's try the old way */ + for_each_node_by_type(np, "cpu") { + const unsigned int *nidp; + const unsigned long *tmp; + + nidp = get_property(np, "node-id", NULL); + if (nidp && *nidp == nid) { + tmp = get_property(np, "ioc-translation", NULL); + if (tmp) { + *base = *tmp; + of_node_put(np); + return 0; + } + } + } - conf = in_be64(p); - pr_debug("iost_conf %016lx, now %016lx\n", conf, conf | IOCMD_CONF_TE); - out_be64(p, conf | IOCMD_CONF_TE); + return -ENODEV; } -static void enable_mapping(void __iomem *base, void __iomem *mmio_base) +static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long size) { - set_iocmd_config(base); - set_iost_origin(mmio_base); -} + struct page *page; + int ret, i; + unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages; + unsigned long xlate_base; + unsigned int virq; + + if (cell_iommu_find_ioc(iommu->nid, &xlate_base)) + panic("%s: missing IOC register mappings for node %d\n", + __FUNCTION__, iommu->nid); + + iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size); + iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset; + + segments = size >> IO_SEGMENT_SHIFT; + pages_per_segment = 1ull << IO_PAGENO_BITS; + + pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n", + __FUNCTION__, iommu->nid, segments, pages_per_segment); + + /* set up the segment table */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->stab = page_address(page); + clear_page(iommu->stab); + + /* ... and the page tables. Since these are contiguous, we can treat + * the page tables as one array of ptes, like pSeries does. + */ + ptab_size = segments * pages_per_segment * sizeof(unsigned long); + pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__, + iommu->nid, ptab_size, get_order(ptab_size)); + page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size)); + BUG_ON(!page); + + iommu->ptab = page_address(page); + memset(iommu->ptab, 0, ptab_size); + + /* allocate a bogus page for the end of each mapping */ + page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); + BUG_ON(!page); + iommu->pad_page = page_address(page); + clear_page(iommu->pad_page); + + /* number of pages needed for a page table */ + n_pte_pages = (pages_per_segment * + sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT; + + pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n", + __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab, + n_pte_pages); + + /* initialise the STEs */ + reg = IOSTE_V | ((n_pte_pages - 1) << 5); + + if (IOMMU_PAGE_SIZE == 0x1000) + reg |= IOSTE_PS_4K; + else if (IOMMU_PAGE_SIZE == 0x10000) + reg |= IOSTE_PS_64K; + else { + extern void __unknown_page_size_error(void); + __unknown_page_size_error(); + } -struct cell_iommu { - unsigned long base; - unsigned long mmio_base; - void __iomem *mapped_base; - void __iomem *mapped_mmio_base; -}; + pr_debug("Setting up IOMMU stab:\n"); + for (i = 0; i * (1ul << IO_SEGMENT_SHIFT) < size; i++) { + iommu->stab[i] = reg | + (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i); + pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]); + } + + /* ensure that the STEs have updated */ + mb(); + + /* setup interrupts for the iommu. */ + reg = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat); + out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, + reg & ~IOC_IO_ExcpStat_V); + out_be64(iommu->xlate_regs + IOC_IO_ExcpMask, + IOC_IO_ExcpMask_PFE | IOC_IO_ExcpMask_SFE); + + virq = irq_create_mapping(NULL, + IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT)); + BUG_ON(virq == NO_IRQ); + + ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED, + iommu->name, iommu); + BUG_ON(ret); -static struct cell_iommu cell_iommus[NR_CPUS]; + /* set the IOC segment table origin register (and turn on the iommu) */ + reg = IOC_IOST_Origin_E | __pa(iommu->stab) | IOC_IOST_Origin_HW; + out_be64(iommu->xlate_regs + IOC_IOST_Origin, reg); + in_be64(iommu->xlate_regs + IOC_IOST_Origin); -/* initialize the iommu to support a simple linear mapping - * for each DMA window used by any device. For now, we - * happen to know that there is only one DMA window in use, - * starting at iopt_phys_offset. */ -static void cell_do_map_iommu(struct cell_iommu *iommu, - unsigned int ioid, - unsigned long map_start, - unsigned long map_size) + /* turn on IO translation */ + reg = in_be64(iommu->cmd_regs + IOC_IOCmd_Cfg) | IOC_IOCmd_Cfg_TE; + out_be64(iommu->cmd_regs + IOC_IOCmd_Cfg, reg); +} + +#if 0/* Unused for now */ +static struct iommu_window *find_window(struct cbe_iommu *iommu, + unsigned long offset, unsigned long size) { - unsigned long io_address, real_address; - void __iomem *ioc_base, *ioc_mmio_base; - ioste ioste; - unsigned long index; + struct iommu_window *window; - /* we pretend the io page table was at a very high address */ - const unsigned long fake_iopt = 0x10000000000ul; - const unsigned long io_page_size = 0x1000000; /* use 16M pages */ - const unsigned long io_segment_size = 0x10000000; /* 256M */ - - ioc_base = iommu->mapped_base; - ioc_mmio_base = iommu->mapped_mmio_base; - - for (real_address = 0, io_address = map_start; - io_address <= map_start + map_size; - real_address += io_page_size, io_address += io_page_size) { - ioste = get_iost_entry(fake_iopt, io_address, io_page_size); - if ((real_address % io_segment_size) == 0) /* segment start */ - set_iost_cache(ioc_mmio_base, - io_address >> 28, ioste); - index = get_ioc_hash_1way(ioste, io_address); - pr_debug("addr %08lx, index %02lx, ioste %016lx\n", - io_address, index, ioste.val); - set_iopt_cache(ioc_mmio_base, - get_ioc_hash_1way(ioste, io_address), - get_ioc_tag(ioste, io_address), - get_iopt_entry(real_address, ioid, IOPT_PROT_RW)); + /* todo: check for overlapping (but not equal) windows) */ + + list_for_each_entry(window, &(iommu->windows), list) { + if (window->offset == offset && window->size == size) + return window; } + + return NULL; } +#endif -static void pci_dma_cell_bus_setup(struct pci_bus *b) +static struct iommu_window * __init +cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np, + unsigned long offset, unsigned long size, + unsigned long pte_offset) { + struct iommu_window *window; const unsigned int *ioid; - unsigned long map_start, map_size, token; - const unsigned long *dma_window; - struct cell_iommu *iommu; - struct device_node *d; - - d = pci_bus_to_OF_node(b); - ioid = get_property(d, "ioid", NULL); - if (!ioid) - pr_debug("No ioid entry found !\n"); + ioid = get_property(np, "ioid", NULL); + if (ioid == NULL) + printk(KERN_WARNING "iommu: missing ioid for %s using 0\n", + np->full_name); + + window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid); + BUG_ON(window == NULL); + + window->offset = offset; + window->size = size; + window->ioid = ioid ? *ioid : 0; + window->iommu = iommu; + window->pte_offset = pte_offset; + + window->table.it_blocksize = 16; + window->table.it_base = (unsigned long)iommu->ptab; + window->table.it_index = iommu->nid; + window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) + + window->pte_offset; + window->table.it_size = size >> IOMMU_PAGE_SHIFT; + + iommu_init_table(&window->table, iommu->nid); + + pr_debug("\tioid %d\n", window->ioid); + pr_debug("\tblocksize %ld\n", window->table.it_blocksize); + pr_debug("\tbase 0x%016lx\n", window->table.it_base); + pr_debug("\toffset 0x%lx\n", window->table.it_offset); + pr_debug("\tsize %ld\n", window->table.it_size); + + list_add(&window->list, &iommu->windows); + + if (offset != 0) + return window; + + /* We need to map and reserve the first IOMMU page since it's used + * by the spider workaround. In theory, we only need to do that when + * running on spider but it doesn't really matter. + * + * This code also assumes that we have a window that starts at 0, + * which is the case on all spider based blades. + */ + __set_bit(0, window->table.it_map); + tce_build_cell(&window->table, window->table.it_offset, 1, + (unsigned long)iommu->pad_page, DMA_TO_DEVICE); + window->table.it_hint = window->table.it_blocksize; + + return window; +} - dma_window = get_property(d, "ibm,dma-window", NULL); - if (!dma_window) - pr_debug("No ibm,dma-window entry found !\n"); +static struct cbe_iommu *cell_iommu_for_node(int nid) +{ + int i; - map_start = dma_window[1]; - map_size = dma_window[2]; - token = dma_window[0] >> 32; + for (i = 0; i < cbe_nr_iommus; i++) + if (iommus[i].nid == nid) + return &iommus[i]; + return NULL; +} - iommu = &cell_iommus[token]; +static void cell_dma_dev_setup(struct device *dev) +{ + struct iommu_window *window; + struct cbe_iommu *iommu; + struct dev_archdata *archdata = &dev->archdata; + + /* If we run without iommu, no need to do anything */ + if (pci_dma_ops == &dma_direct_ops) + return; + + /* Current implementation uses the first window available in that + * node's iommu. We -might- do something smarter later though it may + * never be necessary + */ + iommu = cell_iommu_for_node(archdata->numa_node); + if (iommu == NULL || list_empty(&iommu->windows)) { + printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n", + archdata->of_node ? archdata->of_node->full_name : "?", + archdata->numa_node); + return; + } + window = list_entry(iommu->windows.next, struct iommu_window, list); - cell_do_map_iommu(iommu, *ioid, map_start, map_size); + archdata->dma_data = &window->table; } - -static int cell_map_iommu_hardcoded(int num_nodes) +static void cell_pci_dma_dev_setup(struct pci_dev *dev) { - struct cell_iommu *iommu = NULL; + cell_dma_dev_setup(&dev->dev); +} - pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); +static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action, + void *data) +{ + struct device *dev = data; - /* node 0 */ - iommu = &cell_iommus[0]; - iommu->mapped_base = ioremap(0x20000511000ul, 0x1000); - iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000); + /* We are only intereted in device addition */ + if (action != BUS_NOTIFY_ADD_DEVICE) + return 0; - enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); + /* We use the PCI DMA ops */ + dev->archdata.dma_ops = pci_dma_ops; - cell_do_map_iommu(iommu, 0x048a, - 0x20000000ul,0x20000000ul); + cell_dma_dev_setup(dev); - if (num_nodes < 2) - return 0; + return 0; +} - /* node 1 */ - iommu = &cell_iommus[1]; - iommu->mapped_base = ioremap(0x30000511000ul, 0x1000); - iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000); +static struct notifier_block cell_of_bus_notifier = { + .notifier_call = cell_of_bus_notify +}; - enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); +static int __init cell_iommu_get_window(struct device_node *np, + unsigned long *base, + unsigned long *size) +{ + const void *dma_window; + unsigned long index; - cell_do_map_iommu(iommu, 0x048a, - 0x20000000,0x20000000ul); + /* Use ibm,dma-window if available, else, hard code ! */ + dma_window = get_property(np, "ibm,dma-window", NULL); + if (dma_window == NULL) { + *base = 0; + *size = 0x80000000u; + return -ENODEV; + } + of_parse_dma_window(np, dma_window, &index, base, size); return 0; } - -static int cell_map_iommu(void) +static void __init cell_iommu_init_one(struct device_node *np, unsigned long offset) { - unsigned int num_nodes = 0; - const unsigned int *node_id; - const unsigned long *base, *mmio_base; - struct device_node *dn; - struct cell_iommu *iommu = NULL; - - /* determine number of nodes (=iommus) */ - pr_debug("%s(%d): determining number of nodes...", __FUNCTION__, __LINE__); - for(dn = of_find_node_by_type(NULL, "cpu"); - dn; - dn = of_find_node_by_type(dn, "cpu")) { - node_id = get_property(dn, "node-id", NULL); - - if (num_nodes < *node_id) - num_nodes = *node_id; - } + struct cbe_iommu *iommu; + unsigned long base, size; + int nid, i; + + /* Get node ID */ + nid = of_node_to_nid(np); + if (nid < 0) { + printk(KERN_ERR "iommu: failed to get node for %s\n", + np->full_name); + return; + } + pr_debug("iommu: setting up iommu for node %d (%s)\n", + nid, np->full_name); + + /* XXX todo: If we can have multiple windows on the same IOMMU, which + * isn't the case today, we probably want here to check wether the + * iommu for that node is already setup. + * However, there might be issue with getting the size right so let's + * ignore that for now. We might want to completely get rid of the + * multiple window support since the cell iommu supports per-page ioids + */ + + if (cbe_nr_iommus >= NR_IOMMUS) { + printk(KERN_ERR "iommu: too many IOMMUs detected ! (%s)\n", + np->full_name); + return; + } + + /* Init base fields */ + i = cbe_nr_iommus++; + iommu = &iommus[i]; + iommu->stab = 0; + iommu->nid = nid; + snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i); + INIT_LIST_HEAD(&iommu->windows); - num_nodes++; - pr_debug("%i found.\n", num_nodes); + /* Obtain a window for it */ + cell_iommu_get_window(np, &base, &size); - /* map the iommu registers for each node */ - pr_debug("%s(%d): Looping through nodes\n", __FUNCTION__, __LINE__); - for(dn = of_find_node_by_type(NULL, "cpu"); - dn; - dn = of_find_node_by_type(dn, "cpu")) { + pr_debug("\ttranslating window 0x%lx...0x%lx\n", + base, base + size - 1); - node_id = get_property(dn, "node-id", NULL); - base = get_property(dn, "ioc-cache", NULL); - mmio_base = get_property(dn, "ioc-translation", NULL); + /* Initialize the hardware */ + cell_iommu_setup_hardware(iommu, size); - if (!base || !mmio_base || !node_id) - return cell_map_iommu_hardcoded(num_nodes); + /* Setup the iommu_table */ + cell_iommu_setup_window(iommu, np, base, size, + offset >> IOMMU_PAGE_SHIFT); +} - iommu = &cell_iommus[*node_id]; - iommu->base = *base; - iommu->mmio_base = *mmio_base; +static void __init cell_disable_iommus(void) +{ + int node; + unsigned long base, val; + void __iomem *xregs, *cregs; + + /* Make sure IOC translation is disabled on all nodes */ + for_each_online_node(node) { + if (cell_iommu_find_ioc(node, &base)) + continue; + xregs = ioremap(base, IOC_Reg_Size); + if (xregs == NULL) + continue; + cregs = xregs + IOC_IOCmd_Offset; + + pr_debug("iommu: cleaning up iommu on node %d\n", node); + + out_be64(xregs + IOC_IOST_Origin, 0); + (void)in_be64(xregs + IOC_IOST_Origin); + val = in_be64(cregs + IOC_IOCmd_Cfg); + val &= ~IOC_IOCmd_Cfg_TE; + out_be64(cregs + IOC_IOCmd_Cfg, val); + (void)in_be64(cregs + IOC_IOCmd_Cfg); + + iounmap(xregs); + } +} - iommu->mapped_base = ioremap(*base, 0x1000); - iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000); +static int __init cell_iommu_init_disabled(void) +{ + struct device_node *np = NULL; + unsigned long base = 0, size; - enable_mapping(iommu->mapped_base, - iommu->mapped_mmio_base); + /* When no iommu is present, we use direct DMA ops */ + pci_dma_ops = &dma_direct_ops; - /* everything else will be done in iommu_bus_setup */ + /* First make sure all IOC translation is turned off */ + cell_disable_iommus(); + + /* If we have no Axon, we set up the spider DMA magic offset */ + if (of_find_node_by_name(NULL, "axon") == NULL) + dma_direct_offset = SPIDER_DMA_OFFSET; + + /* Now we need to check to see where the memory is mapped + * in PCI space. We assume that all busses use the same dma + * window which is always the case so far on Cell, thus we + * pick up the first pci-internal node we can find and check + * the DMA window from there. + */ + for_each_node_by_name(np, "axon") { + if (np->parent == NULL || np->parent->parent != NULL) + continue; + if (cell_iommu_get_window(np, &base, &size) == 0) + break; + } + if (np == NULL) { + for_each_node_by_name(np, "pci-internal") { + if (np->parent == NULL || np->parent->parent != NULL) + continue; + if (cell_iommu_get_window(np, &base, &size) == 0) + break; + } + } + of_node_put(np); + + /* If we found a DMA window, we check if it's big enough to enclose + * all of physical memory. If not, we force enable IOMMU + */ + if (np && size < lmb_end_of_DRAM()) { + printk(KERN_WARNING "iommu: force-enabled, dma window" + " (%ldMB) smaller than total memory (%ldMB)\n", + size >> 20, lmb_end_of_DRAM() >> 20); + return -ENODEV; } - return 1; + dma_direct_offset += base; + + printk("iommu: disabled, direct DMA offset is 0x%lx\n", + dma_direct_offset); + + return 0; } -void cell_init_iommu(void) +static int __init cell_iommu_init(void) { - int setup_bus = 0; - - if (of_find_node_by_path("/mambo")) { - pr_info("Not using iommu on systemsim\n"); - } else { - /* If we don't have an Axon bridge, we assume we have a - * spider which requires a DMA offset - */ - if (of_find_node_by_name(NULL, "axon") == NULL) - dma_direct_offset = SPIDER_DMA_VALID; - - if (!(of_chosen && - get_property(of_chosen, "linux,iommu-off", NULL))) - setup_bus = cell_map_iommu(); - - if (setup_bus) { - pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__); - ppc_md.pci_dma_bus_setup = pci_dma_cell_bus_setup; - } else { - pr_debug("%s: IOMMU mapping activated, " - "no device action necessary\n", __FUNCTION__); - /* Direct I/O, IOMMU off */ - } + struct device_node *np; + + if (!machine_is(cell)) + return -ENODEV; + + /* If IOMMU is disabled or we have little enough RAM to not need + * to enable it, we setup a direct mapping. + * + * Note: should we make sure we have the IOMMU actually disabled ? + */ + if (iommu_is_off || + (!iommu_force_on && lmb_end_of_DRAM() <= 0x80000000ull)) + if (cell_iommu_init_disabled() == 0) + goto bail; + + /* Setup various ppc_md. callbacks */ + ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; + ppc_md.tce_build = tce_build_cell; + ppc_md.tce_free = tce_free_cell; + + /* Create an iommu for each /axon node. */ + for_each_node_by_name(np, "axon") { + if (np->parent == NULL || np->parent->parent != NULL) + continue; + cell_iommu_init_one(np, 0); } - pci_dma_ops = &dma_direct_ops; + /* Create an iommu for each toplevel /pci-internal node for + * old hardware/firmware + */ + for_each_node_by_name(np, "pci-internal") { + if (np->parent == NULL || np->parent->parent != NULL) + continue; + cell_iommu_init_one(np, SPIDER_DMA_OFFSET); + } + + /* Setup default PCI iommu ops */ + pci_dma_ops = &dma_iommu_ops; + + bail: + /* Register callbacks on OF platform device addition/removal + * to handle linking them to the right DMA operations + */ + bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); + + return 0; } +arch_initcall(cell_iommu_init); + diff --git a/arch/powerpc/platforms/cell/iommu.h b/arch/powerpc/platforms/cell/iommu.h deleted file mode 100644 index 2a9ab95604a..00000000000 --- a/arch/powerpc/platforms/cell/iommu.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef CELL_IOMMU_H -#define CELL_IOMMU_H - -/* some constants */ -enum { - /* segment table entries */ - IOST_VALID_MASK = 0x8000000000000000ul, - IOST_TAG_MASK = 0x3000000000000000ul, - IOST_PT_BASE_MASK = 0x000003fffffff000ul, - IOST_NNPT_MASK = 0x0000000000000fe0ul, - IOST_PS_MASK = 0x000000000000000ful, - - IOST_PS_4K = 0x1, - IOST_PS_64K = 0x3, - IOST_PS_1M = 0x5, - IOST_PS_16M = 0x7, - - /* iopt tag register */ - IOPT_VALID_MASK = 0x0000000200000000ul, - IOPT_TAG_MASK = 0x00000001fffffffful, - - /* iopt cache register */ - IOPT_PROT_MASK = 0xc000000000000000ul, - IOPT_PROT_NONE = 0x0000000000000000ul, - IOPT_PROT_READ = 0x4000000000000000ul, - IOPT_PROT_WRITE = 0x8000000000000000ul, - IOPT_PROT_RW = 0xc000000000000000ul, - IOPT_COHERENT = 0x2000000000000000ul, - - IOPT_ORDER_MASK = 0x1800000000000000ul, - /* order access to same IOID/VC on same address */ - IOPT_ORDER_ADDR = 0x0800000000000000ul, - /* similar, but only after a write access */ - IOPT_ORDER_WRITES = 0x1000000000000000ul, - /* Order all accesses to same IOID/VC */ - IOPT_ORDER_VC = 0x1800000000000000ul, - - IOPT_RPN_MASK = 0x000003fffffff000ul, - IOPT_HINT_MASK = 0x0000000000000800ul, - IOPT_IOID_MASK = 0x00000000000007fful, - - IOSTO_ENABLE = 0x8000000000000000ul, - IOSTO_ORIGIN = 0x000003fffffff000ul, - IOSTO_HW = 0x0000000000000800ul, - IOSTO_SW = 0x0000000000000400ul, - - IOCMD_CONF_TE = 0x0000800000000000ul, - - /* memory mapped registers */ - IOC_PT_CACHE_DIR = 0x000, - IOC_ST_CACHE_DIR = 0x800, - IOC_PT_CACHE_REG = 0x910, - IOC_ST_ORIGIN = 0x918, - IOC_CONF = 0x930, - - /* The high bit needs to be set on every DMA address when using - * a spider bridge and only 2GB are addressable with the current - * iommu code. - */ - SPIDER_DMA_VALID = 0x80000000, - CELL_DMA_MASK = 0x7fffffff, -}; - - -void cell_init_iommu(void); - -#endif diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 7e18420166c..83d5d0c2faf 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -55,7 +54,6 @@ #include #include "interrupt.h" -#include "iommu.h" #include "cbe_regs.h" #include "pervasive.h" #include "ras.h" @@ -83,38 +81,11 @@ static void cell_progress(char *s, unsigned short hex) printk("*** %04x : %s\n", hex, s ? s : ""); } -static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action, - void *data) -{ - struct device *dev = data; - - if (action != BUS_NOTIFY_ADD_DEVICE) - return 0; - - /* For now, we just use the PCI DMA ops for everything, though - * we'll need something better when we have a real iommu - * implementation. - */ - dev->archdata.dma_ops = pci_dma_ops; - - return 0; -} - -static struct notifier_block cell_of_bus_notifier = { - .notifier_call = cell_of_bus_notify -}; - - static int __init cell_publish_devices(void) { if (!machine_is(cell)) return 0; - /* Register callbacks on OF platform device addition/removal - * to handle linking them to the right DMA operations - */ - bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier); - /* Publish OF platform devices for southbridge IOs */ of_platform_bus_probe(NULL, NULL, NULL); @@ -205,19 +176,6 @@ static void __init cell_setup_arch(void) mmio_nvram_init(); } -/* - * Early initialization. Relocation is on but do not reference unbolted pages - */ -static void __init cell_init_early(void) -{ - DBG(" -> cell_init_early()\n"); - - cell_init_iommu(); - - DBG(" <- cell_init_early()\n"); -} - - static int __init cell_probe(void) { unsigned long root = of_get_flat_dt_root(); @@ -244,7 +202,6 @@ define_machine(cell) { .name = "Cell", .probe = cell_probe, .setup_arch = cell_setup_arch, - .init_early = cell_init_early, .show_cpuinfo = cell_show_cpuinfo, .restart = rtas_restart, .power_off = rtas_power_off, diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index ac784bb5728..1488535b0e1 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -48,9 +48,6 @@ #include "dart.h" -extern int iommu_is_off; -extern int iommu_force_on; - /* Physical base address and size of the DART table */ unsigned long dart_tablebase; /* exported to htab_initialize */ static unsigned long dart_tablesize; -- cgit v1.2.3 From 3d1ea8e8cb4d497a2dd73176cc82095b8f193589 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:25:19 +1100 Subject: [POWERPC] Remove ioremap64 and fixup_bigphys_addr In order to suppose platforms with devices above 4Gb on 32 bits platforms with a >32 bits physical address space, we used to have a special ioremap64 along with a fixup routine fixup_bigphys_addr. This shouldn't be necessary anymore as struct resource now supports 64 bits addresses even on 32 bits archs. This patch enables that option when CONFIG_PHYS_64BIT is set and removes ioremap64 and fixup_bigphys_addr. This is a preliminary work for the upcoming merge of 32 and 64 bits io.h Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + arch/powerpc/mm/pgtable_32.c | 17 ----------------- arch/powerpc/platforms/85xx/misc.c | 8 -------- 3 files changed, 1 insertion(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9547aacc319..b4a3b699433 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -247,6 +247,7 @@ config PTE_64BIT config PHYS_64BIT bool 'Large physical address support' if E500 depends on 44x || E500 + select RESOURCES_64BIT default y if 44x ---help--- This option enables kernel support for larger than 32-bit physical diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 8fcacb0239d..7750c442568 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -141,28 +141,11 @@ void pte_free(struct page *ptepage) __free_page(ptepage); } -#ifndef CONFIG_PHYS_64BIT void __iomem * ioremap(phys_addr_t addr, unsigned long size) { return __ioremap(addr, size, _PAGE_NO_CACHE); } -#else /* CONFIG_PHYS_64BIT */ -void __iomem * -ioremap64(unsigned long long addr, unsigned long size) -{ - return __ioremap(addr, size, _PAGE_NO_CACHE); -} -EXPORT_SYMBOL(ioremap64); - -void __iomem * -ioremap(phys_addr_t addr, unsigned long size) -{ - phys_addr_t addr64 = fixup_bigphys_addr(addr, size); - - return ioremap64(addr64, size); -} -#endif /* CONFIG_PHYS_64BIT */ EXPORT_SYMBOL(ioremap); void __iomem * diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c index 26c5e822c7c..3e62fcb04c1 100644 --- a/arch/powerpc/platforms/85xx/misc.c +++ b/arch/powerpc/platforms/85xx/misc.c @@ -21,11 +21,3 @@ void mpc85xx_restart(char *cmd) local_irq_disable(); abort(); } - -/* For now this is a pass through */ -phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size) -{ - return addr; -}; - -EXPORT_SYMBOL(fixup_bigphys_addr); -- cgit v1.2.3 From 68a64357d15ae4f596e92715719071952006e83c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 13 Nov 2006 09:27:39 +1100 Subject: [POWERPC] Merge 32 and 64 bits asm-powerpc/io.h powerpc: Merge 32 and 64 bits asm-powerpc/io.h The rework on io.h done for the new hookable accessors made it easier, so I just finished the work and merged 32 and 64 bits io.h for arch/powerpc. arch/ppc still uses the old version in asm-ppc, there is just too much gunk in there that I really can't be bothered trying to cleanup. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/io.c | 87 +++++++++++++++++++++++++++++++++ arch/powerpc/kernel/iomap.c | 2 +- arch/powerpc/kernel/pci_32.c | 34 ++----------- arch/powerpc/kernel/rtas_pci.c | 1 + arch/powerpc/kernel/traps.c | 8 +-- arch/powerpc/mm/pgtable_32.c | 22 +++------ arch/powerpc/mm/pgtable_64.c | 16 +++--- arch/powerpc/platforms/chrp/setup.c | 1 - arch/powerpc/platforms/iseries/setup.c | 4 +- arch/powerpc/platforms/powermac/setup.c | 2 - 11 files changed, 113 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 600954df07a..f9ce5d798de 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -72,7 +72,7 @@ obj-$(CONFIG_AUDIT) += audit.o obj64-$(CONFIG_AUDIT) += compat_audit.o ifneq ($(CONFIG_PPC_INDIRECT_IO),y) -pci64-$(CONFIG_PPC64) += iomap.o +obj-y += iomap.o endif ifeq ($(CONFIG_PPC_ISERIES),y) diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c index c1aa07524c2..34ae11494dd 100644 --- a/arch/powerpc/kernel/io.c +++ b/arch/powerpc/kernel/io.c @@ -117,3 +117,90 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count) asm volatile("sync"); } EXPORT_SYMBOL(_outsl_ns); + +#define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0) + +void _memset_io(volatile void __iomem *addr, int c, unsigned long n) +{ + void *p = (void __force *)addr; + u32 lc = c; + lc |= lc << 8; + lc |= lc << 16; + + __asm__ __volatile__ ("sync" : : : "memory"); + while(n && !IO_CHECK_ALIGN(p, 4)) { + *((volatile u8 *)p) = c; + p++; + n--; + } + while(n >= 4) { + *((volatile u32 *)p) = lc; + p += 4; + n -= 4; + } + while(n) { + *((volatile u8 *)p) = c; + p++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); +} +EXPORT_SYMBOL(_memset_io); + +void _memcpy_fromio(void *dest, const volatile void __iomem *src, + unsigned long n) +{ + void *vsrc = (void __force *) src; + + __asm__ __volatile__ ("sync" : : : "memory"); + while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) { + *((u8 *)dest) = *((volatile u8 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc++; + dest++; + n--; + } + while(n > 4) { + *((u32 *)dest) = *((volatile u32 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc += 4; + dest += 4; + n -= 4; + } + while(n) { + *((u8 *)dest) = *((volatile u8 *)vsrc); + __asm__ __volatile__ ("eieio" : : : "memory"); + vsrc++; + dest++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); +} +EXPORT_SYMBOL(_memcpy_fromio); + +void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) +{ + void *vdest = (void __force *) dest; + + __asm__ __volatile__ ("sync" : : : "memory"); + while(n && (!IO_CHECK_ALIGN(vdest, 4) || !IO_CHECK_ALIGN(src, 4))) { + *((volatile u8 *)vdest) = *((u8 *)src); + src++; + vdest++; + n--; + } + while(n > 4) { + *((volatile u32 *)vdest) = *((volatile u32 *)src); + src += 4; + vdest += 4; + n-=4; + } + while(n) { + *((volatile u8 *)vdest) = *((u8 *)src); + src++; + vdest++; + n--; + } + __asm__ __volatile__ ("sync" : : : "memory"); +} +EXPORT_SYMBOL(_memcpy_toio); diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c index a13a93dfc65..c6811337105 100644 --- a/arch/powerpc/kernel/iomap.c +++ b/arch/powerpc/kernel/iomap.c @@ -106,7 +106,7 @@ EXPORT_SYMBOL(iowrite32_rep); void __iomem *ioport_map(unsigned long port, unsigned int len) { - return (void __iomem *) (port+pci_io_base); + return (void __iomem *) (port + _IO_BASE); } void ioport_unmap(void __iomem *addr) diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 0ad101a5fc5..b08238f3050 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -1561,7 +1561,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = hose->io_base_virt - ___IO_BASE; + io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -1816,7 +1816,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, return; if (rsrc->flags & IORESOURCE_IO) - offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + offset = (void __iomem *)_IO_BASE - hose->io_base_virt + + hose->io_base_phys; *start = rsrc->start + offset; *end = rsrc->end + offset; @@ -1835,35 +1836,6 @@ pci_init_resource(struct resource *res, unsigned long start, unsigned long end, res->child = NULL; } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len) - return NULL; - if (max && len > max) - len = max; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - /* Not checking IORESOURCE_CACHEABLE because PPC does - * not currently distinguish between ioremap and - * ioremap_nocache. - */ - return ioremap(start, len); - /* What? */ - return NULL; -} - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - /* Nothing to do */ -} -EXPORT_SYMBOL(pci_iomap); -EXPORT_SYMBOL(pci_iounmap); - unsigned long pci_address_to_pio(phys_addr_t address) { struct pci_controller* hose = hose_head; diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 03cacc25a0a..ace9f4c86e6 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -38,6 +38,7 @@ #include #include #include +#include /* RTAS tokens */ static int read_pci_config; diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index c66b4771ef4..0d4e203fa7a 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -53,10 +53,6 @@ #endif #include -#ifdef CONFIG_PPC64 /* XXX */ -#define _IO_BASE pci_io_base -#endif - #ifdef CONFIG_DEBUGGER int (*__debugger)(struct pt_regs *regs); int (*__debugger_ipi)(struct pt_regs *regs); @@ -241,7 +237,7 @@ void system_reset_exception(struct pt_regs *regs) */ static inline int check_io_access(struct pt_regs *regs) { -#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) +#ifdef CONFIG_PPC32 unsigned long msr = regs->msr; const struct exception_table_entry *entry; unsigned int *nip = (unsigned int *)regs->nip; @@ -274,7 +270,7 @@ static inline int check_io_access(struct pt_regs *regs) return 1; } } -#endif /* CONFIG_PPC_PMAC && CONFIG_PPC32 */ +#endif /* CONFIG_PPC32 */ return 0; } diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 7750c442568..1891dbeeb8e 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -148,6 +148,13 @@ ioremap(phys_addr_t addr, unsigned long size) } EXPORT_SYMBOL(ioremap); +void __iomem * +ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags) +{ + return __ioremap(addr, size, flags); +} +EXPORT_SYMBOL(ioremap_flags); + void __iomem * __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) { @@ -247,20 +254,7 @@ void iounmap(volatile void __iomem *addr) } EXPORT_SYMBOL(iounmap); -void __iomem *ioport_map(unsigned long port, unsigned int len) -{ - return (void __iomem *) (port + _IO_BASE); -} - -void ioport_unmap(void __iomem *addr) -{ - /* Nothing to do */ -} -EXPORT_SYMBOL(ioport_map); -EXPORT_SYMBOL(ioport_unmap); - -int -map_page(unsigned long va, phys_addr_t pa, int flags) +int map_page(unsigned long va, phys_addr_t pa, int flags) { pmd_t *pd; pte_t *pg; diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index e9b21846ccb..16e4ee1c231 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -113,7 +113,7 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags) } -static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, +static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa, unsigned long ea, unsigned long size, unsigned long flags) { @@ -129,7 +129,7 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, return (void __iomem *) (ea + (addr & ~PAGE_MASK)); } -void __iomem * __ioremap(unsigned long addr, unsigned long size, +void __iomem * __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) { unsigned long pa, ea; @@ -169,7 +169,7 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size, } -void __iomem * ioremap(unsigned long addr, unsigned long size) +void __iomem * ioremap(phys_addr_t addr, unsigned long size) { unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED; @@ -178,7 +178,7 @@ void __iomem * ioremap(unsigned long addr, unsigned long size) return __ioremap(addr, size, flags); } -void __iomem * ioremap_flags(unsigned long addr, unsigned long size, +void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags) { if (ppc_md.ioremap) @@ -189,7 +189,7 @@ void __iomem * ioremap_flags(unsigned long addr, unsigned long size, #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) -int __ioremap_explicit(unsigned long pa, unsigned long ea, +int __ioremap_explicit(phys_addr_t pa, unsigned long ea, unsigned long size, unsigned long flags) { struct vm_struct *area; @@ -244,7 +244,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea, * * XXX what about calls before mem_init_done (ie python_countermeasures()) */ -void __iounmap(void __iomem *token) +void __iounmap(volatile void __iomem *token) { void *addr; @@ -256,7 +256,7 @@ void __iounmap(void __iomem *token) im_free(addr); } -void iounmap(void __iomem *token) +void iounmap(volatile void __iomem *token) { if (ppc_md.iounmap) ppc_md.iounmap(token); @@ -282,7 +282,7 @@ static int iounmap_subset_regions(unsigned long addr, unsigned long size) return 0; } -int __iounmap_explicit(void __iomem *start, unsigned long size) +int __iounmap_explicit(volatile void __iomem *start, unsigned long size) { struct vm_struct *area; unsigned long addr; diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index e6807d6d75b..e1f51d45598 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c @@ -588,7 +588,6 @@ static int __init chrp_probe(void) ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; - isa_io_base = CHRP_ISA_IO_BASE; /* default value */ return 1; } diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 2f16d9330cf..0f39bdbbf91 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -617,13 +617,13 @@ static void iseries_dedicated_idle(void) void __init iSeries_init_IRQ(void) { } #endif -static void __iomem *iseries_ioremap(unsigned long address, unsigned long size, +static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size, unsigned long flags) { return (void __iomem *)address; } -static void iseries_iounmap(void __iomem *token) +static void iseries_iounmap(volatile void __iomem *token) { } diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 4ec6a5a65f3..d949e9df41e 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -677,8 +677,6 @@ static int __init pmac_probe(void) #ifdef CONFIG_PPC32 /* isa_io_base gets set in pmac_pci_init */ - isa_mem_base = PMAC_ISA_MEM_BASE; - pci_dram_offset = PMAC_PCI_DRAM_OFFSET; ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 1; DMA_MODE_WRITE = 2; -- cgit v1.2.3 From b06a318372ba95873abfe323076bd7e115d64b67 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Nov 2006 14:16:13 +1100 Subject: [POWERPC] iSeries: fix irq.c for combined build Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index eb9fc621e05..e1936952017 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -268,7 +268,8 @@ void do_IRQ(struct pt_regs *regs) set_irq_regs(old_regs); #ifdef CONFIG_PPC_ISERIES - if (get_lppaca()->int_dword.fields.decr_int) { + if (firmware_has_feature(FW_FEATURE_ISERIES) && + get_lppaca()->int_dword.fields.decr_int) { get_lppaca()->int_dword.fields.decr_int = 0; /* Signal a fake decrementer interrupt */ timer_interrupt(regs); -- cgit v1.2.3 From ad5cb17f730ae49e494cfd680a5c62f81c3ca484 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 13 Nov 2006 14:46:04 +1100 Subject: [POWERPC] iSeries: fix sysfs.c for combined build Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/sysfs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index cda21a27490..22123a0d541 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -200,10 +200,9 @@ static void register_cpu_online(unsigned int cpu) struct cpu *c = &per_cpu(cpu_devices, cpu); struct sys_device *s = &c->sysdev; -#ifndef CONFIG_PPC_ISERIES - if (cpu_has_feature(CPU_FTR_SMT)) + if (!firmware_has_feature(FW_FEATURE_ISERIES) && + cpu_has_feature(CPU_FTR_SMT)) sysdev_create_file(s, &attr_smt_snooze_delay); -#endif /* PMC stuff */ @@ -242,10 +241,9 @@ static void unregister_cpu_online(unsigned int cpu) BUG_ON(c->no_control); -#ifndef CONFIG_PPC_ISERIES - if (cpu_has_feature(CPU_FTR_SMT)) + if (!firmware_has_feature(FW_FEATURE_ISERIES) && + cpu_has_feature(CPU_FTR_SMT)) sysdev_remove_file(s, &attr_smt_snooze_delay); -#endif /* PMC stuff */ -- cgit v1.2.3 From 501b6d2938fd51e85279d950a6d23d515ae22c59 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 21 Nov 2006 15:10:20 +1100 Subject: [POWERPC] iSeries: fix time.c for combined build Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/time.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 46a24de36fe..f6f0c6b07c4 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -631,7 +631,8 @@ void timer_interrupt(struct pt_regs * regs) calculate_steal_time(); #ifdef CONFIG_PPC_ISERIES - get_lppaca()->int_dword.fields.decr_int = 0; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + get_lppaca()->int_dword.fields.decr_int = 0; #endif while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) @@ -674,7 +675,7 @@ void timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - if (hvlpevent_is_pending()) + if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending()) process_hvlpevents(); #endif @@ -774,7 +775,7 @@ int do_settimeofday(struct timespec *tv) * settimeofday to perform this operation. */ #ifdef CONFIG_PPC_ISERIES - if (first_settimeofday) { + if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) { iSeries_tb_recal(); first_settimeofday = 0; } -- cgit v1.2.3 From 1d13581d00a041797c2c14adaccd306c91f87d46 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 13 Nov 2006 14:50:28 +1100 Subject: [POWERPC] iSeries: fix xmon.c for combined build Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/xmon/xmon.c | 52 +++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 0689c084577..d66c3a17032 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -39,6 +39,7 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include @@ -1567,11 +1568,6 @@ void super_regs(void) { int cmd; unsigned long val; -#ifdef CONFIG_PPC_ISERIES - struct paca_struct *ptrPaca = NULL; - struct lppaca *ptrLpPaca = NULL; - struct ItLpRegSave *ptrLpRegSave = NULL; -#endif cmd = skipbl(); if (cmd == '\n') { @@ -1588,26 +1584,32 @@ void super_regs(void) printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); #ifdef CONFIG_PPC_ISERIES - // Dump out relevant Paca data areas. - printf("Paca: \n"); - ptrPaca = get_paca(); - - printf(" Local Processor Control Area (LpPaca): \n"); - ptrLpPaca = ptrPaca->lppaca_ptr; - printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", - ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); - printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", - ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); - printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); - - printf(" Local Processor Register Save Area (LpRegSave): \n"); - ptrLpRegSave = ptrPaca->reg_save_ptr; - printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", - ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); - printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", - ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); - printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", - ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); + if (firmware_has_feature(FW_FEATURE_ISERIES)) { + struct paca_struct *ptrPaca; + struct lppaca *ptrLpPaca; + struct ItLpRegSave *ptrLpRegSave; + + /* Dump out relevant Paca data areas. */ + printf("Paca: \n"); + ptrPaca = get_paca(); + + printf(" Local Processor Control Area (LpPaca): \n"); + ptrLpPaca = ptrPaca->lppaca_ptr; + printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", + ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); + printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", + ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); + printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); + + printf(" Local Processor Register Save Area (LpRegSave): \n"); + ptrLpRegSave = ptrPaca->reg_save_ptr; + printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", + ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); + printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", + ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); + printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", + ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); + } #endif return; -- cgit v1.2.3 From 56291e19e37cf3bb8fc701ebf3aa8ffbf59f73ef Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 14 Nov 2006 12:57:38 +1100 Subject: [POWERPC] iSeries: fix slb.c for combined build Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/mm/slb.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c index d3733912adb..224e960650a 100644 --- a/arch/powerpc/mm/slb.c +++ b/arch/powerpc/mm/slb.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #ifdef DEBUG @@ -193,6 +194,7 @@ static inline void patch_slb_encoding(unsigned int *insn_addr, void slb_initialize(void) { unsigned long linear_llp, vmalloc_llp, io_llp; + unsigned long lflags, vflags; static int slb_encoding_inited; extern unsigned int *slb_miss_kernel_load_linear; extern unsigned int *slb_miss_kernel_load_io; @@ -225,11 +227,12 @@ void slb_initialize(void) #endif } + get_paca()->stab_rr = SLB_NUM_BOLTED; + /* On iSeries the bolted entries have already been set up by * the hypervisor from the lparMap data in head.S */ -#ifndef CONFIG_PPC_ISERIES - { - unsigned long lflags, vflags; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return; lflags = SLB_VSID_KERNEL | linear_llp; vflags = SLB_VSID_KERNEL | vmalloc_llp; @@ -247,8 +250,4 @@ void slb_initialize(void) * elsewhere, we'll call _switch() which will bolt in the new * one. */ asm volatile("isync":::"memory"); - } -#endif /* CONFIG_PPC_ISERIES */ - - get_paca()->stab_rr = SLB_NUM_BOLTED; } -- cgit v1.2.3 From ef2b343e99e772e35f0f9d00f7db318b6629c16e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Fri, 10 Nov 2006 21:32:40 +0000 Subject: [POWERPC] Make soft_enabled irqs preempt safe Rewrite local_get_flags and local_irq_disable to use r13 explicitly, to avoid the risk that gcc will split get_paca()->soft_enabled into a sequence unsafe against preemption. Similar care in local_irq_restore. Signed-off-by: Hugh Dickins Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/irq.c | 57 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index e1936952017..0bd8c766583 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -97,22 +97,69 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; +static inline unsigned long get_hard_enabled(void) +{ + unsigned long enabled; + + __asm__ __volatile__("lbz %0,%1(13)" + : "=r" (enabled) : "i" (offsetof(struct paca_struct, hard_enabled))); + + return enabled; +} + +static inline void set_soft_enabled(unsigned long enable) +{ + __asm__ __volatile__("stb %0,%1(13)" + : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled))); +} + void local_irq_restore(unsigned long en) { - get_paca()->soft_enabled = en; + /* + * get_paca()->soft_enabled = en; + * Is it ever valid to use local_irq_restore(0) when soft_enabled is 1? + * That was allowed before, and in such a case we do need to take care + * that gcc will set soft_enabled directly via r13, not choose to use + * an intermediate register, lest we're preempted to a different cpu. + */ + set_soft_enabled(en); if (!en) return; if (firmware_has_feature(FW_FEATURE_ISERIES)) { - if (get_paca()->lppaca_ptr->int_dword.any_int) + /* + * Do we need to disable preemption here? Not really: in the + * unlikely event that we're preempted to a different cpu in + * between getting r13, loading its lppaca_ptr, and loading + * its any_int, we might call iseries_handle_interrupts without + * an interrupt pending on the new cpu, but that's no disaster, + * is it? And the business of preempting us off the old cpu + * would itself involve a local_irq_restore which handles the + * interrupt to that cpu. + * + * But use "local_paca->lppaca_ptr" instead of "get_lppaca()" + * to avoid any preemption checking added into get_paca(). + */ + if (local_paca->lppaca_ptr->int_dword.any_int) iseries_handle_interrupts(); return; } - if (get_paca()->hard_enabled) + /* + * if (get_paca()->hard_enabled) return; + * But again we need to take care that gcc gets hard_enabled directly + * via r13, not choose to use an intermediate register, lest we're + * preempted to a different cpu in between the two instructions. + */ + if (get_hard_enabled()) return; - /* need to hard-enable interrupts here */ - get_paca()->hard_enabled = en; + + /* + * Need to hard-enable interrupts here. Since currently disabled, + * no need to take further asm precautions against preemption; but + * use local_paca instead of get_paca() to avoid preemption checking. + */ + local_paca->hard_enabled = en; if ((int)mfspr(SPRN_DEC) < 0) mtspr(SPRN_DEC, 1); hard_irq_enable(); -- cgit v1.2.3 From d6a0005c26aea9d470cf80c392d3bf2039dc4679 Mon Sep 17 00:00:00 2001 From: nkalmala Date: Wed, 8 Nov 2006 19:52:56 -0800 Subject: [POWERPC] Book-E reg MCSR msg misquoted PPC/booke reg MCSR value misquoted Signed-off-by: nkalmala Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Acked-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 9661a91183b..2f835b9e95e 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -316,7 +316,7 @@ void machine_check_exception(struct pt_regs *regs) if (reason & MCSR_BUS_RBERR) printk("Bus - Read Data Bus Error\n"); if (reason & MCSR_BUS_WBERR) - printk("Bus - Read Data Bus Error\n"); + printk("Bus - Write Data Bus Error\n"); if (reason & MCSR_BUS_IPERR) printk("Bus - Instruction Parity Error\n"); if (reason & MCSR_BUS_RPERR) -- cgit v1.2.3 From 1d30593e4c406c753e395676ba8b58600ccccbc1 Mon Sep 17 00:00:00 2001 From: Wojtek Kaniewski Date: Wed, 8 Nov 2006 19:52:57 -0800 Subject: [POWERPC] Compilation fixes for ppc4xx PCI-less configs Fix compilation without PCI support for Bubinga, CPCI405 and EP405. bios_fixup() for these boards uses functions available only with CONFIG_PCI, so linker fails. Signed-off-by: Wojtek Kaniewski Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/ppc/platforms/4xx/bubinga.c | 2 ++ arch/ppc/platforms/4xx/cpci405.c | 2 ++ arch/ppc/platforms/4xx/ep405.c | 2 ++ 3 files changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c index 4009f4983ca..75857b38e89 100644 --- a/arch/ppc/platforms/4xx/bubinga.c +++ b/arch/ppc/platforms/4xx/bubinga.c @@ -116,6 +116,7 @@ bubinga_early_serial_map(void) void __init bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) { +#ifdef CONFIG_PCI unsigned int bar_response, bar; /* @@ -211,6 +212,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms))); printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); +#endif #endif } diff --git a/arch/ppc/platforms/4xx/cpci405.c b/arch/ppc/platforms/4xx/cpci405.c index 367430998fc..8474b05b795 100644 --- a/arch/ppc/platforms/4xx/cpci405.c +++ b/arch/ppc/platforms/4xx/cpci405.c @@ -126,6 +126,7 @@ cpci405_setup_arch(void) void __init bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) { +#ifdef CONFIG_PCI unsigned int bar_response, bar; /* Disable region first */ @@ -167,6 +168,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) PCI_FUNC(hose->first_busno), bar, &bar_response); } +#endif } void __init diff --git a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c index ae5c82081c9..e5adf9ba1fc 100644 --- a/arch/ppc/platforms/4xx/ep405.c +++ b/arch/ppc/platforms/4xx/ep405.c @@ -68,6 +68,7 @@ ep405_setup_arch(void) void __init bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) { +#ifdef CONFIG_PCI unsigned int bar_response, bar; /* * Expected PCI mapping: @@ -130,6 +131,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) PCI_FUNC(hose->first_busno), bar, bar_response); } /* end work arround */ +#endif } void __init -- cgit v1.2.3 From 5873c9bdb05e9cc68ff4c45a192032a61f705067 Mon Sep 17 00:00:00 2001 From: Zang Roy-r61911 Date: Tue, 14 Nov 2006 14:31:50 +0800 Subject: [POWERPC] Make pci_read_irq_line the default on mpc7448hpc2 board The following patch adds a tsi108/9 pci interrupt controller host. On mpc7448hpc2 board, pci_irq_fixup function is removed, which makes the pci_read_irq_line be the default pci irq fixup. Signed-off-by: Roy Zang Signed-off-by: Paul Mackerras --- arch/powerpc/boot/dts/mpc7448hpc2.dts | 44 +++++++----- arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c | 88 ++++++----------------- arch/powerpc/sysdev/tsi108_pci.c | 48 +++++++++++-- 3 files changed, 93 insertions(+), 87 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts index d7b985e6bd2..c4d9562cbaa 100644 --- a/arch/powerpc/boot/dts/mpc7448hpc2.dts +++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts @@ -161,29 +161,41 @@ interrupt-map = < /* IDSEL 0x11 */ - 0800 0 0 1 7400 24 0 - 0800 0 0 2 7400 25 0 - 0800 0 0 3 7400 26 0 - 0800 0 0 4 7400 27 0 + 0800 0 0 1 1180 24 0 + 0800 0 0 2 1180 25 0 + 0800 0 0 3 1180 26 0 + 0800 0 0 4 1180 27 0 /* IDSEL 0x12 */ - 1000 0 0 1 7400 25 0 - 1000 0 0 2 7400 26 0 - 1000 0 0 3 7400 27 0 - 1000 0 0 4 7400 24 0 + 1000 0 0 1 1180 25 0 + 1000 0 0 2 1180 26 0 + 1000 0 0 3 1180 27 0 + 1000 0 0 4 1180 24 0 /* IDSEL 0x13 */ - 1800 0 0 1 7400 26 0 - 1800 0 0 2 7400 27 0 - 1800 0 0 3 7400 24 0 - 1800 0 0 4 7400 25 0 + 1800 0 0 1 1180 26 0 + 1800 0 0 2 1180 27 0 + 1800 0 0 3 1180 24 0 + 1800 0 0 4 1180 25 0 /* IDSEL 0x14 */ - 2000 0 0 1 7400 27 0 - 2000 0 0 2 7400 24 0 - 2000 0 0 3 7400 25 0 - 2000 0 0 4 7400 26 0 + 2000 0 0 1 1180 27 0 + 2000 0 0 2 1180 24 0 + 2000 0 0 3 1180 25 0 + 2000 0 0 4 1180 26 0 >; + router@1180 { + linux,phandle = <1180>; + clock-frequency = <0>; + interrupt-controller; + device_type = "pic-router"; + #address-cells = <0>; + #interrupt-cells = <2>; + built-in; + big-endian; + interrupts = <17 2>; + interrupt-parent = <7400>; + }; }; }; diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c index c6113c39009..3fcc85f60fb 100644 --- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c +++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -60,7 +60,7 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; extern int tsi108_setup_pci(struct device_node *dev); extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); -extern void tsi108_pci_int_init(void); +extern void tsi108_pci_int_init(struct device_node *node); extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) @@ -71,59 +71,6 @@ int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) return PCIBIOS_SUCCESSFUL; } -/* - * find pci slot by devfn in interrupt map of OF tree - */ -u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) -{ - int i; - unsigned int tmp; - for (i = 0; i < 4; i++){ - tmp = interrupt_map[i*4*7]; - if ((tmp >> 11) == (devfn >> 3)) - return i; - } - return i; -} - -/* - * Scans the interrupt map for pci device - */ -void __devinit mpc7448_hpc2_fixup_irq(struct pci_dev *dev) -{ - struct pci_controller *hose; - struct device_node *node; - const unsigned int *interrupt; - int busnr; - int len; - u8 slot; - u8 pin; - - /* Lookup the hose */ - busnr = dev->bus->number; - hose = pci_bus_to_hose(busnr); - if (!hose) - printk(KERN_ERR "No pci hose found\n"); - - /* Check it has an OF node associated */ - node = (struct device_node *) hose->arch_data; - if (!node) - printk(KERN_ERR "No pci node found\n"); - - interrupt = get_property(node, "interrupt-map", &len); - slot = find_slot_by_devfn(interrupt, dev->devfn); - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); - if (pin == 0 || pin > 4) - pin = 1; - pin--; - dev->irq = interrupt[slot*4*7 + pin*7 + 5]; - - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - - DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); -} -/* temporary pci irq map fixup*/ - static void __init mpc7448_hpc2_setup_arch(void) { struct device_node *cpu; @@ -186,9 +133,12 @@ static void __init mpc7448_hpc2_init_IRQ(void) { struct mpic *mpic; phys_addr_t mpic_paddr = 0; + struct device_node *tsi_pic; +#ifdef CONFIG_PCI unsigned int cascade_pci_irq; struct device_node *tsi_pci; - struct device_node *tsi_pic; + struct device_node *cascade_node = NULL; +#endif tsi_pic = of_find_node_by_type(NULL, "open-pic"); if (tsi_pic) { @@ -202,31 +152,41 @@ static void __init mpc7448_hpc2_init_IRQ(void) return; } - DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, + DBG("%s: tsi108 pic phys_addr = 0x%x\n", __FUNCTION__, (u32) mpic_paddr); mpic = mpic_alloc(tsi_pic, mpic_paddr, MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, - 0, /* num_sources used */ - 0, /* num_sources used */ + 24, + NR_IRQS-4, /* num_sources used */ "Tsi108_PIC"); - BUG_ON(mpic == NULL); /* XXXX */ + BUG_ON(mpic == NULL); + + mpic_assign_isu(mpic, 0, mpic_paddr + 0x100); + mpic_init(mpic); +#ifdef CONFIG_PCI tsi_pci = of_find_node_by_type(NULL, "pci"); - if (tsi_pci == 0) { + if (tsi_pci == NULL) { printk("%s: No tsi108 pci node found !\n", __FUNCTION__); return; } + cascade_node = of_find_node_by_type(NULL, "pic-router"); + if (cascade_node == NULL) { + printk("%s: No tsi108 pci cascade node found !\n", __FUNCTION__); + return; + } cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); + DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __FUNCTION__, + (u32) cascade_pci_irq); + tsi108_pci_int_init(cascade_node); set_irq_data(cascade_pci_irq, mpic); set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); - - tsi108_pci_int_init(); - +#endif /* Configure MPIC outputs to CPU0 */ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); of_node_put(tsi_pic); @@ -284,7 +244,6 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs) return 1; } return 0; - } define_machine(mpc7448_hpc2){ @@ -294,7 +253,6 @@ define_machine(mpc7448_hpc2){ .init_IRQ = mpc7448_hpc2_init_IRQ, .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, .get_irq = mpic_get_irq, - .pci_irq_fixup = mpc7448_hpc2_fixup_irq, .restart = mpc7448_hpc2_restart, .calibrate_decr = generic_calibrate_decr, .machine_check_exception= mpc7448_machine_check_exception, diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c index 322f86e93de..ae249c6bbbc 100644 --- a/arch/powerpc/sysdev/tsi108_pci.c +++ b/arch/powerpc/sysdev/tsi108_pci.c @@ -3,6 +3,8 @@ * * 2004-2005 (c) Tundra Semiconductor Corp. * Author: Alex Bounine (alexandreb@tundra.com) + * Author: Roy Zang (tie-fei.zang@freescale.com) + * Add pci interrupt router host * * 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 @@ -48,6 +50,8 @@ u32 tsi108_pci_cfg_base; u32 tsi108_csr_vir_base; +static struct device_node *pci_irq_node; +static struct irq_host *pci_irq_host; extern u32 get_vir_csrbase(void); extern u32 tsi108_read_reg(u32 reg_offset); @@ -378,6 +382,38 @@ static struct irq_chip tsi108_pci_irq = { .unmask = tsi108_pci_irq_enable, }; +static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct, + u32 *intspec, unsigned int intsize, + irq_hw_number_t *out_hwirq, unsigned int *out_flags) +{ + *out_hwirq = intspec[0]; + *out_flags = IRQ_TYPE_LEVEL_HIGH; + return 0; +} + +static int pci_irq_host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hw) +{ unsigned int irq; + DBG("%s(%d, 0x%lx)\n", __FUNCTION__, virq, hw); + if ((virq >= 1) && (virq <= 4)){ + irq = virq + IRQ_PCI_INTAD_BASE - 1; + get_irq_desc(irq)->status |= IRQ_LEVEL; + set_irq_chip(irq, &tsi108_pci_irq); + } + return 0; +} + +static int pci_irq_host_match(struct irq_host *h, struct device_node *node) +{ + return pci_irq_node == node; +} + +static struct irq_host_ops pci_irq_host_ops = { + .match = pci_irq_host_match, + .map = pci_irq_host_map, + .xlate = pci_irq_host_xlate, +}; + /* * Exported functions */ @@ -391,15 +427,15 @@ static struct irq_chip tsi108_pci_irq = { * to the MPIC. */ -void __init tsi108_pci_int_init(void) +void __init tsi108_pci_int_init(struct device_node *node) { - u_int i; - DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); - for (i = 0; i < NUM_PCI_IRQS; i++) { - irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq; - irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; + pci_irq_node = of_node_get(node); + pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0); + if (pci_irq_host == NULL) { + printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n"); + return; } init_pci_source(); -- cgit v1.2.3 From 088df4d256227b3d927bb6ed57e66d138da0565c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Thu, 16 Nov 2006 15:41:15 -0600 Subject: [POWERPC] Wrap cpu_die() with CONFIG_HOTPLUG_CPU Per email discussion, it appears that rtas_stop_self() and pSeries_mach_cpu_die() should not be compiled if CONFIG_HOTPLUG_CPU is not defined. This patch adds #ifdefs around these bits of code. Signed-off-by: Linas Vepstas Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/rtas.c | 5 +++-- arch/powerpc/platforms/pseries/setup.c | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 6ef80d4e38d..387ed0d9ad6 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -810,9 +810,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) return 0; } +#ifdef CONFIG_HOTPLUG_CPU /* This version can't take the spinlock, because it never returns */ - -struct rtas_args rtas_stop_self_args = { +static struct rtas_args rtas_stop_self_args = { /* The token is initialized for real in setup_system() */ .token = RTAS_UNKNOWN_SERVICE, .nargs = 0, @@ -834,6 +834,7 @@ void rtas_stop_self(void) panic("Alas, I survived.\n"); } +#endif /* * Call early during boot, before mem init or bootmem, to retrieve the RTAS diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index a8f3812aa38..0dc2548ca9b 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -347,6 +347,7 @@ static int __init pSeries_init_panel(void) } arch_initcall(pSeries_init_panel); +#ifdef CONFIG_HOTPLUG_CPU static void pSeries_mach_cpu_die(void) { local_irq_disable(); @@ -357,6 +358,9 @@ static void pSeries_mach_cpu_die(void) BUG(); for(;;); } +#else +#define pSeries_mach_cpu_die NULL +#endif static int pseries_set_dabr(unsigned long dabr) { -- cgit v1.2.3 From f79e083c2fab601a1c382282344f5a251557dbac Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 16 Nov 2006 15:31:32 +1100 Subject: [POWERPC] Small clarification of initrd handling This patch makes the handling of the initrd (or initramfs) in the zImage wrapper a little easier to follow. Instead of passing the initrd addresses out from prep_kernel() via the cryptic a1 and a2 parameters, use the global struct add_range, 'initrd'. prep_kernel() already passes information through the 'vmlinux' addr_range struct, so this seems like a reasonable extension. Some comments also clarify the logic with prep_kernel(): we use an initrd included in the zImage if present, otherwise we use an initrd passed in by the bootloader in the a1 and a2 parameters (yaboot, at least, uses this mechanism to pass an initrd). Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/boot/main.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 418497482b6..630a453e16f 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -169,7 +169,7 @@ static int is_elf32(void *hdr) return 1; } -static void prep_kernel(unsigned long *a1, unsigned long *a2) +static void prep_kernel(unsigned long a1, unsigned long a2) { int len; @@ -205,11 +205,14 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) } /* - * Now we try to alloc memory for the initrd (and copy it there) + * Now find the initrd + * + * First see if we have an image attached to us. If so + * allocate memory for it and copy it there. */ initrd.size = (unsigned long)(_initrd_end - _initrd_start); initrd.memsize = initrd.size; - if ( initrd.size > 0 ) { + if (initrd.size > 0) { printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size); initrd.addr = (unsigned long)malloc((u32)initrd.size); @@ -218,8 +221,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) "ramdisk !\n\r"); exit(); } - *a1 = initrd.addr; - *a2 = initrd.size; printf("initial ramdisk moving 0x%lx <- 0x%lx " "(0x%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); @@ -227,6 +228,12 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2) initrd.size); printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); + } else if (a2 != 0) { + /* Otherwise, see if yaboot or another loader gave us an initrd */ + initrd.addr = a1; + initrd.memsize = initrd.size = a2; + printf("Using loader supplied initrd at 0x%lx (0x%lx bytes)\n\r", + initrd.addr, initrd.size); } /* Eventually gunzip the kernel */ @@ -307,7 +314,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp); - prep_kernel(&a1, &a2); + prep_kernel(a1, a2); /* If cmdline came from zimage wrapper or if we can edit the one * in the dt, print it out and edit it, if possible. @@ -331,7 +338,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) } else /* XXX initrd addr/size should be passed in properties */ - kentry(a1, a2, promptr); + kentry(initrd.addr, initrd.size, promptr); /* console closed so printf below may not work */ printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); -- cgit v1.2.3 From 35af89eb491a0741005e474626053266e6e635b7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 21 Nov 2006 11:37:37 +1100 Subject: [POWERPC] Cleanup zImage handling of kernel entry with flat device tree This makes 2 changes to clean up the flat device tree handling logic in the zImage wrapper. First, there were two callbacks from the dt_ops structure used for producing a final flat tree to pass to the kerne: dt_ops.ft_pack() which packed the flat tree (possibly a no-op) and dt_ops.ft_addr() which retreived the address of the final blob. Since they were only ever called together, this patch combines the two into a single new callback, dt_ops.finalize(). This new callback does whatever platform-dependent things are necessary to produce a final flat device tree blob, and returns the blob's addres. Second, the current logic calls the kernel with a flat device tree if one is build into the zImage wrapper, otherwise it boots the kernel with a PROM pointer, expecting the kernel to copy the OF device tree itself. This approach precludes the possibility of the platform wrapper code building a flat device tree from whatever platform-specific information firmware provides. Thus, this patch takes the more sensible approach of invoking the kernel with a flat tree if the dt_ops.finalize callback provides one (by whatever means). So, the dt_ops.finalize callback can be NULL, or can be a function which returns NULL. In either case, the zImage wrapper logic assumes that this is a platform with OF and invokes the kernel accordingly. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- arch/powerpc/boot/flatdevtree_misc.c | 9 ++------- arch/powerpc/boot/main.c | 15 +++++++++++---- arch/powerpc/boot/ops.h | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c index c7f9adbf827..04da38fa477 100644 --- a/arch/powerpc/boot/flatdevtree_misc.c +++ b/arch/powerpc/boot/flatdevtree_misc.c @@ -33,13 +33,9 @@ static int ft_setprop(const void *phandle, const char *propname, return ft_set_prop(&cxt, phandle, propname, buf, buflen); } -static void ft_pack(void) +static unsigned long ft_finalize(void) { ft_end_tree(&cxt); -} - -static unsigned long ft_addr(void) -{ return (unsigned long)cxt.bph; } @@ -48,8 +44,7 @@ int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) dt_ops.finddevice = ft_finddevice; dt_ops.getprop = ft_getprop; dt_ops.setprop = ft_setprop; - dt_ops.ft_pack = ft_pack; - dt_ops.ft_addr = ft_addr; + dt_ops.finalize = ft_finalize; return ft_open(&cxt, dt_blob, max_size, max_find_device, platform_ops.realloc); diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index 630a453e16f..6f6b50d238b 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -298,6 +298,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) { kernel_entry_t kentry; char cmdline[COMMAND_LINE_SIZE]; + unsigned long ft_addr = 0; memset(__bss_start, 0, _end - __bss_start); memset(&platform_ops, 0, sizeof(platform_ops)); @@ -328,14 +329,20 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) set_cmdline(cmdline); } + printf("Finalizing device tree..."); + if (dt_ops.finalize) + ft_addr = dt_ops.finalize(); + if (ft_addr) + printf(" flat tree at 0x%lx\n\r", ft_addr); + else + printf(" using OF tree (promptr=%p)\n\r", promptr); + if (console_ops.close) console_ops.close(); kentry = (kernel_entry_t) vmlinux.addr; - if (_dtb_end > _dtb_start) { - dt_ops.ft_pack(); - kentry(dt_ops.ft_addr(), 0, NULL); - } + if (ft_addr) + kentry(ft_addr, 0, NULL); else /* XXX initrd addr/size should be passed in properties */ kentry(initrd.addr, initrd.size, promptr); diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 59832fb0f27..8abb6516bb7 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -35,8 +35,7 @@ struct dt_ops { const int buflen); int (*setprop)(const void *phandle, const char *name, const void *buf, const int buflen); - void (*ft_pack)(void); - unsigned long (*ft_addr)(void); + unsigned long (*finalize)(void); }; extern struct dt_ops dt_ops; -- cgit v1.2.3 From 9a06c3b176976919e223844f8ed9f1acae20b433 Mon Sep 17 00:00:00 2001 From: Adrian Cox Date: Fri, 17 Nov 2006 14:35:48 +0000 Subject: [POWERPC] Fix wraparound problem in smp-tbsync on 32-bit The patch below fixes an arithmetic wrap-around issue on 32bit machines using smp-tbsync. Without this patch a timebase value over 0x000000007fffffff will hang the boot process while bringing up secondary CPUs. Signed-off-by: Adrian Cox Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/smp-tbsync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index de59c6c31a5..e1970f83f14 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -78,7 +78,7 @@ static int __devinit start_contest(int cmd, long offset, int num) { int i, score=0; u64 tb; - long mark; + u64 mark; tbsync->cmd = cmd; -- cgit v1.2.3 From 4687522c0dba89f1f71aeb8cf08acc4e1ee87fda Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Fri, 17 Nov 2006 23:12:14 -0700 Subject: [POWERPC] Don't compile arch/powerpc mpc52xx_pic driver for ARCH=ppc arch/powerpc/sysdev/mpc52xx_pic.c breaks the ppc build Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 8ba11ab5e61..bae874626fc 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -11,11 +11,11 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ -obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_pic.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_83xx) += ipic.o +obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_pic.o endif # Temporary hack until we have migrated to asm-powerpc -- cgit v1.2.3 From adaa3a796282e2fa3bc48bc57bccd01ce891b8d2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 17 Nov 2006 06:21:12 +0100 Subject: [POWERPC] setup_kcore(): Fix incorrect function name in panic() call. Signed-off-by: Geert Uytterhoeven Signed-off-by: Paul Mackerras --- arch/powerpc/mm/init_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 3ff374697e3..9a178549cbc 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -130,7 +130,7 @@ static int __init setup_kcore(void) /* GFP_ATOMIC to avoid might_sleep warnings during boot */ kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); if (!kcore_mem) - panic("mem_init: kmalloc failed\n"); + panic("%s: kmalloc failed\n", __FUNCTION__); kclist_add(kcore_mem, __va(base), size); } -- cgit v1.2.3 From 78dc4c20de0f2cb2aa6d4542f965f889be6da775 Mon Sep 17 00:00:00 2001 From: Kalle Pokki Date: Sat, 11 Nov 2006 12:09:39 +0200 Subject: [POWERPC] 8xx: Off-by-one fixes to SCC parameter RAM definitions The SCC parameter RAM areas are mapped wrong in MPC8xx device descriptions. All memory areas overlap with the next one, so that I2C, SPI, SMC1 and SMC2 cannot be enabled if the four SCCs are. Signed-off-by: Kalle Pokki Acked-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/ppc/syslib/mpc8xx_devices.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c index cf5ab47487a..31fb56593d1 100644 --- a/arch/ppc/syslib/mpc8xx_devices.c +++ b/arch/ppc/syslib/mpc8xx_devices.c @@ -78,7 +78,7 @@ struct platform_device ppc_sys_platform_devices[] = { { .name = "pram", .start = 0x3c00, - .end = 0x3c80, + .end = 0x3c7f, .flags = IORESOURCE_MEM, }, { @@ -103,7 +103,7 @@ struct platform_device ppc_sys_platform_devices[] = { { .name = "pram", .start = 0x3d00, - .end = 0x3d80, + .end = 0x3d7f, .flags = IORESOURCE_MEM, }, @@ -129,7 +129,7 @@ struct platform_device ppc_sys_platform_devices[] = { { .name = "pram", .start = 0x3e00, - .end = 0x3e80, + .end = 0x3e7f, .flags = IORESOURCE_MEM, }, @@ -155,7 +155,7 @@ struct platform_device ppc_sys_platform_devices[] = { { .name = "pram", .start = 0x3f00, - .end = 0x3f80, + .end = 0x3f7f, .flags = IORESOURCE_MEM, }, -- cgit v1.2.3 From 9b5047e249f429722d0adc54cb5ef051bd3d685c Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Mon, 20 Nov 2006 18:44:57 +0100 Subject: [POWERPC] spufs: Change %llx to 0x%llx. This patches changes /npc, /decr, /decr_status, /spu_tag_mask, /event_mask, /event_status, and /srr0 files to provide output according to the format string "0x%llx" instead of "%llx". Before this patch some files used "0x%llx" and other used "%llx" which is inconsistent and potentially confusing. A user might assume "%llx" numbers were decimal if they happened to not contain any a-f digits. This change will break any code cannot tolerate a leading 0x in the file contents. The only known users of these files are the libspe but there might also be some scripts which access these files. This risk is deemed acceptable for future consistency. Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 0ea2361865a..7f126270667 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1391,7 +1391,8 @@ static u64 spufs_npc_get(void *data) spu_release(ctx); return ret; } -DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n") +DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, + "0x%llx\n") static void spufs_decr_set(void *data, u64 val) { @@ -1413,7 +1414,7 @@ static u64 spufs_decr_get(void *data) return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, - "%llx\n") + "0x%llx\n") static void spufs_decr_status_set(void *data, u64 val) { @@ -1435,7 +1436,7 @@ static u64 spufs_decr_status_get(void *data) return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, - spufs_decr_status_set, "%llx\n") + spufs_decr_status_set, "0x%llx\n") static void spufs_spu_tag_mask_set(void *data, u64 val) { @@ -1457,7 +1458,7 @@ static u64 spufs_spu_tag_mask_get(void *data) return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, - spufs_spu_tag_mask_set, "%llx\n") + spufs_spu_tag_mask_set, "0x%llx\n") static void spufs_event_mask_set(void *data, u64 val) { @@ -1479,7 +1480,7 @@ static u64 spufs_event_mask_get(void *data) return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, - spufs_event_mask_set, "%llx\n") + spufs_event_mask_set, "0x%llx\n") static void spufs_srr0_set(void *data, u64 val) { @@ -1501,7 +1502,7 @@ static u64 spufs_srr0_get(void *data) return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, - "%llx\n") + "0x%llx\n") static u64 spufs_id_get(void *data) { -- cgit v1.2.3 From b9e3bd774bb1a90fee9b90f461a51e4ba295fe6d Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Mon, 20 Nov 2006 18:44:58 +0100 Subject: [POWERPC] spufs: Add /lslr, /dma_info and /proxydma files The /lslr file gives read access to the SPU_LSLR register in hex; 0x3fff for example The /dma_info file provides read access to the SPU Command Queue in a binary format. The /proxydma_info files provides read access access to the Proxy Command Queue in a binary format. The spu_info.h file provides data structures for interpreting the binary format of /dma_info and /proxydma_info. Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/backing_ops.c | 1 + arch/powerpc/platforms/cell/spufs/file.c | 133 +++++++++++++++++++++++- arch/powerpc/platforms/cell/spufs/spufs.h | 9 +- 3 files changed, 137 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index 2d22cd59d6f..21b28f61b00 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "spufs.h" diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 7f126270667..5bfabffd117 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "spufs.h" @@ -1482,6 +1483,23 @@ static u64 spufs_event_mask_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, spufs_event_mask_set, "0x%llx\n") +static u64 spufs_event_status_get(void *data) +{ + struct spu_context *ctx = data; + struct spu_state *state = &ctx->csa; + u64 ret = 0; + u64 stat; + + spu_acquire_saved(ctx); + stat = state->spu_chnlcnt_RW[0]; + if (stat) + ret = state->spu_chnldata_RW[0]; + spu_release(ctx); + return ret; +} +DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, + NULL, "0x%llx\n") + static void spufs_srr0_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1535,6 +1553,109 @@ static void spufs_object_id_set(void *data, u64 id) DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, spufs_object_id_set, "0x%llx\n"); +static u64 spufs_lslr_get(void *data) +{ + struct spu_context *ctx = data; + u64 ret; + + spu_acquire_saved(ctx); + ret = ctx->csa.priv2.spu_lslr_RW; + spu_release(ctx); + + return ret; +} +DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n") + +static int spufs_info_open(struct inode *inode, struct file *file) +{ + struct spufs_inode_info *i = SPUFS_I(inode); + struct spu_context *ctx = i->i_ctx; + file->private_data = ctx; + return 0; +} + +static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + struct spu_dma_info info; + struct mfc_cq_sr *qp, *spuqp; + int i; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; + info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; + info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; + info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25]; + info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27]; + for (i = 0; i < 16; i++) { + qp = &info.dma_info_command_data[i]; + spuqp = &ctx->csa.priv2.spuq[i]; + + qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW; + qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW; + qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; + qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; + } + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + return simple_read_from_buffer(buf, len, pos, &info, + sizeof info); +} + +static struct file_operations spufs_dma_info_fops = { + .open = spufs_info_open, + .read = spufs_dma_info_read, +}; + +static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + struct spu_proxydma_info info; + int ret = sizeof info; + struct mfc_cq_sr *qp, *puqp; + int i; + + if (len < ret) + return -EINVAL; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; + info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; + info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; + for (i = 0; i < 8; i++) { + qp = &info.proxydma_info_command_data[i]; + puqp = &ctx->csa.priv2.puq[i]; + + qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW; + qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW; + qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; + qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; + } + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + if (copy_to_user(buf, &info, sizeof info)) + ret = -EFAULT; + + return ret; +} + +static struct file_operations spufs_proxydma_info_fops = { + .open = spufs_info_open, + .read = spufs_proxydma_info_read, +}; + struct tree_descr spufs_dir_contents[] = { { "mem", &spufs_mem_fops, 0666, }, { "regs", &spufs_regs_fops, 0666, }, @@ -1548,19 +1669,23 @@ struct tree_descr spufs_dir_contents[] = { { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, - { "mss", &spufs_mss_fops, 0666, }, - { "mfc", &spufs_mfc_fops, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, - { "npc", &spufs_npc_ops, 0666, }, { "fpcr", &spufs_fpcr_fops, 0666, }, + { "lslr", &spufs_lslr_ops, 0444, }, + { "mfc", &spufs_mfc_fops, 0666, }, + { "mss", &spufs_mss_fops, 0666, }, + { "npc", &spufs_npc_ops, 0666, }, + { "srr0", &spufs_srr0_ops, 0666, }, { "decr", &spufs_decr_ops, 0666, }, { "decr_status", &spufs_decr_status_ops, 0666, }, { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, - { "srr0", &spufs_srr0_ops, 0666, }, + { "event_status", &spufs_event_status_ops, 0444, }, { "psmap", &spufs_psmap_fops, 0666, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, + { "dma_info", &spufs_dma_info_fops, 0444, }, + { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, {}, }; diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index f438f0b8525..3e7cfc24614 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -29,6 +29,7 @@ #include #include +#include /* The magic number for our file system */ enum { @@ -119,8 +120,12 @@ struct spu_context_ops { int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); u32 (*read_mfc_tagstatus)(struct spu_context * ctx); u32 (*get_mfc_free_elements)(struct spu_context *ctx); - int (*send_mfc_command)(struct spu_context *ctx, - struct mfc_dma_command *cmd); + int (*send_mfc_command)(struct spu_context * ctx, + struct mfc_dma_command * cmd); + void (*dma_info_read) (struct spu_context * ctx, + struct spu_dma_info * info); + void (*proxydma_info_read) (struct spu_context * ctx, + struct spu_proxydma_info * info); }; extern struct spu_context_ops spu_hw_ops; -- cgit v1.2.3 From 1182e1d351d2a910bc0fb53c00277c62235333de Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Mon, 20 Nov 2006 18:44:59 +0100 Subject: [POWERPC] spufs: Remove /spu_tag_mask file This patch removes the /spu_tag_mask file from spufs. The data provided by this file is also available from the /dma_info file in the dma_info_mask of the spu_dma_info struct. The file was intended to be used by gdb, but that never used it, and now it has been replaced with the more verbose dma_info file. Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 5bfabffd117..20b2a7aed63 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1439,28 +1439,6 @@ static u64 spufs_decr_status_get(void *data) DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, spufs_decr_status_set, "0x%llx\n") -static void spufs_spu_tag_mask_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->tag_mask.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_spu_tag_mask_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->tag_mask.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, - spufs_spu_tag_mask_set, "0x%llx\n") - static void spufs_event_mask_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1678,7 +1656,6 @@ struct tree_descr spufs_dir_contents[] = { { "srr0", &spufs_srr0_ops, 0666, }, { "decr", &spufs_decr_ops, 0666, }, { "decr_status", &spufs_decr_status_ops, 0666, }, - { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, { "event_mask", &spufs_event_mask_ops, 0666, }, { "event_status", &spufs_event_status_ops, 0444, }, { "psmap", &spufs_psmap_fops, 0666, }, -- cgit v1.2.3 From 69a2f00ce5d3a19a70b36f08eaf9049677277710 Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Mon, 20 Nov 2006 18:45:00 +0100 Subject: [POWERPC] spufs: Implement /mbox_info, /ibox_info, and /wbox_info. This patch implements read only access to /mbox_info - SPU Write Outbound Mailbox /ibox_info - SPU Write Outbound Interrupt Mailbox /wbox_info - SPU Read Inbound Mailbox These files are used by gdb in order to look into the current mailbox queues without changing the contents at the same time. They are not meant for general programming use, since the access requires a context save and is therefore rather slow. It would be good to complement this patch with one that adds write support as well. Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 90 ++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 20b2a7aed63..2a2dd644101 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1552,6 +1552,93 @@ static int spufs_info_open(struct inode *inode, struct file *file) return 0; } +static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + u32 mbox_stat; + u32 data; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + mbox_stat = ctx->csa.prob.mb_stat_R; + if (mbox_stat & 0x0000ff) { + data = ctx->csa.prob.pu_mb_R; + } + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + return simple_read_from_buffer(buf, len, pos, &data, sizeof data); +} + +static struct file_operations spufs_mbox_info_fops = { + .open = spufs_info_open, + .read = spufs_mbox_info_read, + .llseek = generic_file_llseek, +}; + +static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + u32 ibox_stat; + u32 data; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + ibox_stat = ctx->csa.prob.mb_stat_R; + if (ibox_stat & 0xff0000) { + data = ctx->csa.priv2.puint_mb_R; + } + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + return simple_read_from_buffer(buf, len, pos, &data, sizeof data); +} + +static struct file_operations spufs_ibox_info_fops = { + .open = spufs_info_open, + .read = spufs_ibox_info_read, + .llseek = generic_file_llseek, +}; + +static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int i, cnt; + u32 data[4]; + u32 wbox_stat; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + wbox_stat = ctx->csa.prob.mb_stat_R; + cnt = (wbox_stat & 0x00ff00) >> 8; + for (i = 0; i < cnt; i++) { + data[i] = ctx->csa.spu_mailbox_data[i]; + } + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + return simple_read_from_buffer(buf, len, pos, &data, + cnt * sizeof(u32)); +} + +static struct file_operations spufs_wbox_info_fops = { + .open = spufs_info_open, + .read = spufs_wbox_info_read, + .llseek = generic_file_llseek, +}; + static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { @@ -1661,6 +1748,9 @@ struct tree_descr spufs_dir_contents[] = { { "psmap", &spufs_psmap_fops, 0666, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, + { "mbox_info", &spufs_mbox_info_fops, 0444, }, + { "ibox_info", &spufs_ibox_info_fops, 0444, }, + { "wbox_info", &spufs_wbox_info_fops, 0444, }, { "dma_info", &spufs_dma_info_fops, 0444, }, { "proxydma_info", &spufs_proxydma_info_fops, 0444, }, {}, -- cgit v1.2.3 From 17f88cebc2c3aff9d90f0d49f6e0628835eddc32 Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Mon, 20 Nov 2006 18:45:01 +0100 Subject: [POWERPC] spufs: Read from signal files only if data is there We need to check the channel count of the signal notification registers before reading them, because it can be undefined when the count is zero. In order to read count and data atomically, we read from the saved context. This patch uses spu_acquire_saved() to force a context save before a /signal1 or /signal2 read. Because of this it is no longer necessary to have backing_ops and hw_ops versions of this function so they have been removed. Regular applications should not rely on reading this register to be fast, as it's conceptually a write-only file from the PPE perspective. Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 30 ++++++++++++++++++++++-------- arch/powerpc/platforms/cell/spufs/hw_ops.c | 12 ------------ 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 2a2dd644101..c0cf9ee4d45 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -723,19 +723,27 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; + int ret = 0; u32 data; if (len < 4) return -EINVAL; - spu_acquire(ctx); - data = ctx->ops->signal1_read(ctx); + spu_acquire_saved(ctx); + if (ctx->csa.spu_chnlcnt_RW[3]) { + data = ctx->csa.spu_chnldata_RW[3]; + ret = 4; + } spu_release(ctx); + if (!ret) + goto out; + if (copy_to_user(buf, &data, 4)) return -EFAULT; - return 4; +out: + return ret; } static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, @@ -811,21 +819,27 @@ static int spufs_signal2_open(struct inode *inode, struct file *file) static ssize_t spufs_signal2_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx; + struct spu_context *ctx = file->private_data; + int ret = 0; u32 data; - ctx = file->private_data; - if (len < 4) return -EINVAL; - spu_acquire(ctx); - data = ctx->ops->signal2_read(ctx); + spu_acquire_saved(ctx); + if (ctx->csa.spu_chnlcnt_RW[4]) { + data = ctx->csa.spu_chnldata_RW[4]; + ret = 4; + } spu_release(ctx); + if (!ret) + goto out; + if (copy_to_user(buf, &data, 4)) return -EFAULT; +out: return 4; } diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index 59c87f12da5..79c304e815a 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -135,21 +135,11 @@ static int spu_hw_wbox_write(struct spu_context *ctx, u32 data) return ret; } -static u32 spu_hw_signal1_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->signal_notify1); -} - static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) { out_be32(&ctx->spu->problem->signal_notify1, data); } -static u32 spu_hw_signal2_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->signal_notify2); -} - static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) { out_be32(&ctx->spu->problem->signal_notify2, data); @@ -294,9 +284,7 @@ struct spu_context_ops spu_hw_ops = { .mbox_stat_poll = spu_hw_mbox_stat_poll, .ibox_read = spu_hw_ibox_read, .wbox_write = spu_hw_wbox_write, - .signal1_read = spu_hw_signal1_read, .signal1_write = spu_hw_signal1_write, - .signal2_read = spu_hw_signal2_read, .signal2_write = spu_hw_signal2_write, .signal1_type_set = spu_hw_signal1_type_set, .signal1_type_get = spu_hw_signal1_type_get, -- cgit v1.2.3 From 0021550c0199b2bf5e434eda0216144074537fc7 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Mon, 20 Nov 2006 18:45:02 +0100 Subject: [POWERPC] spufs: Replace spu.nid with spu.node Replace the use of the platform specific variable spu.nid with the platform independednt variable spu.node. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d5aeb3c6dd4..56ff8b36103 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -835,14 +835,14 @@ static int spu_create_sysdev(struct spu *spu) return ret; } - sysfs_add_device_to_node(&spu->sysdev, spu->nid); + sysfs_add_device_to_node(&spu->sysdev, spu->node); return 0; } static void spu_destroy_sysdev(struct spu *spu) { - sysfs_remove_device_from_node(&spu->sysdev, spu->nid); + sysfs_remove_device_from_node(&spu->sysdev, spu->node); sysdev_unregister(&spu->sysdev); } -- cgit v1.2.3 From 453d9f72a91d798c3e3c4b4bed26210926dfb57b Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Nov 2006 18:45:03 +0100 Subject: [POWERPC] spufs: Return correct event for data storage interrupt When we attempt an MFC DMA to an unmapped address, the event returned from spu_run should be SPE_EVENT_SPE_DATA_STORAGE, not SPE_EVENT_INVALID_DMA. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spu_base.c | 2 +- arch/powerpc/platforms/cell/spufs/run.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 56ff8b36103..d4f4f396288 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -507,7 +507,7 @@ int spu_irq_class_1_bottom(struct spu *spu) if (!error) { spu_restart_dma(spu); } else { - __spu_trap_invalid_dma(spu); + spu->dma_callback(spu, SPE_EVENT_SPE_DATA_STORAGE); } return ret; } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index a4a0080c223..88a41d83a79 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -26,6 +26,7 @@ void spufs_dma_callback(struct spu *spu, int type) } else { switch (type) { case SPE_EVENT_DMA_ALIGNMENT: + case SPE_EVENT_SPE_DATA_STORAGE: case SPE_EVENT_INVALID_DMA: force_sig(SIGBUS, /* info, */ current); break; -- cgit v1.2.3 From 2ebb2477f9a61b436dd22b75189857df1a77e585 Mon Sep 17 00:00:00 2001 From: Masato Noguchi Date: Mon, 20 Nov 2006 18:45:04 +0100 Subject: [POWERPC] spufs: Fix missing stop-and-signal When there is pending signals, current spufs_run_spu() always returns -ERESTARTSYS and it is called again automatically. But, if spe already stopped by stop-and-signal or halt instruction, returning -ERESTARTSYS makes stop-and-signal/halt lost and spu run over the end-point. For your convenience, I attached a sample code to restage this bug. If there is no bug, printed NPC will be 0x4000. Signed-off-by: Masato Noguchi Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/run.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 88a41d83a79..c88fd7f9ea7 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -79,13 +79,7 @@ static inline int spu_run_fini(struct spu_context *ctx, u32 * npc, if (signal_pending(current)) ret = -ERESTARTSYS; - if (unlikely(current->ptrace & PT_PTRACED)) { - if ((*status & SPU_STATUS_STOPPED_BY_STOP) - && (*status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { - force_sig(SIGTRAP, current); - ret = -ERESTARTSYS; - } - } + return ret; } @@ -232,7 +226,7 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { ret = spu_reacquire_runnable(ctx, npc, &status); if (ret) - goto out; + goto out2; continue; } ret = spu_process_events(ctx); @@ -242,10 +236,24 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, ctx->ops->runcntl_stop(ctx); ret = spu_run_fini(ctx, npc, &status); - if (!ret) - ret = status; spu_yield(ctx); +out2: + if ((ret == 0) || + ((ret == -ERESTARTSYS) && + ((status & SPU_STATUS_STOPPED_BY_HALT) || + ((status & SPU_STATUS_STOPPED_BY_STOP) && + (status >> SPU_STOP_STATUS_SHIFT != 0x2104))))) + ret = status; + + if (unlikely(current->ptrace & PT_PTRACED)) { + if ((status & SPU_STATUS_STOPPED_BY_STOP) + && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { + force_sig(SIGTRAP, current); + ret = -ERESTARTSYS; + } + } + out: *event = ctx->event_return; up(&ctx->run_sema); -- cgit v1.2.3 From 5c3ecd659bd20cda214a402a3132c790cc886cd2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 20 Nov 2006 18:45:05 +0100 Subject: [POWERPC] spufs: Avoid user-triggered oops in ptrace When one of the spufs files is mapped into a process address space, regular users can use ptrace to attempt accessing them with access_process_vm(). With the way that the mappings currently work, this likely causes an oops. Setting the vm_flags to VM_IO makes sure that ptrace can not access them but returns an error code. This is not the perfect solution in case of the local store mapping, but it fixes the oops in a well-defined way. Also remove leftover VM_RESERVED flags in spufs. The VM_RESERVED flag is on it's way out and not checked by the memory managment code anymore. Signed-off-by: Arnd Bergmann Signed-off-by: Christoph Hellwig Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index c0cf9ee4d45..55d7e0f4bb3 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -132,7 +132,7 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - /* FIXME: */ + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE); @@ -201,7 +201,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -791,7 +791,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -889,8 +889,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - /* FIXME: */ - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -973,7 +972,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -1015,7 +1014,7 @@ static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); @@ -1056,7 +1055,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma->vm_flags |= VM_RESERVED; + vma->vm_flags |= VM_IO; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | _PAGE_NO_CACHE | _PAGE_GUARDED); -- cgit v1.2.3 From 932f535dd4c83dc3eb631c2cee1dfd6ae289b88c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Nov 2006 18:45:06 +0100 Subject: [POWERPC] spufs: Always map local store non-guarded When fixing spufs to map the 'mem' file backing store cacheable, I incorrectly set the physical mapping to use both cache-inhibited and guarded mapping, which resulted in a serious performance degradation. Debugged-by: Michael Ellerman Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 55d7e0f4bb3..1c1af71d19c 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -105,11 +105,11 @@ spufs_mem_mmap_nopage(struct vm_area_struct *vma, if (ctx->state == SPU_STATE_SAVED) { vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - & ~(_PAGE_NO_CACHE | _PAGE_GUARDED)); + & ~_PAGE_NO_CACHE); page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); } else { vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE | _PAGE_GUARDED); + | _PAGE_NO_CACHE); page = pfn_to_page((ctx->spu->local_store_phys + offset) >> PAGE_SHIFT); } -- cgit v1.2.3 From 3692dc66149dc17cd82ec785a06478322c0eddff Mon Sep 17 00:00:00 2001 From: Masato Noguchi Date: Mon, 20 Nov 2006 18:45:07 +0100 Subject: [POWERPC] spufs: Fix return value of spufs_mfc_write This patch changes spufs_mfc_write() to return correct size instead of 0. Signed-off-by: Masato Noguchi Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 1c1af71d19c..e6667530332 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1279,6 +1279,7 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer, goto out; ctx->tagwait |= 1 << cmd.tag; + ret = size; out: return ret; -- cgit v1.2.3 From ee2d7340cbf3b123e1c3b7454f3e2b7e65d33bb2 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Nov 2006 18:45:08 +0100 Subject: [POWERPC] spufs: Use SPU master control to prevent wild SPU execution When the user changes the runcontrol register, an SPU might be running without a process being attached to it and waiting for events. In order to prevent this, make sure we always disable the priv1 master control when we're not inside of spu_run. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/backing_ops.c | 24 ++++++++++++-- arch/powerpc/platforms/cell/spufs/context.c | 42 ++++++++++++------------- arch/powerpc/platforms/cell/spufs/hw_ops.c | 28 ++++++++++++----- arch/powerpc/platforms/cell/spufs/inode.c | 15 +++++++-- arch/powerpc/platforms/cell/spufs/run.c | 3 +- arch/powerpc/platforms/cell/spufs/spufs.h | 3 +- 6 files changed, 79 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index 21b28f61b00..4a8e998c6be 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -280,9 +280,26 @@ static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val) spin_unlock(&ctx->csa.register_lock); } -static void spu_backing_runcntl_stop(struct spu_context *ctx) +static void spu_backing_master_start(struct spu_context *ctx) { - spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); + struct spu_state *csa = &ctx->csa; + u64 sr1; + + spin_lock(&csa->register_lock); + sr1 = csa->priv1.mfc_sr1_RW | MFC_STATE1_MASTER_RUN_CONTROL_MASK; + csa->priv1.mfc_sr1_RW = sr1; + spin_unlock(&csa->register_lock); +} + +static void spu_backing_master_stop(struct spu_context *ctx) +{ + struct spu_state *csa = &ctx->csa; + u64 sr1; + + spin_lock(&csa->register_lock); + sr1 = csa->priv1.mfc_sr1_RW & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; + csa->priv1.mfc_sr1_RW = sr1; + spin_unlock(&csa->register_lock); } static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask, @@ -347,7 +364,8 @@ struct spu_context_ops spu_backing_ops = { .status_read = spu_backing_status_read, .get_ls = spu_backing_get_ls, .runcntl_write = spu_backing_runcntl_write, - .runcntl_stop = spu_backing_runcntl_stop, + .master_start = spu_backing_master_start, + .master_stop = spu_backing_master_stop, .set_mfc_query = spu_backing_set_mfc_query, .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus, .get_mfc_free_elements = spu_backing_get_mfc_free_elements, diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 48eb050bcf4..0870009f56d 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -122,29 +122,29 @@ void spu_unmap_mappings(struct spu_context *ctx) int spu_acquire_exclusive(struct spu_context *ctx) { - int ret = 0; - - down_write(&ctx->state_sema); - /* ctx is about to be freed, can't acquire any more */ - if (!ctx->owner) { - ret = -EINVAL; - goto out; - } - - if (ctx->state == SPU_STATE_SAVED) { - ret = spu_activate(ctx, 0); - if (ret) - goto out; - ctx->state = SPU_STATE_RUNNABLE; - } else { - /* We need to exclude userspace access to the context. */ - spu_unmap_mappings(ctx); - } + int ret = 0; + + down_write(&ctx->state_sema); + /* ctx is about to be freed, can't acquire any more */ + if (!ctx->owner) { + ret = -EINVAL; + goto out; + } + + if (ctx->state == SPU_STATE_SAVED) { + ret = spu_activate(ctx, 0); + if (ret) + goto out; + ctx->state = SPU_STATE_RUNNABLE; + } else { + /* We need to exclude userspace access to the context. */ + spu_unmap_mappings(ctx); + } out: - if (ret) - up_write(&ctx->state_sema); - return ret; + if (ret) + up_write(&ctx->state_sema); + return ret; } int spu_acquire_runnable(struct spu_context *ctx) diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index 79c304e815a..69fc342e063 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -216,13 +216,26 @@ static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) spin_unlock_irq(&ctx->spu->register_lock); } -static void spu_hw_runcntl_stop(struct spu_context *ctx) +static void spu_hw_master_start(struct spu_context *ctx) { - spin_lock_irq(&ctx->spu->register_lock); - out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP); - while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING) - cpu_relax(); - spin_unlock_irq(&ctx->spu->register_lock); + struct spu *spu = ctx->spu; + u64 sr1; + + spin_lock_irq(&spu->register_lock); + sr1 = spu_mfc_sr1_get(spu) | MFC_STATE1_MASTER_RUN_CONTROL_MASK; + spu_mfc_sr1_set(spu, sr1); + spin_unlock_irq(&spu->register_lock); +} + +static void spu_hw_master_stop(struct spu_context *ctx) +{ + struct spu *spu = ctx->spu; + u64 sr1; + + spin_lock_irq(&spu->register_lock); + sr1 = spu_mfc_sr1_get(spu) & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK; + spu_mfc_sr1_set(spu, sr1); + spin_unlock_irq(&spu->register_lock); } static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) @@ -295,7 +308,8 @@ struct spu_context_ops spu_hw_ops = { .status_read = spu_hw_status_read, .get_ls = spu_hw_get_ls, .runcntl_write = spu_hw_runcntl_write, - .runcntl_stop = spu_hw_runcntl_stop, + .master_start = spu_hw_master_start, + .master_stop = spu_hw_master_stop, .set_mfc_query = spu_hw_set_mfc_query, .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus, .get_mfc_free_elements = spu_hw_get_mfc_free_elements, diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 9e457be140e..1fbcc536924 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -248,8 +248,13 @@ static int spu_setup_isolated(struct spu_context *ctx) if (!isolated_loader) return -ENODEV; - if ((ret = spu_acquire_exclusive(ctx)) != 0) - return ret; + /* prevent concurrent operation with spu_run */ + down(&ctx->run_sema); + ctx->ops->master_start(ctx); + + ret = spu_acquire_exclusive(ctx); + if (ret) + goto out; mfc_cntl = &ctx->spu->priv2->mfc_control_RW; @@ -315,12 +320,14 @@ out_drop_priv: out_unlock: spu_release_exclusive(ctx); +out: + ctx->ops->master_stop(ctx); + up(&ctx->run_sema); return ret; } int spu_recycle_isolated(struct spu_context *ctx) { - ctx->ops->runcntl_stop(ctx); return spu_setup_isolated(ctx); } @@ -435,6 +442,8 @@ out: if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) { int setup_err = spu_setup_isolated( SPUFS_I(dentry->d_inode)->i_ctx); + /* FIXME: clean up context again on failure to avoid + leak. */ if (setup_err) ret = setup_err; } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index c88fd7f9ea7..212b9c2f04a 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -207,6 +207,7 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, if (down_interruptible(&ctx->run_sema)) return -ERESTARTSYS; + ctx->ops->master_start(ctx); ctx->event_return = 0; ret = spu_run_init(ctx, npc); if (ret) @@ -234,7 +235,7 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx, } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_STOPPED_BY_HALT))); - ctx->ops->runcntl_stop(ctx); + ctx->ops->master_stop(ctx); ret = spu_run_fini(ctx, npc, &status); spu_yield(ctx); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 3e7cfc24614..135fbb53d8e 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -116,7 +116,8 @@ struct spu_context_ops { u32(*status_read) (struct spu_context * ctx); char*(*get_ls) (struct spu_context * ctx); void (*runcntl_write) (struct spu_context * ctx, u32 data); - void (*runcntl_stop) (struct spu_context * ctx); + void (*master_start) (struct spu_context * ctx); + void (*master_stop) (struct spu_context * ctx); int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); u32 (*read_mfc_tagstatus)(struct spu_context * ctx); u32 (*get_mfc_free_elements)(struct spu_context *ctx); -- cgit v1.2.3 From 3960c260204bc33404a6e54e9dcd44f1f83bc701 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 20 Nov 2006 18:45:09 +0100 Subject: [POWERPC] spufs: Add runcntrl read accessors This change adds a read accessor for the SPE problem-state run control register. This is required for for applying (userspace) changes made to the run control register while the SPE is stopped - simply asserting the master run control bit is not sufficient. My next patch for isolated-mode setup requires this. Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/backing_ops.c | 6 ++++++ arch/powerpc/platforms/cell/spufs/hw_ops.c | 6 ++++++ arch/powerpc/platforms/cell/spufs/spufs.h | 1 + 3 files changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index 4a8e998c6be..1898f0d3a8b 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -268,6 +268,11 @@ static char *spu_backing_get_ls(struct spu_context *ctx) return ctx->csa.lscsa->ls; } +static u32 spu_backing_runcntl_read(struct spu_context *ctx) +{ + return ctx->csa.prob.spu_runcntl_RW; +} + static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val) { spin_lock(&ctx->csa.register_lock); @@ -363,6 +368,7 @@ struct spu_context_ops spu_backing_ops = { .npc_write = spu_backing_npc_write, .status_read = spu_backing_status_read, .get_ls = spu_backing_get_ls, + .runcntl_read = spu_backing_runcntl_read, .runcntl_write = spu_backing_runcntl_write, .master_start = spu_backing_master_start, .master_stop = spu_backing_master_stop, diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index 69fc342e063..ae42e03b8c8 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c @@ -207,6 +207,11 @@ static char *spu_hw_get_ls(struct spu_context *ctx) return ctx->spu->local_store; } +static u32 spu_hw_runcntl_read(struct spu_context *ctx) +{ + return in_be32(&ctx->spu->problem->spu_runcntl_RW); +} + static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) { spin_lock_irq(&ctx->spu->register_lock); @@ -307,6 +312,7 @@ struct spu_context_ops spu_hw_ops = { .npc_write = spu_hw_npc_write, .status_read = spu_hw_status_read, .get_ls = spu_hw_get_ls, + .runcntl_read = spu_hw_runcntl_read, .runcntl_write = spu_hw_runcntl_write, .master_start = spu_hw_master_start, .master_stop = spu_hw_master_stop, diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 135fbb53d8e..ca56b9b11c1 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -115,6 +115,7 @@ struct spu_context_ops { void (*npc_write) (struct spu_context * ctx, u32 data); u32(*status_read) (struct spu_context * ctx); char*(*get_ls) (struct spu_context * ctx); + u32 (*runcntl_read) (struct spu_context * ctx); void (*runcntl_write) (struct spu_context * ctx, u32 data); void (*master_start) (struct spu_context * ctx); void (*master_stop) (struct spu_context * ctx); -- cgit v1.2.3 From c6730ed4c280ff9e55766796523c94a7d111da09 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 20 Nov 2006 18:45:10 +0100 Subject: [POWERPC] spufs: Load isolation kernel from spu_run In order to fit with the "don't-run-spus-outside-of-spu_run" model, this patch starts the isolated-mode loader in spu_run, rather than spu_create. If spu_run is passed an isolated-mode context that isn't in isolated mode state, it will run the loader. This fixes potential races with the isolated SPE app doing a stop-and-signal before the PPE has called spu_run: bugzilla #29111. Also (in conjunction with a mambo patch), this addresses #28565, as we always set the runcntrl register when entering spu_run. It is up to libspe to ensure that isolated-mode apps are cleaned up after running to completion - ie, put the app through the "ISOLATE EXIT" state (see Ch11 of the CBEA). Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/file.c | 32 -------- arch/powerpc/platforms/cell/spufs/inode.c | 109 +--------------------------- arch/powerpc/platforms/cell/spufs/run.c | 117 ++++++++++++++++++++++++++++-- arch/powerpc/platforms/cell/spufs/spufs.h | 3 +- 4 files changed, 113 insertions(+), 148 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index e6667530332..50e0afc46ad 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -1358,37 +1358,6 @@ static struct file_operations spufs_mfc_fops = { .mmap = spufs_mfc_mmap, }; - -static int spufs_recycle_open(struct inode *inode, struct file *file) -{ - file->private_data = SPUFS_I(inode)->i_ctx; - return nonseekable_open(inode, file); -} - -static ssize_t spufs_recycle_write(struct file *file, - const char __user *buffer, size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - int ret; - - if (!(ctx->flags & SPU_CREATE_ISOLATE)) - return -EINVAL; - - if (size < 1) - return -EINVAL; - - ret = spu_recycle_isolated(ctx); - - if (ret) - return ret; - return size; -} - -static struct file_operations spufs_recycle_fops = { - .open = spufs_recycle_open, - .write = spufs_recycle_write, -}; - static void spufs_npc_set(void *data, u64 val) { struct spu_context *ctx = data; @@ -1789,6 +1758,5 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "psmap", &spufs_psmap_fops, 0666, }, { "phys-id", &spufs_id_ops, 0666, }, { "object-id", &spufs_object_id_ops, 0666, }, - { "recycle", &spufs_recycle_fops, 0222, }, {}, }; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 1fbcc536924..d5f0a21a19d 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -34,8 +34,6 @@ #include #include -#include -#include #include #include #include @@ -43,7 +41,7 @@ #include "spufs.h" static kmem_cache_t *spufs_inode_cache; -static char *isolated_loader; +char *isolated_loader; static struct inode * spufs_alloc_inode(struct super_block *sb) @@ -235,102 +233,6 @@ struct file_operations spufs_context_fops = { .fsync = simple_sync_file, }; -static int spu_setup_isolated(struct spu_context *ctx) -{ - int ret; - u64 __iomem *mfc_cntl; - u64 sr1; - u32 status; - unsigned long timeout; - const u32 status_loading = SPU_STATUS_RUNNING - | SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS; - - if (!isolated_loader) - return -ENODEV; - - /* prevent concurrent operation with spu_run */ - down(&ctx->run_sema); - ctx->ops->master_start(ctx); - - ret = spu_acquire_exclusive(ctx); - if (ret) - goto out; - - mfc_cntl = &ctx->spu->priv2->mfc_control_RW; - - /* purge the MFC DMA queue to ensure no spurious accesses before we - * enter kernel mode */ - timeout = jiffies + HZ; - out_be64(mfc_cntl, MFC_CNTL_PURGE_DMA_REQUEST); - while ((in_be64(mfc_cntl) & MFC_CNTL_PURGE_DMA_STATUS_MASK) - != MFC_CNTL_PURGE_DMA_COMPLETE) { - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n", - __FUNCTION__); - ret = -EIO; - goto out_unlock; - } - cond_resched(); - } - - /* put the SPE in kernel mode to allow access to the loader */ - sr1 = spu_mfc_sr1_get(ctx->spu); - sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK; - spu_mfc_sr1_set(ctx->spu, sr1); - - /* start the loader */ - ctx->ops->signal1_write(ctx, (unsigned long)isolated_loader >> 32); - ctx->ops->signal2_write(ctx, - (unsigned long)isolated_loader & 0xffffffff); - - ctx->ops->runcntl_write(ctx, - SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); - - ret = 0; - timeout = jiffies + HZ; - while (((status = ctx->ops->status_read(ctx)) & status_loading) == - status_loading) { - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "%s: timeout waiting for loader\n", - __FUNCTION__); - ret = -EIO; - goto out_drop_priv; - } - cond_resched(); - } - - if (!(status & SPU_STATUS_RUNNING)) { - /* If isolated LOAD has failed: run SPU, we will get a stop-and - * signal later. */ - pr_debug("%s: isolated LOAD failed\n", __FUNCTION__); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); - ret = -EACCES; - - } else if (!(status & SPU_STATUS_ISOLATED_STATE)) { - /* This isn't allowed by the CBEA, but check anyway */ - pr_debug("%s: SPU fell out of isolated mode?\n", __FUNCTION__); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_STOP); - ret = -EINVAL; - } - -out_drop_priv: - /* Finished accessing the loader. Drop kernel mode */ - sr1 |= MFC_STATE1_PROBLEM_STATE_MASK; - spu_mfc_sr1_set(ctx->spu, sr1); - -out_unlock: - spu_release_exclusive(ctx); -out: - ctx->ops->master_stop(ctx); - up(&ctx->run_sema); - return ret; -} - -int spu_recycle_isolated(struct spu_context *ctx) -{ - return spu_setup_isolated(ctx); -} - static int spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, int mode) @@ -439,15 +341,6 @@ static int spufs_create_context(struct inode *inode, out_unlock: mutex_unlock(&inode->i_mutex); out: - if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) { - int setup_err = spu_setup_isolated( - SPUFS_I(dentry->d_inode)->i_ctx); - /* FIXME: clean up context again on failure to avoid - leak. */ - if (setup_err) - ret = setup_err; - } - dput(dentry); return ret; } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 212b9c2f04a..1be4e3339d8 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include "spufs.h" @@ -51,21 +53,122 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat) return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; } +static int spu_setup_isolated(struct spu_context *ctx) +{ + int ret; + u64 __iomem *mfc_cntl; + u64 sr1; + u32 status; + unsigned long timeout; + const u32 status_loading = SPU_STATUS_RUNNING + | SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS; + + if (!isolated_loader) + return -ENODEV; + + ret = spu_acquire_exclusive(ctx); + if (ret) + goto out; + + mfc_cntl = &ctx->spu->priv2->mfc_control_RW; + + /* purge the MFC DMA queue to ensure no spurious accesses before we + * enter kernel mode */ + timeout = jiffies + HZ; + out_be64(mfc_cntl, MFC_CNTL_PURGE_DMA_REQUEST); + while ((in_be64(mfc_cntl) & MFC_CNTL_PURGE_DMA_STATUS_MASK) + != MFC_CNTL_PURGE_DMA_COMPLETE) { + if (time_after(jiffies, timeout)) { + printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n", + __FUNCTION__); + ret = -EIO; + goto out_unlock; + } + cond_resched(); + } + + /* put the SPE in kernel mode to allow access to the loader */ + sr1 = spu_mfc_sr1_get(ctx->spu); + sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK; + spu_mfc_sr1_set(ctx->spu, sr1); + + /* start the loader */ + ctx->ops->signal1_write(ctx, (unsigned long)isolated_loader >> 32); + ctx->ops->signal2_write(ctx, + (unsigned long)isolated_loader & 0xffffffff); + + ctx->ops->runcntl_write(ctx, + SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); + + ret = 0; + timeout = jiffies + HZ; + while (((status = ctx->ops->status_read(ctx)) & status_loading) == + status_loading) { + if (time_after(jiffies, timeout)) { + printk(KERN_ERR "%s: timeout waiting for loader\n", + __FUNCTION__); + ret = -EIO; + goto out_drop_priv; + } + cond_resched(); + } + + if (!(status & SPU_STATUS_RUNNING)) { + /* If isolated LOAD has failed: run SPU, we will get a stop-and + * signal later. */ + pr_debug("%s: isolated LOAD failed\n", __FUNCTION__); + ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); + ret = -EACCES; + + } else if (!(status & SPU_STATUS_ISOLATED_STATE)) { + /* This isn't allowed by the CBEA, but check anyway */ + pr_debug("%s: SPU fell out of isolated mode?\n", __FUNCTION__); + ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_STOP); + ret = -EINVAL; + } + +out_drop_priv: + /* Finished accessing the loader. Drop kernel mode */ + sr1 |= MFC_STATE1_PROBLEM_STATE_MASK; + spu_mfc_sr1_set(ctx->spu, sr1); + +out_unlock: + spu_release_exclusive(ctx); +out: + return ret; +} + static inline int spu_run_init(struct spu_context *ctx, u32 * npc) { int ret; unsigned long runcntl = SPU_RUNCNTL_RUNNABLE; - if ((ret = spu_acquire_runnable(ctx)) != 0) + ret = spu_acquire_runnable(ctx); + if (ret) return ret; - /* if we're in isolated mode, we would have started the SPU - * earlier, so don't do it again now. */ - if (!(ctx->flags & SPU_CREATE_ISOLATE)) { + if (ctx->flags & SPU_CREATE_ISOLATE) { + if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) { + /* Need to release ctx, because spu_setup_isolated will + * acquire it exclusively. + */ + spu_release(ctx); + ret = spu_setup_isolated(ctx); + if (!ret) + ret = spu_acquire_runnable(ctx); + } + + /* if userspace has set the runcntrl register (eg, to issue an + * isolated exit), we need to re-set it here */ + runcntl = ctx->ops->runcntl_read(ctx) & + (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); + if (runcntl == 0) + runcntl = SPU_RUNCNTL_RUNNABLE; + } else ctx->ops->npc_write(ctx, *npc); - ctx->ops->runcntl_write(ctx, runcntl); - } - return 0; + + ctx->ops->runcntl_write(ctx, runcntl); + return ret; } static inline int spu_run_fini(struct spu_context *ctx, u32 * npc, diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index ca56b9b11c1..23d20f38056 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -183,7 +183,8 @@ void spu_yield(struct spu_context *ctx); int __init spu_sched_init(void); void __exit spu_sched_exit(void); -int spu_recycle_isolated(struct spu_context *ctx); +extern char *isolated_loader; + /* * spufs_wait * Same as wait_event_interruptible(), except that here -- cgit v1.2.3 From 5231800c6fb99c106951a5e1a8e739ad9657e93f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Nov 2006 18:45:12 +0100 Subject: [POWERPC] cell: Add symbol exports for oprofile Add symbol-exports for the new routines in arch/powerpc/platforms/cell/pmu.c. They are needed for Oprofile, which can be built as a module. Signed-off-by: Kevin Corry Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/pmu.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 30d17ce236a..22ac732b1f8 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -85,6 +85,7 @@ u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr) return val; } +EXPORT_SYMBOL_GPL(cbe_read_phys_ctr); void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) { @@ -111,6 +112,7 @@ void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) } } } +EXPORT_SYMBOL_GPL(cbe_write_phys_ctr); /* * "Logical" counter registers. @@ -130,6 +132,7 @@ u32 cbe_read_ctr(u32 cpu, u32 ctr) return val; } +EXPORT_SYMBOL_GPL(cbe_read_ctr); void cbe_write_ctr(u32 cpu, u32 ctr, u32 val) { @@ -149,6 +152,7 @@ void cbe_write_ctr(u32 cpu, u32 ctr, u32 val) cbe_write_phys_ctr(cpu, phys_ctr, val); } +EXPORT_SYMBOL_GPL(cbe_write_ctr); /* * Counter-control registers. @@ -164,12 +168,14 @@ u32 cbe_read_pm07_control(u32 cpu, u32 ctr) return pm07_control; } +EXPORT_SYMBOL_GPL(cbe_read_pm07_control); void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val) { if (ctr < NR_CTRS) WRITE_WO_MMIO(pm07_control[ctr], val); } +EXPORT_SYMBOL_GPL(cbe_write_pm07_control); /* * Other PMU control registers. Most of these are write-only. @@ -215,6 +221,7 @@ u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg) return val; } +EXPORT_SYMBOL_GPL(cbe_read_pm); void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) { @@ -252,6 +259,7 @@ void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) break; } } +EXPORT_SYMBOL_GPL(cbe_write_pm); /* * Get/set the size of a physical counter to either 16 or 32 bits. @@ -268,6 +276,7 @@ u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr) return size; } +EXPORT_SYMBOL_GPL(cbe_get_ctr_size); void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) { @@ -287,6 +296,7 @@ void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) cbe_write_pm(cpu, pm_control, pm_ctrl); } } +EXPORT_SYMBOL_GPL(cbe_set_ctr_size); /* * Enable/disable the entire performance monitoring unit. @@ -304,6 +314,7 @@ void cbe_enable_pm(u32 cpu) pm_ctrl = cbe_read_pm(cpu, pm_control) | CBE_PM_ENABLE_PERF_MON; cbe_write_pm(cpu, pm_control, pm_ctrl); } +EXPORT_SYMBOL_GPL(cbe_enable_pm); void cbe_disable_pm(u32 cpu) { @@ -311,6 +322,7 @@ void cbe_disable_pm(u32 cpu) pm_ctrl = cbe_read_pm(cpu, pm_control) & ~CBE_PM_ENABLE_PERF_MON; cbe_write_pm(cpu, pm_control, pm_ctrl); } +EXPORT_SYMBOL_GPL(cbe_disable_pm); /* * Reading from the trace_buffer. @@ -325,4 +337,5 @@ void cbe_read_trace_buffer(u32 cpu, u64 *buf) *buf++ = in_be64(&pmd_regs->trace_buffer_0_63); *buf++ = in_be64(&pmd_regs->trace_buffer_64_127); } +EXPORT_SYMBOL_GPL(cbe_read_trace_buffer); -- cgit v1.2.3 From c93dfa0766bae3c92ec8311bddbbf16b8e661f59 Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Mon, 20 Nov 2006 18:45:13 +0100 Subject: [POWERPC] cell: PMU register macros More macros for manipulating bits in the Cell PMU control registers. Signed-off-by: Kevin Corry Signed-off-by: Carl Love Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_regs.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index 91083f51a0c..bc94e664c61 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -38,7 +38,28 @@ /* Macros for the pm_control register. */ #define CBE_PM_16BIT_CTR(ctr) (1 << (24 - ((ctr) & (NR_PHYS_CTRS - 1)))) #define CBE_PM_ENABLE_PERF_MON 0x80000000 - +#define CBE_PM_STOP_AT_MAX 0x40000000 +#define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3) +#define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28) +#define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18) +#define CBE_PM_FREEZE_ALL_CTRS 0x00100000 +#define CBE_PM_ENABLE_EXT_TRACE 0x00008000 + +/* Macros for the trace_address register. */ +#define CBE_PM_TRACE_BUF_FULL 0x00000800 +#define CBE_PM_TRACE_BUF_EMPTY 0x00000400 +#define CBE_PM_TRACE_BUF_DATA_COUNT(ta) ((ta) & 0x3ff) +#define CBE_PM_TRACE_BUF_MAX_COUNT 0x400 + +/* Macros for the pm07_control registers. */ +#define CBE_PM_CTR_INPUT_MUX(pm07_control) (((pm07_control) >> 26) & 0x3f) +#define CBE_PM_CTR_INPUT_CONTROL 0x02000000 +#define CBE_PM_CTR_POLARITY 0x01000000 +#define CBE_PM_CTR_COUNT_CYCLES 0x00800000 +#define CBE_PM_CTR_ENABLE 0x00400000 + +/* Macros for the pm_status register. */ +#define CBE_PM_CTR_OVERFLOW_INTR(ctr) (1 << (31 - ((ctr) & 7))) union spe_reg { u64 val; -- cgit v1.2.3 From e4f6948cfc8b9626022db0f93e7cf2ce5c0998cd Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Mon, 20 Nov 2006 18:45:14 +0100 Subject: [POWERPC] cell: Move PMU-related stuff to include/asm-powerpc/cell-pmu.h Move some PMU-related macros and function prototypes from cbe_regs.h and pmu.h in arch/powerpc/platforms/cell/ to a new header at include/asm-powerpc/cell-pmu.h This is cleaner to use from the oprofile code, since that sits in arch/powerpc/oprofile, not in the cell platform directory. Signed-off-by: Kevin Corry Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_regs.h | 31 ++---------------- arch/powerpc/platforms/cell/pmu.c | 1 - arch/powerpc/platforms/cell/pmu.h | 57 ---------------------------------- 3 files changed, 2 insertions(+), 87 deletions(-) delete mode 100644 arch/powerpc/platforms/cell/pmu.h (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index bc94e664c61..a29f4a5f52c 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -15,6 +15,8 @@ #ifndef CBE_REGS_H #define CBE_REGS_H +#include + /* * * Some HID register definitions @@ -35,32 +37,6 @@ * */ -/* Macros for the pm_control register. */ -#define CBE_PM_16BIT_CTR(ctr) (1 << (24 - ((ctr) & (NR_PHYS_CTRS - 1)))) -#define CBE_PM_ENABLE_PERF_MON 0x80000000 -#define CBE_PM_STOP_AT_MAX 0x40000000 -#define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3) -#define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28) -#define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18) -#define CBE_PM_FREEZE_ALL_CTRS 0x00100000 -#define CBE_PM_ENABLE_EXT_TRACE 0x00008000 - -/* Macros for the trace_address register. */ -#define CBE_PM_TRACE_BUF_FULL 0x00000800 -#define CBE_PM_TRACE_BUF_EMPTY 0x00000400 -#define CBE_PM_TRACE_BUF_DATA_COUNT(ta) ((ta) & 0x3ff) -#define CBE_PM_TRACE_BUF_MAX_COUNT 0x400 - -/* Macros for the pm07_control registers. */ -#define CBE_PM_CTR_INPUT_MUX(pm07_control) (((pm07_control) >> 26) & 0x3f) -#define CBE_PM_CTR_INPUT_CONTROL 0x02000000 -#define CBE_PM_CTR_POLARITY 0x01000000 -#define CBE_PM_CTR_COUNT_CYCLES 0x00800000 -#define CBE_PM_CTR_ENABLE 0x00400000 - -/* Macros for the pm_status register. */ -#define CBE_PM_CTR_OVERFLOW_INTR(ctr) (1 << (31 - ((ctr) & 7))) - union spe_reg { u64 val; u8 spe[8]; @@ -160,9 +136,6 @@ extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu); * counters currently have a value waiting to be written. */ -#define NR_PHYS_CTRS 4 -#define NR_CTRS (NR_PHYS_CTRS * 2) - struct cbe_pmd_shadow_regs { u32 group_control; u32 debug_bus_control; diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 22ac732b1f8..ae6fd1c12d4 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -30,7 +30,6 @@ #include "cbe_regs.h" #include "interrupt.h" -#include "pmu.h" /* * When writing to write-only mmio addresses, save a shadow copy. All of the diff --git a/arch/powerpc/platforms/cell/pmu.h b/arch/powerpc/platforms/cell/pmu.h deleted file mode 100644 index eb1e8e0af91..00000000000 --- a/arch/powerpc/platforms/cell/pmu.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Cell Broadband Engine Performance Monitor - * - * (C) Copyright IBM Corporation 2001,2006 - * - * Author: - * David Erb (djerb@us.ibm.com) - * Kevin Corry (kevcorry@us.ibm.com) - * - * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef __PERFMON_H__ -#define __PERFMON_H__ - -enum pm_reg_name { - group_control, - debug_bus_control, - trace_address, - ext_tr_timer, - pm_status, - pm_control, - pm_interval, - pm_start_stop, -}; - -extern u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr); -extern void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val); -extern u32 cbe_read_ctr(u32 cpu, u32 ctr); -extern void cbe_write_ctr(u32 cpu, u32 ctr, u32 val); - -extern u32 cbe_read_pm07_control(u32 cpu, u32 ctr); -extern void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val); -extern u32 cbe_read_pm (u32 cpu, enum pm_reg_name reg); -extern void cbe_write_pm (u32 cpu, enum pm_reg_name reg, u32 val); - -extern u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr); -extern void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size); - -extern void cbe_enable_pm(u32 cpu); -extern void cbe_disable_pm(u32 cpu); - -extern void cbe_read_trace_buffer(u32 cpu, u64 *buf); - -#endif -- cgit v1.2.3 From 0443bbd3d8496f9c2bc3e8c9d1833c6638722743 Mon Sep 17 00:00:00 2001 From: Kevin Corry Date: Mon, 20 Nov 2006 18:45:15 +0100 Subject: [POWERPC] cell: Add routines for managing PMU interrupts The following routines are added to arch/powerpc/platforms/cell/pmu.c: cbe_clear_pm_interrupts() cbe_enable_pm_interrupts() cbe_disable_pm_interrupts() cbe_query_pm_interrupts() cbe_pm_irq() cbe_init_pm_irq() This also adds a routine in arch/powerpc/platforms/cell/interrupt.c and some macros in cbe_regs.h to manipulate the IIC_IR register: iic_set_interrupt_routing() Signed-off-by: Kevin Corry Signed-off-by: Carl Love Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_regs.h | 8 ++++ arch/powerpc/platforms/cell/interrupt.c | 16 ++++++++ arch/powerpc/platforms/cell/interrupt.h | 2 + arch/powerpc/platforms/cell/pmu.c | 70 +++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index a29f4a5f52c..440a7ecc66e 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -185,6 +185,14 @@ struct cbe_iic_regs { struct cbe_iic_thread_regs thread[2]; /* 0x0400 */ u64 iic_ir; /* 0x0440 */ +#define CBE_IIC_IR_PRIO(x) (((x) & 0xf) << 12) +#define CBE_IIC_IR_DEST_NODE(x) (((x) & 0xf) << 4) +#define CBE_IIC_IR_DEST_UNIT(x) ((x) & 0xf) +#define CBE_IIC_IR_IOC_0 0x0 +#define CBE_IIC_IR_IOC_1S 0xb +#define CBE_IIC_IR_PT_0 0xe +#define CBE_IIC_IR_PT_1 0xf + u64 iic_is; /* 0x0448 */ #define CBE_IIC_IS_PMI 0x2 diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index a914c12b406..6666d037eb4 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c @@ -396,3 +396,19 @@ void __init iic_init_IRQ(void) /* Enable on current CPU */ iic_setup_cpu(); } + +void iic_set_interrupt_routing(int cpu, int thread, int priority) +{ + struct cbe_iic_regs __iomem *iic_regs = cbe_get_cpu_iic_regs(cpu); + u64 iic_ir = 0; + int node = cpu >> 1; + + /* Set which node and thread will handle the next interrupt */ + iic_ir |= CBE_IIC_IR_PRIO(priority) | + CBE_IIC_IR_DEST_NODE(node); + if (thread == 0) + iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_0); + else + iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_1); + out_be64(&iic_regs->iic_ir, iic_ir); +} diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h index 9ba1d3c17b4..942dc39d604 100644 --- a/arch/powerpc/platforms/cell/interrupt.h +++ b/arch/powerpc/platforms/cell/interrupt.h @@ -83,5 +83,7 @@ extern u8 iic_get_target_id(int cpu); extern void spider_init_IRQ(void); +extern void iic_set_interrupt_routing(int cpu, int thread, int priority); + #endif #endif /* ASM_CELL_PIC_H */ diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index ae6fd1c12d4..f28abf2fc27 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -22,9 +22,11 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include +#include #include #include @@ -338,3 +340,71 @@ void cbe_read_trace_buffer(u32 cpu, u64 *buf) } EXPORT_SYMBOL_GPL(cbe_read_trace_buffer); +/* + * Enabling/disabling interrupts for the entire performance monitoring unit. + */ + +u32 cbe_query_pm_interrupts(u32 cpu) +{ + return cbe_read_pm(cpu, pm_status); +} +EXPORT_SYMBOL_GPL(cbe_query_pm_interrupts); + +u32 cbe_clear_pm_interrupts(u32 cpu) +{ + /* Reading pm_status clears the interrupt bits. */ + return cbe_query_pm_interrupts(cpu); +} +EXPORT_SYMBOL_GPL(cbe_clear_pm_interrupts); + +void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask) +{ + /* Set which node and thread will handle the next interrupt. */ + iic_set_interrupt_routing(cpu, thread, 0); + + /* Enable the interrupt bits in the pm_status register. */ + if (mask) + cbe_write_pm(cpu, pm_status, mask); +} +EXPORT_SYMBOL_GPL(cbe_enable_pm_interrupts); + +void cbe_disable_pm_interrupts(u32 cpu) +{ + cbe_clear_pm_interrupts(cpu); + cbe_write_pm(cpu, pm_status, 0); +} +EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts); + +static irqreturn_t cbe_pm_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + perf_irq(regs); + return IRQ_HANDLED; +} + +int __init cbe_init_pm_irq(void) +{ + unsigned int irq; + int rc, node; + + for_each_node(node) { + irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | + (node << IIC_IRQ_NODE_SHIFT)); + if (irq == NO_IRQ) { + printk("ERROR: Unable to allocate irq for node %d\n", + node); + return -EINVAL; + } + + rc = request_irq(irq, cbe_pm_irq, + IRQF_DISABLED, "cbe-pmu-0", NULL); + if (rc) { + printk("ERROR: Request for irq on node %d failed\n", + node); + return rc; + } + } + + return 0; +} +arch_initcall(cbe_init_pm_irq); + -- cgit v1.2.3 From 18f2190d796198fbb5d4bc4c87511acf3ced7d47 Mon Sep 17 00:00:00 2001 From: Maynard Johnson Date: Mon, 20 Nov 2006 18:45:16 +0100 Subject: [POWERPC] cell: Add oprofile support Add PPU event-based and cycle-based profiling support to Oprofile for Cell. Oprofile is expected to collect data on all CPUs simultaneously. However, there is one set of performance counters per node. There are two hardware threads or virtual CPUs on each node. Hence, OProfile must multiplex in time the performance counter collection on the two virtual CPUs. The multiplexing of the performance counters is done by a virtual counter routine. Initially, the counters are configured to collect data on the even CPUs in the system, one CPU per node. In order to capture the PC for the virtual CPU when the performance counter interrupt occurs (the specified number of events between samples has occurred), the even processors are configured to handle the performance counter interrupts for their node. The virtual counter routine is called via a kernel timer after the virtual sample time. The routine stops the counters, saves the current counts, loads the last counts for the other virtual CPU on the node, sets interrupts to be handled by the other virtual CPU and restarts the counters, the virtual timer routine is scheduled to run again. The virtual sample time is kept relatively small to make sure sampling occurs on both CPUs on the node with a relatively small granularity. Whenever the counters overflow, the performance counter interrupt is called to collect the PC for the CPU where data is being collected. The oprofile driver relies on a firmware RTAS call to setup the debug bus to route the desired signals to the performance counter hardware to be counted. The RTAS call must set the routing registers appropriately in each of the islands to pass the signals down the debug bus as well as routing the signals from a particular island onto the bus. There is a second firmware RTAS call to reset the debug bus to the non pass thru state when the counters are not in use. Signed-off-by: Carl Love Signed-off-by: Maynard Johnson Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/configs/cell_defconfig | 3 +- arch/powerpc/kernel/cputable.c | 3 + arch/powerpc/oprofile/Makefile | 1 + arch/powerpc/oprofile/common.c | 15 +- arch/powerpc/oprofile/op_model_cell.c | 724 +++++++++++++++++++++++++++++++++ arch/powerpc/platforms/cell/cbe_regs.c | 12 + arch/powerpc/platforms/cell/pmu.c | 23 +- 7 files changed, 776 insertions(+), 5 deletions(-) create mode 100644 arch/powerpc/oprofile/op_model_cell.c (limited to 'arch') diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index dbcd4e3329d..3d6a2f10a7d 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -1121,7 +1121,8 @@ CONFIG_PLIST=y # # Instrumentation Support # -# CONFIG_PROFILING is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=y # CONFIG_KPROBES is not set # diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 1e4ed0731d1..992121b2d26 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -304,6 +304,9 @@ static struct cpu_spec cpu_specs[] = { PPC_FEATURE_SMT, .icache_bsize = 128, .dcache_bsize = 128, + .num_pmcs = 4, + .oprofile_cpu_type = "ppc64/cell-be", + .oprofile_type = PPC_OPROFILE_CELL, .platform = "ppc-cell-be", }, { /* PA Semi PA6T */ diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 0b5df9c96ae..51c510fed7f 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile @@ -11,6 +11,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) common.o backtrace.o +oprofile-$(CONFIG_PPC_CELL) += op_model_cell.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o oprofile-$(CONFIG_6xx) += op_model_7450.o diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 63bbef3b63f..7a423437977 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -69,7 +69,10 @@ static void op_powerpc_cpu_start(void *dummy) static int op_powerpc_start(void) { - on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); + if (model->global_start) + model->global_start(ctr); + if (model->start) + on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); return 0; } @@ -80,7 +83,10 @@ static inline void op_powerpc_cpu_stop(void *dummy) static void op_powerpc_stop(void) { - on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1); + if (model->stop) + on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1); + if (model->global_stop) + model->global_stop(); } static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) @@ -141,6 +147,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) switch (cur_cpu_spec->oprofile_type) { #ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_CELL + case PPC_OPROFILE_CELL: + model = &op_model_cell; + break; +#endif case PPC_OPROFILE_RS64: model = &op_model_rs64; break; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c new file mode 100644 index 00000000000..2eb15f38810 --- /dev/null +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -0,0 +1,724 @@ +/* + * Cell Broadband Engine OProfile Support + * + * (C) Copyright IBM Corporation 2006 + * + * Author: David Erb (djerb@us.ibm.com) + * Modifications: + * Carl Love + * Maynard Johnson + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../platforms/cell/interrupt.h" + +#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */ +#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */ + +#define NUM_THREADS 2 +#define VIRT_CNTR_SW_TIME_NS 100000000 // 0.5 seconds + +struct pmc_cntrl_data { + unsigned long vcntr; + unsigned long evnts; + unsigned long masks; + unsigned long enabled; +}; + +/* + * ibm,cbe-perftools rtas parameters + */ + +struct pm_signal { + u16 cpu; /* Processor to modify */ + u16 sub_unit; /* hw subunit this applies to (if applicable) */ + u16 signal_group; /* Signal Group to Enable/Disable */ + u8 bus_word; /* Enable/Disable on this Trace/Trigger/Event + * Bus Word(s) (bitmask) + */ + u8 bit; /* Trigger/Event bit (if applicable) */ +}; + +/* + * rtas call arguments + */ +enum { + SUBFUNC_RESET = 1, + SUBFUNC_ACTIVATE = 2, + SUBFUNC_DEACTIVATE = 3, + + PASSTHRU_IGNORE = 0, + PASSTHRU_ENABLE = 1, + PASSTHRU_DISABLE = 2, +}; + +struct pm_cntrl { + u16 enable; + u16 stop_at_max; + u16 trace_mode; + u16 freeze; + u16 count_mode; +}; + +static struct { + u32 group_control; + u32 debug_bus_control; + struct pm_cntrl pm_cntrl; + u32 pm07_cntrl[NR_PHYS_CTRS]; +} pm_regs; + + +#define GET_SUB_UNIT(x) ((x & 0x0000f000) >> 12) +#define GET_BUS_WORD(x) ((x & 0x000000f0) >> 4) +#define GET_BUS_TYPE(x) ((x & 0x00000300) >> 8) +#define GET_POLARITY(x) ((x & 0x00000002) >> 1) +#define GET_COUNT_CYCLES(x) (x & 0x00000001) +#define GET_INPUT_CONTROL(x) ((x & 0x00000004) >> 2) + + +static DEFINE_PER_CPU(unsigned long[NR_PHYS_CTRS], pmc_values); + +static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS]; + +/* Interpetation of hdw_thread: + * 0 - even virtual cpus 0, 2, 4,... + * 1 - odd virtual cpus 1, 3, 5, ... + */ +static u32 hdw_thread; + +static u32 virt_cntr_inter_mask; +static struct timer_list timer_virt_cntr; + +/* pm_signal needs to be global since it is initialized in + * cell_reg_setup at the time when the necessary information + * is available. + */ +static struct pm_signal pm_signal[NR_PHYS_CTRS]; +static int pm_rtas_token; + +static u32 reset_value[NR_PHYS_CTRS]; +static int num_counters; +static int oprofile_running; +static spinlock_t virt_cntr_lock = SPIN_LOCK_UNLOCKED; + +static u32 ctr_enabled; + +static unsigned char trace_bus[4]; +static unsigned char input_bus[2]; + +/* + * Firmware interface functions + */ +static int +rtas_ibm_cbe_perftools(int subfunc, int passthru, + void *address, unsigned long length) +{ + u64 paddr = __pa(address); + + return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, passthru, + paddr >> 32, paddr & 0xffffffff, length); +} + +static void pm_rtas_reset_signals(u32 node) +{ + int ret; + struct pm_signal pm_signal_local; + + /* The debug bus is being set to the passthru disable state. + * However, the FW still expects atleast one legal signal routing + * entry or it will return an error on the arguments. If we don't + * supply a valid entry, we must ignore all return values. Ignoring + * all return values means we might miss an error we should be + * concerned about. + */ + + /* fw expects physical cpu #. */ + pm_signal_local.cpu = node; + pm_signal_local.signal_group = 21; + pm_signal_local.bus_word = 1; + pm_signal_local.sub_unit = 0; + pm_signal_local.bit = 0; + + ret = rtas_ibm_cbe_perftools(SUBFUNC_RESET, PASSTHRU_DISABLE, + &pm_signal_local, + sizeof(struct pm_signal)); + + if (ret) + printk(KERN_WARNING "%s: rtas returned: %d\n", + __FUNCTION__, ret); +} + +static void pm_rtas_activate_signals(u32 node, u32 count) +{ + int ret; + int j; + struct pm_signal pm_signal_local[NR_PHYS_CTRS]; + + for (j = 0; j < count; j++) { + /* fw expects physical cpu # */ + pm_signal_local[j].cpu = node; + pm_signal_local[j].signal_group = pm_signal[j].signal_group; + pm_signal_local[j].bus_word = pm_signal[j].bus_word; + pm_signal_local[j].sub_unit = pm_signal[j].sub_unit; + pm_signal_local[j].bit = pm_signal[j].bit; + } + + ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, PASSTHRU_ENABLE, + pm_signal_local, + count * sizeof(struct pm_signal)); + + if (ret) + printk(KERN_WARNING "%s: rtas returned: %d\n", + __FUNCTION__, ret); +} + +/* + * PM Signal functions + */ +static void set_pm_event(u32 ctr, int event, u32 unit_mask) +{ + struct pm_signal *p; + u32 signal_bit; + u32 bus_word, bus_type, count_cycles, polarity, input_control; + int j, i; + + if (event == PPU_CYCLES_EVENT_NUM) { + /* Special Event: Count all cpu cycles */ + pm_regs.pm07_cntrl[ctr] = CBE_COUNT_ALL_CYCLES; + p = &(pm_signal[ctr]); + p->signal_group = 21; + p->bus_word = 1; + p->sub_unit = 0; + p->bit = 0; + goto out; + } else { + pm_regs.pm07_cntrl[ctr] = 0; + } + + bus_word = GET_BUS_WORD(unit_mask); + bus_type = GET_BUS_TYPE(unit_mask); + count_cycles = GET_COUNT_CYCLES(unit_mask); + polarity = GET_POLARITY(unit_mask); + input_control = GET_INPUT_CONTROL(unit_mask); + signal_bit = (event % 100); + + p = &(pm_signal[ctr]); + + p->signal_group = event / 100; + p->bus_word = bus_word; + p->sub_unit = unit_mask & 0x0000f000; + + pm_regs.pm07_cntrl[ctr] = 0; + pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles); + pm_regs.pm07_cntrl[ctr] |= PM07_CTR_POLARITY(polarity); + pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_CONTROL(input_control); + + if (input_control == 0) { + if (signal_bit > 31) { + signal_bit -= 32; + if (bus_word == 0x3) + bus_word = 0x2; + else if (bus_word == 0xc) + bus_word = 0x8; + } + + if ((bus_type == 0) && p->signal_group >= 60) + bus_type = 2; + if ((bus_type == 1) && p->signal_group >= 50) + bus_type = 0; + + pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_MUX(signal_bit); + } else { + pm_regs.pm07_cntrl[ctr] = 0; + p->bit = signal_bit; + } + + for (i = 0; i < 4; i++) { + if (bus_word & (1 << i)) { + pm_regs.debug_bus_control |= + (bus_type << (31 - (2 * i) + 1)); + + for (j = 0; j < 2; j++) { + if (input_bus[j] == 0xff) { + input_bus[j] = i; + pm_regs.group_control |= + (i << (31 - i)); + break; + } + } + } + } +out: + ; +} + +static void write_pm_cntrl(int cpu, struct pm_cntrl *pm_cntrl) +{ + /* Oprofile will use 32 bit counters, set bits 7:10 to 0 */ + u32 val = 0; + if (pm_cntrl->enable == 1) + val |= CBE_PM_ENABLE_PERF_MON; + + if (pm_cntrl->stop_at_max == 1) + val |= CBE_PM_STOP_AT_MAX; + + if (pm_cntrl->trace_mode == 1) + val |= CBE_PM_TRACE_MODE_SET(pm_cntrl->trace_mode); + + if (pm_cntrl->freeze == 1) + val |= CBE_PM_FREEZE_ALL_CTRS; + + /* Routine set_count_mode must be called previously to set + * the count mode based on the user selection of user and kernel. + */ + val |= CBE_PM_COUNT_MODE_SET(pm_cntrl->count_mode); + cbe_write_pm(cpu, pm_control, val); +} + +static inline void +set_count_mode(u32 kernel, u32 user, struct pm_cntrl *pm_cntrl) +{ + /* The user must specify user and kernel if they want them. If + * neither is specified, OProfile will count in hypervisor mode + */ + if (kernel) { + if (user) + pm_cntrl->count_mode = CBE_COUNT_ALL_MODES; + else + pm_cntrl->count_mode = CBE_COUNT_SUPERVISOR_MODE; + } else { + if (user) + pm_cntrl->count_mode = CBE_COUNT_PROBLEM_MODE; + else + pm_cntrl->count_mode = CBE_COUNT_HYPERVISOR_MODE; + } +} + +static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl) +{ + + pm07_cntrl[ctr] |= PM07_CTR_ENABLE(1); + cbe_write_pm07_control(cpu, ctr, pm07_cntrl[ctr]); +} + +/* + * Oprofile is expected to collect data on all CPUs simultaneously. + * However, there is one set of performance counters per node. There are + * two hardware threads or virtual CPUs on each node. Hence, OProfile must + * multiplex in time the performance counter collection on the two virtual + * CPUs. The multiplexing of the performance counters is done by this + * virtual counter routine. + * + * The pmc_values used below is defined as 'per-cpu' but its use is + * more akin to 'per-node'. We need to store two sets of counter + * values per node -- one for the previous run and one for the next. + * The per-cpu[NR_PHYS_CTRS] gives us the storage we need. Each odd/even + * pair of per-cpu arrays is used for storing the previous and next + * pmc values for a given node. + * NOTE: We use the per-cpu variable to improve cache performance. + */ +static void cell_virtual_cntr(unsigned long data) +{ + /* This routine will alternate loading the virtual counters for + * virtual CPUs + */ + int i, prev_hdw_thread, next_hdw_thread; + u32 cpu; + unsigned long flags; + + /* Make sure that the interrupt_hander and + * the virt counter are not both playing with + * the counters on the same node. + */ + + spin_lock_irqsave(&virt_cntr_lock, flags); + + prev_hdw_thread = hdw_thread; + + /* switch the cpu handling the interrupts */ + hdw_thread = 1 ^ hdw_thread; + next_hdw_thread = hdw_thread; + + /* The following is done only once per each node, but + * we need cpu #, not node #, to pass to the cbe_xxx functions. + */ + for_each_online_cpu(cpu) { + if (cbe_get_hw_thread_id(cpu)) + continue; + + /* stop counters, save counter values, restore counts + * for previous thread + */ + cbe_disable_pm(cpu); + cbe_disable_pm_interrupts(cpu); + for (i = 0; i < num_counters; i++) { + per_cpu(pmc_values, cpu + prev_hdw_thread)[i] + = cbe_read_ctr(cpu, i); + + if (per_cpu(pmc_values, cpu + next_hdw_thread)[i] + == 0xFFFFFFFF) + /* If the cntr value is 0xffffffff, we must + * reset that to 0xfffffff0 when the current + * thread is restarted. This will generate a new + * interrupt and make sure that we never restore + * the counters to the max value. If the counters + * were restored to the max value, they do not + * increment and no interrupts are generated. Hence + * no more samples will be collected on that cpu. + */ + cbe_write_ctr(cpu, i, 0xFFFFFFF0); + else + cbe_write_ctr(cpu, i, + per_cpu(pmc_values, + cpu + + next_hdw_thread)[i]); + } + + /* Switch to the other thread. Change the interrupt + * and control regs to be scheduled on the CPU + * corresponding to the thread to execute. + */ + for (i = 0; i < num_counters; i++) { + if (pmc_cntrl[next_hdw_thread][i].enabled) { + /* There are some per thread events. + * Must do the set event, enable_cntr + * for each cpu. + */ + set_pm_event(i, + pmc_cntrl[next_hdw_thread][i].evnts, + pmc_cntrl[next_hdw_thread][i].masks); + enable_ctr(cpu, i, + pm_regs.pm07_cntrl); + } else { + cbe_write_pm07_control(cpu, i, 0); + } + } + + /* Enable interrupts on the CPU thread that is starting */ + cbe_enable_pm_interrupts(cpu, next_hdw_thread, + virt_cntr_inter_mask); + cbe_enable_pm(cpu); + } + + spin_unlock_irqrestore(&virt_cntr_lock, flags); + + mod_timer(&timer_virt_cntr, jiffies + HZ / 10); +} + +static void start_virt_cntrs(void) +{ + init_timer(&timer_virt_cntr); + timer_virt_cntr.function = cell_virtual_cntr; + timer_virt_cntr.data = 0UL; + timer_virt_cntr.expires = jiffies + HZ / 10; + add_timer(&timer_virt_cntr); +} + +/* This function is called once for all cpus combined */ +static void +cell_reg_setup(struct op_counter_config *ctr, + struct op_system_config *sys, int num_ctrs) +{ + int i, j, cpu; + + pm_rtas_token = rtas_token("ibm,cbe-perftools"); + if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) { + printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n", + __FUNCTION__); + goto out; + } + + num_counters = num_ctrs; + + pm_regs.group_control = 0; + pm_regs.debug_bus_control = 0; + + /* setup the pm_control register */ + memset(&pm_regs.pm_cntrl, 0, sizeof(struct pm_cntrl)); + pm_regs.pm_cntrl.stop_at_max = 1; + pm_regs.pm_cntrl.trace_mode = 0; + pm_regs.pm_cntrl.freeze = 1; + + set_count_mode(sys->enable_kernel, sys->enable_user, + &pm_regs.pm_cntrl); + + /* Setup the thread 0 events */ + for (i = 0; i < num_ctrs; ++i) { + + pmc_cntrl[0][i].evnts = ctr[i].event; + pmc_cntrl[0][i].masks = ctr[i].unit_mask; + pmc_cntrl[0][i].enabled = ctr[i].enabled; + pmc_cntrl[0][i].vcntr = i; + + for_each_possible_cpu(j) + per_cpu(pmc_values, j)[i] = 0; + } + + /* Setup the thread 1 events, map the thread 0 event to the + * equivalent thread 1 event. + */ + for (i = 0; i < num_ctrs; ++i) { + if ((ctr[i].event >= 2100) && (ctr[i].event <= 2111)) + pmc_cntrl[1][i].evnts = ctr[i].event + 19; + else if (ctr[i].event == 2203) + pmc_cntrl[1][i].evnts = ctr[i].event; + else if ((ctr[i].event >= 2200) && (ctr[i].event <= 2215)) + pmc_cntrl[1][i].evnts = ctr[i].event + 16; + else + pmc_cntrl[1][i].evnts = ctr[i].event; + + pmc_cntrl[1][i].masks = ctr[i].unit_mask; + pmc_cntrl[1][i].enabled = ctr[i].enabled; + pmc_cntrl[1][i].vcntr = i; + } + + for (i = 0; i < 4; i++) + trace_bus[i] = 0xff; + + for (i = 0; i < 2; i++) + input_bus[i] = 0xff; + + /* Our counters count up, and "count" refers to + * how much before the next interrupt, and we interrupt + * on overflow. So we calculate the starting value + * which will give us "count" until overflow. + * Then we set the events on the enabled counters. + */ + for (i = 0; i < num_counters; ++i) { + /* start with virtual counter set 0 */ + if (pmc_cntrl[0][i].enabled) { + /* Using 32bit counters, reset max - count */ + reset_value[i] = 0xFFFFFFFF - ctr[i].count; + set_pm_event(i, + pmc_cntrl[0][i].evnts, + pmc_cntrl[0][i].masks); + + /* global, used by cell_cpu_setup */ + ctr_enabled |= (1 << i); + } + } + + /* initialize the previous counts for the virtual cntrs */ + for_each_online_cpu(cpu) + for (i = 0; i < num_counters; ++i) { + per_cpu(pmc_values, cpu)[i] = reset_value[i]; + } +out: + ; +} + +/* This function is called once for each cpu */ +static void cell_cpu_setup(struct op_counter_config *cntr) +{ + u32 cpu = smp_processor_id(); + u32 num_enabled = 0; + int i; + + /* There is one performance monitor per processor chip (i.e. node), + * so we only need to perform this function once per node. + */ + if (cbe_get_hw_thread_id(cpu)) + goto out; + + if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) { + printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n", + __FUNCTION__); + goto out; + } + + /* Stop all counters */ + cbe_disable_pm(cpu); + cbe_disable_pm_interrupts(cpu); + + cbe_write_pm(cpu, pm_interval, 0); + cbe_write_pm(cpu, pm_start_stop, 0); + cbe_write_pm(cpu, group_control, pm_regs.group_control); + cbe_write_pm(cpu, debug_bus_control, pm_regs.debug_bus_control); + write_pm_cntrl(cpu, &pm_regs.pm_cntrl); + + for (i = 0; i < num_counters; ++i) { + if (ctr_enabled & (1 << i)) { + pm_signal[num_enabled].cpu = cbe_cpu_to_node(cpu); + num_enabled++; + } + } + + pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled); +out: + ; +} + +static void cell_global_start(struct op_counter_config *ctr) +{ + u32 cpu; + u32 interrupt_mask = 0; + u32 i; + + /* This routine gets called once for the system. + * There is one performance monitor per node, so we + * only need to perform this function once per node. + */ + for_each_online_cpu(cpu) { + if (cbe_get_hw_thread_id(cpu)) + continue; + + interrupt_mask = 0; + + for (i = 0; i < num_counters; ++i) { + if (ctr_enabled & (1 << i)) { + cbe_write_ctr(cpu, i, reset_value[i]); + enable_ctr(cpu, i, pm_regs.pm07_cntrl); + interrupt_mask |= + CBE_PM_CTR_OVERFLOW_INTR(i); + } else { + /* Disable counter */ + cbe_write_pm07_control(cpu, i, 0); + } + } + + cbe_clear_pm_interrupts(cpu); + cbe_enable_pm_interrupts(cpu, hdw_thread, interrupt_mask); + cbe_enable_pm(cpu); + } + + virt_cntr_inter_mask = interrupt_mask; + oprofile_running = 1; + smp_wmb(); + + /* NOTE: start_virt_cntrs will result in cell_virtual_cntr() being + * executed which manipulates the PMU. We start the "virtual counter" + * here so that we do not need to synchronize access to the PMU in + * the above for-loop. + */ + start_virt_cntrs(); +} + +static void cell_global_stop(void) +{ + int cpu; + + /* This routine will be called once for the system. + * There is one performance monitor per node, so we + * only need to perform this function once per node. + */ + del_timer_sync(&timer_virt_cntr); + oprofile_running = 0; + smp_wmb(); + + for_each_online_cpu(cpu) { + if (cbe_get_hw_thread_id(cpu)) + continue; + + cbe_sync_irq(cbe_cpu_to_node(cpu)); + /* Stop the counters */ + cbe_disable_pm(cpu); + + /* Deactivate the signals */ + pm_rtas_reset_signals(cbe_cpu_to_node(cpu)); + + /* Deactivate interrupts */ + cbe_disable_pm_interrupts(cpu); + } +} + +static void +cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr) +{ + u32 cpu; + u64 pc; + int is_kernel; + unsigned long flags = 0; + u32 interrupt_mask; + int i; + + cpu = smp_processor_id(); + + /* Need to make sure the interrupt handler and the virt counter + * routine are not running at the same time. See the + * cell_virtual_cntr() routine for additional comments. + */ + spin_lock_irqsave(&virt_cntr_lock, flags); + + /* Need to disable and reenable the performance counters + * to get the desired behavior from the hardware. This + * is hardware specific. + */ + + cbe_disable_pm(cpu); + + interrupt_mask = cbe_clear_pm_interrupts(cpu); + + /* If the interrupt mask has been cleared, then the virt cntr + * has cleared the interrupt. When the thread that generated + * the interrupt is restored, the data count will be restored to + * 0xffffff0 to cause the interrupt to be regenerated. + */ + + if ((oprofile_running == 1) && (interrupt_mask != 0)) { + pc = regs->nip; + is_kernel = is_kernel_addr(pc); + + for (i = 0; i < num_counters; ++i) { + if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i)) + && ctr[i].enabled) { + oprofile_add_pc(pc, is_kernel, i); + cbe_write_ctr(cpu, i, reset_value[i]); + } + } + + /* The counters were frozen by the interrupt. + * Reenable the interrupt and restart the counters. + * If there was a race between the interrupt handler and + * the virtual counter routine. The virutal counter + * routine may have cleared the interrupts. Hence must + * use the virt_cntr_inter_mask to re-enable the interrupts. + */ + cbe_enable_pm_interrupts(cpu, hdw_thread, + virt_cntr_inter_mask); + + /* The writes to the various performance counters only writes + * to a latch. The new values (interrupt setting bits, reset + * counter value etc.) are not copied to the actual registers + * until the performance monitor is enabled. In order to get + * this to work as desired, the permormance monitor needs to + * be disabled while writting to the latches. This is a + * HW design issue. + */ + cbe_enable_pm(cpu); + } + spin_unlock_irqrestore(&virt_cntr_lock, flags); +} + +struct op_powerpc_model op_model_cell = { + .reg_setup = cell_reg_setup, + .cpu_setup = cell_cpu_setup, + .global_start = cell_global_start, + .global_stop = cell_global_stop, + .handle_interrupt = cell_handle_interrupt, +}; diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c index 5a91b75c2f0..9a0ee62691d 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.c +++ b/arch/powerpc/platforms/cell/cbe_regs.c @@ -130,6 +130,18 @@ struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu) } EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs); +/* FIXME + * This is little more than a stub at the moment. It should be + * fleshed out so that it works for both SMT and non-SMT, no + * matter if the passed cpu is odd or even. + * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1. + * For SMT disabled, returns 0 for all cpus. + */ +u32 cbe_get_hw_thread_id(int cpu) +{ + return (cpu & 1); +} +EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id); void __init cbe_regs_init(void) { diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index f28abf2fc27..99c612025e8 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -375,9 +376,9 @@ void cbe_disable_pm_interrupts(u32 cpu) } EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts); -static irqreturn_t cbe_pm_irq(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t cbe_pm_irq(int irq, void *dev_id) { - perf_irq(regs); + perf_irq(get_irq_regs()); return IRQ_HANDLED; } @@ -408,3 +409,21 @@ int __init cbe_init_pm_irq(void) } arch_initcall(cbe_init_pm_irq); +void cbe_sync_irq(int node) +{ + unsigned int irq; + + irq = irq_find_mapping(NULL, + IIC_IRQ_IOEX_PMI + | (node << IIC_IRQ_NODE_SHIFT)); + + if (irq == NO_IRQ) { + printk(KERN_WARNING "ERROR, unable to get existing irq %d " \ + "for node %d\n", irq, node); + return; + } + + synchronize_irq(irq); +} +EXPORT_SYMBOL_GPL(cbe_sync_irq); + -- cgit v1.2.3 From 974a76f51355d22f4f63d83d6bb1ccecd019ec58 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 10 Nov 2006 20:38:53 +1100 Subject: [POWERPC] Distinguish POWER6 partition modes and tell userspace This adds code to look at the properties firmware puts in the device tree to determine what compatibility mode the partition is in on POWER6 machines, and set the ELF aux vector AT_HWCAP and AT_PLATFORM entries appropriately. Specifically, we look at the cpu-version property in the cpu node(s). If that contains a "logical" PVR value (of the form 0x0f00000x), we call identify_cpu again with this PVR value. A value of 0x0f000001 indicates the partition is in POWER5+ compatibility mode, and a value of 0x0f000002 indicates "POWER6 architected" mode, with various extensions disabled. We also look for various other properties: ibm,dfp, ibm,purr and ibm,spurr. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 43 +++++++++++-- arch/powerpc/kernel/prom.c | 110 +++++++++++++++++++++++---------- arch/powerpc/kernel/prom_init.c | 3 +- arch/powerpc/kernel/setup_32.c | 2 +- arch/powerpc/kernel/setup_64.c | 2 +- arch/powerpc/platforms/iseries/setup.c | 2 +- arch/ppc/kernel/setup.c | 2 +- 7 files changed, 119 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 992121b2d26..911ac442f44 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -277,10 +277,45 @@ static struct cpu_spec cpu_specs[] = { .oprofile_mmcra_sipr = MMCRA_SIPR, .platform = "power5+", }, + { /* POWER6 in P5+ mode; 2.04-compliant processor */ + .pvr_mask = 0xffffffff, + .pvr_value = 0x0f000001, + .cpu_name = "POWER5+", + .cpu_features = CPU_FTRS_POWER5, + .cpu_user_features = COMMON_USER_POWER5_PLUS, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .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 */ .pvr_mask = 0xffff0000, .pvr_value = 0x003e0000, - .cpu_name = "POWER6", + .cpu_name = "POWER6 (raw)", + .cpu_features = CPU_FTRS_POWER6, + .cpu_user_features = COMMON_USER_POWER6 | + PPC_FEATURE_POWER6_EXT, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .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 = "power6x", + }, + { /* 2.05-compliant processor, i.e. Power6 "architected" mode */ + .pvr_mask = 0xffffffff, + .pvr_value = 0x0f000002, + .cpu_name = "POWER6 (architected)", .cpu_features = CPU_FTRS_POWER6, .cpu_user_features = COMMON_USER_POWER6, .icache_bsize = 128, @@ -1173,19 +1208,15 @@ static struct cpu_spec cpu_specs[] = { #endif /* CONFIG_PPC32 */ }; -struct cpu_spec *identify_cpu(unsigned long offset) +struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr) { struct cpu_spec *s = cpu_specs; struct cpu_spec **cur = &cur_cpu_spec; - unsigned int pvr = mfspr(SPRN_PVR); int i; s = PTRRELOC(s); cur = PTRRELOC(cur); - if (*cur != NULL) - return PTRRELOC(*cur); - for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) if ((pvr & s->pvr_mask) == s->pvr_value) { *cur = cpu_specs + i; diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 16d29d16b96..c18dbe77fdc 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -538,35 +538,31 @@ static struct ibm_pa_feature { {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, }; -static void __init check_cpu_pa_features(unsigned long node) +static void __init scan_features(unsigned long node, unsigned char *ftrs, + unsigned long tablelen, + struct ibm_pa_feature *fp, + unsigned long ft_size) { - unsigned char *pa_ftrs; - unsigned long len, tablelen, i, bit; - - pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen); - if (pa_ftrs == NULL) - return; + unsigned long i, len, bit; /* find descriptor with type == 0 */ for (;;) { if (tablelen < 3) return; - len = 2 + pa_ftrs[0]; + len = 2 + ftrs[0]; if (tablelen < len) return; /* descriptor 0 not found */ - if (pa_ftrs[1] == 0) + if (ftrs[1] == 0) break; tablelen -= len; - pa_ftrs += len; + ftrs += len; } /* loop over bits we know about */ - for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) { - struct ibm_pa_feature *fp = &ibm_pa_features[i]; - - if (fp->pabyte >= pa_ftrs[0]) + for (i = 0; i < ft_size; ++i, ++fp) { + if (fp->pabyte >= ftrs[0]) continue; - bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; + bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; if (bit ^ fp->invert) { cur_cpu_spec->cpu_features |= fp->cpu_features; cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; @@ -577,16 +573,59 @@ static void __init check_cpu_pa_features(unsigned long node) } } +static void __init check_cpu_pa_features(unsigned long node) +{ + unsigned char *pa_ftrs; + unsigned long tablelen; + + pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen); + if (pa_ftrs == NULL) + return; + + scan_features(node, pa_ftrs, tablelen, + ibm_pa_features, ARRAY_SIZE(ibm_pa_features)); +} + +static struct feature_property { + const char *name; + u32 min_value; + unsigned long cpu_feature; + unsigned long cpu_user_ftr; +} feature_properties[] __initdata = { +#ifdef CONFIG_ALTIVEC + {"altivec", 0, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC}, + {"ibm,vmx", 1, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC}, +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_PPC64 + {"ibm,dfp", 1, 0, PPC_FEATURE_HAS_DFP}, + {"ibm,purr", 1, CPU_FTR_PURR, 0}, + {"ibm,spurr", 1, CPU_FTR_SPURR, 0}, +#endif /* CONFIG_PPC64 */ +}; + +static void __init check_cpu_feature_properties(unsigned long node) +{ + unsigned long i; + struct feature_property *fp = feature_properties; + const u32 *prop; + + for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) { + prop = of_get_flat_dt_prop(node, fp->name, NULL); + if (prop && *prop >= fp->min_value) { + cur_cpu_spec->cpu_features |= fp->cpu_feature; + cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr; + } + } +} + static int __init early_init_dt_scan_cpus(unsigned long node, const char *uname, int depth, void *data) { static int logical_cpuid = 0; char *type = of_get_flat_dt_prop(node, "device_type", NULL); -#ifdef CONFIG_ALTIVEC - u32 *prop; -#endif - u32 *intserv; + const u32 *prop; + const u32 *intserv; int i, nthreads; unsigned long len; int found = 0; @@ -643,24 +682,27 @@ static int __init early_init_dt_scan_cpus(unsigned long node, intserv[i]); boot_cpuid = logical_cpuid; set_hard_smp_processor_id(boot_cpuid, intserv[i]); - } -#ifdef CONFIG_ALTIVEC - /* Check if we have a VMX and eventually update CPU features */ - prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL); - if (prop && (*prop) > 0) { - cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; - cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; - } - - /* Same goes for Apple's "altivec" property */ - prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL); - if (prop) { - cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; - cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; + /* + * PAPR defines "logical" PVR values for cpus that + * meet various levels of the architecture: + * 0x0f000001 Architecture version 2.04 + * 0x0f000002 Architecture version 2.05 + * If the cpu-version property in the cpu node contains + * such a value, we call identify_cpu again with the + * logical PVR value in order to use the cpu feature + * bits appropriate for the architecture level. + * + * A POWER6 partition in "POWER6 architected" mode + * uses the 0x0f000002 PVR value; in POWER5+ mode + * it uses 0x0f000001. + */ + prop = of_get_flat_dt_prop(node, "cpu-version", NULL); + if (prop && (*prop & 0xff000000) == 0x0f000000) + identify_cpu(0, *prop); } -#endif /* CONFIG_ALTIVEC */ + check_cpu_feature_properties(node); check_cpu_pa_features(node); #ifdef CONFIG_PPC_PSERIES diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 8671eb634a9..396109a537c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -627,6 +627,7 @@ static void __init early_cmdline_parse(void) /* Option vector 3: processor options supported */ #define OV3_FP 0x80 /* floating point */ #define OV3_VMX 0x40 /* VMX/Altivec */ +#define OV3_DFP 0x20 /* decimal FP */ /* Option vector 5: PAPR/OF options supported */ #define OV5_LPAR 0x80 /* logical partitioning supported */ @@ -668,7 +669,7 @@ static unsigned char ibm_architecture_vec[] = { /* option vector 3: processor options supported */ 3 - 2, /* length */ 0, /* don't ignore, don't halt */ - OV3_FP | OV3_VMX, + OV3_FP | OV3_VMX | OV3_DFP, /* option vector 4: IBM PAPR implementation */ 2 - 2, /* length */ diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 04df53a3c86..61c65d19ef0 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -97,7 +97,7 @@ unsigned long __init early_init(unsigned long dt_ptr) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - spec = identify_cpu(offset); + spec = identify_cpu(offset, mfspr(SPRN_PVR)); do_feature_fixups(spec->cpu_features, PTRRELOC(&__start___ftr_fixup), diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index f602a53b1b7..3733de30e84 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -171,7 +171,7 @@ void __init setup_paca(int cpu) void __init early_setup(unsigned long dt_ptr) { /* Identify CPU type */ - identify_cpu(0); + identify_cpu(0, mfspr(SPRN_PVR)); /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ setup_paca(0); diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 0f39bdbbf91..1796644ec7d 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -677,7 +677,7 @@ void * __init iSeries_early_setup(void) /* Identify CPU type. This is done again by the common code later * on but calling this function multiple times is fine. */ - identify_cpu(0); + identify_cpu(0, mfspr(SPRN_PVR)); powerpc_firmware_features |= FW_FEATURE_ISERIES; powerpc_firmware_features |= FW_FEATURE_LPAR; diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 27faeca2c7a..3c506af1988 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -313,7 +313,7 @@ early_init(int r3, int r4, int r5) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - spec = identify_cpu(offset); + spec = identify_cpu(offset, mfspr(SPRN_PVR)); do_feature_fixups(spec->cpu_features, PTRRELOC(&__start___ftr_fixup), PTRRELOC(&__stop___ftr_fixup)); -- cgit v1.2.3 From 9309180f11f0107c9858a61a1ac2b04518a91080 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Tue, 21 Nov 2006 14:56:37 +1100 Subject: [POWERPC] powerpc: Workaround for of_platform without "reg" nor "dcr-reg" Devices with no "reg" nor "dcr-reg" property are given a bus_id which is the node name alone. This means that if more than one such device with the same names are present in the system, sysfs will have collisions when creating the symlinks and will fail registering the devices. This works around that problem by assigning successive numbers to such devices. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/of_platform.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index 6029543c1b5..b3189d0161b 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -27,6 +27,8 @@ #include #include #include +#include + /* * The list of OF IDs below is used for matching bus types in the @@ -51,6 +53,8 @@ static struct of_device_id of_default_bus_ids[] = { {}, }; +static atomic_t bus_no_reg_magic; + /* * * OF platform device type definition & base infrastructure @@ -165,6 +169,7 @@ static void of_platform_make_bus_id(struct of_device *dev) char *name = dev->dev.bus_id; const u32 *reg; u64 addr; + long magic; /* * If it's a DCR based device, use 'd' for native DCRs @@ -203,9 +208,11 @@ static void of_platform_make_bus_id(struct of_device *dev) } /* - * No BusID, use the node name and pray + * No BusID, use the node name and add a globally incremented + * counter (and pray...) */ - snprintf(name, BUS_ID_SIZE, "%s", node->name); + magic = atomic_add_return(1, &bus_no_reg_magic); + snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1); } struct of_device* of_platform_device_create(struct device_node *np, -- cgit v1.2.3 From bf1ab978be2318c5a564de9aa0f1a217b44170d4 Mon Sep 17 00:00:00 2001 From: Dwayne Grant McConnell Date: Thu, 23 Nov 2006 00:46:37 +0100 Subject: [POWERPC] coredump: Add SPU elf notes to coredump. This patch adds SPU elf notes to the coredump. It creates a separate note for each of /regs, /fpcr, /lslr, /decr, /decr_status, /mem, /signal1, /signal1_type, /signal2, /signal2_type, /event_mask, /event_status, /mbox_info, /ibox_info, /wbox_info, /dma_info, /proxydma_info, /object-id. A new macro, ARCH_HAVE_EXTRA_NOTES, was created for architectures to specify they have extra elf core notes. A new macro, ELF_CORE_EXTRA_NOTES_SIZE, was created so the size of the additional notes could be calculated and added to the notes phdr entry. A new macro, ELF_CORE_WRITE_EXTRA_NOTES, was created so the new notes would be written after the existing notes. The SPU coredump code resides in spufs. Stub functions are provided in the kernel which are hooked into the spufs code which does the actual work via register_arch_coredump_calls(). A new set of __spufs__read/get() functions was provided to allow the coredump code to read from the spufs files without having to lock the SPU context for each file read from. Cc: Signed-off-by: Dwayne Grant McConnell Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/Makefile | 1 + arch/powerpc/platforms/cell/spu_coredump.c | 81 +++++++ arch/powerpc/platforms/cell/spufs/Makefile | 2 +- arch/powerpc/platforms/cell/spufs/coredump.c | 238 +++++++++++++++++++ arch/powerpc/platforms/cell/spufs/file.c | 327 ++++++++++++++++++++------- arch/powerpc/platforms/cell/spufs/inode.c | 7 + arch/powerpc/platforms/cell/spufs/spufs.h | 11 + 7 files changed, 580 insertions(+), 87 deletions(-) create mode 100644 arch/powerpc/platforms/cell/spu_coredump.c create mode 100644 arch/powerpc/platforms/cell/spufs/coredump.c (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 62c011e8092..f90e8337796 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile @@ -15,5 +15,6 @@ spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ + spu_coredump.o \ $(spufs-modular-m) \ $(spu-priv1-y) spufs/ diff --git a/arch/powerpc/platforms/cell/spu_coredump.c b/arch/powerpc/platforms/cell/spu_coredump.c new file mode 100644 index 00000000000..6915b418ee7 --- /dev/null +++ b/arch/powerpc/platforms/cell/spu_coredump.c @@ -0,0 +1,81 @@ +/* + * SPU core dump code + * + * (C) Copyright 2006 IBM Corp. + * + * Author: Dwayne Grant McConnell + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include + +#include + +static struct spu_coredump_calls spu_coredump_calls; +static DEFINE_MUTEX(spu_coredump_mutex); + +int arch_notes_size(void) +{ + long ret; + struct module *owner = spu_coredump_calls.owner; + + ret = -ENOSYS; + mutex_lock(&spu_coredump_mutex); + if (owner && try_module_get(owner)) { + ret = spu_coredump_calls.arch_notes_size(); + module_put(owner); + } + mutex_unlock(&spu_coredump_mutex); + return ret; +} + +void arch_write_notes(struct file *file) +{ + struct module *owner = spu_coredump_calls.owner; + + mutex_lock(&spu_coredump_mutex); + if (owner && try_module_get(owner)) { + spu_coredump_calls.arch_write_notes(file); + module_put(owner); + } + mutex_unlock(&spu_coredump_mutex); +} + +int register_arch_coredump_calls(struct spu_coredump_calls *calls) +{ + if (spu_coredump_calls.owner) + return -EBUSY; + + mutex_lock(&spu_coredump_mutex); + spu_coredump_calls.arch_notes_size = calls->arch_notes_size; + spu_coredump_calls.arch_write_notes = calls->arch_write_notes; + spu_coredump_calls.owner = calls->owner; + mutex_unlock(&spu_coredump_mutex); + return 0; +} +EXPORT_SYMBOL_GPL(register_arch_coredump_calls); + +void unregister_arch_coredump_calls(struct spu_coredump_calls *calls) +{ + BUG_ON(spu_coredump_calls.owner != calls->owner); + + mutex_lock(&spu_coredump_mutex); + spu_coredump_calls.owner = NULL; + mutex_unlock(&spu_coredump_mutex); +} +EXPORT_SYMBOL_GPL(unregister_arch_coredump_calls); diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index ecdfbb35f82..472217d19fa 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile @@ -1,7 +1,7 @@ obj-y += switch.o obj-$(CONFIG_SPU_FS) += spufs.o -spufs-y += inode.o file.o context.o syscalls.o +spufs-y += inode.o file.o context.o syscalls.o coredump.o spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o # Rules to build switch.o with the help of SPU tool chain diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c new file mode 100644 index 00000000000..26945c491f6 --- /dev/null +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -0,0 +1,238 @@ +/* + * SPU core dump code + * + * (C) Copyright 2006 IBM Corp. + * + * Author: Dwayne Grant McConnell + * + * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "spufs.h" + +struct spufs_ctx_info { + struct list_head list; + int dfd; + int memsize; /* in bytes */ + struct spu_context *ctx; +}; + +static LIST_HEAD(ctx_info_list); + +static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer, + size_t size, loff_t *off) +{ + u64 data; + int ret; + + if (spufs_coredump_read[num].read) + return spufs_coredump_read[num].read(ctx, buffer, size, off); + + data = spufs_coredump_read[num].get(ctx); + ret = copy_to_user(buffer, &data, 8); + return ret ? -EFAULT : 8; +} + +/* + * These are the only things you should do on a core-file: use only these + * functions to write out all the necessary info. + */ +static int spufs_dump_write(struct file *file, const void *addr, int nr) +{ + return file->f_op->write(file, addr, nr, &file->f_pos) == nr; +} + +static int spufs_dump_seek(struct file *file, loff_t off) +{ + if (file->f_op->llseek) { + if (file->f_op->llseek(file, off, 0) != off) + return 0; + } else + file->f_pos = off; + return 1; +} + +static void spufs_fill_memsize(struct spufs_ctx_info *ctx_info) +{ + struct spu_context *ctx; + unsigned long long lslr; + + ctx = ctx_info->ctx; + lslr = ctx->csa.priv2.spu_lslr_RW; + ctx_info->memsize = lslr + 1; +} + +static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info) +{ + int dfd, memsize, i, sz, total = 0; + char *name; + char fullname[80]; + + dfd = ctx_info->dfd; + memsize = ctx_info->memsize; + + for (i = 0; spufs_coredump_read[i].name; i++) { + name = spufs_coredump_read[i].name; + sz = spufs_coredump_read[i].size; + + sprintf(fullname, "SPU/%d/%s", dfd, name); + + total += sizeof(struct elf_note); + total += roundup(strlen(fullname) + 1, 4); + if (!strcmp(name, "mem")) + total += roundup(memsize, 4); + else + total += roundup(sz, 4); + } + + return total; +} + +static int spufs_add_one_context(struct file *file, int dfd) +{ + struct spu_context *ctx; + struct spufs_ctx_info *ctx_info; + int size; + + ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx; + if (ctx->flags & SPU_CREATE_NOSCHED) + return 0; + + ctx_info = kzalloc(sizeof(*ctx_info), GFP_KERNEL); + if (unlikely(!ctx_info)) + return -ENOMEM; + + ctx_info->dfd = dfd; + ctx_info->ctx = ctx; + + spufs_fill_memsize(ctx_info); + + size = spufs_ctx_note_size(ctx_info); + list_add(&ctx_info->list, &ctx_info_list); + return size; +} + +/* + * The additional architecture-specific notes for Cell are various + * context files in the spu context. + * + * This function iterates over all open file descriptors and sees + * if they are a directory in spufs. In that case we use spufs + * internal functionality to dump them without needing to actually + * open the files. + */ +static int spufs_arch_notes_size(void) +{ + struct fdtable *fdt = files_fdtable(current->files); + int size = 0, fd; + + for (fd = 0; fd < fdt->max_fdset && fd < fdt->max_fds; fd++) { + if (FD_ISSET(fd, fdt->open_fds)) { + struct file *file = fcheck(fd); + + if (file && file->f_op == &spufs_context_fops) { + int rval = spufs_add_one_context(file, fd); + if (rval < 0) + break; + size += rval; + } + } + } + + return size; +} + +static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i, + struct file *file) +{ + struct spu_context *ctx; + loff_t pos = 0; + int sz, dfd, rc, total = 0; + const int bufsz = 4096; + char *name; + char fullname[80], *buf; + struct elf_note en; + + buf = kmalloc(bufsz, GFP_KERNEL); + if (!buf) + return; + + dfd = ctx_info->dfd; + name = spufs_coredump_read[i].name; + + if (!strcmp(name, "mem")) + sz = ctx_info->memsize; + else + sz = spufs_coredump_read[i].size; + + ctx = ctx_info->ctx; + if (!ctx) { + return; + } + + sprintf(fullname, "SPU/%d/%s", dfd, name); + en.n_namesz = strlen(fullname) + 1; + en.n_descsz = sz; + en.n_type = NT_SPU; + + if (!spufs_dump_write(file, &en, sizeof(en))) + return; + if (!spufs_dump_write(file, fullname, en.n_namesz)) + return; + if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4))) + return; + + do { + rc = do_coredump_read(i, ctx, buf, bufsz, &pos); + if (rc > 0) { + if (!spufs_dump_write(file, buf, rc)) + return; + total += rc; + } + } while (rc == bufsz && total < sz); + + spufs_dump_seek(file, roundup((unsigned long)file->f_pos + - total + sz, 4)); +} + +static void spufs_arch_write_notes(struct file *file) +{ + int j; + struct spufs_ctx_info *ctx_info, *next; + + list_for_each_entry_safe(ctx_info, next, &ctx_info_list, list) { + spu_acquire_saved(ctx_info->ctx); + for (j = 0; j < spufs_coredump_num_notes; j++) + spufs_arch_write_note(ctx_info, j, file); + spu_release(ctx_info->ctx); + list_del(&ctx_info->list); + kfree(ctx_info); + } +} + +struct spu_coredump_calls spufs_coredump_calls = { + .arch_notes_size = spufs_arch_notes_size, + .arch_write_notes = spufs_arch_write_notes, + .owner = THIS_MODULE, +}; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 50e0afc46ad..347eff56fcb 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -39,7 +39,6 @@ #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) - static int spufs_mem_open(struct inode *inode, struct file *file) { @@ -51,19 +50,24 @@ spufs_mem_open(struct inode *inode, struct file *file) return 0; } +static ssize_t +__spufs_mem_read(struct spu_context *ctx, char __user *buffer, + size_t size, loff_t *pos) +{ + char *local_store = ctx->ops->get_ls(ctx); + return simple_read_from_buffer(buffer, size, pos, local_store, + LS_SIZE); +} + static ssize_t spufs_mem_read(struct file *file, char __user *buffer, size_t size, loff_t *pos) { - struct spu_context *ctx = file->private_data; - char *local_store; int ret; + struct spu_context *ctx = file->private_data; spu_acquire(ctx); - - local_store = ctx->ops->get_ls(ctx); - ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE); - + ret = __spufs_mem_read(ctx, buffer, size, pos); spu_release(ctx); return ret; } @@ -261,19 +265,24 @@ spufs_regs_open(struct inode *inode, struct file *file) return 0; } +static ssize_t +__spufs_regs_read(struct spu_context *ctx, char __user *buffer, + size_t size, loff_t *pos) +{ + struct spu_lscsa *lscsa = ctx->csa.lscsa; + return simple_read_from_buffer(buffer, size, pos, + lscsa->gprs, sizeof lscsa->gprs); +} + static ssize_t spufs_regs_read(struct file *file, char __user *buffer, size_t size, loff_t *pos) { - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; int ret; + struct spu_context *ctx = file->private_data; spu_acquire_saved(ctx); - - ret = simple_read_from_buffer(buffer, size, pos, - lscsa->gprs, sizeof lscsa->gprs); - + ret = __spufs_regs_read(ctx, buffer, size, pos); spu_release(ctx); return ret; } @@ -307,19 +316,24 @@ static struct file_operations spufs_regs_fops = { .llseek = generic_file_llseek, }; +static ssize_t +__spufs_fpcr_read(struct spu_context *ctx, char __user * buffer, + size_t size, loff_t * pos) +{ + struct spu_lscsa *lscsa = ctx->csa.lscsa; + return simple_read_from_buffer(buffer, size, pos, + &lscsa->fpcr, sizeof(lscsa->fpcr)); +} + static ssize_t spufs_fpcr_read(struct file *file, char __user * buffer, size_t size, loff_t * pos) { - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; int ret; + struct spu_context *ctx = file->private_data; spu_acquire_saved(ctx); - - ret = simple_read_from_buffer(buffer, size, pos, - &lscsa->fpcr, sizeof(lscsa->fpcr)); - + ret = __spufs_fpcr_read(ctx, buffer, size, pos); spu_release(ctx); return ret; } @@ -719,22 +733,19 @@ static int spufs_signal1_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static ssize_t spufs_signal1_read(struct file *file, char __user *buf, +static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx = file->private_data; int ret = 0; u32 data; if (len < 4) return -EINVAL; - spu_acquire_saved(ctx); if (ctx->csa.spu_chnlcnt_RW[3]) { data = ctx->csa.spu_chnldata_RW[3]; ret = 4; } - spu_release(ctx); if (!ret) goto out; @@ -746,6 +757,19 @@ out: return ret; } +static ssize_t spufs_signal1_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + int ret; + struct spu_context *ctx = file->private_data; + + spu_acquire_saved(ctx); + ret = __spufs_signal1_read(ctx, buf, len, pos); + spu_release(ctx); + + return ret; +} + static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, size_t len, loff_t *pos) { @@ -816,22 +840,19 @@ static int spufs_signal2_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static ssize_t spufs_signal2_read(struct file *file, char __user *buf, +static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx = file->private_data; int ret = 0; u32 data; if (len < 4) return -EINVAL; - spu_acquire_saved(ctx); if (ctx->csa.spu_chnlcnt_RW[4]) { data = ctx->csa.spu_chnldata_RW[4]; ret = 4; } - spu_release(ctx); if (!ret) goto out; @@ -840,7 +861,20 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf, return -EFAULT; out: - return 4; + return ret; +} + +static ssize_t spufs_signal2_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int ret; + + spu_acquire_saved(ctx); + ret = __spufs_signal2_read(ctx, buf, len, pos); + spu_release(ctx); + + return ret; } static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, @@ -916,13 +950,19 @@ static void spufs_signal1_type_set(void *data, u64 val) spu_release(ctx); } +static u64 __spufs_signal1_type_get(void *data) +{ + struct spu_context *ctx = data; + return ctx->ops->signal1_type_get(ctx); +} + static u64 spufs_signal1_type_get(void *data) { struct spu_context *ctx = data; u64 ret; spu_acquire(ctx); - ret = ctx->ops->signal1_type_get(ctx); + ret = __spufs_signal1_type_get(data); spu_release(ctx); return ret; @@ -939,13 +979,19 @@ static void spufs_signal2_type_set(void *data, u64 val) spu_release(ctx); } +static u64 __spufs_signal2_type_get(void *data) +{ + struct spu_context *ctx = data; + return ctx->ops->signal2_type_get(ctx); +} + static u64 spufs_signal2_type_get(void *data) { struct spu_context *ctx = data; u64 ret; spu_acquire(ctx); - ret = ctx->ops->signal2_type_get(ctx); + ret = __spufs_signal2_type_get(data); spu_release(ctx); return ret; @@ -1387,13 +1433,19 @@ static void spufs_decr_set(void *data, u64 val) spu_release(ctx); } -static u64 spufs_decr_get(void *data) +static u64 __spufs_decr_get(void *data) { struct spu_context *ctx = data; struct spu_lscsa *lscsa = ctx->csa.lscsa; + return lscsa->decr.slot[0]; +} + +static u64 spufs_decr_get(void *data) +{ + struct spu_context *ctx = data; u64 ret; spu_acquire_saved(ctx); - ret = lscsa->decr.slot[0]; + ret = __spufs_decr_get(data); spu_release(ctx); return ret; } @@ -1409,13 +1461,19 @@ static void spufs_decr_status_set(void *data, u64 val) spu_release(ctx); } -static u64 spufs_decr_status_get(void *data) +static u64 __spufs_decr_status_get(void *data) { struct spu_context *ctx = data; struct spu_lscsa *lscsa = ctx->csa.lscsa; + return lscsa->decr_status.slot[0]; +} + +static u64 spufs_decr_status_get(void *data) +{ + struct spu_context *ctx = data; u64 ret; spu_acquire_saved(ctx); - ret = lscsa->decr_status.slot[0]; + ret = __spufs_decr_status_get(data); spu_release(ctx); return ret; } @@ -1431,30 +1489,43 @@ static void spufs_event_mask_set(void *data, u64 val) spu_release(ctx); } -static u64 spufs_event_mask_get(void *data) +static u64 __spufs_event_mask_get(void *data) { struct spu_context *ctx = data; struct spu_lscsa *lscsa = ctx->csa.lscsa; + return lscsa->event_mask.slot[0]; +} + +static u64 spufs_event_mask_get(void *data) +{ + struct spu_context *ctx = data; u64 ret; spu_acquire_saved(ctx); - ret = lscsa->event_mask.slot[0]; + ret = __spufs_event_mask_get(data); spu_release(ctx); return ret; } DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, spufs_event_mask_set, "0x%llx\n") -static u64 spufs_event_status_get(void *data) +static u64 __spufs_event_status_get(void *data) { struct spu_context *ctx = data; struct spu_state *state = &ctx->csa; - u64 ret = 0; u64 stat; - - spu_acquire_saved(ctx); stat = state->spu_chnlcnt_RW[0]; if (stat) - ret = state->spu_chnldata_RW[0]; + return state->spu_chnldata_RW[0]; + return 0; +} + +static u64 spufs_event_status_get(void *data) +{ + struct spu_context *ctx = data; + u64 ret = 0; + + spu_acquire_saved(ctx); + ret = __spufs_event_status_get(data); spu_release(ctx); return ret; } @@ -1499,12 +1570,18 @@ static u64 spufs_id_get(void *data) } DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") -static u64 spufs_object_id_get(void *data) +static u64 __spufs_object_id_get(void *data) { struct spu_context *ctx = data; return ctx->object_id; } +static u64 spufs_object_id_get(void *data) +{ + /* FIXME: Should there really be no locking here? */ + return __spufs_object_id_get(data); +} + static void spufs_object_id_set(void *data, u64 id) { struct spu_context *ctx = data; @@ -1514,13 +1591,19 @@ static void spufs_object_id_set(void *data, u64 id) DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, spufs_object_id_set, "0x%llx\n"); +static u64 __spufs_lslr_get(void *data) +{ + struct spu_context *ctx = data; + return ctx->csa.priv2.spu_lslr_RW; +} + static u64 spufs_lslr_get(void *data) { struct spu_context *ctx = data; u64 ret; spu_acquire_saved(ctx); - ret = ctx->csa.priv2.spu_lslr_RW; + ret = __spufs_lslr_get(data); spu_release(ctx); return ret; @@ -1535,26 +1618,36 @@ static int spufs_info_open(struct inode *inode, struct file *file) return 0; } +static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) +{ + u32 mbox_stat; + u32 data; + + mbox_stat = ctx->csa.prob.mb_stat_R; + if (mbox_stat & 0x0000ff) { + data = ctx->csa.prob.pu_mb_R; + } + + return simple_read_from_buffer(buf, len, pos, &data, sizeof data); +} + static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { + int ret; struct spu_context *ctx = file->private_data; - u32 mbox_stat; - u32 data; if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; spu_acquire_saved(ctx); spin_lock(&ctx->csa.register_lock); - mbox_stat = ctx->csa.prob.mb_stat_R; - if (mbox_stat & 0x0000ff) { - data = ctx->csa.prob.pu_mb_R; - } + ret = __spufs_mbox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); spu_release(ctx); - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); + return ret; } static struct file_operations spufs_mbox_info_fops = { @@ -1563,26 +1656,36 @@ static struct file_operations spufs_mbox_info_fops = { .llseek = generic_file_llseek, }; +static ssize_t __spufs_ibox_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) +{ + u32 ibox_stat; + u32 data; + + ibox_stat = ctx->csa.prob.mb_stat_R; + if (ibox_stat & 0xff0000) { + data = ctx->csa.priv2.puint_mb_R; + } + + return simple_read_from_buffer(buf, len, pos, &data, sizeof data); +} + static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf, size_t len, loff_t *pos) { struct spu_context *ctx = file->private_data; - u32 ibox_stat; - u32 data; + int ret; if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; spu_acquire_saved(ctx); spin_lock(&ctx->csa.register_lock); - ibox_stat = ctx->csa.prob.mb_stat_R; - if (ibox_stat & 0xff0000) { - data = ctx->csa.priv2.puint_mb_R; - } + ret = __spufs_ibox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); spu_release(ctx); - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); + return ret; } static struct file_operations spufs_ibox_info_fops = { @@ -1591,29 +1694,39 @@ static struct file_operations spufs_ibox_info_fops = { .llseek = generic_file_llseek, }; -static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) +static ssize_t __spufs_wbox_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx = file->private_data; int i, cnt; u32 data[4]; u32 wbox_stat; + wbox_stat = ctx->csa.prob.mb_stat_R; + cnt = 4 - ((wbox_stat & 0x00ff00) >> 8); + for (i = 0; i < cnt; i++) { + data[i] = ctx->csa.spu_mailbox_data[i]; + } + + return simple_read_from_buffer(buf, len, pos, &data, + cnt * sizeof(u32)); +} + +static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int ret; + if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; spu_acquire_saved(ctx); spin_lock(&ctx->csa.register_lock); - wbox_stat = ctx->csa.prob.mb_stat_R; - cnt = (wbox_stat & 0x00ff00) >> 8; - for (i = 0; i < cnt; i++) { - data[i] = ctx->csa.spu_mailbox_data[i]; - } + ret = __spufs_wbox_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); spu_release(ctx); - return simple_read_from_buffer(buf, len, pos, &data, - cnt * sizeof(u32)); + return ret; } static struct file_operations spufs_wbox_info_fops = { @@ -1622,19 +1735,13 @@ static struct file_operations spufs_wbox_info_fops = { .llseek = generic_file_llseek, }; -static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) +static ssize_t __spufs_dma_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx = file->private_data; struct spu_dma_info info; struct mfc_cq_sr *qp, *spuqp; int i; - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - - spu_acquire_saved(ctx); - spin_lock(&ctx->csa.register_lock); info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW; info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0]; info.dma_info_status = ctx->csa.spu_chnldata_RW[24]; @@ -1649,25 +1756,40 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW; qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW; } - spin_unlock(&ctx->csa.register_lock); - spu_release(ctx); return simple_read_from_buffer(buf, len, pos, &info, sizeof info); } +static ssize_t spufs_dma_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int ret; + + if (!access_ok(VERIFY_WRITE, buf, len)) + return -EFAULT; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + ret = __spufs_dma_info_read(ctx, buf, len, pos); + spin_unlock(&ctx->csa.register_lock); + spu_release(ctx); + + return ret; +} + static struct file_operations spufs_dma_info_fops = { .open = spufs_info_open, .read = spufs_dma_info_read, }; -static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) +static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx, + char __user *buf, size_t len, loff_t *pos) { - struct spu_context *ctx = file->private_data; struct spu_proxydma_info info; - int ret = sizeof info; struct mfc_cq_sr *qp, *puqp; + int ret = sizeof info; int i; if (len < ret) @@ -1676,8 +1798,6 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, if (!access_ok(VERIFY_WRITE, buf, len)) return -EFAULT; - spu_acquire_saved(ctx); - spin_lock(&ctx->csa.register_lock); info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW; info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW; info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R; @@ -1690,12 +1810,23 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW; qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW; } + + return simple_read_from_buffer(buf, len, pos, &info, + sizeof info); +} + +static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf, + size_t len, loff_t *pos) +{ + struct spu_context *ctx = file->private_data; + int ret; + + spu_acquire_saved(ctx); + spin_lock(&ctx->csa.register_lock); + ret = __spufs_proxydma_info_read(ctx, buf, len, pos); spin_unlock(&ctx->csa.register_lock); spu_release(ctx); - if (copy_to_user(buf, &info, sizeof info)) - ret = -EFAULT; - return ret; } @@ -1760,3 +1891,27 @@ struct tree_descr spufs_dir_nosched_contents[] = { { "object-id", &spufs_object_id_ops, 0666, }, {}, }; + +struct spufs_coredump_reader spufs_coredump_read[] = { + { "regs", __spufs_regs_read, NULL, 128 * 16 }, + { "fpcr", __spufs_fpcr_read, NULL, 16 }, + { "lslr", NULL, __spufs_lslr_get, 11 }, + { "decr", NULL, __spufs_decr_get, 11 }, + { "decr_status", NULL, __spufs_decr_status_get, 11 }, + { "mem", __spufs_mem_read, NULL, 256 * 1024, }, + { "signal1", __spufs_signal1_read, NULL, 4 }, + { "signal1_type", NULL, __spufs_signal1_type_get, 2 }, + { "signal2", __spufs_signal2_read, NULL, 4 }, + { "signal2_type", NULL, __spufs_signal2_type_get, 2 }, + { "event_mask", NULL, __spufs_event_mask_get, 8 }, + { "event_status", NULL, __spufs_event_status_get, 8 }, + { "mbox_info", __spufs_mbox_info_read, NULL, 4 }, + { "ibox_info", __spufs_ibox_info_read, NULL, 4 }, + { "wbox_info", __spufs_wbox_info_read, NULL, 16 }, + { "dma_info", __spufs_dma_info_read, NULL, 69 * 8 }, + { "proxydma_info", __spufs_proxydma_info_read, NULL, 35 * 8 }, + { "object-id", NULL, __spufs_object_id_get, 19 }, + { }, +}; +int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read) - 1; + diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index d5f0a21a19d..a3ca06bd0ca 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -232,6 +232,7 @@ struct file_operations spufs_context_fops = { .readdir = dcache_readdir, .fsync = simple_sync_file, }; +EXPORT_SYMBOL_GPL(spufs_context_fops); static int spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, @@ -647,6 +648,7 @@ static struct file_system_type spufs_type = { static int __init spufs_init(void) { int ret; + ret = -ENOMEM; spufs_inode_cache = kmem_cache_create("spufs_inode_cache", sizeof(struct spufs_inode_info), 0, @@ -662,10 +664,14 @@ static int __init spufs_init(void) if (ret) goto out_cache; ret = register_spu_syscalls(&spufs_calls); + if (ret) + goto out_fs; + ret = register_arch_coredump_calls(&spufs_coredump_calls); if (ret) goto out_fs; spufs_init_isolated_loader(); + return 0; out_fs: unregister_filesystem(&spufs_type); @@ -679,6 +685,7 @@ module_init(spufs_init); static void __exit spufs_exit(void) { spu_sched_exit(); + unregister_arch_coredump_calls(&spufs_coredump_calls); unregister_spu_syscalls(&spufs_calls); unregister_filesystem(&spufs_type); kmem_cache_destroy(spufs_inode_cache); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 23d20f38056..70fb13395c0 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -223,4 +223,15 @@ void spufs_stop_callback(struct spu *spu); void spufs_mfc_callback(struct spu *spu); void spufs_dma_callback(struct spu *spu, int type); +extern struct spu_coredump_calls spufs_coredump_calls; +struct spufs_coredump_reader { + char *name; + ssize_t (*read)(struct spu_context *ctx, + char __user *buffer, size_t size, loff_t *pos); + u64 (*get)(void *data); + size_t size; +}; +extern struct spufs_coredump_reader spufs_coredump_read[]; +extern int spufs_coredump_num_notes; + #endif -- cgit v1.2.3 From 5850dd8f6d4e79484d498c0d77b223d1041f9954 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 23 Nov 2006 00:46:38 +0100 Subject: [POWERPC] cell: hard disable interrupts in power_save() With soft-disabled interrupts in power_save, we can still get external exceptions on Cell, even if we are in pause(0) a.k.a. sleep state. When the CPU really wakes up through the 0x100 (system reset) vector, while we have already started processing the 0x500 (external) exception, we get a panic in unrecoverable_exception() because of the lost state. This occurred in Systemsim for Cell, but as far as I can see, it can theoretically occur on any machine that uses the system reset exception to get out of sleep state. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/pervasive.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index c68fabdc787..8c20f0fb865 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -41,6 +41,15 @@ static void cbe_power_save(void) { unsigned long ctrl, thread_switch_control; + + /* + * We need to hard disable interrupts, but we also need to mark them + * hard disabled in the PACA so that the local_irq_enable() done by + * our caller upon return propertly hard enables. + */ + hard_irq_disable(); + get_paca()->hard_enabled = 0; + ctrl = mfspr(SPRN_CTRLF); /* Enable DEC and EE interrupt request */ -- cgit v1.2.3 From 437a0706837d09d8ab071c6790da07d9d6bb3d22 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:39 +0100 Subject: [POWERPC] Fix sparse warning in xmon Cell code My patch to add spu helpers to xmon (a898497088f46252e6750405504064e2dce53117) introduced a few sparse warnings, because I was dereferencing an __iomem pointer. I think the best way to handle it is to actually use the appropriate in_beXX functions. Need to rejigger the DUMP macro a little to accomodate that. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/xmon.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d66c3a17032..6b9d720f7ff 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2748,13 +2748,13 @@ static void restart_spus(void) } #define DUMP_WIDTH 23 -#define DUMP_FIELD(obj, format, field) \ +#define DUMP_VALUE(format, field, value) \ do { \ if (setjmp(bus_error_jmp) == 0) { \ catch_memory_errors = 1; \ sync(); \ printf(" %-*s = "format"\n", DUMP_WIDTH, \ - #field, obj->field); \ + #field, value); \ sync(); \ __delay(200); \ } else { \ @@ -2765,6 +2765,9 @@ do { \ catch_memory_errors = 0; \ } while (0) +#define DUMP_FIELD(obj, format, field) \ + DUMP_VALUE(format, field, obj->field) + static void dump_spu_fields(struct spu *spu) { printf("Dumping spu fields at address %p:\n", spu); @@ -2793,13 +2796,18 @@ static void dump_spu_fields(struct spu *spu) DUMP_FIELD(spu, "0x%p", timestamp); DUMP_FIELD(spu, "0x%lx", problem_phys); DUMP_FIELD(spu, "0x%p", problem); - DUMP_FIELD(spu, "0x%x", problem->spu_runcntl_RW); - DUMP_FIELD(spu, "0x%x", problem->spu_status_R); - DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW); + DUMP_VALUE("0x%x", problem->spu_runcntl_RW, + in_be32(&spu->problem->spu_runcntl_RW)); + DUMP_VALUE("0x%x", problem->spu_status_R, + in_be32(&spu->problem->spu_status_R)); + DUMP_VALUE("0x%x", problem->spu_npc_RW, + in_be32(&spu->problem->spu_npc_RW)); DUMP_FIELD(spu, "0x%p", priv1); - if (spu->priv1) - DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW); + if (spu->priv1) { + DUMP_VALUE("0x%lx", priv1->mfc_sr1_RW, + in_be64(&spu->priv1->mfc_sr1_RW)); + } DUMP_FIELD(spu, "0x%p", priv2); } -- cgit v1.2.3 From 2a14442bfebfea23d004fa4dfd067a94f5720ed7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:40 +0100 Subject: [POWERPC] Show state of spus as theyre stopped in Cell xmon helper After stopping spus in xmon I often find myself trawling through the field dumps to find out which spus were running. The spu stopping code actually knows what's running, so let's print it out to save the user some futzing. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/xmon.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 6b9d720f7ff..ac17abbe3ef 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2702,7 +2702,10 @@ static void stop_spus(void) __delay(200); spu_info[i].stopped_ok = 1; - printf("Stopped spu %.2d\n", i); + + printf("Stopped spu %.2d (was %s)\n", i, + spu_info[i].saved_spu_runcntl_RW ? + "running" : "stopped"); } else { catch_memory_errors = 0; printf("*** Error stopping spu %.2d\n", i); -- cgit v1.2.3 From 24a24c85d3c35790a355138d7cd34c074cb1b3ac Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:41 +0100 Subject: [POWERPC] Add a sd command (spu dump) to xmon to dump spu local store Add a command to xmon to dump the memory of a spu's local store. This mimics the 'd' command which dumps regular memory, but does a little hand holding by taking the user supplied address and finding that offset in the local store for the specified spu. This makes it easy for example to look at what was executing on a spu: 1:mon> ss ... Stopped spu 04 (was running) ... 1:mon> sf 4 Dumping spu fields at address c0000000019e0a00: ... problem->spu_npc_RW = 0x228 ... 1:mon> sd 4 0x228 d000080080318228 01a00c021cffc408 4020007f217ff488 |........@ ..!...| Aha, 01a00c02, which is of course rdch $2,$ch24 ! -- Updated to only do the setjmp goo around the spu access, and not around prdump because it does its own (via mread). Also the num variable is now common between sf and sd, so you don't have to keep typing the spu number in if you're repeating commands on the same spu. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/xmon.c | 60 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index ac17abbe3ef..be2c12d6878 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -218,7 +218,8 @@ Commands:\n\ #ifdef CONFIG_PPC_CELL " ss stop execution on all spus\n\ sr restore execution on stopped spus\n\ - sf # dump spu fields for spu # (in hex)\n" + sf # dump spu fields for spu # (in hex)\n\ + sd # dump spu local store for spu # (in hex)\n" #endif " S print special registers\n\ t print backtrace\n\ @@ -2651,6 +2652,7 @@ struct spu_info { struct spu *spu; u64 saved_mfc_sr1_RW; u32 saved_spu_runcntl_RW; + unsigned long dump_addr; u8 stopped_ok; }; @@ -2670,6 +2672,8 @@ void xmon_register_spus(struct list_head *list) spu_info[spu->number].spu = spu; spu_info[spu->number].stopped_ok = 0; + spu_info[spu->number].dump_addr = (unsigned long) + spu_info[spu->number].spu->local_store; } } @@ -2815,9 +2819,43 @@ static void dump_spu_fields(struct spu *spu) DUMP_FIELD(spu, "0x%p", priv2); } +static void dump_spu_ls(unsigned long num) +{ + unsigned long offset, addr, ls_addr; + + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + ls_addr = (unsigned long)spu_info[num].spu->local_store; + sync(); + __delay(200); + } else { + catch_memory_errors = 0; + printf("*** Error: accessing spu info for spu %d\n", num); + return; + } + catch_memory_errors = 0; + + if (scanhex(&offset)) + addr = ls_addr + offset; + else + addr = spu_info[num].dump_addr; + + if (addr >= ls_addr + LS_SIZE) { + printf("*** Error: address outside of local store\n"); + return; + } + + prdump(addr, 64); + addr += 64; + last_cmd = "sd\n"; + + spu_info[num].dump_addr = addr; +} + static int do_spu_cmd(void) { - unsigned long num = 0; + static unsigned long num = 0; int cmd; cmd = inchar(); @@ -2829,10 +2867,22 @@ static int do_spu_cmd(void) restart_spus(); break; case 'f': - if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu) - dump_spu_fields(spu_info[num].spu); - else + case 'd': + scanhex(&num); + if (num >= XMON_NUM_SPUS || !spu_info[num].spu) { printf("*** Error: invalid spu number\n"); + return 0; + } + + switch (cmd) { + case 'f': + dump_spu_fields(spu_info[num].spu); + break; + default: + dump_spu_ls(num); + break; + } + break; default: return -1; -- cgit v1.2.3 From 4c4c8723684b1b2cd0dfdf5e0685f35642bde253 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:42 +0100 Subject: [POWERPC] Prepare for spu disassembly in xmon In order to do disassembly of spu binaries in xmon, we need to abstract the disassembly function from ppc_inst_dump. We do this by making the actual disassembly function a function pointer that we pass to ppc_inst_dump(). To save updating all the callers, we turn ppc_inst_dump() into generic_inst_dump() and make ppc_inst_dump() a wrapper which always uses print_insn_powerpc(). Currently we pass the dialect into print_insn_powerpc(), but we always pass 0 - so just make it a local. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/ppc-dis.c | 6 +++--- arch/powerpc/xmon/xmon.c | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c index ac0a9d2427e..3b67bee4830 100644 --- a/arch/powerpc/xmon/ppc-dis.c +++ b/arch/powerpc/xmon/ppc-dis.c @@ -27,14 +27,14 @@ extern void print_address (unsigned long memaddr); /* Print a PowerPC or POWER instruction. */ int -print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect) +print_insn_powerpc (unsigned long insn, unsigned long memaddr) { const struct powerpc_opcode *opcode; const struct powerpc_opcode *opcode_end; unsigned long op; + int dialect; - if (dialect == 0) - dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON + dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; /* Get the major opcode of the instruction. */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index be2c12d6878..a39b17638b7 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -154,7 +154,7 @@ static int do_spu_cmd(void); int xmon_no_auto_backtrace; -extern int print_insn_powerpc(unsigned long, unsigned long, int); +extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr); extern void xmon_enter(void); extern void xmon_leave(void); @@ -2068,8 +2068,11 @@ prdump(unsigned long adrs, long ndump) } } +typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr); + int -ppc_inst_dump(unsigned long adr, long count, int praddr) +generic_inst_dump(unsigned long adr, long count, int praddr, + instruction_dump_func dump_func) { int nr, dotted; unsigned long first_adr; @@ -2099,12 +2102,18 @@ ppc_inst_dump(unsigned long adr, long count, int praddr) if (praddr) printf(REG" %.8x", adr, inst); printf("\t"); - print_insn_powerpc(inst, adr, 0); /* always returns 4 */ + dump_func(inst, adr); printf("\n"); } return adr - first_adr; } +int +ppc_inst_dump(unsigned long adr, long count, int praddr) +{ + return generic_inst_dump(adr, count, praddr, print_insn_powerpc); +} + void print_address(unsigned long addr) { -- cgit v1.2.3 From ae06e374c15c5d62e08c19c15f2c247a86e240d4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:43 +0100 Subject: [POWERPC] Import spu disassembly code into xmon This patch imports and munges the spu disassembly code from binutils. All files originated from version 1.1 in binutils cvs. * spu.h, spu-insns.h and spu-opc.c are unchanged except for pathnames. * spu-dis.c has been edited heavily: * use printf instead of info->fprintf_func and similar. * pass the instruction in rather than reading it. * we have no equivalent to symbol_at_address_func, so we just assume there is never a symbol at the address given. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/spu-dis.c | 249 +++++++++++++++++++++++++ arch/powerpc/xmon/spu-insns.h | 410 ++++++++++++++++++++++++++++++++++++++++++ arch/powerpc/xmon/spu-opc.c | 44 +++++ arch/powerpc/xmon/spu.h | 126 +++++++++++++ 4 files changed, 829 insertions(+) create mode 100644 arch/powerpc/xmon/spu-dis.c create mode 100644 arch/powerpc/xmon/spu-insns.h create mode 100644 arch/powerpc/xmon/spu-opc.c create mode 100644 arch/powerpc/xmon/spu.h (limited to 'arch') diff --git a/arch/powerpc/xmon/spu-dis.c b/arch/powerpc/xmon/spu-dis.c new file mode 100644 index 00000000000..75ac0815f1a --- /dev/null +++ b/arch/powerpc/xmon/spu-dis.c @@ -0,0 +1,249 @@ +/* Disassemble SPU instructions + + Copyright 2006 Free Software Foundation, Inc. + + This file is part of GDB, GAS, and the GNU binutils. + + 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., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include +#include "nonstdio.h" +#include "ansidecl.h" +#include "spu.h" + +extern void print_address (unsigned long memaddr); + +/* This file provides a disassembler function which uses + the disassembler interface defined in dis-asm.h. */ + +extern const struct spu_opcode spu_opcodes[]; +extern const int spu_num_opcodes; + +#define SPU_DISASM_TBL_SIZE (1 << 11) +static const struct spu_opcode *spu_disassemble_table[SPU_DISASM_TBL_SIZE]; + +static void +init_spu_disassemble (void) +{ + int i; + + /* If two instructions have the same opcode then we prefer the first + * one. In most cases it is just an alternate mnemonic. */ + for (i = 0; i < spu_num_opcodes; i++) + { + int o = spu_opcodes[i].opcode; + if (o >= SPU_DISASM_TBL_SIZE) + continue; /* abort (); */ + if (spu_disassemble_table[o] == 0) + spu_disassemble_table[o] = &spu_opcodes[i]; + } +} + +/* Determine the instruction from the 10 least significant bits. */ +static const struct spu_opcode * +get_index_for_opcode (unsigned int insn) +{ + const struct spu_opcode *index; + unsigned int opcode = insn >> (32-11); + + /* Init the table. This assumes that element 0/opcode 0 (currently + * NOP) is always used */ + if (spu_disassemble_table[0] == 0) + init_spu_disassemble (); + + if ((index = spu_disassemble_table[opcode & 0x780]) != 0 + && index->insn_type == RRR) + return index; + + if ((index = spu_disassemble_table[opcode & 0x7f0]) != 0 + && (index->insn_type == RI18 || index->insn_type == LBT)) + return index; + + if ((index = spu_disassemble_table[opcode & 0x7f8]) != 0 + && index->insn_type == RI10) + return index; + + if ((index = spu_disassemble_table[opcode & 0x7fc]) != 0 + && (index->insn_type == RI16)) + return index; + + if ((index = spu_disassemble_table[opcode & 0x7fe]) != 0 + && (index->insn_type == RI8)) + return index; + + if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0) + return index; + + return 0; +} + +/* Print a Spu instruction. */ + +int +print_insn_spu (unsigned long insn, unsigned long memaddr) +{ + int value; + int hex_value; + const struct spu_opcode *index; + enum spu_insns tag; + + index = get_index_for_opcode (insn); + + if (index == 0) + { + printf(".long 0x%x", insn); + } + else + { + int i; + int paren = 0; + tag = (enum spu_insns)(index - spu_opcodes); + printf("%s", index->mnemonic); + if (tag == M_BI || tag == M_BISL || tag == M_IRET || tag == M_BISLED + || tag == M_BIHNZ || tag == M_BIHZ || tag == M_BINZ || tag == M_BIZ + || tag == M_SYNC || tag == M_HBR) + { + int fb = (insn >> (32-18)) & 0x7f; + if (fb & 0x40) + printf(tag == M_SYNC ? "c" : "p"); + if (fb & 0x20) + printf("d"); + if (fb & 0x10) + printf("e"); + } + if (index->arg[0] != 0) + printf("\t"); + hex_value = 0; + for (i = 1; i <= index->arg[0]; i++) + { + int arg = index->arg[i]; + if (arg != A_P && !paren && i > 1) + printf(","); + + switch (arg) + { + case A_T: + printf("$%d", + DECODE_INSN_RT (insn)); + break; + case A_A: + printf("$%d", + DECODE_INSN_RA (insn)); + break; + case A_B: + printf("$%d", + DECODE_INSN_RB (insn)); + break; + case A_C: + printf("$%d", + DECODE_INSN_RC (insn)); + break; + case A_S: + printf("$sp%d", + DECODE_INSN_RA (insn)); + break; + case A_H: + printf("$ch%d", + DECODE_INSN_RA (insn)); + break; + case A_P: + paren++; + printf("("); + break; + case A_U7A: + printf("%d", + 173 - DECODE_INSN_U8 (insn)); + break; + case A_U7B: + printf("%d", + 155 - DECODE_INSN_U8 (insn)); + break; + case A_S3: + case A_S6: + case A_S7: + case A_S7N: + case A_U3: + case A_U5: + case A_U6: + case A_U7: + hex_value = DECODE_INSN_I7 (insn); + printf("%d", hex_value); + break; + case A_S11: + print_address(memaddr + DECODE_INSN_I9a (insn) * 4); + break; + case A_S11I: + print_address(memaddr + DECODE_INSN_I9b (insn) * 4); + break; + case A_S10: + case A_S10B: + hex_value = DECODE_INSN_I10 (insn); + printf("%d", hex_value); + break; + case A_S14: + hex_value = DECODE_INSN_I10 (insn) * 16; + printf("%d", hex_value); + break; + case A_S16: + hex_value = DECODE_INSN_I16 (insn); + printf("%d", hex_value); + break; + case A_X16: + hex_value = DECODE_INSN_U16 (insn); + printf("%u", hex_value); + break; + case A_R18: + value = DECODE_INSN_I16 (insn) * 4; + if (value == 0) + printf("%d", value); + else + { + hex_value = memaddr + value; + print_address(hex_value & 0x3ffff); + } + break; + case A_S18: + value = DECODE_INSN_U16 (insn) * 4; + if (value == 0) + printf("%d", value); + else + print_address(value); + break; + case A_U18: + value = DECODE_INSN_U18 (insn); + if (value == 0 || 1) + { + hex_value = value; + printf("%u", value); + } + else + print_address(value); + break; + case A_U14: + hex_value = DECODE_INSN_U14 (insn); + printf("%u", hex_value); + break; + } + if (arg != A_P && paren) + { + printf(")"); + paren--; + } + } + if (hex_value > 16) + printf("\t# %x", hex_value); + } + return 4; +} diff --git a/arch/powerpc/xmon/spu-insns.h b/arch/powerpc/xmon/spu-insns.h new file mode 100644 index 00000000000..99dc452821a --- /dev/null +++ b/arch/powerpc/xmon/spu-insns.h @@ -0,0 +1,410 @@ +/* SPU ELF support for BFD. + + Copyright 2006 Free Software Foundation, Inc. + + This file is part of BFD, the Binary File Descriptor library. + + 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* SPU Opcode Table + +-=-=-= FORMAT =-=-=- + + +----+-------+-------+-------+-------+ +------------+-------+-------+-------+ +RRR | op | RC | RB | RA | RT | RI7 | op | I7 | RA | RT | + +----+-------+-------+-------+-------+ +------------+-------+-------+-------+ + 0 3 1 1 2 3 0 1 1 2 3 + 0 7 4 1 0 7 4 1 + + +-----------+--------+-------+-------+ +---------+----------+-------+-------+ +RI8 | op | I8 | RA | RT | RI10 | op | I10 | RA | RT | + +-----------+--------+-------+-------+ +---------+----------+-------+-------+ + 0 9 1 2 3 0 7 1 2 3 + 7 4 1 7 4 1 + + +----------+-----------------+-------+ +--------+-------------------+-------+ +RI16 | op | I16 | RT | RI18 | op | I18 | RT | + +----------+-----------------+-------+ +--------+-------------------+-------+ + 0 8 2 3 0 6 2 3 + 4 1 4 1 + + +------------+-------+-------+-------+ +-------+--+-----------------+-------+ +RR | op | RB | RA | RT | LBT | op |RO| I16 | RO | + +------------+-------+-------+-------+ +-------+--+-----------------+-------+ + 0 1 1 2 3 0 6 8 2 3 + 0 7 4 1 4 1 + + +------------+----+--+-------+-------+ + LBTI | op | // |RO| RA | RO | + +------------+----+--+-------+-------+ + 0 1 1 1 2 3 + 0 5 7 4 1 + +-=-=-= OPCODE =-=-=- + +OPCODE field specifies the most significant 11bit of the instruction. Some formats don't have 11bits for opcode field, and in this +case, bit field other than op are defined as 0s. For example, opcode of fma instruction which is RRR format is defined as 0x700, +since 0x700 -> 11'b11100000000, this means opcode is 4'b1110, and other 7bits are defined as 7'b0000000. + +-=-=-= ASM_FORMAT =-=-=- + +RRR category RI7 category + ASM_RRR mnemonic RC, RA, RB, RT ASM_RI4 mnemonic RT, RA, I4 + ASM_RI7 mnemonic RT, RA, I7 + +RI8 category RI10 category + ASM_RUI8 mnemonic RT, RA, UI8 ASM_AI10 mnemonic RA, I10 + ASM_RI10 mnemonic RT, RA, R10 + ASM_RI10IDX mnemonic RT, I10(RA) + +RI16 category RI18 category + ASM_I16W mnemonic I16W ASM_RI18 mnemonic RT, I18 + ASM_RI16 mnemonic RT, I16 + ASM_RI16W mnemonic RT, I16W + +RR category LBT category + ASM_MFSPR mnemonic RT, SA ASM_LBT mnemonic brinst, brtarg + ASM_MTSPR mnemonic SA, RT + ASM_NOOP mnemonic LBTI category + ASM_RA mnemonic RA ASM_LBTI mnemonic brinst, RA + ASM_RAB mnemonic RA, RB + ASM_RDCH mnemonic RT, CA + ASM_RR mnemonic RT, RA, RB + ASM_RT mnemonic RT + ASM_RTA mnemonic RT, RA + ASM_WRCH mnemonic CA, RT + +Note that RRR instructions have the names for RC and RT reversed from +what's in the ISA, in order to put RT in the same position it appears +for other formats. + +-=-=-= DEPENDENCY =-=-=- + +DEPENDENCY filed consists of 5 digits. This represents which register is used as source and which register is used as target. +The first(most significant) digit is always 0. Then it is followd by RC, RB, RA and RT digits. +If the digit is 0, this means the corresponding register is not used in the instruction. +If the digit is 1, this means the corresponding register is used as a source in the instruction. +If the digit is 2, this means the corresponding register is used as a target in the instruction. +If the digit is 3, this means the corresponding register is used as both source and target in the instruction. +For example, fms instruction has 00113 as the DEPENDENCY field. This means RC is not used in this operation, RB and RA are +used as sources and RT is the target. + +-=-=-= PIPE =-=-=- + +This field shows which execution pipe is used for the instruction + +pipe0 execution pipelines: + FP6 SP floating pipeline + FP7 integer operations executed in SP floating pipeline + FPD DP floating pipeline + FX2 FXU pipeline + FX3 Rotate/Shift pipeline + FXB Byte pipeline + NOP No pipeline + +pipe1 execution pipelines: + BR Branch pipeline + LNOP No pipeline + LS Load/Store pipeline + SHUF Shuffle pipeline + SPR SPR/CH pipeline + +*/ + +#define _A0() {0} +#define _A1(a) {1,a} +#define _A2(a,b) {2,a,b} +#define _A3(a,b,c) {3,a,b,c} +#define _A4(a,b,c,d) {4,a,b,c,d} + +/* TAG FORMAT OPCODE MNEMONIC ASM_FORMAT DEPENDENCY PIPE COMMENT */ +/* 0[RC][RB][RA][RT] */ +/* 1:src, 2:target */ + +APUOP(M_BR, RI16, 0x190, "br", _A1(A_R18), 00000, BR) /* BRel IP<-IP+I16 */ +APUOP(M_BRSL, RI16, 0x198, "brsl", _A2(A_T,A_R18), 00002, BR) /* BRelSetLink RT,IP<-IP,IP+I16 */ +APUOP(M_BRA, RI16, 0x180, "bra", _A1(A_S18), 00000, BR) /* BRAbs IP<-I16 */ +APUOP(M_BRASL, RI16, 0x188, "brasl", _A2(A_T,A_S18), 00002, BR) /* BRAbsSetLink RT,IP<-IP,I16 */ +APUOP(M_FSMBI, RI16, 0x194, "fsmbi", _A2(A_T,A_X16), 00002, SHUF) /* FormSelMask%I RT<-fsm(I16) */ +APUOP(M_LQA, RI16, 0x184, "lqa", _A2(A_T,A_S18), 00002, LS) /* LoadQAbs RT<-M[I16] */ +APUOP(M_LQR, RI16, 0x19C, "lqr", _A2(A_T,A_R18), 00002, LS) /* LoadQRel RT<-M[IP+I16] */ +APUOP(M_STOP, RR, 0x000, "stop", _A0(), 00000, BR) /* STOP stop */ +APUOP(M_STOP2, RR, 0x000, "stop", _A1(A_U14), 00000, BR) /* STOP stop */ +APUOP(M_STOPD, RR, 0x140, "stopd", _A3(A_T,A_A,A_B), 00111, BR) /* STOPD stop (with register dependencies) */ +APUOP(M_LNOP, RR, 0x001, "lnop", _A0(), 00000, LNOP) /* LNOP no_operation */ +APUOP(M_SYNC, RR, 0x002, "sync", _A0(), 00000, BR) /* SYNC flush_pipe */ +APUOP(M_DSYNC, RR, 0x003, "dsync", _A0(), 00000, BR) /* DSYNC flush_store_queue */ +APUOP(M_MFSPR, RR, 0x00c, "mfspr", _A2(A_T,A_S), 00002, SPR) /* MFSPR RT<-SA */ +APUOP(M_RDCH, RR, 0x00d, "rdch", _A2(A_T,A_H), 00002, SPR) /* ReaDCHannel RT<-CA:data */ +APUOP(M_RCHCNT, RR, 0x00f, "rchcnt", _A2(A_T,A_H), 00002, SPR) /* ReaDCHanCouNT RT<-CA:count */ +APUOP(M_HBRA, LBT, 0x080, "hbra", _A2(A_S11,A_S18), 00000, LS) /* HBRA BTB[B9]<-M[I16] */ +APUOP(M_HBRR, LBT, 0x090, "hbrr", _A2(A_S11,A_R18), 00000, LS) /* HBRR BTB[B9]<-M[IP+I16] */ +APUOP(M_BRZ, RI16, 0x100, "brz", _A2(A_T,A_R18), 00001, BR) /* BRZ IP<-IP+I16_if(RT) */ +APUOP(M_BRNZ, RI16, 0x108, "brnz", _A2(A_T,A_R18), 00001, BR) /* BRNZ IP<-IP+I16_if(RT) */ +APUOP(M_BRHZ, RI16, 0x110, "brhz", _A2(A_T,A_R18), 00001, BR) /* BRHZ IP<-IP+I16_if(RT) */ +APUOP(M_BRHNZ, RI16, 0x118, "brhnz", _A2(A_T,A_R18), 00001, BR) /* BRHNZ IP<-IP+I16_if(RT) */ +APUOP(M_STQA, RI16, 0x104, "stqa", _A2(A_T,A_S18), 00001, LS) /* SToreQAbs M[I16]<-RT */ +APUOP(M_STQR, RI16, 0x11C, "stqr", _A2(A_T,A_R18), 00001, LS) /* SToreQRel M[IP+I16]<-RT */ +APUOP(M_MTSPR, RR, 0x10c, "mtspr", _A2(A_S,A_T), 00001, SPR) /* MTSPR SA<-RT */ +APUOP(M_WRCH, RR, 0x10d, "wrch", _A2(A_H,A_T), 00001, SPR) /* ChanWRite CA<-RT */ +APUOP(M_LQD, RI10, 0x1a0, "lqd", _A4(A_T,A_S14,A_P,A_A), 00012, LS) /* LoadQDisp RT<-M[Ra+I10] */ +APUOP(M_BI, RR, 0x1a8, "bi", _A1(A_A), 00010, BR) /* BI IP<-RA */ +APUOP(M_BISL, RR, 0x1a9, "bisl", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */ +APUOP(M_IRET, RR, 0x1aa, "iret", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */ +APUOP(M_IRET2, RR, 0x1aa, "iret", _A0(), 00010, BR) /* IRET IP<-SRR0 */ +APUOP(M_BISLED, RR, 0x1ab, "bisled", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */ +APUOP(M_HBR, LBTI, 0x1ac, "hbr", _A2(A_S11I,A_A), 00010, LS) /* HBR BTB[B9]<-M[Ra] */ +APUOP(M_FREST, RR, 0x1b8, "frest", _A2(A_T,A_A), 00012, SHUF) /* FREST RT<-recip(RA) */ +APUOP(M_FRSQEST, RR, 0x1b9, "frsqest", _A2(A_T,A_A), 00012, SHUF) /* FRSQEST RT<-rsqrt(RA) */ +APUOP(M_FSM, RR, 0x1b4, "fsm", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */ +APUOP(M_FSMH, RR, 0x1b5, "fsmh", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */ +APUOP(M_FSMB, RR, 0x1b6, "fsmb", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */ +APUOP(M_GB, RR, 0x1b0, "gb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */ +APUOP(M_GBH, RR, 0x1b1, "gbh", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */ +APUOP(M_GBB, RR, 0x1b2, "gbb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */ +APUOP(M_CBD, RI7, 0x1f4, "cbd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */ +APUOP(M_CHD, RI7, 0x1f5, "chd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */ +APUOP(M_CWD, RI7, 0x1f6, "cwd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */ +APUOP(M_CDD, RI7, 0x1f7, "cdd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */ +APUOP(M_ROTQBII, RI7, 0x1f8, "rotqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* ROTQBII RT<-RA<<I10) */ +APUOP(M_CGTHI, RI10, 0x268, "cgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */ +APUOP(M_CGTI, RI10, 0x260, "cgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */ +APUOP(M_CLGTBI, RI10, 0x2f0, "clgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CLGT%I RT<-(RA>I10) */ +APUOP(M_CLGTHI, RI10, 0x2e8, "clgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */ +APUOP(M_CLGTI, RI10, 0x2e0, "clgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */ +APUOP(M_CEQBI, RI10, 0x3f0, "ceqbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CEQ%I RT<-(RA=I10) */ +APUOP(M_CEQHI, RI10, 0x3e8, "ceqhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */ +APUOP(M_CEQI, RI10, 0x3e0, "ceqi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */ +APUOP(M_HGTI, RI10, 0x278, "hgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */ +APUOP(M_HGTI2, RI10, 0x278, "hgti", _A2(A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */ +APUOP(M_HLGTI, RI10, 0x2f8, "hlgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */ +APUOP(M_HLGTI2, RI10, 0x2f8, "hlgti", _A2(A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */ +APUOP(M_HEQI, RI10, 0x3f8, "heqi", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */ +APUOP(M_HEQI2, RI10, 0x3f8, "heqi", _A2(A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */ +APUOP(M_MPYI, RI10, 0x3a0, "mpyi", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYI RT<-RA*I10 */ +APUOP(M_MPYUI, RI10, 0x3a8, "mpyui", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYUI RT<-RA*I10 */ +APUOP(M_CFLTS, RI8, 0x3b0, "cflts", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTS RT<-int(RA,I8) */ +APUOP(M_CFLTU, RI8, 0x3b2, "cfltu", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTU RT<-int(RA,I8) */ +APUOP(M_CSFLT, RI8, 0x3b4, "csflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CSFLT RT<-flt(RA,I8) */ +APUOP(M_CUFLT, RI8, 0x3b6, "cuflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CUFLT RT<-flt(RA,I8) */ +APUOP(M_FESD, RR, 0x3b8, "fesd", _A2(A_T,A_A), 00012, FPD) /* FESD RT<-double(RA) */ +APUOP(M_FRDS, RR, 0x3b9, "frds", _A2(A_T,A_A), 00012, FPD) /* FRDS RT<-single(RA) */ +APUOP(M_FSCRRD, RR, 0x398, "fscrrd", _A1(A_T), 00002, FPD) /* FSCRRD RT<-FP_status */ +APUOP(M_FSCRWR, RR, 0x3ba, "fscrwr", _A2(A_T,A_A), 00010, FP7) /* FSCRWR FP_status<-RA */ +APUOP(M_FSCRWR2, RR, 0x3ba, "fscrwr", _A1(A_A), 00010, FP7) /* FSCRWR FP_status<-RA */ +APUOP(M_CLZ, RR, 0x2a5, "clz", _A2(A_T,A_A), 00012, FX2) /* CLZ RT<-clz(RA) */ +APUOP(M_CNTB, RR, 0x2b4, "cntb", _A2(A_T,A_A), 00012, FXB) /* CNT RT<-pop(RA) */ +APUOP(M_XSBH, RR, 0x2b6, "xsbh", _A2(A_T,A_A), 00012, FX2) /* eXtSignBtoH RT<-sign_ext(RA) */ +APUOP(M_XSHW, RR, 0x2ae, "xshw", _A2(A_T,A_A), 00012, FX2) /* eXtSignHtoW RT<-sign_ext(RA) */ +APUOP(M_XSWD, RR, 0x2a6, "xswd", _A2(A_T,A_A), 00012, FX2) /* eXtSignWtoD RT<-sign_ext(RA) */ +APUOP(M_ROTI, RI7, 0x078, "roti", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<RB) */ +APUOP(M_CGTB, RR, 0x250, "cgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */ +APUOP(M_CGTH, RR, 0x248, "cgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */ +APUOP(M_CLGT, RR, 0x2c0, "clgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */ +APUOP(M_CLGTB, RR, 0x2d0, "clgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */ +APUOP(M_CLGTH, RR, 0x2c8, "clgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */ +APUOP(M_CEQ, RR, 0x3c0, "ceq", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */ +APUOP(M_CEQB, RR, 0x3d0, "ceqb", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */ +APUOP(M_CEQH, RR, 0x3c8, "ceqh", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */ +APUOP(M_HGT, RR, 0x258, "hgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */ +APUOP(M_HGT2, RR, 0x258, "hgt", _A2(A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */ +APUOP(M_HLGT, RR, 0x2d8, "hlgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */ +APUOP(M_HLGT2, RR, 0x2d8, "hlgt", _A2(A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */ +APUOP(M_HEQ, RR, 0x3d8, "heq", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */ +APUOP(M_HEQ2, RR, 0x3d8, "heq", _A2(A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */ +APUOP(M_FCEQ, RR, 0x3c2, "fceq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCEQ RT<-(RA=RB) */ +APUOP(M_FCMEQ, RR, 0x3ca, "fcmeq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMEQ RT<-(|RA|=|RB|) */ +APUOP(M_FCGT, RR, 0x2c2, "fcgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCGT RT<-(RA>16 */ +APUOP(M_MPYU, RR, 0x3cc, "mpyu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYU RT<-RA*RB */ +APUOP(M_FI, RR, 0x3d4, "fi", _A3(A_T,A_A,A_B), 00112, FP7) /* FInterpolate RT<-f(RA,RB) */ +APUOP(M_ROT, RR, 0x058, "rot", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<> (32-size)) +#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1)) + +#define DECODE_INSN_RT(insn) (insn & 0x7f) +#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f) +#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f) +#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f) + +#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14) +#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14) + +/* For branching, immediate loads, hbr and lqa/stqa. */ +#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7) +#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7) + +/* for stop */ +#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0) + +/* For ila */ +#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7) +#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7) + +/* For rotate and shift and generate control mask */ +#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14) +#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14) + +/* For float <-> int conversion */ +#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14) +#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14) + +/* For hbr */ +#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) +#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) +#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0)) +#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0)) + -- cgit v1.2.3 From af89fb8041562508895c8f3ba04790d7c2f4338c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:44 +0100 Subject: [POWERPC] Add spu disassembly to xmon This patch adds a "sdi" command to xmon, to disassemble the contents of an spu's local store. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/Makefile | 1 + arch/powerpc/xmon/xmon.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 109d874ecfb..4f274056e77 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -5,3 +5,4 @@ EXTRA_CFLAGS += -mno-minimal-toc endif obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \ nonstdio.o +obj-$(CONFIG_PPC_CELL) += spu-dis.o spu-opc.o diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a39b17638b7..7a0eec23cb9 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -155,6 +155,7 @@ static int do_spu_cmd(void); int xmon_no_auto_backtrace; extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr); +extern int print_insn_spu(unsigned long insn, unsigned long memaddr); extern void xmon_enter(void); extern void xmon_leave(void); @@ -219,7 +220,8 @@ Commands:\n\ " ss stop execution on all spus\n\ sr restore execution on stopped spus\n\ sf # dump spu fields for spu # (in hex)\n\ - sd # dump spu local store for spu # (in hex)\n" + sd # dump spu local store for spu # (in hex)\ + sdi # disassemble spu local store for spu # (in hex)\n" #endif " S print special registers\n\ t print backtrace\n\ @@ -2828,7 +2830,13 @@ static void dump_spu_fields(struct spu *spu) DUMP_FIELD(spu, "0x%p", priv2); } -static void dump_spu_ls(unsigned long num) +int +spu_inst_dump(unsigned long adr, long count, int praddr) +{ + return generic_inst_dump(adr, count, praddr, print_insn_spu); +} + +static void dump_spu_ls(unsigned long num, int subcmd) { unsigned long offset, addr, ls_addr; @@ -2855,9 +2863,17 @@ static void dump_spu_ls(unsigned long num) return; } - prdump(addr, 64); - addr += 64; - last_cmd = "sd\n"; + switch (subcmd) { + case 'i': + addr += spu_inst_dump(addr, 16, 1); + last_cmd = "sdi\n"; + break; + default: + prdump(addr, 64); + addr += 64; + last_cmd = "sd\n"; + break; + } spu_info[num].dump_addr = addr; } @@ -2865,7 +2881,7 @@ static void dump_spu_ls(unsigned long num) static int do_spu_cmd(void) { static unsigned long num = 0; - int cmd; + int cmd, subcmd = 0; cmd = inchar(); switch (cmd) { @@ -2875,8 +2891,11 @@ static int do_spu_cmd(void) case 'r': restart_spus(); break; - case 'f': case 'd': + subcmd = inchar(); + if (isxdigit(subcmd) || subcmd == '\n') + termch = subcmd; + case 'f': scanhex(&num); if (num >= XMON_NUM_SPUS || !spu_info[num].spu) { printf("*** Error: invalid spu number\n"); @@ -2888,7 +2907,7 @@ static int do_spu_cmd(void) dump_spu_fields(spu_info[num].spu); break; default: - dump_spu_ls(num); + dump_spu_ls(num, subcmd); break; } -- cgit v1.2.3 From e0426047cb684842700f0098f74842a38260dbae Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:45 +0100 Subject: [POWERPC] Make xmon disassembly optional While adding spu disassembly support it struck me that we're actually carrying quite a lot of code around, just to do disassembly in the case of a crash. While on large systems it's not an issue, on smaller ones it might be nice to have xmon - but without the weight of the disassembly support. For a Cell build this saves ~230KB (!), and for pSeries ~195KB. We still support the 'di' and 'sdi' commands, however they just dump the instruction in hex. Move the definitions into a header to clean xmon.c just a tiny bit. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/Kconfig.debug | 9 +++++++++ arch/powerpc/xmon/Makefile | 8 ++++++-- arch/powerpc/xmon/dis-asm.h | 31 +++++++++++++++++++++++++++++++ arch/powerpc/xmon/ppc-dis.c | 3 +-- arch/powerpc/xmon/spu-dis.c | 3 +-- arch/powerpc/xmon/xmon.c | 5 +---- 6 files changed, 49 insertions(+), 10 deletions(-) create mode 100644 arch/powerpc/xmon/dis-asm.h (limited to 'arch') diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 5ad149b47e3..ff16063d67f 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -98,6 +98,15 @@ config XMON_DEFAULT xmon is normally disabled unless booted with 'xmon=on'. Use 'xmon=off' to disable xmon init during runtime. +config XMON_DISASSEMBLY + bool "Include disassembly support in xmon" + depends on XMON + default y + help + Include support for disassembling in xmon. You probably want + to say Y here, unless you're building for a memory-constrained + system. + config IRQSTACKS bool "Use separate kernel stacks when processing interrupts" depends on PPC64 diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 4f274056e77..69303575d3d 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -3,6 +3,10 @@ ifdef CONFIG_PPC64 EXTRA_CFLAGS += -mno-minimal-toc endif -obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \ - nonstdio.o + +obj-y += xmon.o setjmp.o start.o nonstdio.o + +ifdef CONFIG_XMON_DISASSEMBLY +obj-y += ppc-dis.o ppc-opc.o obj-$(CONFIG_PPC_CELL) += spu-dis.o spu-opc.o +endif diff --git a/arch/powerpc/xmon/dis-asm.h b/arch/powerpc/xmon/dis-asm.h new file mode 100644 index 00000000000..be3533b93f3 --- /dev/null +++ b/arch/powerpc/xmon/dis-asm.h @@ -0,0 +1,31 @@ +#ifndef _POWERPC_XMON_DIS_ASM_H +#define _POWERPC_XMON_DIS_ASM_H +/* + * Copyright (C) 2006 Michael Ellerman, IBM Corporation. + * + * 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. + */ + +extern void print_address (unsigned long memaddr); + +#ifdef CONFIG_XMON_DISASSEMBLY +extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr); +extern int print_insn_spu(unsigned long insn, unsigned long memaddr); +#else +static inline int print_insn_powerpc(unsigned long insn, unsigned long memaddr) +{ + printf("%.8x", insn); + return 0; +} + +static inline int print_insn_spu(unsigned long insn, unsigned long memaddr) +{ + printf("%.8x", insn); + return 0; +} +#endif + +#endif /* _POWERPC_XMON_DIS_ASM_H */ diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c index 3b67bee4830..08652742fa7 100644 --- a/arch/powerpc/xmon/ppc-dis.c +++ b/arch/powerpc/xmon/ppc-dis.c @@ -21,8 +21,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #include "nonstdio.h" #include "ansidecl.h" #include "ppc.h" - -extern void print_address (unsigned long memaddr); +#include "dis-asm.h" /* Print a PowerPC or POWER instruction. */ diff --git a/arch/powerpc/xmon/spu-dis.c b/arch/powerpc/xmon/spu-dis.c index 75ac0815f1a..ee929c641bf 100644 --- a/arch/powerpc/xmon/spu-dis.c +++ b/arch/powerpc/xmon/spu-dis.c @@ -22,8 +22,7 @@ #include "nonstdio.h" #include "ansidecl.h" #include "spu.h" - -extern void print_address (unsigned long memaddr); +#include "dis-asm.h" /* This file provides a disassembler function which uses the disassembler interface defined in dis-asm.h. */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 7a0eec23cb9..c999638cc2d 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -47,6 +47,7 @@ #endif #include "nonstdio.h" +#include "dis-asm.h" #define scanhex xmon_scanhex #define skipbl xmon_skipbl @@ -110,7 +111,6 @@ static int bsesc(void); static void dump(void); static void prdump(unsigned long, long); static int ppc_inst_dump(unsigned long, long, int); -void print_address(unsigned long); static void backtrace(struct pt_regs *); static void excprint(struct pt_regs *); static void prregs(struct pt_regs *); @@ -154,9 +154,6 @@ static int do_spu_cmd(void); int xmon_no_auto_backtrace; -extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr); -extern int print_insn_spu(unsigned long insn, unsigned long memaddr); - extern void xmon_enter(void); extern void xmon_leave(void); -- cgit v1.2.3 From 897f112bb42ed9e220ce441e7e52aba3a144a7d6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:47 +0100 Subject: [POWERPC] Import updated version of ppc disassembly code for xmon This includes: * version 1.24 of ppc-dis.c * version 1.88 of ppc-opc.c * version 1.23 of ppc.h I can't vouch for the accuracy etc. of these changes, but it brings us into line with binutils - and from a cursory test appears to work fine. Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/ppc-dis.c | 20 +- arch/powerpc/xmon/ppc-opc.c | 778 ++++++++++++++++++++++++++++++++------------ arch/powerpc/xmon/ppc.h | 39 ++- 3 files changed, 618 insertions(+), 219 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c index 08652742fa7..89098f320ad 100644 --- a/arch/powerpc/xmon/ppc-dis.c +++ b/arch/powerpc/xmon/ppc-dis.c @@ -1,5 +1,6 @@ /* ppc-dis.c -- Disassemble PowerPC instructions - Copyright 1994 Free Software Foundation, Inc. + Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support This file is part of GDB, GAS, and the GNU binutils. @@ -16,8 +17,9 @@ the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include "nonstdio.h" #include "ansidecl.h" #include "ppc.h" @@ -36,6 +38,15 @@ print_insn_powerpc (unsigned long insn, unsigned long memaddr) dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; + if (cpu_has_feature(CPU_FTRS_POWER5)) + dialect |= PPC_OPCODE_POWER5; + + if (cpu_has_feature(CPU_FTRS_CELL)) + dialect |= PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC; + + if (cpu_has_feature(CPU_FTRS_POWER6)) + dialect |= PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC; + /* Get the major opcode of the instruction. */ op = PPC_OP (insn); @@ -120,7 +131,8 @@ print_insn_powerpc (unsigned long insn, unsigned long memaddr) } /* Print the operand as directed by the flags. */ - if ((operand->flags & PPC_OPERAND_GPR) != 0) + if ((operand->flags & PPC_OPERAND_GPR) != 0 + || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) printf("r%ld", value); else if ((operand->flags & PPC_OPERAND_FPR) != 0) printf("f%ld", value); @@ -136,7 +148,7 @@ print_insn_powerpc (unsigned long insn, unsigned long memaddr) else { if (operand->bits == 3) - printf("cr%d", value); + printf("cr%ld", value); else { static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; diff --git a/arch/powerpc/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c index 5ee8fc32f82..5d841f4b353 100644 --- a/arch/powerpc/xmon/ppc-opc.c +++ b/arch/powerpc/xmon/ppc-opc.c @@ -1,6 +1,6 @@ /* ppc-opc.c -- PowerPC opcode list - Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, + 2005 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support This file is part of GDB, GAS, and the GNU binutils. @@ -17,8 +17,8 @@ You should have received a copy of the GNU General Public License along with this file; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ #include #include "nonstdio.h" @@ -86,6 +86,8 @@ static unsigned long insert_sh6 (unsigned long, long, int, const char **); static long extract_sh6 (unsigned long, int, int *); static unsigned long insert_spr (unsigned long, long, int, const char **); static long extract_spr (unsigned long, int, int *); +static unsigned long insert_sprg (unsigned long, long, int, const char **); +static long extract_sprg (unsigned long, int, int *); static unsigned long insert_tbr (unsigned long, long, int, const char **); static long extract_tbr (unsigned long, int, int *); static unsigned long insert_ev2 (unsigned long, long, int, const char **); @@ -196,8 +198,11 @@ const struct powerpc_operand powerpc_operands[] = #define BOE BO + 1 { 5, 21, insert_boe, extract_boe, 0 }, +#define BH BOE + 1 + { 2, 11, NULL, NULL, PPC_OPERAND_OPTIONAL }, + /* The BT field in an X or XL form instruction. */ -#define BT BOE + 1 +#define BT BH + 1 { 5, 21, NULL, NULL, PPC_OPERAND_CR }, /* The condition register number portion of the BI field in a B form @@ -301,10 +306,14 @@ const struct powerpc_operand powerpc_operands[] = #define L FXM4 + 1 { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, - /* The LEV field in a POWER SC form instruction. */ -#define LEV L + 1 + /* The LEV field in a POWER SVC form instruction. */ +#define SVC_LEV L + 1 { 7, 5, NULL, NULL, 0 }, + /* The LEV field in an SC form instruction. */ +#define LEV SVC_LEV + 1 + { 7, 5, NULL, NULL, PPC_OPERAND_OPTIONAL }, + /* The LI field in an I form instruction. The lower two bits are forced to zero. */ #define LI LEV + 1 @@ -346,7 +355,7 @@ const struct powerpc_operand powerpc_operands[] = /* The MO field in an mbar instruction. */ #define MO MB6 + 1 - { 5, 21, NULL, NULL, 0 }, + { 5, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, /* The NB field in an X form instruction. The value 32 is stored as 0. */ @@ -364,30 +373,38 @@ const struct powerpc_operand powerpc_operands[] = #define RA_MASK (0x1f << 16) { 5, 16, NULL, NULL, PPC_OPERAND_GPR }, + /* As above, but 0 in the RA field means zero, not r0. */ +#define RA0 RA + 1 + { 5, 16, NULL, NULL, PPC_OPERAND_GPR_0 }, + /* The RA field in the DQ form lq instruction, which has special value restrictions. */ -#define RAQ RA + 1 - { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR }, +#define RAQ RA0 + 1 + { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR_0 }, /* The RA field in a D or X form instruction which is an updating load, which means that the RA field may not be zero and may not equal the RT field. */ #define RAL RAQ + 1 - { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR }, + { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR_0 }, /* The RA field in an lmw instruction, which has special value restrictions. */ #define RAM RAL + 1 - { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR }, + { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR_0 }, /* The RA field in a D or X form instruction which is an updating store or an updating floating point load, which means that the RA field may not be zero. */ #define RAS RAM + 1 - { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR }, + { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR_0 }, + + /* The RA field of the tlbwe instruction, which is optional. */ +#define RAOPT RAS + 1 + { 5, 16, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL }, /* The RB field in an X, XO, M, or MDS form instruction. */ -#define RB RAS + 1 +#define RB RAOPT + 1 #define RB_MASK (0x1f << 11) { 5, 11, NULL, NULL, PPC_OPERAND_GPR }, @@ -408,15 +425,20 @@ const struct powerpc_operand powerpc_operands[] = /* The RS field of the DS form stq instruction, which has special value restrictions. */ #define RSQ RS + 1 - { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR }, + { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR_0 }, /* The RT field of the DQ form lq instruction, which has special value restrictions. */ #define RTQ RSQ + 1 - { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR }, + { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR_0 }, + + /* The RS field of the tlbwe instruction, which is optional. */ +#define RSO RTQ + 1 +#define RTO RSO + { 5, 21, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL }, /* The SH field in an X or M form instruction. */ -#define SH RTQ + 1 +#define SH RSO + 1 #define SH_MASK (0x1f << 11) { 5, 11, NULL, NULL, 0 }, @@ -425,8 +447,12 @@ const struct powerpc_operand powerpc_operands[] = #define SH6_MASK ((0x1f << 11) | (1 << 1)) { 6, 1, insert_sh6, extract_sh6, 0 }, + /* The SH field of the tlbwe instruction, which is optional. */ +#define SHO SH6 + 1 + { 5, 11,NULL, NULL, PPC_OPERAND_OPTIONAL }, + /* The SI field in a D form instruction. */ -#define SI SH6 + 1 +#define SI SHO + 1 { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED }, /* The SI field in a D form instruction when we accept a wide range @@ -448,8 +474,7 @@ const struct powerpc_operand powerpc_operands[] = /* The SPRG register number in an XFX form m[ft]sprg instruction. */ #define SPRG SPRBAT + 1 -#define SPRG_MASK (0x3 << 16) - { 2, 16, NULL, NULL, 0 }, + { 5, 16, insert_sprg, extract_sprg, 0 }, /* The SR field in an X form instruction. */ #define SR SPRG + 1 @@ -536,10 +561,45 @@ const struct powerpc_operand powerpc_operands[] = #define WS_MASK (0x7 << 11) { 3, 11, NULL, NULL, 0 }, - /* The L field in an mtmsrd instruction */ + /* The L field in an mtmsrd or A form instruction. */ #define MTMSRD_L WS + 1 +#define A_L MTMSRD_L { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL }, + /* The DCM field in a Z form instruction. */ +#define DCM MTMSRD_L + 1 + { 6, 16, NULL, NULL, 0 }, + + /* Likewise, the DGM field in a Z form instruction. */ +#define DGM DCM + 1 + { 6, 16, NULL, NULL, 0 }, + +#define TE DGM + 1 + { 5, 11, NULL, NULL, 0 }, + +#define RMC TE + 1 + { 2, 21, NULL, NULL, 0 }, + +#define R RMC + 1 + { 1, 15, NULL, NULL, 0 }, + +#define SP R + 1 + { 2, 11, NULL, NULL, 0 }, + +#define S SP + 1 + { 1, 11, NULL, NULL, 0 }, + + /* SH field starting at bit position 16. */ +#define SH16 S + 1 + { 6, 10, NULL, NULL, 0 }, + + /* The L field in an X form with the RT field fixed instruction. */ +#define XRT_L SH16 + 1 + { 2, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, + + /* The EH field in larx instruction. */ +#define EH XRT_L + 1 + { 1, 0, NULL, NULL, PPC_OPERAND_OPTIONAL }, }; /* The functions used to insert and extract complicated operands. */ @@ -550,7 +610,6 @@ const struct powerpc_operand powerpc_operands[] = and the extraction function just checks that the fields are the same. */ -/*ARGSUSED*/ static unsigned long insert_bat (unsigned long insn, long value ATTRIBUTE_UNUSED, @@ -576,7 +635,6 @@ extract_bat (unsigned long insn, and the extraction function just checks that the fields are the same. */ -/*ARGSUSED*/ static unsigned long insert_bba (unsigned long insn, long value ATTRIBUTE_UNUSED, @@ -599,7 +657,6 @@ extract_bba (unsigned long insn, /* The BD field in a B form instruction. The lower two bits are forced to zero. */ -/*ARGSUSED*/ static unsigned long insert_bd (unsigned long insn, long value, @@ -609,7 +666,6 @@ insert_bd (unsigned long insn, return insn | (value & 0xfffc); } -/*ARGSUSED*/ static long extract_bd (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -631,7 +687,6 @@ extract_bd (unsigned long insn, in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000 for branch on CTR. We only handle the taken/not-taken hint here. */ -/*ARGSUSED*/ static unsigned long insert_bdm (unsigned long insn, long value, @@ -677,7 +732,6 @@ extract_bdm (unsigned long insn, This is like BDM, above, except that the branch is expected to be taken. */ -/*ARGSUSED*/ static unsigned long insert_bdp (unsigned long insn, long value, @@ -831,7 +885,6 @@ extract_boe (unsigned long insn, /* The DQ field in a DQ form instruction. This is like D, but the lower four bits are forced to zero. */ -/*ARGSUSED*/ static unsigned long insert_dq (unsigned long insn, long value, @@ -843,7 +896,6 @@ insert_dq (unsigned long insn, return insn | (value & 0xfff0); } -/*ARGSUSED*/ static long extract_dq (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -918,7 +970,6 @@ extract_ev8 (unsigned long insn, /* The DS field in a DS form instruction. This is like D, but the lower two bits are forced to zero. */ -/*ARGSUSED*/ static unsigned long insert_ds (unsigned long insn, long value, @@ -930,7 +981,6 @@ insert_ds (unsigned long insn, return insn | (value & 0xfffc); } -/*ARGSUSED*/ static long extract_ds (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -941,7 +991,6 @@ extract_ds (unsigned long insn, /* The DE field in a DE form instruction. */ -/*ARGSUSED*/ static unsigned long insert_de (unsigned long insn, long value, @@ -953,7 +1002,6 @@ insert_de (unsigned long insn, return insn | ((value << 4) & 0xfff0); } -/*ARGSUSED*/ static long extract_de (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -964,7 +1012,6 @@ extract_de (unsigned long insn, /* The DES field in a DES form instruction. */ -/*ARGSUSED*/ static unsigned long insert_des (unsigned long insn, long value, @@ -978,7 +1025,6 @@ insert_des (unsigned long insn, return insn | ((value << 2) & 0xfff0); } -/*ARGSUSED*/ static long extract_des (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -995,17 +1041,33 @@ insert_fxm (unsigned long insn, int dialect, const char **errmsg) { + /* If we're handling the mfocrf and mtocrf insns ensure that exactly + one bit of the mask field is set. */ + if ((insn & (1 << 20)) != 0) + { + if (value == 0 || (value & -value) != value) + { + *errmsg = _("invalid mask field"); + value = 0; + } + } + /* If the optional field on mfcr is missing that means we want to use the old form of the instruction that moves the whole cr. In that case we'll have VALUE zero. There doesn't seem to be a way to distinguish this from the case where someone writes mfcr %r3,0. */ - if (value == 0) + else if (value == 0) ; /* If only one bit of the FXM field is set, we can use the new form of the instruction, which is faster. Unlike the Power4 branch hint - encoding, this is not backward compatible. */ - else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value) + encoding, this is not backward compatible. Do not generate the + new form unless -mpower4 has been given, or -many and the two + operand form of mfcr was used. */ + else if ((value & -value) == value + && ((dialect & PPC_OPCODE_POWER4) != 0 + || ((dialect & PPC_OPCODE_ANY) != 0 + && (insn & (0x3ff << 1)) == 19 << 1))) insn |= 1 << 20; /* Any other value on mfcr is an error. */ @@ -1020,7 +1082,7 @@ insert_fxm (unsigned long insn, static long extract_fxm (unsigned long insn, - int dialect, + int dialect ATTRIBUTE_UNUSED, int *invalid) { long mask = (insn >> 12) & 0xff; @@ -1028,14 +1090,9 @@ extract_fxm (unsigned long insn, /* Is this a Power4 insn? */ if ((insn & (1 << 20)) != 0) { - if ((dialect & PPC_OPCODE_POWER4) == 0) + /* Exactly one bit of MASK should be set. */ + if (mask == 0 || (mask & -mask) != mask) *invalid = 1; - else - { - /* Exactly one bit of MASK should be set. */ - if (mask == 0 || (mask & -mask) != mask) - *invalid = 1; - } } /* Check that non-power4 form of mfcr has a zero MASK. */ @@ -1051,7 +1108,6 @@ extract_fxm (unsigned long insn, /* The LI field in an I form instruction. The lower two bits are forced to zero. */ -/*ARGSUSED*/ static unsigned long insert_li (unsigned long insn, long value, @@ -1063,7 +1119,6 @@ insert_li (unsigned long insn, return insn | (value & 0x3fffffc); } -/*ARGSUSED*/ static long extract_li (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -1163,7 +1218,6 @@ extract_mbe (unsigned long insn, /* The MB or ME field in an MD or MDS form instruction. The high bit is wrapped to the low end. */ -/*ARGSUSED*/ static unsigned long insert_mb6 (unsigned long insn, long value, @@ -1173,7 +1227,6 @@ insert_mb6 (unsigned long insn, return insn | ((value & 0x1f) << 6) | (value & 0x20); } -/*ARGSUSED*/ static long extract_mb6 (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -1198,7 +1251,6 @@ insert_nb (unsigned long insn, return insn | ((value & 0x1f) << 11); } -/*ARGSUSED*/ static long extract_nb (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -1217,7 +1269,6 @@ extract_nb (unsigned long insn, invalid, since we never want to recognize an instruction which uses a field of this type. */ -/*ARGSUSED*/ static unsigned long insert_nsi (unsigned long insn, long value, @@ -1269,7 +1320,6 @@ insert_ram (unsigned long insn, /* The RA field in the DQ form lq instruction, which has special value restrictions. */ -/*ARGSUSED*/ static unsigned long insert_raq (unsigned long insn, long value, @@ -1304,7 +1354,6 @@ insert_ras (unsigned long insn, function just copies the BT field into the BA field, and the extraction function just checks that the fields are the same. */ -/*ARGSUSED*/ static unsigned long insert_rbs (unsigned long insn, long value ATTRIBUTE_UNUSED, @@ -1327,7 +1376,6 @@ extract_rbs (unsigned long insn, /* The RT field of the DQ form lq instruction, which has special value restrictions. */ -/*ARGSUSED*/ static unsigned long insert_rtq (unsigned long insn, long value, @@ -1342,7 +1390,6 @@ insert_rtq (unsigned long insn, /* The RS field of the DS form stq instruction, which has special value restrictions. */ -/*ARGSUSED*/ static unsigned long insert_rsq (unsigned long insn, long value ATTRIBUTE_UNUSED, @@ -1356,7 +1403,6 @@ insert_rsq (unsigned long insn, /* The SH field in an MD form instruction. This is split. */ -/*ARGSUSED*/ static unsigned long insert_sh6 (unsigned long insn, long value, @@ -1366,7 +1412,6 @@ insert_sh6 (unsigned long insn, return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4); } -/*ARGSUSED*/ static long extract_sh6 (unsigned long insn, int dialect ATTRIBUTE_UNUSED, @@ -1395,6 +1440,47 @@ extract_spr (unsigned long insn, return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); } +/* Some dialects have 8 SPRG registers instead of the standard 4. */ + +static unsigned long +insert_sprg (unsigned long insn, + long value, + int dialect, + const char **errmsg) +{ + /* This check uses PPC_OPCODE_403 because PPC405 is later defined + as a synonym. If ever a 405 specific dialect is added this + check should use that instead. */ + if (value > 7 + || (value > 3 + && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0)) + *errmsg = _("invalid sprg number"); + + /* If this is mfsprg4..7 then use spr 260..263 which can be read in + user mode. Anything else must use spr 272..279. */ + if (value <= 3 || (insn & 0x100) != 0) + value |= 0x10; + + return insn | ((value & 0x17) << 16); +} + +static long +extract_sprg (unsigned long insn, + int dialect, + int *invalid) +{ + unsigned long val = (insn >> 16) & 0x1f; + + /* mfsprg can use 260..263 and 272..279. mtsprg only uses spr 272..279 + If not BOOKE or 405, then both use only 272..275. */ + if (val <= 3 + || (val < 0x10 && (insn & 0x100) != 0) + || (val - 0x10 > 3 + && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0)) + *invalid = 1; + return val & 7; +} + /* The TBR field in an XFX instruction. This is just like SPR, but it is optional. When TBR is omitted, it must be inserted as 268 (the magic number of the TB register). These functions treat 0 @@ -1460,6 +1546,9 @@ extract_tbr (unsigned long insn, /* An A_MASK with the FRA and FRC fields fixed. */ #define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK) +/* An AFRAFRC_MASK, but with L bit clear. */ +#define AFRALFRC_MASK (AFRAFRC_MASK & ~((unsigned long) 1 << 16)) + /* A B form instruction. */ #define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1)) #define B_MASK B (0x3f, 1, 1) @@ -1494,11 +1583,11 @@ extract_tbr (unsigned long insn, /* An Context form instruction. */ #define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7)) -#define CTX_MASK CTX(0x3f, 0x7) +#define CTX_MASK CTX(0x3f, 0x7) /* An User Context form instruction. */ #define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) -#define UCTX_MASK UCTX(0x3f, 0x1f) +#define UCTX_MASK UCTX(0x3f, 0x1f) /* The main opcode mask with the RA field clear. */ #define DRA_MASK (OP_MASK | RA_MASK) @@ -1570,12 +1659,21 @@ extract_tbr (unsigned long insn, /* An X form instruction. */ #define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) +/* A Z form instruction. */ +#define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1)) + /* An X form instruction with the RC bit specified. */ #define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1)) +/* A Z form instruction with the RC bit specified. */ +#define ZRC(op, xop, rc) (Z ((op), (xop)) | ((rc) & 1)) + /* The mask for an X form instruction. */ #define X_MASK XRC (0x3f, 0x3ff, 1) +/* The mask for a Z form instruction. */ +#define Z_MASK ZRC (0x3f, 0x1ff, 1) + /* An X_MASK with the RA field fixed. */ #define XRA_MASK (X_MASK | RA_MASK) @@ -1585,6 +1683,9 @@ extract_tbr (unsigned long insn, /* An X_MASK with the RT field fixed. */ #define XRT_MASK (X_MASK | RT_MASK) +/* An XRT_MASK mask with the L bits clear. */ +#define XLRT_MASK (XRT_MASK & ~((unsigned long) 0x3 << 21)) + /* An X_MASK with the RA and RB fields fixed. */ #define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) @@ -1597,8 +1698,8 @@ extract_tbr (unsigned long insn, /* An XRTRA_MASK, but with L bit clear. */ #define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21)) -/* An X form comparison instruction. */ -#define XCMPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) +/* An X form instruction with the L bit specified. */ +#define XOPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) /* The mask for an X form comparison instruction. */ #define XCMP_MASK (X_MASK | (((unsigned long)1) << 22)) @@ -1621,6 +1722,9 @@ extract_tbr (unsigned long insn, /* An X form sync instruction with everything filled in except the LS field. */ #define XSYNC_MASK (0xff9fffff) +/* An X_MASK, but with the EH bit clear. */ +#define XEH_MASK (X_MASK & ~((unsigned long )1)) + /* An X form AltiVec dss instruction. */ #define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25)) #define XDSS_MASK XDSS(0x3f, 0x3ff, 1) @@ -1663,6 +1767,9 @@ extract_tbr (unsigned long insn, #define XLYBB_MASK (XLYLK_MASK | BB_MASK) #define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK) +/* A mask for branch instructions using the BH field. */ +#define XLBH_MASK (XL_MASK | (0x1c << 11)) + /* An XL_MASK with the BO and BB fields fixed. */ #define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK) @@ -1682,11 +1789,12 @@ extract_tbr (unsigned long insn, #define XS_MASK XS (0x3f, 0x1ff, 1) /* A mask for the FXM version of an XFX form instruction. */ -#define XFXFXM_MASK (X_MASK | (1 << 11)) +#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20)) /* An XFX form instruction with the FXM field filled in. */ -#define XFXM(op, xop, fxm) \ - (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12)) +#define XFXM(op, xop, fxm, p4) \ + (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \ + | ((unsigned long)(p4) << 20)) /* An XFX form instruction with the SPR field filled in. */ #define XSPR(op, xop, spr) \ @@ -1699,7 +1807,7 @@ extract_tbr (unsigned long insn, /* An XFX form instruction with the SPR field filled in except for the SPRG field. */ -#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK) +#define XSPRG_MASK (XSPR_MASK & ~(0x17 << 16)) /* An X form instruction with everything filled in except the E field. */ #define XE_MASK (0xffff7fff) @@ -1769,6 +1877,9 @@ extract_tbr (unsigned long insn, #define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON #define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM #define POWER4 PPC_OPCODE_POWER4 +#define POWER5 PPC_OPCODE_POWER5 +#define POWER6 PPC_OPCODE_POWER6 +#define CELL PPC_OPCODE_CELL #define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC #define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC #define PPC403 PPC_OPCODE_403 @@ -1776,7 +1887,7 @@ extract_tbr (unsigned long insn, #define PPC440 PPC_OPCODE_440 #define PPC750 PPC #define PPC860 PPC -#define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC +#define PPCVEC PPC_OPCODE_ALTIVEC #define POWER PPC_OPCODE_POWER #define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 #define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 @@ -1790,6 +1901,7 @@ extract_tbr (unsigned long insn, #define BOOKE PPC_OPCODE_BOOKE #define BOOKE64 PPC_OPCODE_BOOKE64 #define CLASSIC PPC_OPCODE_CLASSIC +#define PPCE300 PPC_OPCODE_E300 #define PPCSPE PPC_OPCODE_SPE #define PPCISEL PPC_OPCODE_ISEL #define PPCEFS PPC_OPCODE_EFS @@ -1952,6 +2064,41 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "nmaclhwso.", XO(4,494,1,1), XO_MASK, PPC405|PPC440, { RT, RA, RB } }, { "mfvscr", VX(4, 1540), VX_MASK, PPCVEC, { VD } }, { "mtvscr", VX(4, 1604), VX_MASK, PPCVEC, { VB } }, + + /* Double-precision opcodes. */ + /* Some of these conflict with AltiVec, so move them before, since + PPCVEC includes the PPC_OPCODE_PPC set. */ +{ "efscfd", VX(4, 719), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdabs", VX(4, 740), VX_MASK, PPCEFS, { RS, RA } }, +{ "efdnabs", VX(4, 741), VX_MASK, PPCEFS, { RS, RA } }, +{ "efdneg", VX(4, 742), VX_MASK, PPCEFS, { RS, RA } }, +{ "efdadd", VX(4, 736), VX_MASK, PPCEFS, { RS, RA, RB } }, +{ "efdsub", VX(4, 737), VX_MASK, PPCEFS, { RS, RA, RB } }, +{ "efdmul", VX(4, 744), VX_MASK, PPCEFS, { RS, RA, RB } }, +{ "efddiv", VX(4, 745), VX_MASK, PPCEFS, { RS, RA, RB } }, +{ "efdcmpgt", VX(4, 748), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdcmplt", VX(4, 749), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdcmpeq", VX(4, 750), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdtstgt", VX(4, 764), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdtstlt", VX(4, 765), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdtsteq", VX(4, 766), VX_MASK, PPCEFS, { CRFD, RA, RB } }, +{ "efdcfsi", VX(4, 753), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfsid", VX(4, 739), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfui", VX(4, 752), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfuid", VX(4, 738), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfsf", VX(4, 755), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfuf", VX(4, 754), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctsi", VX(4, 757), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctsidz",VX(4, 747), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctsiz", VX(4, 762), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctui", VX(4, 756), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctuidz",VX(4, 746), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctuiz", VX(4, 760), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctsf", VX(4, 759), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdctuf", VX(4, 758), VX_MASK, PPCEFS, { RS, RB } }, +{ "efdcfs", VX(4, 751), VX_MASK, PPCEFS, { RS, RB } }, + /* End of double-precision opcodes. */ + { "vaddcuw", VX(4, 384), VX_MASK, PPCVEC, { VD, VA, VB } }, { "vaddfp", VX(4, 10), VX_MASK, PPCVEC, { VD, VA, VB } }, { "vaddsbs", VX(4, 768), VX_MASK, PPCVEC, { VD, VA, VB } }, @@ -2389,16 +2536,16 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } }, { "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI } }, -{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA, SI } }, -{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA } }, -{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA, NSI } }, -{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA } }, +{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA0, SI } }, +{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA0 } }, +{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA0, NSI } }, +{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA0 } }, { "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT } }, { "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT } }, -{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA,SISIGNOPT } }, -{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA,SISIGNOPT } }, -{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA, NSI } }, +{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA0,SISIGNOPT } }, +{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA0,SISIGNOPT } }, +{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA0, NSI } }, { "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } }, { "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } }, @@ -2665,9 +2812,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "bcla+", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDPA } }, { "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA } }, -{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } }, -{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } }, -{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } }, +{ "sc", SC(17,1,0), SC_MASK, PPC, { LEV } }, +{ "svc", SC(17,0,0), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } }, +{ "svcl", SC(17,0,1), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } }, { "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } }, { "svcla", SC(17,1,1), SC_MASK, POWER, { SV } }, @@ -2890,12 +3037,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI } }, { "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4, { BI } }, { "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } }, -{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPCCOM, { BO, BI } }, -{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPCCOM, { BO, BI } }, { "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, { "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, { "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, { "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, +{ "bclr", XLLK(19,16,0), XLBH_MASK, PPCCOM, { BO, BI, BH } }, +{ "bclrl", XLLK(19,16,1), XLBH_MASK, PPCCOM, { BO, BI, BH } }, { "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI } }, { "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI } }, { "bclre", XLLK(19,17,0), XLBB_MASK, BOOKE64, { BO, BI } }, @@ -2924,14 +3071,23 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB } }, +{ "hrfid", XL(19,274), 0xffffffff, POWER5 | CELL, { 0 } }, + { "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA } }, { "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB } }, +{ "doze", XL(19,402), 0xffffffff, POWER6, { 0 } }, + { "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB } }, +{ "nap", XL(19,434), 0xffffffff, POWER6, { 0 } }, + { "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA } }, { "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB } }, +{ "sleep", XL(19,466), 0xffffffff, POWER6, { 0 } }, +{ "rvwinkle", XL(19,498), 0xffffffff, POWER6, { 0 } }, + { "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } }, { "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } }, { "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } }, @@ -3074,12 +3230,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI } }, { "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI } }, { "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI } }, -{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPCCOM, { BO, BI } }, { "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, { "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, -{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPCCOM, { BO, BI } }, { "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, { "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, +{ "bcctr", XLLK(19,528,0), XLBH_MASK, PPCCOM, { BO, BI, BH } }, +{ "bcctrl", XLLK(19,528,1), XLBH_MASK, PPCCOM, { BO, BI, BH } }, { "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI } }, { "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI } }, { "bcctre", XLLK(19,529,0), XLYBB_MASK, BOOKE64, { BO, BI } }, @@ -3158,8 +3314,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 } }, { "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 } }, -{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, -{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, +{ "cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, +{ "cmpd", XOPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, { "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } }, { "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, @@ -3228,17 +3384,18 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB } }, { "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } }, -{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4, { RT } }, +{ "mfocrf", XFXM(31,19,0,1), XFXFXM_MASK, COM, { RT, FXM } }, +{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4 | COM, { RT } }, { "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } }, -{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } }, +{ "lwarx", X(31,20), XEH_MASK, PPC, { RT, RA0, RB, EH } }, -{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA, RB } }, +{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB } }, -{ "icbt", X(31,22), X_MASK, BOOKE, { CT, RA, RB } }, +{ "icbt", X(31,22), X_MASK, BOOKE|PPCE300, { CT, RA, RB } }, { "icbt", X(31,262), XRT_MASK, PPC403, { RA, RB } }, -{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA, RB } }, +{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA0, RB } }, { "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB } }, { "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } }, @@ -3262,10 +3419,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "icbte", X(31,30), X_MASK, BOOKE64, { CT, RA, RB } }, -{ "lwzxe", X(31,31), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lwzxe", X(31,31), X_MASK, BOOKE64, { RT, RA0, RB } }, -{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, -{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, +{ "cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, +{ "cmpld", XOPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, { "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } }, { "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, @@ -3324,15 +3481,16 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfmsr", X(31,83), XRARB_MASK, COM, { RT } }, -{ "ldarx", X(31,84), X_MASK, PPC64, { RT, RA, RB } }, +{ "ldarx", X(31,84), XEH_MASK, PPC64, { RT, RA0, RB, EH } }, -{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } }, +{ "dcbfl", XOPL(31,86,1), XRT_MASK, POWER5, { RA, RB } }, +{ "dcbf", X(31,86), XLRT_MASK, PPC, { RA, RB, XRT_L } }, -{ "lbzx", X(31,87), X_MASK, COM, { RT, RA, RB } }, +{ "lbzx", X(31,87), X_MASK, COM, { RT, RA0, RB } }, { "dcbfe", X(31,94), XRT_MASK, BOOKE64, { RA, RB } }, -{ "lbzxe", X(31,95), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lbzxe", X(31,95), X_MASK, BOOKE64, { RT, RA0, RB } }, { "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } }, { "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA } }, @@ -3350,12 +3508,14 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB } }, +{ "popcntb", X(31,122), XRB_MASK, POWER5, { RA, RS } }, + { "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } }, { "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } }, { "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS } }, { "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB } }, -{ "lwarxe", X(31,126), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lwarxe", X(31,126), X_MASK, BOOKE64, { RT, RA0, RB } }, { "lbzuxe", X(31,127), X_MASK, BOOKE64, { RT, RAL, RB } }, @@ -3383,21 +3543,22 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }}, -{ "mtcr", XFXM(31,144,0xff), XRARB_MASK, COM, { RS }}, +{ "mtocrf", XFXM(31,144,0,1), XFXFXM_MASK, COM, { FXM, RS } }, +{ "mtcr", XFXM(31,144,0xff,0), XRARB_MASK, COM, { RS }}, { "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } }, { "mtmsr", X(31,146), XRARB_MASK, COM, { RS } }, -{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA, RB } }, +{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA0, RB } }, -{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } }, +{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA0, RB } }, -{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA, RB } }, +{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA0, RB } }, { "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB } }, -{ "stwcxe.", XRC(31,158,1), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "stwcxe.", XRC(31,158,1), X_MASK, BOOKE64, { RS, RA0, RB } }, -{ "stwxe", X(31,159), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "stwxe", X(31,159), X_MASK, BOOKE64, { RS, RA0, RB } }, { "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB } }, { "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB } }, @@ -3405,6 +3566,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB } }, { "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB } }, +{ "prtyw", X(31,154), XRB_MASK, POWER6, { RA, RS } }, + { "wrteei", X(31,163), XE_MASK, PPC403 | BOOKE, { E } }, { "dcbtls", X(31,166), X_MASK, PPCCHLK, { CT, RA, RB }}, @@ -3415,11 +3578,13 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB } }, { "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB } }, -{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA, RB } }, +{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA0, RB } }, { "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH } }, { "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH } }, +{ "prtyd", X(31,186), XRB_MASK, POWER6, { RA, RS } }, + { "stwuxe", X(31,191), X_MASK, BOOKE64, { RS, RAS, RB } }, { "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA } }, @@ -3442,9 +3607,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mtsr", X(31,210), XRB_MASK|(1<<20), COM32, { SR, RS } }, -{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA, RB } }, +{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA0, RB } }, -{ "stbx", X(31,215), X_MASK, COM, { RS, RA, RB } }, +{ "stbx", X(31,215), X_MASK, COM, { RS, RA0, RB } }, { "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB } }, { "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB } }, @@ -3452,7 +3617,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB } }, { "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB } }, -{ "stbxe", X(31,223), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "stbxe", X(31,223), X_MASK, BOOKE64, { RS, RA0, RB } }, { "icblc", X(31,230), X_MASK, PPCCHLK, { CT, RA, RB }}, @@ -3492,7 +3657,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB } }, { "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB } }, -{ "dcbtst", X(31,246), XRT_MASK, PPC, { CT, RA, RB } }, +{ "dcbtst", X(31,246), X_MASK, PPC, { CT, RA, RB } }, { "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB } }, @@ -3519,26 +3684,26 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } }, { "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } }, -{ "tlbiel", X(31,274), XRTRA_MASK, POWER4, { RB } }, +{ "tlbiel", X(31,274), XRTLRA_MASK, POWER4, { RB, L } }, { "mfapidi", X(31,275), X_MASK, BOOKE, { RT, RA } }, { "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } }, { "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } }, -{ "dcbt", X(31,278), XRT_MASK, PPC, { CT, RA, RB } }, +{ "dcbt", X(31,278), X_MASK, PPC, { CT, RA, RB } }, -{ "lhzx", X(31,279), X_MASK, COM, { RT, RA, RB } }, +{ "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB } }, { "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB } }, { "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB } }, { "dcbte", X(31,286), X_MASK, BOOKE64, { CT, RA, RB } }, -{ "lhzxe", X(31,287), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lhzxe", X(31,287), X_MASK, BOOKE64, { RT, RA0, RB } }, { "tlbie", X(31,306), XRTLRA_MASK, PPC, { RB, L } }, -{ "tlbi", X(31,306), XRT_MASK, POWER, { RA, RB } }, +{ "tlbi", X(31,306), XRT_MASK, POWER, { RA0, RB } }, { "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } }, @@ -3607,6 +3772,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT } }, { "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT } }, { "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT } }, +{ "mfcfar", XSPR(31,339,28), XSPR_MASK, POWER6, { RT } }, { "mfpid", XSPR(31,339,48), XSPR_MASK, BOOKE, { RT } }, { "mfpid", XSPR(31,339,945), XSPR_MASK, PPC403, { RT } }, { "mfcsrr0", XSPR(31,339,58), XSPR_MASK, BOOKE, { RT } }, @@ -3634,21 +3800,21 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT } }, { "mfvrsave", XSPR(31,339,256), XSPR_MASK, PPCVEC, { RT } }, { "mfusprg0", XSPR(31,339,256), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } }, -{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405, { RT } }, { "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } }, { "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } }, { "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, { "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT } }, { "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT } }, -{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } }, +{ "mfsprg", XSPR(31,339,256), XSPRG_MASK, PPC, { RT, SPRG } }, { "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } }, { "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } }, { "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT } }, { "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT } }, +{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405 | BOOKE, { RT } }, +{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405 | BOOKE, { RT } }, { "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } }, { "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } }, { "mfpir", XSPR(31,339,286), XSPR_MASK, BOOKE, { RT } }, @@ -3699,6 +3865,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfspefscr", XSPR(31,339,512), XSPR_MASK, PPCSPE, { RT } }, { "mfbbear", XSPR(31,339,513), XSPR_MASK, PPCBRLK, { RT } }, { "mfbbtar", XSPR(31,339,514), XSPR_MASK, PPCBRLK, { RT } }, +{ "mfivor32", XSPR(31,339,528), XSPR_MASK, PPCSPE, { RT } }, +{ "mfivor33", XSPR(31,339,529), XSPR_MASK, PPCSPE, { RT } }, +{ "mfivor34", XSPR(31,339,530), XSPR_MASK, PPCSPE, { RT } }, +{ "mfivor35", XSPR(31,339,531), XSPR_MASK, PPCPMR, { RT } }, { "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, { "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, { "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, @@ -3708,10 +3878,11 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfic_dat", XSPR(31,339,562), XSPR_MASK, PPC860, { RT } }, { "mfdc_cst", XSPR(31,339,568), XSPR_MASK, PPC860, { RT } }, { "mfdc_adr", XSPR(31,339,569), XSPR_MASK, PPC860, { RT } }, -{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT } }, { "mfmcsrr0", XSPR(31,339,570), XSPR_MASK, PPCRFMCI, { RT } }, +{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT } }, { "mfmcsrr1", XSPR(31,339,571), XSPR_MASK, PPCRFMCI, { RT } }, { "mfmcsr", XSPR(31,339,572), XSPR_MASK, PPCRFMCI, { RT } }, +{ "mfmcar", XSPR(31,339,573), XSPR_MASK, PPCRFMCI, { RT } }, { "mfdpdr", XSPR(31,339,630), XSPR_MASK, PPC860, { RT } }, { "mfdpir", XSPR(31,339,631), XSPR_MASK, PPC860, { RT } }, { "mfimmr", XSPR(31,339,638), XSPR_MASK, PPC860, { RT } }, @@ -3775,14 +3946,14 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT } }, { "mfspr", X(31,339), X_MASK, COM, { RT, SPR } }, -{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA, RB } }, +{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA0, RB } }, { "dst", XDSS(31,342,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, { "dstt", XDSS(31,342,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, -{ "lhax", X(31,343), X_MASK, COM, { RT, RA, RB } }, +{ "lhax", X(31,343), X_MASK, COM, { RT, RA0, RB } }, -{ "lhaxe", X(31,351), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lhaxe", X(31,351), X_MASK, BOOKE64, { RT, RA0, RB } }, { "dstst", XDSS(31,374,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, { "dststt", XDSS(31,374,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, @@ -3821,14 +3992,20 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "slbmte", X(31,402), XRA_MASK, PPC64, { RS, RB } }, -{ "sthx", X(31,407), X_MASK, COM, { RS, RA, RB } }, +{ "sthx", X(31,407), X_MASK, COM, { RS, RA0, RB } }, + +{ "cmpb", X(31,508), X_MASK, POWER6, { RA, RS, RB } }, { "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } }, +{ "lfdpx", X(31,791), X_MASK, POWER6, { FRT, RA, RB } }, + { "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } }, { "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } }, +{ "stfdpx", X(31,919), X_MASK, POWER6, { FRS, RA, RB } }, + { "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } }, { "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB } }, @@ -3837,7 +4014,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 } }, { "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 } }, -{ "sthxe", X(31,415), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "sthxe", X(31,415), X_MASK, BOOKE64, { RS, RA0, RB } }, { "slbie", X(31,434), XRTRA_MASK, PPC64, { RB } }, @@ -3918,6 +4095,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS } }, { "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS } }, { "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS } }, +{ "mtcfar", XSPR(31,467,28), XSPR_MASK, POWER6, { RS } }, { "mtpid", XSPR(31,467,48), XSPR_MASK, BOOKE, { RS } }, { "mtpid", XSPR(31,467,945), XSPR_MASK, PPC403, { RS } }, { "mtdecar", XSPR(31,467,54), XSPR_MASK, BOOKE, { RS } }, @@ -3946,7 +4124,7 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mtbar", XSPR(31,467,159), XSPR_MASK, PPC860, { RS } }, { "mtvrsave", XSPR(31,467,256), XSPR_MASK, PPCVEC, { RS } }, { "mtusprg0", XSPR(31,467,256), XSPR_MASK, BOOKE, { RS } }, -{ "mtsprg", XSPR(31,467,272), XSPRG_MASK,PPC, { SPRG, RS } }, +{ "mtsprg", XSPR(31,467,256), XSPRG_MASK,PPC, { SPRG, RS } }, { "mtsprg0", XSPR(31,467,272), XSPR_MASK, PPC, { RS } }, { "mtsprg1", XSPR(31,467,273), XSPR_MASK, PPC, { RS } }, { "mtsprg2", XSPR(31,467,274), XSPR_MASK, PPC, { RS } }, @@ -4005,6 +4183,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RS } }, { "mtbbear", XSPR(31,467,513), XSPR_MASK, PPCBRLK, { RS } }, { "mtbbtar", XSPR(31,467,514), XSPR_MASK, PPCBRLK, { RS } }, +{ "mtivor32", XSPR(31,467,528), XSPR_MASK, PPCSPE, { RS } }, +{ "mtivor33", XSPR(31,467,529), XSPR_MASK, PPCSPE, { RS } }, +{ "mtivor34", XSPR(31,467,530), XSPR_MASK, PPCSPE, { RS } }, +{ "mtivor35", XSPR(31,467,531), XSPR_MASK, PPCPMR, { RS } }, { "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, { "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, { "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, @@ -4101,13 +4283,15 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "clcs", X(31,531), XRB_MASK, M601, { RT, RA } }, -{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA, RB } }, +{ "ldbrx", X(31,532), X_MASK, CELL, { RT, RA0, RB } }, + +{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA0, RB } }, { "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB } }, -{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA, RB } }, +{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA0, RB } }, { "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB } }, -{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA, RB } }, +{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA0, RB } }, { "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } }, { "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB } }, @@ -4123,11 +4307,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB } }, { "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB } }, -{ "lwbrxe", X(31,542), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lwbrxe", X(31,542), X_MASK, BOOKE64, { RT, RA0, RB } }, -{ "lfsxe", X(31,543), X_MASK, BOOKE64, { FRT, RA, RB } }, +{ "lfsxe", X(31,543), X_MASK, BOOKE64, { FRT, RA0, RB } }, { "bbelr", X(31,550), X_MASK, PPCBRLK, { 0 }}, + { "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } }, { "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB } }, @@ -4136,8 +4321,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfsr", X(31,595), XRB_MASK|(1<<20), COM32, { RT, SR } }, -{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB } }, -{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA, NB } }, +{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA0, NB } }, +{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA0, NB } }, { "lwsync", XSYNC(31,598,1), 0xffffffff, PPC, { 0 } }, { "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 } }, @@ -4145,9 +4330,11 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } }, { "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 } }, -{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA, RB } }, +{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA0, RB } }, + +{ "lfdxe", X(31,607), X_MASK, BOOKE64, { FRT, RA0, RB } }, -{ "lfdxe", X(31,607), X_MASK, BOOKE64, { FRT, RA, RB } }, +{ "mffgpr", XRC(31,607,0), XRA_MASK, POWER6, { FRT, RB } }, { "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB } }, @@ -4159,13 +4346,15 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB } }, -{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA, RB } }, -{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA, RB } }, +{ "stdbrx", X(31,660), X_MASK, CELL, { RS, RA0, RB } }, + +{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA0, RB } }, +{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA0, RB } }, -{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA, RB } }, -{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA, RB } }, +{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA0, RB } }, +{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA0, RB } }, -{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA, RB } }, +{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA0, RB } }, { "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB } }, { "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB } }, @@ -4173,9 +4362,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB } }, { "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB } }, -{ "stwbrxe", X(31,670), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "stwbrxe", X(31,670), X_MASK, BOOKE64, { RS, RA0, RB } }, -{ "stfsxe", X(31,671), X_MASK, BOOKE64, { FRS, RA, RB } }, +{ "stfsxe", X(31,671), X_MASK, BOOKE64, { FRS, RA0, RB } }, { "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB } }, @@ -4184,10 +4373,10 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "stfsuxe", X(31,703), X_MASK, BOOKE64, { FRS, RAS, RB } }, -{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA, NB } }, -{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA, NB } }, +{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA0, NB } }, +{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA0, NB } }, -{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA, RB } }, +{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA0, RB } }, { "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB } }, { "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB } }, @@ -4195,7 +4384,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB } }, { "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB } }, -{ "stfdxe", X(31,735), X_MASK, BOOKE64, { FRS, RA, RB } }, +{ "stfdxe", X(31,735), X_MASK, BOOKE64, { FRS, RA0, RB } }, + +{ "mftgpr", XRC(31,735,0), XRA_MASK, POWER6, { RT, FRB } }, { "dcba", X(31,758), XRT_MASK, PPC405 | BOOKE, { RA, RB } }, @@ -4211,7 +4402,9 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "tlbivax", X(31,786), XRT_MASK, BOOKE, { RA, RB } }, { "tlbivaxe",X(31,787), XRT_MASK, BOOKE64, { RA, RB } }, -{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA, RB } }, +{ "lwzcix", X(31,789), X_MASK, POWER6, { RT, RA0, RB } }, + +{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA0, RB } }, { "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } }, { "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB } }, @@ -4221,13 +4414,15 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB } }, { "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB } }, -{ "lhbrxe", X(31,798), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "lhbrxe", X(31,798), X_MASK, BOOKE64, { RT, RA0, RB } }, -{ "ldxe", X(31,799), X_MASK, BOOKE64, { RT, RA, RB } }, -{ "lduxe", X(31,831), X_MASK, BOOKE64, { RT, RA, RB } }, +{ "ldxe", X(31,799), X_MASK, BOOKE64, { RT, RA0, RB } }, +{ "lduxe", X(31,831), X_MASK, BOOKE64, { RT, RA0, RB } }, { "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB } }, +{ "lhzcix", X(31,821), X_MASK, POWER6, { RT, RA0, RB } }, + { "dss", XDSS(31,822,0), XDSS_MASK, PPCVEC, { STRM } }, { "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { 0 } }, @@ -4238,19 +4433,25 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "slbmfev", X(31,851), XRA_MASK, PPC64, { RT, RB } }, +{ "lbzcix", X(31,853), X_MASK, POWER6, { RT, RA0, RB } }, + { "mbar", X(31,854), X_MASK, BOOKE, { MO } }, { "eieio", X(31,854), 0xffffffff, PPC, { 0 } }, -{ "tlbsx", XRC(31,914,0), X_MASK, BOOKE, { RA, RB } }, -{ "tlbsx", XRC(31,914,0), X_MASK, PPC403, { RT, RA, RB } }, -{ "tlbsx.", XRC(31,914,1), X_MASK, BOOKE, { RA, RB } }, -{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403, { RT, RA, RB } }, +{ "lfiwax", X(31,855), X_MASK, POWER6, { FRT, RA0, RB } }, + +{ "ldcix", X(31,885), X_MASK, POWER6, { RT, RA0, RB } }, + +{ "tlbsx", XRC(31,914,0), X_MASK, PPC403|BOOKE, { RTO, RA, RB } }, +{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403|BOOKE, { RTO, RA, RB } }, { "tlbsxe", XRC(31,915,0), X_MASK, BOOKE64, { RA, RB } }, { "tlbsxe.", XRC(31,915,1), X_MASK, BOOKE64, { RA, RB } }, { "slbmfee", X(31,915), XRA_MASK, PPC64, { RT, RB } }, -{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA, RB } }, +{ "stwcix", X(31,917), X_MASK, POWER6, { RS, RA0, RB } }, + +{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA0, RB } }, { "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB } }, { "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB } }, @@ -4263,14 +4464,15 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS } }, { "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS } }, -{ "sthbrxe", X(31,926), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "sthbrxe", X(31,926), X_MASK, BOOKE64, { RS, RA0, RB } }, -{ "stdxe", X(31,927), X_MASK, BOOKE64, { RS, RA, RB } }, +{ "stdxe", X(31,927), X_MASK, BOOKE64, { RS, RA0, RB } }, { "tlbrehi", XTLB(31,946,0), XTLB_MASK, PPC403, { RT, RA } }, { "tlbrelo", XTLB(31,946,1), XTLB_MASK, PPC403, { RT, RA } }, -{ "tlbre", X(31,946), X_MASK, BOOKE, { 0 } }, -{ "tlbre", X(31,946), X_MASK, PPC403, { RS, RA, SH } }, +{ "tlbre", X(31,946), X_MASK, PPC403|BOOKE, { RSO, RAOPT, SHO } }, + +{ "sthcix", X(31,949), X_MASK, POWER6, { RS, RA0, RB } }, { "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } }, { "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } }, @@ -4284,13 +4486,14 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, { RT, RA } }, { "tlbwelo", XTLB(31,978,1), XTLB_MASK, PPC403, { RT, RA } }, -{ "tlbwe", X(31,978), X_MASK, BOOKE, { 0 } }, -{ "tlbwe", X(31,978), X_MASK, PPC403, { RS, RA, SH } }, +{ "tlbwe", X(31,978), X_MASK, PPC403|BOOKE, { RSO, RAOPT, SHO } }, { "tlbld", X(31,978), XRTRA_MASK, PPC, { RB } }, +{ "stbcix", X(31,981), X_MASK, POWER6, { RS, RA0, RB } }, + { "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } }, -{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB } }, +{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA0, RB } }, { "extsw", XRC(31,986,0), XRB_MASK, PPC64 | BOOKE64,{ RA, RS } }, { "extsw.", XRC(31,986,1), XRB_MASK, PPC64, { RA, RS } }, @@ -4298,10 +4501,13 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "icread", X(31,998), XRT_MASK, PPC403|PPC440, { RA, RB } }, { "icbie", X(31,990), XRT_MASK, BOOKE64, { RA, RB } }, -{ "stfiwxe", X(31,991), X_MASK, BOOKE64, { FRS, RA, RB } }, +{ "stfiwxe", X(31,991), X_MASK, BOOKE64, { FRS, RA0, RB } }, { "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB } }, +{ "stdcix", X(31,1013), X_MASK, POWER6, { RS, RA0, RB } }, + +{ "dcbzl", XOPL(31,1014,1), XRT_MASK,POWER4, { RA, RB } }, { "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } }, { "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } }, @@ -4320,86 +4526,104 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "stvx", X(31, 231), X_MASK, PPCVEC, { VS, RA, RB } }, { "stvxl", X(31, 487), X_MASK, PPCVEC, { VS, RA, RB } }, -{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA } }, -{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA } }, +/* New load/store left/right index vector instructions that are in the Cell only. */ +{ "lvlx", X(31, 519), X_MASK, CELL, { VD, RA0, RB } }, +{ "lvlxl", X(31, 775), X_MASK, CELL, { VD, RA0, RB } }, +{ "lvrx", X(31, 551), X_MASK, CELL, { VD, RA0, RB } }, +{ "lvrxl", X(31, 807), X_MASK, CELL, { VD, RA0, RB } }, +{ "stvlx", X(31, 647), X_MASK, CELL, { VS, RA0, RB } }, +{ "stvlxl", X(31, 903), X_MASK, CELL, { VS, RA0, RB } }, +{ "stvrx", X(31, 679), X_MASK, CELL, { VS, RA0, RB } }, +{ "stvrxl", X(31, 935), X_MASK, CELL, { VS, RA0, RB } }, + +{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA0 } }, +{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA0 } }, { "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL } }, -{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA } }, +{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA0 } }, -{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA } }, +{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA0 } }, { "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL } }, -{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA } }, -{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA } }, +{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA0 } }, +{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA0 } }, { "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } }, -{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA } }, +{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA0 } }, -{ "stb", OP(38), OP_MASK, COM, { RS, D, RA } }, +{ "stb", OP(38), OP_MASK, COM, { RS, D, RA0 } }, { "stbu", OP(39), OP_MASK, COM, { RS, D, RAS } }, -{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA } }, +{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA0 } }, { "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL } }, -{ "lha", OP(42), OP_MASK, COM, { RT, D, RA } }, +{ "lha", OP(42), OP_MASK, COM, { RT, D, RA0 } }, { "lhau", OP(43), OP_MASK, COM, { RT, D, RAL } }, -{ "sth", OP(44), OP_MASK, COM, { RS, D, RA } }, +{ "sth", OP(44), OP_MASK, COM, { RS, D, RA0 } }, { "sthu", OP(45), OP_MASK, COM, { RS, D, RAS } }, { "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM } }, -{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA } }, +{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA0 } }, -{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA } }, -{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA } }, +{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA0 } }, +{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA0 } }, -{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA } }, +{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA0 } }, { "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS } }, -{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA } }, +{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA0 } }, { "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS } }, -{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA } }, +{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA0 } }, { "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS } }, -{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA } }, +{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA0 } }, { "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } }, { "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } }, -{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } }, +{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA0 } }, + +{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA0 } }, -{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } }, +{ "lfdp", OP(57), OP_MASK, POWER6, { FRT, D, RA0 } }, -{ "lbze", DEO(58,0), DE_MASK, BOOKE64, { RT, DE, RA } }, +{ "lbze", DEO(58,0), DE_MASK, BOOKE64, { RT, DE, RA0 } }, { "lbzue", DEO(58,1), DE_MASK, BOOKE64, { RT, DE, RAL } }, -{ "lhze", DEO(58,2), DE_MASK, BOOKE64, { RT, DE, RA } }, +{ "lhze", DEO(58,2), DE_MASK, BOOKE64, { RT, DE, RA0 } }, { "lhzue", DEO(58,3), DE_MASK, BOOKE64, { RT, DE, RAL } }, -{ "lhae", DEO(58,4), DE_MASK, BOOKE64, { RT, DE, RA } }, +{ "lhae", DEO(58,4), DE_MASK, BOOKE64, { RT, DE, RA0 } }, { "lhaue", DEO(58,5), DE_MASK, BOOKE64, { RT, DE, RAL } }, -{ "lwze", DEO(58,6), DE_MASK, BOOKE64, { RT, DE, RA } }, +{ "lwze", DEO(58,6), DE_MASK, BOOKE64, { RT, DE, RA0 } }, { "lwzue", DEO(58,7), DE_MASK, BOOKE64, { RT, DE, RAL } }, -{ "stbe", DEO(58,8), DE_MASK, BOOKE64, { RS, DE, RA } }, +{ "stbe", DEO(58,8), DE_MASK, BOOKE64, { RS, DE, RA0 } }, { "stbue", DEO(58,9), DE_MASK, BOOKE64, { RS, DE, RAS } }, -{ "sthe", DEO(58,10), DE_MASK, BOOKE64, { RS, DE, RA } }, +{ "sthe", DEO(58,10), DE_MASK, BOOKE64, { RS, DE, RA0 } }, { "sthue", DEO(58,11), DE_MASK, BOOKE64, { RS, DE, RAS } }, -{ "stwe", DEO(58,14), DE_MASK, BOOKE64, { RS, DE, RA } }, +{ "stwe", DEO(58,14), DE_MASK, BOOKE64, { RS, DE, RA0 } }, { "stwue", DEO(58,15), DE_MASK, BOOKE64, { RS, DE, RAS } }, -{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA } }, +{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA0 } }, { "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL } }, -{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA } }, +{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA0 } }, + +{ "dadd", XRC(59,2,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "dadd.", XRC(59,2,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "dqua", ZRC(59,3,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, +{ "dqua.", ZRC(59,3,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, { "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, { "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } }, @@ -4413,12 +4637,15 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, { "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, -{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, -{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, +{ "fres", A(59,24,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } }, +{ "fres.", A(59,24,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } }, { "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } }, { "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } }, +{ "frsqrtes", A(59,26,0), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L } }, +{ "frsqrtes.",A(59,26,1), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L } }, + { "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, { "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, @@ -4431,31 +4658,103 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, { "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, +{ "dmul", XRC(59,34,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "dmul.", XRC(59,34,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "drrnd", ZRC(59,35,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, +{ "drrnd.", ZRC(59,35,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, + +{ "dscli", ZRC(59,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 } }, +{ "dscli.", ZRC(59,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 } }, + +{ "dquai", ZRC(59,67,0), Z_MASK, POWER6, { TE, FRT, FRB, RMC } }, +{ "dquai.", ZRC(59,67,1), Z_MASK, POWER6, { TE, FRT, FRB, RMC } }, + +{ "dscri", ZRC(59,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 } }, +{ "dscri.", ZRC(59,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 } }, + +{ "drintx", ZRC(59,99,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, +{ "drintx.", ZRC(59,99,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, + +{ "dcmpo", X(59,130), X_MASK, POWER6, { BF, FRA, FRB } }, + +{ "dtstex", X(59,162), X_MASK, POWER6, { BF, FRA, FRB } }, +{ "dtstdc", Z(59,194), Z_MASK, POWER6, { BF, FRA, DCM } }, +{ "dtstdg", Z(59,226), Z_MASK, POWER6, { BF, FRA, DGM } }, + +{ "drintn", ZRC(59,227,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, +{ "drintn.", ZRC(59,227,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, + +{ "dctdp", XRC(59,258,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dctdp.", XRC(59,258,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "dctfix", XRC(59,290,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dctfix.", XRC(59,290,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "ddedpd", XRC(59,322,0), X_MASK, POWER6, { SP, FRT, FRB } }, +{ "ddedpd.", XRC(59,322,1), X_MASK, POWER6, { SP, FRT, FRB } }, + +{ "dxex", XRC(59,354,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dxex.", XRC(59,354,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "dsub", XRC(59,514,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "dsub.", XRC(59,514,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "ddiv", XRC(59,546,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "ddiv.", XRC(59,546,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "dcmpu", X(59,642), X_MASK, POWER6, { BF, FRA, FRB } }, + +{ "dtstsf", X(59,674), X_MASK, POWER6, { BF, FRA, FRB } }, + +{ "drsp", XRC(59,770,0), X_MASK, POWER6, { FRT, FRB } }, +{ "drsp.", XRC(59,770,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "dcffix", XRC(59,802,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dcffix.", XRC(59,802,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "denbcd", XRC(59,834,0), X_MASK, POWER6, { S, FRT, FRB } }, +{ "denbcd.", XRC(59,834,1), X_MASK, POWER6, { S, FRT, FRB } }, + +{ "diex", XRC(59,866,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "diex.", XRC(59,866,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + { "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } }, { "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } }, -{ "lde", DEO(62,0), DE_MASK, BOOKE64, { RT, DES, RA } }, -{ "ldue", DEO(62,1), DE_MASK, BOOKE64, { RT, DES, RA } }, -{ "lfse", DEO(62,4), DE_MASK, BOOKE64, { FRT, DES, RA } }, +{ "stfdp", OP(61), OP_MASK, POWER6, { FRT, D, RA0 } }, + +{ "lde", DEO(62,0), DE_MASK, BOOKE64, { RT, DES, RA0 } }, +{ "ldue", DEO(62,1), DE_MASK, BOOKE64, { RT, DES, RA0 } }, +{ "lfse", DEO(62,4), DE_MASK, BOOKE64, { FRT, DES, RA0 } }, { "lfsue", DEO(62,5), DE_MASK, BOOKE64, { FRT, DES, RAS } }, -{ "lfde", DEO(62,6), DE_MASK, BOOKE64, { FRT, DES, RA } }, +{ "lfde", DEO(62,6), DE_MASK, BOOKE64, { FRT, DES, RA0 } }, { "lfdue", DEO(62,7), DE_MASK, BOOKE64, { FRT, DES, RAS } }, -{ "stde", DEO(62,8), DE_MASK, BOOKE64, { RS, DES, RA } }, +{ "stde", DEO(62,8), DE_MASK, BOOKE64, { RS, DES, RA0 } }, { "stdue", DEO(62,9), DE_MASK, BOOKE64, { RS, DES, RAS } }, -{ "stfse", DEO(62,12), DE_MASK, BOOKE64, { FRS, DES, RA } }, +{ "stfse", DEO(62,12), DE_MASK, BOOKE64, { FRS, DES, RA0 } }, { "stfsue", DEO(62,13), DE_MASK, BOOKE64, { FRS, DES, RAS } }, -{ "stfde", DEO(62,14), DE_MASK, BOOKE64, { FRS, DES, RA } }, +{ "stfde", DEO(62,14), DE_MASK, BOOKE64, { FRS, DES, RA0 } }, { "stfdue", DEO(62,15), DE_MASK, BOOKE64, { FRS, DES, RAS } }, -{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA } }, +{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA0 } }, { "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } }, -{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA } }, +{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA0 } }, { "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, +{ "daddq", XRC(63,2,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "daddq.", XRC(63,2,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "dquaq", ZRC(63,3,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, +{ "dquaq.", ZRC(63,3,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, + +{ "fcpsgn", XRC(63,8,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "fcpsgn.", XRC(63,8,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + { "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } }, { "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB } }, @@ -4490,13 +4789,16 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, { "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, +{ "fre", A(63,24,0), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L } }, +{ "fre.", A(63,24,1), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L } }, + { "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } }, { "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } }, { "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } }, { "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } }, -{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, -{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, +{ "frsqrte", A(63,26,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } }, +{ "frsqrte.",A(63,26,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } }, { "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } }, { "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } }, @@ -4520,6 +4822,12 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "fcmpo", X(63,32), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, +{ "dmulq", XRC(63,34,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "dmulq.", XRC(63,34,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "drrndq", ZRC(63,35,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, +{ "drrndq.", ZRC(63,35,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, + { "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT } }, { "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT } }, @@ -4528,36 +4836,100 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } }, +{ "dscliq", ZRC(63,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 } }, +{ "dscliq.", ZRC(63,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 } }, + +{ "dquaiq", ZRC(63,67,0), Z_MASK, POWER6, { TE, FRT, FRB, RMC } }, +{ "dquaiq.", ZRC(63,67,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } }, + { "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT } }, { "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT } }, { "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB } }, { "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB } }, +{ "dscriq", ZRC(63,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 } }, +{ "dscriq.", ZRC(63,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 } }, + +{ "drintxq", ZRC(63,99,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, +{ "drintxq.",ZRC(63,99,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, + +{ "dcmpoq", X(63,130), X_MASK, POWER6, { BF, FRA, FRB } }, + { "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } }, { "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } }, { "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } }, { "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } }, +{ "dtstexq", X(63,162), X_MASK, POWER6, { BF, FRA, FRB } }, +{ "dtstdcq", Z(63,194), Z_MASK, POWER6, { BF, FRA, DCM } }, +{ "dtstdgq", Z(63,226), Z_MASK, POWER6, { BF, FRA, DGM } }, + +{ "drintnq", ZRC(63,227,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, +{ "drintnq.",ZRC(63,227,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } }, + +{ "dctqpq", XRC(63,258,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dctqpq.", XRC(63,258,1), X_MASK, POWER6, { FRT, FRB } }, + { "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB } }, { "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB } }, +{ "dctfixq", XRC(63,290,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dctfixq.",XRC(63,290,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "ddedpdq", XRC(63,322,0), X_MASK, POWER6, { SP, FRT, FRB } }, +{ "ddedpdq.",XRC(63,322,1), X_MASK, POWER6, { SP, FRT, FRB } }, + +{ "dxexq", XRC(63,354,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dxexq.", XRC(63,354,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "frin", XRC(63,392,0), XRA_MASK, POWER5, { FRT, FRB } }, +{ "frin.", XRC(63,392,1), XRA_MASK, POWER5, { FRT, FRB } }, +{ "friz", XRC(63,424,0), XRA_MASK, POWER5, { FRT, FRB } }, +{ "friz.", XRC(63,424,1), XRA_MASK, POWER5, { FRT, FRB } }, +{ "frip", XRC(63,456,0), XRA_MASK, POWER5, { FRT, FRB } }, +{ "frip.", XRC(63,456,1), XRA_MASK, POWER5, { FRT, FRB } }, +{ "frim", XRC(63,488,0), XRA_MASK, POWER5, { FRT, FRB } }, +{ "frim.", XRC(63,488,1), XRA_MASK, POWER5, { FRT, FRB } }, + +{ "dsubq", XRC(63,514,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "dsubq.", XRC(63,514,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + +{ "ddivq", XRC(63,546,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "ddivq.", XRC(63,546,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + { "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } }, { "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } }, +{ "dcmpuq", X(63,642), X_MASK, POWER6, { BF, FRA, FRB } }, + +{ "dtstsfq", X(63,674), X_MASK, POWER6, { BF, FRA, FRB } }, + { "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } }, { "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } }, +{ "drdpq", XRC(63,770,0), X_MASK, POWER6, { FRT, FRB } }, +{ "drdpq.", XRC(63,770,1), X_MASK, POWER6, { FRT, FRB } }, + +{ "dcffixq", XRC(63,802,0), X_MASK, POWER6, { FRT, FRB } }, +{ "dcffixq.",XRC(63,802,1), X_MASK, POWER6, { FRT, FRB } }, + { "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB } }, { "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB } }, { "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB } }, { "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB } }, +{ "denbcdq", XRC(63,834,0), X_MASK, POWER6, { S, FRT, FRB } }, +{ "denbcdq.",XRC(63,834,1), X_MASK, POWER6, { S, FRT, FRB } }, + { "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } }, { "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } }, +{ "diexq", XRC(63,866,0), X_MASK, POWER6, { FRT, FRA, FRB } }, +{ "diexq.", XRC(63,866,1), X_MASK, POWER6, { FRT, FRA, FRB } }, + }; const int powerpc_num_opcodes = diff --git a/arch/powerpc/xmon/ppc.h b/arch/powerpc/xmon/ppc.h index 342237e8dd6..110df96354b 100644 --- a/arch/powerpc/xmon/ppc.h +++ b/arch/powerpc/xmon/ppc.h @@ -1,5 +1,5 @@ /* ppc.h -- Header file for PowerPC opcode table - Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003 + Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support @@ -17,7 +17,7 @@ the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this file; see the file COPYING. If not, write to the Free -Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PPC_H #define PPC_H @@ -134,6 +134,18 @@ extern const int powerpc_num_opcodes; /* Opcode is supported by machine check APU. */ #define PPC_OPCODE_RFMCI 0x800000 +/* Opcode is only supported by Power5 architecture. */ +#define PPC_OPCODE_POWER5 0x1000000 + +/* Opcode is supported by PowerPC e300 family. */ +#define PPC_OPCODE_E300 0x2000000 + +/* Opcode is only supported by Power6 architecture. */ +#define PPC_OPCODE_POWER6 0x4000000 + +/* Opcode is only supported by PowerPC Cell family. */ +#define PPC_OPCODE_CELL 0x8000000 + /* A macro to extract the major opcode from an instruction. */ #define PPC_OP(i) (((i) >> 26) & 0x3f) @@ -233,25 +245,28 @@ extern const struct powerpc_operand powerpc_operands[]; register names with a leading 'r'. */ #define PPC_OPERAND_GPR (040) +/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */ +#define PPC_OPERAND_GPR_0 (0100) + /* This operand names a floating point register. The disassembler prints these with a leading 'f'. */ -#define PPC_OPERAND_FPR (0100) +#define PPC_OPERAND_FPR (0200) /* This operand is a relative branch displacement. The disassembler prints these symbolically if possible. */ -#define PPC_OPERAND_RELATIVE (0200) +#define PPC_OPERAND_RELATIVE (0400) /* This operand is an absolute branch address. The disassembler prints these symbolically if possible. */ -#define PPC_OPERAND_ABSOLUTE (0400) +#define PPC_OPERAND_ABSOLUTE (01000) /* This operand is optional, and is zero if omitted. This is used for - the optional BF and L fields in the comparison instructions. The + example, in the optional BF field in the comparison instructions. The assembler must count the number of operands remaining on the line, and the number of operands remaining for the opcode, and decide whether this operand is present or not. The disassembler should print this operand out only if it is not zero. */ -#define PPC_OPERAND_OPTIONAL (01000) +#define PPC_OPERAND_OPTIONAL (02000) /* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand is omitted, then for the next operand use this operand value plus @@ -259,24 +274,24 @@ extern const struct powerpc_operand powerpc_operands[]; hack is needed because the Power rotate instructions can take either 4 or 5 operands. The disassembler should print this operand out regardless of the PPC_OPERAND_OPTIONAL field. */ -#define PPC_OPERAND_NEXT (02000) +#define PPC_OPERAND_NEXT (04000) /* This operand should be regarded as a negative number for the purposes of overflow checking (i.e., the normal most negative number is disallowed and one more than the normal most positive number is allowed). This flag will only be set for a signed operand. */ -#define PPC_OPERAND_NEGATIVE (04000) +#define PPC_OPERAND_NEGATIVE (010000) /* This operand names a vector unit register. The disassembler prints these with a leading 'v'. */ -#define PPC_OPERAND_VR (010000) +#define PPC_OPERAND_VR (020000) /* This operand is for the DS field in a DS form instruction. */ -#define PPC_OPERAND_DS (020000) +#define PPC_OPERAND_DS (040000) /* This operand is for the DQ field in a DQ form instruction. */ -#define PPC_OPERAND_DQ (040000) +#define PPC_OPERAND_DQ (0100000) /* The POWER and PowerPC assemblers use a few macros. We keep them with the operands table for simplicity. The macro table is an -- cgit v1.2.3 From e28b003136b5b2f10c25b49c32df9b7742550c23 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:49 +0100 Subject: [POWERPC] cell: abstract spu management routines This adds a platform specific spu management abstraction and the coresponding routines to support the IBM Cell Blade. It also removes the hypervisor only resources that were included in struct spu. Three new platform specific routines are introduced, spu_enumerate_spus(), spu_create_spu() and spu_destroy_spu(). The underlying design uses a new type, struct spu_management_ops, to hold function pointers that the platform setup code is expected to initialize to instances appropriate to that platform. For the IBM Cell Blade support, I put the hypervisor only resources that were in struct spu into a platform specific data structure struct spu_pdata. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/cbe_thermal.c | 5 +- arch/powerpc/platforms/cell/setup.c | 3 +- arch/powerpc/platforms/cell/spu_base.c | 334 ++------------------- arch/powerpc/platforms/cell/spu_priv1_mmio.c | 424 +++++++++++++++++++++++++-- arch/powerpc/platforms/cell/spu_priv1_mmio.h | 26 ++ 5 files changed, 454 insertions(+), 338 deletions(-) create mode 100644 arch/powerpc/platforms/cell/spu_priv1_mmio.h (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c index 17831a92d91..616a0a3fd0e 100644 --- a/arch/powerpc/platforms/cell/cbe_thermal.c +++ b/arch/powerpc/platforms/cell/cbe_thermal.c @@ -29,6 +29,7 @@ #include #include "cbe_regs.h" +#include "spu_priv1_mmio.h" static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev) { @@ -36,7 +37,7 @@ static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev) spu = container_of(sysdev, struct spu, sysdev); - return cbe_get_pmd_regs(spu->devnode); + return cbe_get_pmd_regs(spu_devnode(spu)); } /* returns the value for a given spu in a given register */ @@ -49,7 +50,7 @@ static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iom /* getting the id from the reg attribute will not work on future device-tree layouts * in future we should store the id to the spu struct and use it here */ spu = container_of(sysdev, struct spu, sysdev); - id = (unsigned int *)get_property(spu->devnode, "reg", NULL); + id = (unsigned int *)get_property(spu_devnode(spu), "reg", NULL); value.val = in_be64(®->val); return value.spe[*id]; diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 83d5d0c2faf..36989c2eee6 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -145,7 +145,8 @@ static void __init cell_init_irq(void) static void __init cell_setup_arch(void) { #ifdef CONFIG_SPU_BASE - spu_priv1_ops = &spu_priv1_mmio_ops; + spu_priv1_ops = &spu_priv1_mmio_ops; + spu_management_ops = &spu_management_of_ops; #endif cbe_regs_init(); diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index d4f4f396288..841ed359802 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -25,23 +25,17 @@ #include #include #include -#include -#include #include #include #include - -#include -#include -#include +#include +#include #include #include #include -#include #include -#include "interrupt.h" - +const struct spu_management_ops *spu_management_ops; const struct spu_priv1_ops *spu_priv1_ops; EXPORT_SYMBOL_GPL(spu_priv1_ops); @@ -512,261 +506,6 @@ int spu_irq_class_1_bottom(struct spu *spu) return ret; } -static int __init find_spu_node_id(struct device_node *spe) -{ - const unsigned int *id; - struct device_node *cpu; - cpu = spe->parent->parent; - id = get_property(cpu, "node-id", NULL); - return id ? *id : 0; -} - -static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, - const char *prop) -{ - static DEFINE_MUTEX(add_spumem_mutex); - - const struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *p; - int proplen; - - unsigned long start_pfn, nr_pages; - struct pglist_data *pgdata; - struct zone *zone; - int ret; - - p = get_property(spe, prop, &proplen); - WARN_ON(proplen != sizeof (*p)); - - start_pfn = p->address >> PAGE_SHIFT; - nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; - - pgdata = NODE_DATA(spu->nid); - zone = pgdata->node_zones; - - /* XXX rethink locking here */ - mutex_lock(&add_spumem_mutex); - ret = __add_pages(zone, start_pfn, nr_pages); - mutex_unlock(&add_spumem_mutex); - - return ret; -} - -static void __iomem * __init map_spe_prop(struct spu *spu, - struct device_node *n, const char *name) -{ - const struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *prop; - - const void *p; - int proplen; - void __iomem *ret = NULL; - int err = 0; - - p = get_property(n, name, &proplen); - if (proplen != sizeof (struct address_prop)) - return NULL; - - prop = p; - - err = cell_spuprop_present(spu, n, name); - if (err && (err != -EEXIST)) - goto out; - - ret = ioremap(prop->address, prop->len); - - out: - return ret; -} - -static void spu_unmap(struct spu *spu) -{ - iounmap(spu->priv2); - iounmap(spu->priv1); - iounmap(spu->problem); - iounmap((__force u8 __iomem *)spu->local_store); -} - -/* This function shall be abstracted for HV platforms */ -static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np) -{ - unsigned int isrc; - const u32 *tmp; - - /* Get the interrupt source unit from the device-tree */ - tmp = get_property(np, "isrc", NULL); - if (!tmp) - return -ENODEV; - isrc = tmp[0]; - - /* Add the node number */ - isrc |= spu->node << IIC_IRQ_NODE_SHIFT; - - /* Now map interrupts of all 3 classes */ - spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); - spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); - spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); - - /* Right now, we only fail if class 2 failed */ - return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; -} - -static int __init spu_map_device_old(struct spu *spu, struct device_node *node) -{ - const char *prop; - int ret; - - ret = -ENODEV; - spu->name = get_property(node, "name", NULL); - if (!spu->name) - goto out; - - prop = get_property(node, "local-store", NULL); - if (!prop) - goto out; - spu->local_store_phys = *(unsigned long *)prop; - - /* we use local store as ram, not io memory */ - spu->local_store = (void __force *) - map_spe_prop(spu, node, "local-store"); - if (!spu->local_store) - goto out; - - prop = get_property(node, "problem", NULL); - if (!prop) - goto out_unmap; - spu->problem_phys = *(unsigned long *)prop; - - spu->problem= map_spe_prop(spu, node, "problem"); - if (!spu->problem) - goto out_unmap; - - spu->priv1= map_spe_prop(spu, node, "priv1"); - /* priv1 is not available on a hypervisor */ - - spu->priv2= map_spe_prop(spu, node, "priv2"); - if (!spu->priv2) - goto out_unmap; - ret = 0; - goto out; - -out_unmap: - spu_unmap(spu); -out: - return ret; -} - -static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) -{ - struct of_irq oirq; - int ret; - int i; - - for (i=0; i < 3; i++) { - ret = of_irq_map_one(np, i, &oirq); - if (ret) { - pr_debug("spu_new: failed to get irq %d\n", i); - goto err; - } - ret = -EINVAL; - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], - oirq.controller->full_name); - spu->irqs[i] = irq_create_of_mapping(oirq.controller, - oirq.specifier, oirq.size); - if (spu->irqs[i] == NO_IRQ) { - pr_debug("spu_new: failed to map it !\n"); - goto err; - } - } - return 0; - -err: - pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name); - for (; i >= 0; i--) { - if (spu->irqs[i] != NO_IRQ) - irq_dispose_mapping(spu->irqs[i]); - } - return ret; -} - -static int spu_map_resource(struct device_node *node, int nr, - void __iomem** virt, unsigned long *phys) -{ - struct resource resource = { }; - int ret; - - ret = of_address_to_resource(node, nr, &resource); - if (ret) - goto out; - - if (phys) - *phys = resource.start; - *virt = ioremap(resource.start, resource.end - resource.start); - if (!*virt) - ret = -EINVAL; - -out: - return ret; -} - -static int __init spu_map_device(struct spu *spu, struct device_node *node) -{ - int ret = -ENODEV; - spu->name = get_property(node, "name", NULL); - if (!spu->name) - goto out; - - ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, - &spu->local_store_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 0\n", - node->full_name); - goto out; - } - ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, - &spu->problem_phys); - if (ret) { - pr_debug("spu_new: failed to map %s resource 1\n", - node->full_name); - goto out_unmap; - } - ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, - NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 2\n", - node->full_name); - goto out_unmap; - } - - if (!firmware_has_feature(FW_FEATURE_LPAR)) - ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1, - NULL); - if (ret) { - pr_debug("spu_new: failed to map %s resource 3\n", - node->full_name); - goto out_unmap; - } - pr_debug("spu_new: %s maps:\n", node->full_name); - pr_debug(" local store : 0x%016lx -> 0x%p\n", - spu->local_store_phys, spu->local_store); - pr_debug(" problem state : 0x%016lx -> 0x%p\n", - spu->problem_phys, spu->problem); - pr_debug(" priv2 : 0x%p\n", spu->priv2); - pr_debug(" priv1 : 0x%p\n", spu->priv1); - - return 0; - -out_unmap: - spu_unmap(spu); -out: - pr_debug("failed to map spe %s: %d\n", spu->name, ret); - return ret; -} - struct sysdev_class spu_sysdev_class = { set_kset_name("spu") }; @@ -846,7 +585,7 @@ static void spu_destroy_sysdev(struct spu *spu) sysdev_unregister(&spu->sysdev); } -static int __init create_spu(struct device_node *spe) +static int __init create_spu(void *data) { struct spu *spu; int ret; @@ -857,60 +596,37 @@ static int __init create_spu(struct device_node *spe) if (!spu) goto out; - spu->node = find_spu_node_id(spe); - if (spu->node >= MAX_NUMNODES) { - printk(KERN_WARNING "SPE %s on node %d ignored," - " node number too big\n", spe->full_name, spu->node); - printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); - return -ENODEV; - } - spu->nid = of_node_to_nid(spe); - if (spu->nid == -1) - spu->nid = 0; + spin_lock_init(&spu->register_lock); + mutex_lock(&spu_mutex); + spu->number = number++; + mutex_unlock(&spu_mutex); + + ret = spu_create_spu(spu, data); - ret = spu_map_device(spu, spe); - /* try old method */ - if (ret) - ret = spu_map_device_old(spu, spe); if (ret) goto out_free; - ret = spu_map_interrupts(spu, spe); - if (ret) - ret = spu_map_interrupts_old(spu, spe); - if (ret) - goto out_unmap; - spin_lock_init(&spu->register_lock); spu_mfc_sdr_setup(spu); spu_mfc_sr1_set(spu, 0x33); - mutex_lock(&spu_mutex); - - spu->number = number++; ret = spu_request_irqs(spu); if (ret) - goto out_unlock; + goto out_destroy; ret = spu_create_sysdev(spu); if (ret) goto out_free_irqs; + mutex_lock(&spu_mutex); list_add(&spu->list, &spu_list[spu->node]); list_add(&spu->full_list, &spu_full_list); - spu->devnode = of_node_get(spe); - mutex_unlock(&spu_mutex); - pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", - spu->name, spu->local_store, - spu->problem, spu->priv1, spu->priv2, spu->number); goto out; out_free_irqs: spu_free_irqs(spu); -out_unlock: - mutex_unlock(&spu_mutex); -out_unmap: - spu_unmap(spu); +out_destroy: + spu_destroy_spu(spu); out_free: kfree(spu); out: @@ -922,11 +638,9 @@ static void destroy_spu(struct spu *spu) list_del_init(&spu->list); list_del_init(&spu->full_list); - of_node_put(spu->devnode); - spu_destroy_sysdev(spu); spu_free_irqs(spu); - spu_unmap(spu); + spu_destroy_spu(spu); kfree(spu); } @@ -947,7 +661,6 @@ module_exit(cleanup_spu_base); static int __init init_spu_base(void) { - struct device_node *node; int i, ret; /* create sysdev class for spus */ @@ -958,16 +671,13 @@ static int __init init_spu_base(void) for (i = 0; i < MAX_NUMNODES; i++) INIT_LIST_HEAD(&spu_list[i]); - ret = -ENODEV; - for (node = of_find_node_by_type(NULL, "spe"); - node; node = of_find_node_by_type(node, "spe")) { - ret = create_spu(node); - if (ret) { - printk(KERN_WARNING "%s: Error initializing %s\n", - __FUNCTION__, node->name); - cleanup_spu_base(); - break; - } + ret = spu_enumerate_spus(create_spu); + + if (ret) { + printk(KERN_WARNING "%s: Error initializing spus\n", + __FUNCTION__); + cleanup_spu_base(); + return ret; } xmon_register_spus(&spu_full_list); diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c index 90011f9aab3..a5de0430c56 100644 --- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c @@ -18,120 +18,498 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include +#include #include +#include +#include +#include +#include +#include +#include +#include -#include #include #include +#include +#include #include "interrupt.h" +#include "spu_priv1_mmio.h" + +struct spu_pdata { + int nid; + struct device_node *devnode; + struct spu_priv1 __iomem *priv1; +}; + +static struct spu_pdata *spu_get_pdata(struct spu *spu) +{ + BUG_ON(!spu->pdata); + return spu->pdata; +} + +struct device_node *spu_devnode(struct spu *spu) +{ + return spu_get_pdata(spu)->devnode; +} + +EXPORT_SYMBOL_GPL(spu_devnode); + +static int __init find_spu_node_id(struct device_node *spe) +{ + const unsigned int *id; + struct device_node *cpu; + cpu = spe->parent->parent; + id = get_property(cpu, "node-id", NULL); + return id ? *id : 0; +} + +static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, + const char *prop) +{ + static DEFINE_MUTEX(add_spumem_mutex); + + const struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *p; + int proplen; + + unsigned long start_pfn, nr_pages; + struct pglist_data *pgdata; + struct zone *zone; + int ret; + + p = get_property(spe, prop, &proplen); + WARN_ON(proplen != sizeof (*p)); + + start_pfn = p->address >> PAGE_SHIFT; + nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; + + pgdata = NODE_DATA(spu_get_pdata(spu)->nid); + zone = pgdata->node_zones; + + /* XXX rethink locking here */ + mutex_lock(&add_spumem_mutex); + ret = __add_pages(zone, start_pfn, nr_pages); + mutex_unlock(&add_spumem_mutex); + + return ret; +} + +static void __iomem * __init map_spe_prop(struct spu *spu, + struct device_node *n, const char *name) +{ + const struct address_prop { + unsigned long address; + unsigned int len; + } __attribute__((packed)) *prop; + + const void *p; + int proplen; + void __iomem *ret = NULL; + int err = 0; + + p = get_property(n, name, &proplen); + if (proplen != sizeof (struct address_prop)) + return NULL; + + prop = p; + + err = cell_spuprop_present(spu, n, name); + if (err && (err != -EEXIST)) + goto out; + + ret = ioremap(prop->address, prop->len); + + out: + return ret; +} + +static void spu_unmap(struct spu *spu) +{ + iounmap(spu->priv2); + iounmap(spu_get_pdata(spu)->priv1); + iounmap(spu->problem); + iounmap((__force u8 __iomem *)spu->local_store); +} + +static int __init spu_map_interrupts_old(struct spu *spu, + struct device_node *np) +{ + unsigned int isrc; + const u32 *tmp; + + /* Get the interrupt source unit from the device-tree */ + tmp = get_property(np, "isrc", NULL); + if (!tmp) + return -ENODEV; + isrc = tmp[0]; + + /* Add the node number */ + isrc |= spu->node << IIC_IRQ_NODE_SHIFT; + + /* Now map interrupts of all 3 classes */ + spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); + spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); + spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); + + /* Right now, we only fail if class 2 failed */ + return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; +} + +static int __init spu_map_device_old(struct spu *spu, struct device_node *node) +{ + const char *prop; + int ret; + + ret = -ENODEV; + spu->name = get_property(node, "name", NULL); + if (!spu->name) + goto out; + + prop = get_property(node, "local-store", NULL); + if (!prop) + goto out; + spu->local_store_phys = *(unsigned long *)prop; + + /* we use local store as ram, not io memory */ + spu->local_store = (void __force *) + map_spe_prop(spu, node, "local-store"); + if (!spu->local_store) + goto out; + + prop = get_property(node, "problem", NULL); + if (!prop) + goto out_unmap; + spu->problem_phys = *(unsigned long *)prop; + + spu->problem= map_spe_prop(spu, node, "problem"); + if (!spu->problem) + goto out_unmap; + + spu_get_pdata(spu)->priv1= map_spe_prop(spu, node, "priv1"); + + spu->priv2= map_spe_prop(spu, node, "priv2"); + if (!spu->priv2) + goto out_unmap; + ret = 0; + goto out; + +out_unmap: + spu_unmap(spu); +out: + return ret; +} + +static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) +{ + struct of_irq oirq; + int ret; + int i; + + for (i=0; i < 3; i++) { + ret = of_irq_map_one(np, i, &oirq); + if (ret) { + pr_debug("spu_new: failed to get irq %d\n", i); + goto err; + } + ret = -EINVAL; + pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], + oirq.controller->full_name); + spu->irqs[i] = irq_create_of_mapping(oirq.controller, + oirq.specifier, oirq.size); + if (spu->irqs[i] == NO_IRQ) { + pr_debug("spu_new: failed to map it !\n"); + goto err; + } + } + return 0; + +err: + pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, + spu->name); + for (; i >= 0; i--) { + if (spu->irqs[i] != NO_IRQ) + irq_dispose_mapping(spu->irqs[i]); + } + return ret; +} + +static int spu_map_resource(struct device_node *node, int nr, + void __iomem** virt, unsigned long *phys) +{ + struct resource resource = { }; + int ret; + + ret = of_address_to_resource(node, nr, &resource); + if (ret) + goto out; + + if (phys) + *phys = resource.start; + *virt = ioremap(resource.start, resource.end - resource.start); + if (!*virt) + ret = -EINVAL; + +out: + return ret; +} + +static int __init spu_map_device(struct spu *spu, struct device_node *node) +{ + int ret = -ENODEV; + spu->name = get_property(node, "name", NULL); + if (!spu->name) + goto out; + + ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store, + &spu->local_store_phys); + if (ret) { + pr_debug("spu_new: failed to map %s resource 0\n", + node->full_name); + goto out; + } + ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem, + &spu->problem_phys); + if (ret) { + pr_debug("spu_new: failed to map %s resource 1\n", + node->full_name); + goto out_unmap; + } + ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2, + NULL); + if (ret) { + pr_debug("spu_new: failed to map %s resource 2\n", + node->full_name); + goto out_unmap; + } + if (!firmware_has_feature(FW_FEATURE_LPAR)) + ret = spu_map_resource(node, 3, + (void __iomem**)&spu_get_pdata(spu)->priv1, NULL); + if (ret) { + pr_debug("spu_new: failed to map %s resource 3\n", + node->full_name); + goto out_unmap; + } + pr_debug("spu_new: %s maps:\n", node->full_name); + pr_debug(" local store : 0x%016lx -> 0x%p\n", + spu->local_store_phys, spu->local_store); + pr_debug(" problem state : 0x%016lx -> 0x%p\n", + spu->problem_phys, spu->problem); + pr_debug(" priv2 : 0x%p\n", spu->priv2); + pr_debug(" priv1 : 0x%p\n", + spu_get_pdata(spu)->priv1); + + return 0; + +out_unmap: + spu_unmap(spu); +out: + pr_debug("failed to map spe %s: %d\n", spu->name, ret); + return ret; +} + +static int __init of_enumerate_spus(int (*fn)(void *data)) +{ + int ret; + struct device_node *node; + + ret = -ENODEV; + for (node = of_find_node_by_type(NULL, "spe"); + node; node = of_find_node_by_type(node, "spe")) { + ret = fn(node); + if (ret) { + printk(KERN_WARNING "%s: Error initializing %s\n", + __FUNCTION__, node->name); + break; + } + } + return ret; +} + +static int __init of_create_spu(struct spu *spu, void *data) +{ + int ret; + struct device_node *spe = (struct device_node *)data; + + spu->pdata = kzalloc(sizeof(struct spu_pdata), + GFP_KERNEL); + if (!spu->pdata) { + ret = -ENOMEM; + goto out; + } + + spu->node = find_spu_node_id(spe); + if (spu->node >= MAX_NUMNODES) { + printk(KERN_WARNING "SPE %s on node %d ignored," + " node number too big\n", spe->full_name, spu->node); + printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); + ret = -ENODEV; + goto out_free; + } + + spu_get_pdata(spu)->nid = of_node_to_nid(spe); + if (spu_get_pdata(spu)->nid == -1) + spu_get_pdata(spu)->nid = 0; + + ret = spu_map_device(spu, spe); + /* try old method */ + if (ret) + ret = spu_map_device_old(spu, spe); + if (ret) + goto out_free; + + ret = spu_map_interrupts(spu, spe); + if (ret) + ret = spu_map_interrupts_old(spu, spe); + if (ret) + goto out_unmap; + + spu_get_pdata(spu)->devnode = of_node_get(spe); + + pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name, + spu->local_store, spu->problem, spu_get_pdata(spu)->priv1, + spu->priv2, spu->number); + goto out; + +out_unmap: + spu_unmap(spu); +out_free: + kfree(spu->pdata); + spu->pdata = NULL; +out: + return ret; +} + +static int of_destroy_spu(struct spu *spu) +{ + spu_unmap(spu); + of_node_put(spu_get_pdata(spu)->devnode); + kfree(spu->pdata); + spu->pdata = NULL; + return 0; +} + +const struct spu_management_ops spu_management_of_ops = { + .enumerate_spus = of_enumerate_spus, + .create_spu = of_create_spu, + .destroy_spu = of_destroy_spu, +}; static void int_mask_and(struct spu *spu, int class, u64 mask) { u64 old_mask; - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); + old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], + old_mask & mask); } static void int_mask_or(struct spu *spu, int class, u64 mask) { u64 old_mask; - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); + old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], + old_mask | mask); } static void int_mask_set(struct spu *spu, int class, u64 mask) { - out_be64(&spu->priv1->int_mask_RW[class], mask); + out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], mask); } static u64 int_mask_get(struct spu *spu, int class) { - return in_be64(&spu->priv1->int_mask_RW[class]); + return in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); } static void int_stat_clear(struct spu *spu, int class, u64 stat) { - out_be64(&spu->priv1->int_stat_RW[class], stat); + out_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class], stat); } static u64 int_stat_get(struct spu *spu, int class) { - return in_be64(&spu->priv1->int_stat_RW[class]); + return in_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class]); } static void cpu_affinity_set(struct spu *spu, int cpu) { u64 target = iic_get_target_id(cpu); u64 route = target << 48 | target << 32 | target << 16; - out_be64(&spu->priv1->int_route_RW, route); + out_be64(&spu_get_pdata(spu)->priv1->int_route_RW, route); } static u64 mfc_dar_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_dar_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_dar_RW); } static u64 mfc_dsisr_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_dsisr_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW); } static void mfc_dsisr_set(struct spu *spu, u64 dsisr) { - out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); + out_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW, dsisr); } static void mfc_sdr_setup(struct spu *spu) { - out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); + out_be64(&spu_get_pdata(spu)->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); } static void mfc_sr1_set(struct spu *spu, u64 sr1) { - out_be64(&spu->priv1->mfc_sr1_RW, sr1); + out_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW, sr1); } static u64 mfc_sr1_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_sr1_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW); } static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) { - out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); + out_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW, tclass_id); } static u64 mfc_tclass_id_get(struct spu *spu) { - return in_be64(&spu->priv1->mfc_tclass_id_RW); + return in_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW); } static void tlb_invalidate(struct spu *spu) { - out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); + out_be64(&spu_get_pdata(spu)->priv1->tlb_invalidate_entry_W, 0ul); } static void resource_allocation_groupID_set(struct spu *spu, u64 id) { - out_be64(&spu->priv1->resource_allocation_groupID_RW, id); + out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW, + id); } static u64 resource_allocation_groupID_get(struct spu *spu) { - return in_be64(&spu->priv1->resource_allocation_groupID_RW); + return in_be64( + &spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW); } static void resource_allocation_enable_set(struct spu *spu, u64 enable) { - out_be64(&spu->priv1->resource_allocation_enable_RW, enable); + out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_enable_RW, + enable); } static u64 resource_allocation_enable_get(struct spu *spu) { - return in_be64(&spu->priv1->resource_allocation_enable_RW); + return in_be64( + &spu_get_pdata(spu)->priv1->resource_allocation_enable_RW); } const struct spu_priv1_ops spu_priv1_mmio_ops = diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.h b/arch/powerpc/platforms/cell/spu_priv1_mmio.h new file mode 100644 index 00000000000..7b62bd1cc25 --- /dev/null +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.h @@ -0,0 +1,26 @@ +/* + * spu hypervisor abstraction for direct hardware access. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 + */ + +#ifndef SPU_PRIV1_MMIO_H +#define SPU_PRIV1_MMIO_H + +struct device_node *spu_devnode(struct spu *spu); + +#endif /* SPU_PRIV1_MMIO_H */ -- cgit v1.2.3 From a985239bdf017e00e985c3a31149d6ae128fdc5f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 23 Nov 2006 00:46:50 +0100 Subject: [POWERPC] cell: spu management xmon routines This fixes the xmon support for the cell spu to be compatable with the split spu platform code. Signed-off-by: Geoff Levand Signed-off-by: Michael Ellerman Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/xmon.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index c999638cc2d..1cf90c8ac34 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2789,8 +2789,6 @@ static void dump_spu_fields(struct spu *spu) DUMP_FIELD(spu, "0x%x", number); DUMP_FIELD(spu, "%s", name); - DUMP_FIELD(spu, "%s", devnode->full_name); - DUMP_FIELD(spu, "0x%x", nid); DUMP_FIELD(spu, "0x%lx", local_store_phys); DUMP_FIELD(spu, "0x%p", local_store); DUMP_FIELD(spu, "0x%lx", ls_size); @@ -2817,14 +2815,8 @@ static void dump_spu_fields(struct spu *spu) in_be32(&spu->problem->spu_status_R)); DUMP_VALUE("0x%x", problem->spu_npc_RW, in_be32(&spu->problem->spu_npc_RW)); - DUMP_FIELD(spu, "0x%p", priv1); - - if (spu->priv1) { - DUMP_VALUE("0x%lx", priv1->mfc_sr1_RW, - in_be64(&spu->priv1->mfc_sr1_RW)); - } - DUMP_FIELD(spu, "0x%p", priv2); + DUMP_FIELD(spu, "0x%p", pdata); } int -- cgit v1.2.3 From f58a9d171a346afb1b09190427e6c28c6118703e Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:51 +0100 Subject: [POWERPC] ps3: add support for ps3 platform Adds the core platform support for the PS3 game console and other devices using the PS3 hypervisor. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/Kconfig | 11 +- arch/powerpc/platforms/Makefile | 1 + arch/powerpc/platforms/ps3/Kconfig | 32 ++ arch/powerpc/platforms/ps3/Makefile | 2 + arch/powerpc/platforms/ps3/mm.c | 827 ++++++++++++++++++++++++++++++++++ arch/powerpc/platforms/ps3/platform.h | 60 +++ arch/powerpc/platforms/ps3/setup.c | 173 +++++++ arch/powerpc/platforms/ps3/smp.c | 158 +++++++ arch/powerpc/platforms/ps3/time.c | 104 +++++ 9 files changed, 1367 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/ps3/Kconfig create mode 100644 arch/powerpc/platforms/ps3/Makefile create mode 100644 arch/powerpc/platforms/ps3/mm.c create mode 100644 arch/powerpc/platforms/ps3/platform.h create mode 100644 arch/powerpc/platforms/ps3/setup.c create mode 100644 arch/powerpc/platforms/ps3/smp.c create mode 100644 arch/powerpc/platforms/ps3/time.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index b4a3b699433..c0146a40c6f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -495,6 +495,14 @@ config UDBG_RTAS_CONSOLE depends on PPC_RTAS default n +config PPC_PS3 + bool "Sony PS3" + depends on PPC_MULTIPLATFORM && PPC64 + select PPC_CELL + help + This option enables support for the Sony PS3 game console + and other platforms using the PS3 hypervisor. + config XICS depends on PPC_PSERIES bool @@ -647,6 +655,7 @@ source arch/powerpc/platforms/85xx/Kconfig source arch/powerpc/platforms/86xx/Kconfig source arch/powerpc/platforms/8xx/Kconfig source arch/powerpc/platforms/cell/Kconfig +source arch/powerpc/platforms/ps3/Kconfig menu "Kernel options" @@ -917,7 +926,7 @@ config MCA config PCI bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ - || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 + || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 || PPC_PS3 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ && !PPC_85xx && !PPC_86xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 7ad2673d0aa..56caf4fbd73 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -16,4 +16,5 @@ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ obj-$(CONFIG_PPC_PASEMI) += pasemi/ obj-$(CONFIG_PPC_CELL) += cell/ +obj-$(CONFIG_PS3) += ps3/ obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig new file mode 100644 index 00000000000..f023719f645 --- /dev/null +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -0,0 +1,32 @@ +menu "PS3 Platform Options" + depends on PPC_PS3 + +config PS3_HTAB_SIZE + depends on PPC_PS3 + int "PS3 Platform pagetable size" + range 18 20 + default 20 + help + This option is only for experts who may have the desire to fine + tune the pagetable size on their system. The value here is + expressed as the log2 of the page table size. Valid values are + 18, 19, and 20, corresponding to 256KB, 512KB and 1MB respectively. + + If unsure, choose the default (20) with the confidence that your + system will have optimal runtime performance. + +config PS3_DYNAMIC_DMA + depends on PPC_PS3 && EXPERIMENTAL + bool "PS3 Platform dynamic DMA page table management" + default n + help + This option will enable kernel support to take advantage of the + per device dynamic DMA page table management provided by the Cell + processor's IO Controller. This support incurs some runtime + overhead and also slightly increases kernel memory usage. The + current implementation should be considered experimental. + + This support is mainly for Linux kernel development. If unsure, + say N. + +endmenu diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile new file mode 100644 index 00000000000..8d6c72c6ea7 --- /dev/null +++ b/arch/powerpc/platforms/ps3/Makefile @@ -0,0 +1,2 @@ +obj-y += setup.o mm.o smp.o time.o hvcall.o htab.o repository.o +obj-y += interrupt.o exports.o diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c new file mode 100644 index 00000000000..a57f7036dd1 --- /dev/null +++ b/arch/powerpc/platforms/ps3/mm.c @@ -0,0 +1,827 @@ +/* + * PS3 address space management. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +#if defined(DEBUG) +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#endif + +enum { +#if defined(CONFIG_PS3_USE_LPAR_ADDR) + USE_LPAR_ADDR = 1, +#else + USE_LPAR_ADDR = 0, +#endif +#if defined(CONFIG_PS3_DYNAMIC_DMA) + USE_DYNAMIC_DMA = 1, +#else + USE_DYNAMIC_DMA = 0, +#endif +}; + +enum { + PAGE_SHIFT_4K = 12U, + PAGE_SHIFT_64K = 16U, + PAGE_SHIFT_16M = 24U, +}; + +static unsigned long make_page_sizes(unsigned long a, unsigned long b) +{ + return (a << 56) | (b << 48); +} + +enum { + ALLOCATE_MEMORY_TRY_ALT_UNIT = 0X04, + ALLOCATE_MEMORY_ADDR_ZERO = 0X08, +}; + +/* valid htab sizes are {18,19,20} = 256K, 512K, 1M */ + +enum { + HTAB_SIZE_MAX = 20U, /* HV limit of 1MB */ + HTAB_SIZE_MIN = 18U, /* CPU limit of 256KB */ +}; + +/*============================================================================*/ +/* virtual address space routines */ +/*============================================================================*/ + +/** + * struct mem_region - memory region structure + * @base: base address + * @size: size in bytes + * @offset: difference between base and rm.size + */ + +struct mem_region { + unsigned long base; + unsigned long size; + unsigned long offset; +}; + +/** + * struct map - address space state variables holder + * @total: total memory available as reported by HV + * @vas_id - HV virtual address space id + * @htab_size: htab size in bytes + * + * The HV virtual address space (vas) allows for hotplug memory regions. + * Memory regions can be created and destroyed in the vas at runtime. + * @rm: real mode (bootmem) region + * @r1: hotplug memory region(s) + * + * ps3 addresses + * virt_addr: a cpu 'translated' effective address + * phys_addr: an address in what Linux thinks is the physical address space + * lpar_addr: an address in the HV virtual address space + * bus_addr: an io controller 'translated' address on a device bus + */ + +struct map { + unsigned long total; + unsigned long vas_id; + unsigned long htab_size; + struct mem_region rm; + struct mem_region r1; +}; + +#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__) +static void _debug_dump_map(const struct map* m, const char* func, int line) +{ + DBG("%s:%d: map.total = %lxh\n", func, line, m->total); + DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size); + DBG("%s:%d: map.vas_id = %lu\n", func, line, m->vas_id); + DBG("%s:%d: map.htab_size = %lxh\n", func, line, m->htab_size); + DBG("%s:%d: map.r1.base = %lxh\n", func, line, m->r1.base); + DBG("%s:%d: map.r1.offset = %lxh\n", func, line, m->r1.offset); + DBG("%s:%d: map.r1.size = %lxh\n", func, line, m->r1.size); +} + +static struct map map; + +/** + * ps3_mm_phys_to_lpar - translate a linux physical address to lpar address + * @phys_addr: linux physical address + */ + +unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr) +{ + BUG_ON(is_kernel_addr(phys_addr)); + if (USE_LPAR_ADDR) + return phys_addr; + else + return (phys_addr < map.rm.size || phys_addr >= map.total) + ? phys_addr : phys_addr + map.r1.offset; +} + +EXPORT_SYMBOL(ps3_mm_phys_to_lpar); + +/** + * ps3_mm_vas_create - create the virtual address space + */ + +void __init ps3_mm_vas_create(unsigned long* htab_size) +{ + int result; + unsigned long start_address; + unsigned long size; + unsigned long access_right; + unsigned long max_page_size; + unsigned long flags; + + result = lv1_query_logical_partition_address_region_info(0, + &start_address, &size, &access_right, &max_page_size, + &flags); + + if (result) { + DBG("%s:%d: lv1_query_logical_partition_address_region_info " + "failed: %s\n", __func__, __LINE__, + ps3_result(result)); + goto fail; + } + + if (max_page_size < PAGE_SHIFT_16M) { + DBG("%s:%d: bad max_page_size %lxh\n", __func__, __LINE__, + max_page_size); + goto fail; + } + + BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE > HTAB_SIZE_MAX); + BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE < HTAB_SIZE_MIN); + + result = lv1_construct_virtual_address_space(CONFIG_PS3_HTAB_SIZE, + 2, make_page_sizes(PAGE_SHIFT_16M, PAGE_SHIFT_64K), + &map.vas_id, &map.htab_size); + + if (result) { + DBG("%s:%d: lv1_construct_virtual_address_space failed: %s\n", + __func__, __LINE__, ps3_result(result)); + goto fail; + } + + result = lv1_select_virtual_address_space(map.vas_id); + + if (result) { + DBG("%s:%d: lv1_select_virtual_address_space failed: %s\n", + __func__, __LINE__, ps3_result(result)); + goto fail; + } + + *htab_size = map.htab_size; + + debug_dump_map(&map); + + return; + +fail: + panic("ps3_mm_vas_create failed"); +} + +/** + * ps3_mm_vas_destroy - + */ + +void ps3_mm_vas_destroy(void) +{ + if (map.vas_id) { + lv1_select_virtual_address_space(0); + lv1_destruct_virtual_address_space(map.vas_id); + map.vas_id = 0; + } +} + +/*============================================================================*/ +/* memory hotplug routines */ +/*============================================================================*/ + +/** + * ps3_mm_region_create - create a memory region in the vas + * @r: pointer to a struct mem_region to accept initialized values + * @size: requested region size + * + * This implementation creates the region with the vas large page size. + * @size is rounded down to a multiple of the vas large page size. + */ + +int ps3_mm_region_create(struct mem_region *r, unsigned long size) +{ + int result; + unsigned long muid; + + r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M); + + DBG("%s:%d requested %lxh\n", __func__, __LINE__, size); + DBG("%s:%d actual %lxh\n", __func__, __LINE__, r->size); + DBG("%s:%d difference %lxh (%luMB)\n", __func__, __LINE__, + (unsigned long)(size - r->size), + (size - r->size) / 1024 / 1024); + + if (r->size == 0) { + DBG("%s:%d: size == 0\n", __func__, __LINE__); + result = -1; + goto zero_region; + } + + result = lv1_allocate_memory(r->size, PAGE_SHIFT_16M, 0, + ALLOCATE_MEMORY_TRY_ALT_UNIT, &r->base, &muid); + + if (result || r->base < map.rm.size) { + DBG("%s:%d: lv1_allocate_memory failed: %s\n", + __func__, __LINE__, ps3_result(result)); + goto zero_region; + } + + r->offset = r->base - map.rm.size; + return result; + +zero_region: + r->size = r->base = r->offset = 0; + return result; +} + +/** + * ps3_mm_region_destroy - destroy a memory region + * @r: pointer to struct mem_region + */ + +void ps3_mm_region_destroy(struct mem_region *r) +{ + if (r->base) { + lv1_release_memory(r->base); + r->size = r->base = r->offset = 0; + map.total = map.rm.size; + } +} + +/** + * ps3_mm_add_memory - hot add memory + */ + +static int __init ps3_mm_add_memory(void) +{ + int result; + unsigned long start_addr; + unsigned long start_pfn; + unsigned long nr_pages; + + BUG_ON(!mem_init_done); + + start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; + start_pfn = start_addr >> PAGE_SHIFT; + nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT; + + DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n", + __func__, __LINE__, start_addr, start_pfn, nr_pages); + + result = add_memory(0, start_addr, map.r1.size); + + if (result) { + DBG("%s:%d: add_memory failed: (%d)\n", + __func__, __LINE__, result); + return result; + } + + result = online_pages(start_pfn, nr_pages); + + if (result) + DBG("%s:%d: online_pages failed: (%d)\n", + __func__, __LINE__, result); + + return result; +} + +core_initcall(ps3_mm_add_memory); + +/*============================================================================*/ +/* dma routines */ +/*============================================================================*/ + +/** + * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address. + * @r: pointer to dma region structure + * @lpar_addr: HV lpar address + */ + +static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r, + unsigned long lpar_addr) +{ + BUG_ON(lpar_addr >= map.r1.base + map.r1.size); + return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr + : lpar_addr - map.r1.offset); +} + +#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__) +static void _dma_dump_region(const struct ps3_dma_region *r, const char* func, + int line) +{ + DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, + r->did.dev_id); + DBG("%s:%d: page_size %u\n", func, line, r->page_size); + DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); + DBG("%s:%d: len %lxh\n", func, line, r->len); +} + +/** + * dma_chunk - A chunk of dma pages mapped by the io controller. + * @region - The dma region that owns this chunk. + * @lpar_addr: Starting lpar address of the area to map. + * @bus_addr: Starting ioc bus address of the area to map. + * @len: Length in bytes of the area to map. + * @link: A struct list_head used with struct ps3_dma_region.chunk_list, the + * list of all chuncks owned by the region. + * + * This implementation uses a very simple dma page manager + * based on the dma_chunk structure. This scheme assumes + * that all drivers use very well behaved dma ops. + */ + +struct dma_chunk { + struct ps3_dma_region *region; + unsigned long lpar_addr; + unsigned long bus_addr; + unsigned long len; + struct list_head link; + unsigned int usage_count; +}; + +#define dma_dump_chunk(_a) _dma_dump_chunk(_a, __func__, __LINE__) +static void _dma_dump_chunk (const struct dma_chunk* c, const char* func, + int line) +{ + DBG("%s:%d: r.dev %u:%u\n", func, line, + c->region->did.bus_id, c->region->did.dev_id); + DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); + DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); + DBG("%s:%d: r.len %lxh\n", func, line, c->region->len); + DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr); + DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr); + DBG("%s:%d: c.len %lxh\n", func, line, c->len); +} + +static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r, + unsigned long bus_addr, unsigned long len) +{ + struct dma_chunk *c; + unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size); + unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); + + list_for_each_entry(c, &r->chunk_list.head, link) { + /* intersection */ + if (aligned_bus >= c->bus_addr + && aligned_bus < c->bus_addr + c->len + && aligned_bus + aligned_len <= c->bus_addr + c->len) { + return c; + } + /* below */ + if (aligned_bus + aligned_len <= c->bus_addr) { + continue; + } + /* above */ + if (aligned_bus >= c->bus_addr + c->len) { + continue; + } + + /* we don't handle the multi-chunk case for now */ + + dma_dump_chunk(c); + BUG(); + } + return NULL; +} + +static int dma_free_chunk(struct dma_chunk *c) +{ + int result = 0; + + if (c->bus_addr) { + result = lv1_unmap_device_dma_region(c->region->did.bus_id, + c->region->did.dev_id, c->bus_addr, c->len); + BUG_ON(result); + } + + kfree(c); + return result; +} + +/** + * dma_map_pages - Maps dma pages into the io controller bus address space. + * @r: Pointer to a struct ps3_dma_region. + * @phys_addr: Starting physical address of the area to map. + * @len: Length in bytes of the area to map. + * c_out: A pointer to receive an allocated struct dma_chunk for this area. + * + * This is the lowest level dma mapping routine, and is the one that will + * make the HV call to add the pages into the io controller address space. + */ + +static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, + unsigned long len, struct dma_chunk **c_out) +{ + int result; + struct dma_chunk *c; + + c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC); + + if (!c) { + result = -ENOMEM; + goto fail_alloc; + } + + c->region = r; + c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr); + c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr); + c->len = len; + + result = lv1_map_device_dma_region(c->region->did.bus_id, + c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len, + 0xf800000000000000UL); + + if (result) { + DBG("%s:%d: lv1_map_device_dma_region failed: %s\n", + __func__, __LINE__, ps3_result(result)); + goto fail_map; + } + + list_add(&c->link, &r->chunk_list.head); + + *c_out = c; + return 0; + +fail_map: + kfree(c); +fail_alloc: + *c_out = NULL; + DBG(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +/** + * dma_region_create - Create a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * + * This is the lowest level dma region create routine, and is the one that + * will make the HV call to create the region. + */ + +static int dma_region_create(struct ps3_dma_region* r) +{ + int result; + + r->len = _ALIGN_UP(map.total, 1 << r->page_size); + INIT_LIST_HEAD(&r->chunk_list.head); + spin_lock_init(&r->chunk_list.lock); + + result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id, + r->len, r->page_size, r->region_type, &r->bus_addr); + + dma_dump_region(r); + + if (result) { + DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n", + __func__, __LINE__, ps3_result(result)); + r->len = r->bus_addr = 0; + } + + return result; +} + +/** + * dma_region_free - Free a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * + * This is the lowest level dma region free routine, and is the one that + * will make the HV call to free the region. + */ + +static int dma_region_free(struct ps3_dma_region* r) +{ + int result; + struct dma_chunk *c; + struct dma_chunk *tmp; + + list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) { + list_del(&c->link); + dma_free_chunk(c); + } + + result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id, + r->bus_addr); + + if (result) + DBG("%s:%d: lv1_free_device_dma_region failed: %s\n", + __func__, __LINE__, ps3_result(result)); + + r->len = r->bus_addr = 0; + + return result; +} + +/** + * dma_map_area - Map an area of memory into a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @virt_addr: Starting virtual address of the area to map. + * @len: Length in bytes of the area to map. + * @bus_addr: A pointer to return the starting ioc bus address of the area to + * map. + * + * This is the common dma mapping routine. + */ + +static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr, + unsigned long len, unsigned long *bus_addr) +{ + int result; + unsigned long flags; + struct dma_chunk *c; + unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) + : virt_addr; + + *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); + + if (!USE_DYNAMIC_DMA) { + unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr); + DBG(" -> %s:%d\n", __func__, __LINE__); + DBG("%s:%d virt_addr %lxh\n", __func__, __LINE__, + virt_addr); + DBG("%s:%d phys_addr %lxh\n", __func__, __LINE__, + phys_addr); + DBG("%s:%d lpar_addr %lxh\n", __func__, __LINE__, + lpar_addr); + DBG("%s:%d len %lxh\n", __func__, __LINE__, len); + DBG("%s:%d bus_addr %lxh (%lxh)\n", __func__, __LINE__, + *bus_addr, len); + } + + spin_lock_irqsave(&r->chunk_list.lock, flags); + c = dma_find_chunk(r, *bus_addr, len); + + if (c) { + c->usage_count++; + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return 0; + } + + result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size), + _ALIGN_UP(len, 1 << r->page_size), &c); + + if (result) { + *bus_addr = 0; + DBG("%s:%d: dma_map_pages failed (%d)\n", + __func__, __LINE__, result); + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return result; + } + + c->usage_count = 1; + + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return result; +} + +/** + * dma_unmap_area - Unmap an area of memory from a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @bus_addr: The starting ioc bus address of the area to unmap. + * @len: Length in bytes of the area to unmap. + * + * This is the common dma unmap routine. + */ + +int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr, + unsigned long len) +{ + unsigned long flags; + struct dma_chunk *c; + + spin_lock_irqsave(&r->chunk_list.lock, flags); + c = dma_find_chunk(r, bus_addr, len); + + if (!c) { + unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, + 1 << r->page_size); + unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size); + DBG("%s:%d: not found: bus_addr %lxh\n", + __func__, __LINE__, bus_addr); + DBG("%s:%d: not found: len %lxh\n", + __func__, __LINE__, len); + DBG("%s:%d: not found: aligned_bus %lxh\n", + __func__, __LINE__, aligned_bus); + DBG("%s:%d: not found: aligned_len %lxh\n", + __func__, __LINE__, aligned_len); + BUG(); + } + + c->usage_count--; + + if (!c->usage_count) { + list_del(&c->link); + dma_free_chunk(c); + } + + spin_unlock_irqrestore(&r->chunk_list.lock, flags); + return 0; +} + +/** + * dma_region_create_linear - Setup a linear dma maping for a device. + * @r: Pointer to a struct ps3_dma_region. + * + * This routine creates an HV dma region for the device and maps all available + * ram into the io controller bus address space. + */ + +static int dma_region_create_linear(struct ps3_dma_region *r) +{ + int result; + unsigned long tmp; + + /* force 16M dma pages for linear mapping */ + + if (r->page_size != PS3_DMA_16M) { + pr_info("%s:%d: forcing 16M pages for linear map\n", + __func__, __LINE__); + r->page_size = PS3_DMA_16M; + } + + result = dma_region_create(r); + BUG_ON(result); + + result = dma_map_area(r, map.rm.base, map.rm.size, &tmp); + BUG_ON(result); + + if (USE_LPAR_ADDR) + result = dma_map_area(r, map.r1.base, map.r1.size, + &tmp); + else + result = dma_map_area(r, map.rm.size, map.r1.size, + &tmp); + + BUG_ON(result); + + return result; +} + +/** + * dma_region_free_linear - Free a linear dma mapping for a device. + * @r: Pointer to a struct ps3_dma_region. + * + * This routine will unmap all mapped areas and free the HV dma region. + */ + +static int dma_region_free_linear(struct ps3_dma_region *r) +{ + int result; + + result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size); + BUG_ON(result); + + result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base), + map.r1.size); + BUG_ON(result); + + result = dma_region_free(r); + BUG_ON(result); + + return result; +} + +/** + * dma_map_area_linear - Map an area of memory into a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @virt_addr: Starting virtual address of the area to map. + * @len: Length in bytes of the area to map. + * @bus_addr: A pointer to return the starting ioc bus address of the area to + * map. + * + * This routine just returns the coresponding bus address. Actual mapping + * occurs in dma_region_create_linear(). + */ + +static int dma_map_area_linear(struct ps3_dma_region *r, + unsigned long virt_addr, unsigned long len, unsigned long *bus_addr) +{ + unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr) + : virt_addr; + *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr)); + return 0; +} + +/** + * dma_unmap_area_linear - Unmap an area of memory from a device dma region. + * @r: Pointer to a struct ps3_dma_region. + * @bus_addr: The starting ioc bus address of the area to unmap. + * @len: Length in bytes of the area to unmap. + * + * This routine does nothing. Unmapping occurs in dma_region_free_linear(). + */ + +static int dma_unmap_area_linear(struct ps3_dma_region *r, + unsigned long bus_addr, unsigned long len) +{ + return 0; +} + +int ps3_dma_region_create(struct ps3_dma_region *r) +{ + return (USE_DYNAMIC_DMA) + ? dma_region_create(r) + : dma_region_create_linear(r); +} + +int ps3_dma_region_free(struct ps3_dma_region *r) +{ + return (USE_DYNAMIC_DMA) + ? dma_region_free(r) + : dma_region_free_linear(r); +} + +int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, + unsigned long len, unsigned long *bus_addr) +{ + return (USE_DYNAMIC_DMA) + ? dma_map_area(r, virt_addr, len, bus_addr) + : dma_map_area_linear(r, virt_addr, len, bus_addr); +} + +int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, + unsigned long len) +{ + return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len) + : dma_unmap_area_linear(r, bus_addr, len); +} + +/*============================================================================*/ +/* system startup routines */ +/*============================================================================*/ + +/** + * ps3_mm_init - initialize the address space state variables + */ + +void __init ps3_mm_init(void) +{ + int result; + + DBG(" -> %s:%d\n", __func__, __LINE__); + + result = ps3_repository_read_mm_info(&map.rm.base, &map.rm.size, + &map.total); + + if (result) + panic("ps3_repository_read_mm_info() failed"); + + map.rm.offset = map.rm.base; + map.vas_id = map.htab_size = 0; + + /* this implementation assumes map.rm.base is zero */ + + BUG_ON(map.rm.base); + BUG_ON(!map.rm.size); + + lmb_add(map.rm.base, map.rm.size); + lmb_analyze(); + + /* arrange to do this in ps3_mm_add_memory */ + ps3_mm_region_create(&map.r1, map.total - map.rm.size); + + DBG(" <- %s:%d\n", __func__, __LINE__); +} + +/** + * ps3_mm_shutdown - final cleanup of address space + */ + +void ps3_mm_shutdown(void) +{ + ps3_mm_region_destroy(&map.r1); + map.total = map.rm.size; +} diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h new file mode 100644 index 00000000000..d9948df6ccd --- /dev/null +++ b/arch/powerpc/platforms/ps3/platform.h @@ -0,0 +1,60 @@ +/* + * PS3 platform declarations. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 + */ + +#if !defined(_PS3_PLATFORM_H) +#define _PS3_PLATFORM_H + +#include + +/* htab */ + +void __init ps3_hpte_init(unsigned long htab_size); +void __init ps3_map_htab(void); + +/* mm */ + +void __init ps3_mm_init(void); +void __init ps3_mm_vas_create(unsigned long* htab_size); +void ps3_mm_vas_destroy(void); +void ps3_mm_shutdown(void); + +/* irq */ + +void ps3_init_IRQ(void); +void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); + +/* smp */ + +void smp_init_ps3(void); +void ps3_smp_cleanup_cpu(int cpu); + +/* time */ + +void __init ps3_calibrate_decr(void); +unsigned long __init ps3_get_boot_time(void); +void ps3_get_rtc_time(struct rtc_time *time); +int ps3_set_rtc_time(struct rtc_time *time); + +/* os area */ + +int __init ps3_os_area_init(void); +u64 ps3_os_area_rtc_diff(void); + +#endif diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c new file mode 100644 index 00000000000..c1f6de50654 --- /dev/null +++ b/arch/powerpc/platforms/ps3/setup.c @@ -0,0 +1,173 @@ +/* + * PS3 platform setup routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 +#include + +#include "platform.h" + +#if defined(DEBUG) +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#endif + +static void ps3_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "machine\t\t: %s\n", ppc_md.name); +} + +static void ps3_power_save(void) +{ + /* + * lv1_pause() puts the PPE thread into inactive state until an + * irq on an unmasked plug exists. MSR[EE] has no effect. + * flags: 0 = wake on DEC interrupt, 1 = ignore DEC interrupt. + */ + + lv1_pause(0); +} + +static void ps3_panic(char *str) +{ + DBG("%s:%d %s\n", __func__, __LINE__, str); + +#ifdef CONFIG_SMP + smp_send_stop(); +#endif + printk("\n"); + printk(" System does not reboot automatically.\n"); + printk(" Please press POWER button.\n"); + printk("\n"); + + for (;;) ; +} + +static void __init ps3_setup_arch(void) +{ + DBG(" -> %s:%d\n", __func__, __LINE__); + + ps3_spu_set_platform(); + ps3_map_htab(); + +#ifdef CONFIG_SMP + smp_init_ps3(); +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + ppc_md.power_save = ps3_power_save; + + DBG(" <- %s:%d\n", __func__, __LINE__); +} + +static void __init ps3_progress(char *s, unsigned short hex) +{ + printk("*** %04x : %s\n", hex, s ? s : ""); +} + +static int __init ps3_probe(void) +{ + unsigned long htab_size; + unsigned long dt_root; + + DBG(" -> %s:%d\n", __func__, __LINE__); + + dt_root = of_get_flat_dt_root(); + if (!of_flat_dt_is_compatible(dt_root, "PS3")) + return 0; + + powerpc_firmware_features |= FW_FEATURE_LPAR; + + ps3_os_area_init(); + ps3_mm_init(); + ps3_mm_vas_create(&htab_size); + ps3_hpte_init(htab_size); + + DBG(" <- %s:%d\n", __func__, __LINE__); + return 1; +} + +#if defined(CONFIG_KEXEC) +static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) +{ + DBG(" -> %s:%d\n", __func__, __LINE__); + + if (secondary) { + int cpu; + for_each_online_cpu(cpu) + if (cpu) + ps3_smp_cleanup_cpu(cpu); + } else + ps3_smp_cleanup_cpu(0); + + DBG(" <- %s:%d\n", __func__, __LINE__); +} + +static void ps3_machine_kexec(struct kimage *image) +{ + unsigned long ppe_id; + + DBG(" -> %s:%d\n", __func__, __LINE__); + + lv1_get_logical_ppe_id(&ppe_id); + lv1_configure_irq_state_bitmap(ppe_id, 0, 0); + ps3_mm_shutdown(); + ps3_mm_vas_destroy(); + + default_machine_kexec(image); + + DBG(" <- %s:%d\n", __func__, __LINE__); +} +#endif + +define_machine(ps3) { + .name = "PS3", + .probe = ps3_probe, + .setup_arch = ps3_setup_arch, + .show_cpuinfo = ps3_show_cpuinfo, + .init_IRQ = ps3_init_IRQ, + .panic = ps3_panic, + .get_boot_time = ps3_get_boot_time, + .set_rtc_time = ps3_set_rtc_time, + .get_rtc_time = ps3_get_rtc_time, + .calibrate_decr = ps3_calibrate_decr, + .progress = ps3_progress, +#if defined(CONFIG_KEXEC) + .kexec_cpu_down = ps3_kexec_cpu_down, + .machine_kexec = ps3_machine_kexec, + .machine_kexec_prepare = default_machine_kexec_prepare, + .machine_crash_shutdown = default_machine_crash_shutdown, +#endif +}; diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c new file mode 100644 index 00000000000..11d2080607e --- /dev/null +++ b/arch/powerpc/platforms/ps3/smp.c @@ -0,0 +1,158 @@ +/* + * PS3 SMP routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +#if defined(DEBUG) +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#endif + +static irqreturn_t ipi_function_handler(int irq, void *msg) +{ + smp_message_recv((int)(long)msg); + return IRQ_HANDLED; +} + +/** + * virqs - a per cpu array of virqs for ipi use + */ + +#define MSG_COUNT 4 +static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]); + +static const char *names[MSG_COUNT] = { + "ipi call", + "ipi reschedule", + "ipi migrate", + "ipi debug brk" +}; + +static void do_message_pass(int target, int msg) +{ + int result; + unsigned int virq; + + if (msg >= MSG_COUNT) { + DBG("%s:%d: bad msg: %d\n", __func__, __LINE__, msg); + return; + } + + virq = per_cpu(virqs, target)[msg]; + result = ps3_send_event_locally(virq); + + if (result) + DBG("%s:%d: ps3_send_event_locally(%d, %d) failed" + " (%d)\n", __func__, __LINE__, target, msg, result); +} + +static void ps3_smp_message_pass(int target, int msg) +{ + int cpu; + + if (target < NR_CPUS) + do_message_pass(target, msg); + else if (target == MSG_ALL_BUT_SELF) { + for_each_online_cpu(cpu) + if (cpu != smp_processor_id()) + do_message_pass(cpu, msg); + } else { + for_each_online_cpu(cpu) + do_message_pass(cpu, msg); + } +} + +static int ps3_smp_probe(void) +{ + return 2; +} + +static void __init ps3_smp_setup_cpu(int cpu) +{ + int result; + unsigned int *virqs = per_cpu(virqs, cpu); + int i; + + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + + /* + * Check assumptions on virqs[] indexing. If this + * check fails, then a different mapping of PPC_MSG_ + * to index needs to be setup. + */ + + BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); + BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); + BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); + + for (i = 0; i < MSG_COUNT; i++) { + result = ps3_alloc_event_irq(&virqs[i]); + + if (result) + continue; + + DBG("%s:%d: (%d, %d) => virq %u\n", + __func__, __LINE__, cpu, i, virqs[i]); + + + request_irq(virqs[i], ipi_function_handler, IRQF_DISABLED, + names[i], (void*)(long)i); + } + + ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]); + + DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); +} + +void ps3_smp_cleanup_cpu(int cpu) +{ + unsigned int *virqs = per_cpu(virqs, cpu); + int i; + + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + for (i = 0; i < MSG_COUNT; i++) { + ps3_free_event_irq(virqs[i]); + free_irq(virqs[i], (void*)(long)i); + virqs[i] = NO_IRQ; + } + DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); +} + +static struct smp_ops_t ps3_smp_ops = { + .probe = ps3_smp_probe, + .message_pass = ps3_smp_message_pass, + .kick_cpu = smp_generic_kick_cpu, + .setup_cpu = ps3_smp_setup_cpu, +}; + +void smp_init_ps3(void) +{ + DBG(" -> %s\n", __func__); + smp_ops = &ps3_smp_ops; + DBG(" <- %s\n", __func__); +} diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c new file mode 100644 index 00000000000..1bae8b19b36 --- /dev/null +++ b/arch/powerpc/platforms/ps3/time.c @@ -0,0 +1,104 @@ +/* + * PS3 time and rtc routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +#define dump_tm(_a) _dump_tm(_a, __func__, __LINE__) +static void _dump_tm(const struct rtc_time *tm, const char* func, int line) +{ + pr_debug("%s:%d tm_sec %d\n", func, line, tm->tm_sec); + pr_debug("%s:%d tm_min %d\n", func, line, tm->tm_min); + pr_debug("%s:%d tm_hour %d\n", func, line, tm->tm_hour); + pr_debug("%s:%d tm_mday %d\n", func, line, tm->tm_mday); + pr_debug("%s:%d tm_mon %d\n", func, line, tm->tm_mon); + pr_debug("%s:%d tm_year %d\n", func, line, tm->tm_year); + pr_debug("%s:%d tm_wday %d\n", func, line, tm->tm_wday); +} + +#define dump_time(_a) _dump_time(_a, __func__, __LINE__) +static void __attribute__ ((unused)) _dump_time(int time, const char* func, + int line) +{ + struct rtc_time tm; + + to_tm(time, &tm); + + pr_debug("%s:%d time %d\n", func, line, time); + _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; + u64 tmp; + + result = ps3_repository_read_be_tb_freq(0, &tmp); + BUG_ON(result); + + ppc_tb_freq = tmp; + ppc_proc_freq = ppc_tb_freq * 40; + + rtc_shift = ps3_os_area_rtc_diff(); +} + +static u64 read_rtc(void) +{ + int result; + u64 rtc_val; + u64 tb_val; + + result = lv1_get_rtc(&rtc_val, &tb_val); + BUG_ON(result); + + return rtc_val; +} + +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); + + rtc_shift = now - read_rtc(); + return 0; +} + +void ps3_get_rtc_time(struct rtc_time *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() + rtc_shift; +} -- cgit v1.2.3 From 1e4ed915d133aaa2802d11914a7e80b3e31304e6 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:52 +0100 Subject: [POWERPC] ps3: add lv1 hvcalls Adds the PS3 hvcalls. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/exports.c | 27 ++ arch/powerpc/platforms/ps3/hvcall.S | 804 +++++++++++++++++++++++++++++++++++ 2 files changed, 831 insertions(+) create mode 100644 arch/powerpc/platforms/ps3/exports.c create mode 100644 arch/powerpc/platforms/ps3/hvcall.S (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/exports.c b/arch/powerpc/platforms/ps3/exports.c new file mode 100644 index 00000000000..a7e8ffd24a6 --- /dev/null +++ b/arch/powerpc/platforms/ps3/exports.c @@ -0,0 +1,27 @@ +/* + * PS3 hvcall exports for modules. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 + +#define LV1_CALL(name, in, out, num) \ + extern s64 _lv1_##name(LV1_##in##_IN_##out##_OUT_ARG_DECL); \ + EXPORT_SYMBOL(_lv1_##name); + +#include diff --git a/arch/powerpc/platforms/ps3/hvcall.S b/arch/powerpc/platforms/ps3/hvcall.S new file mode 100644 index 00000000000..54be6523a0e --- /dev/null +++ b/arch/powerpc/platforms/ps3/hvcall.S @@ -0,0 +1,804 @@ +/* + * PS3 hvcall interface. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * Copyright 2003, 2004 (c) MontaVista Software, Inc. + * + * 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; version 2 of the License. + * + * 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 + +#define lv1call .long 0x44000022; extsw r3, r3 + +#define LV1_N_IN_0_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_0_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_1_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_2_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_3_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_4_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_5_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_6_IN_0_OUT LV1_N_IN_0_OUT +#define LV1_7_IN_0_OUT LV1_N_IN_0_OUT + +#define LV1_0_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r3, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_0_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r3, -8(r1); \ + stdu r4, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_0_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r3, -8(r1); \ + std r4, -16(r1); \ + stdu r5, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_0_IN_7_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r3, -8(r1); \ + std r4, -16(r1); \ + std r5, -24(r1); \ + std r6, -32(r1); \ + std r7, -40(r1); \ + std r8, -48(r1); \ + stdu r9, -56(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 56; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + ld r11, -40(r1); \ + std r8, 0(r11); \ + ld r11, -48(r1); \ + std r9, 0(r11); \ + ld r11, -56(r1); \ + std r10, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r4, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + stdu r5, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + std r5, -16(r1); \ + stdu r6, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_4_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + std r5, -16(r1); \ + std r6, -24(r1); \ + stdu r7, -32(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 32; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_5_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + std r5, -16(r1); \ + std r6, -24(r1); \ + std r7, -32(r1); \ + stdu r8, -40(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 40; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + ld r11, -40(r1); \ + std r8, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_6_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + std r5, -16(r1); \ + std r6, -24(r1); \ + std r7, -32(r1); \ + std r8, -40(r1); \ + stdu r9, -48(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 48; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + ld r11, -40(r1); \ + std r8, 0(r11); \ + ld r11, -48(r1); \ + std r9, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_1_IN_7_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r4, -8(r1); \ + std r5, -16(r1); \ + std r6, -24(r1); \ + std r7, -32(r1); \ + std r8, -40(r1); \ + std r9, -48(r1); \ + stdu r10, -56(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 56; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + ld r11, -40(r1); \ + std r8, 0(r11); \ + ld r11, -48(r1); \ + std r9, 0(r11); \ + ld r11, -56(r1); \ + std r10, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_2_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r5, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_2_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r5, -8(r1); \ + stdu r6, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_2_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r5, -8(r1); \ + std r6, -16(r1); \ + stdu r7, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_2_IN_4_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r5, -8(r1); \ + std r6, -16(r1); \ + std r7, -24(r1); \ + stdu r8, -32(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 32; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_2_IN_5_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r5, -8(r1); \ + std r6, -16(r1); \ + std r7, -24(r1); \ + std r8, -32(r1); \ + stdu r9, -40(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 40; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + ld r11, -32(r1); \ + std r7, 0(r11); \ + ld r11, -40(r1); \ + std r8, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_3_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r6, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_3_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r6, -8(r1); \ + stdu r7, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_3_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r6, -8(r1); \ + std r7, -16(r1); \ + stdu r8, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_4_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r7, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_4_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r7, -8(r1); \ + stdu r8, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_4_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r7, -8(r1); \ + std r8, -16(r1); \ + stdu r9, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_5_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r8, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_5_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r8, -8(r1); \ + stdu r9, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_5_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r8, -8(r1); \ + std r9, -16(r1); \ + stdu r10, -24(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 24; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, -24(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_6_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r9, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_6_IN_2_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r9, -8(r1); \ + stdu r10, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_6_IN_3_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r9, -8(r1); \ + stdu r10, -16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 16; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + ld r11, -16(r1); \ + std r5, 0(r11); \ + ld r11, 48+8*8(r1); \ + std r6, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_7_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + stdu r10, -8(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + addi r1, r1, 8; \ + ld r11, -8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_7_IN_6_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + std r10, 48+8*7(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + ld r11, 48+8*7(r1); \ + std r4, 0(r11); \ + ld r11, 48+8*8(r1); \ + std r5, 0(r11); \ + ld r11, 48+8*9(r1); \ + std r6, 0(r11); \ + ld r11, 48+8*10(r1); \ + std r7, 0(r11); \ + ld r11, 48+8*11(r1); \ + std r8, 0(r11); \ + ld r11, 48+8*12(r1); \ + std r9, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + +#define LV1_8_IN_1_OUT(API_NAME, API_NUMBER) \ +_GLOBAL(_##API_NAME) \ + \ + mflr r0; \ + std r0, 16(r1); \ + \ + li r11, API_NUMBER; \ + lv1call; \ + \ + ld r11, 48+8*8(r1); \ + std r4, 0(r11); \ + \ + ld r0, 16(r1); \ + mtlr r0; \ + blr + + .text + +/* the lv1 underscored call definitions expand here */ + +#define LV1_CALL(name, in, out, num) LV1_##in##_IN_##out##_OUT(lv1_##name, num) +#include -- cgit v1.2.3 From c6cec72b7ca05822688a952df97b1c24e69a0ef6 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:54 +0100 Subject: [POWERPC] ps3: add htab routines Adds pagetable management routines for the PS3. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/htab.c | 277 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 arch/powerpc/platforms/ps3/htab.c (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c new file mode 100644 index 00000000000..8fe1769655a --- /dev/null +++ b/arch/powerpc/platforms/ps3/htab.c @@ -0,0 +1,277 @@ +/* + * PS3 pagetable management routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +#if defined(DEBUG) +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#endif + +static hpte_t *htab; +static unsigned long htab_addr; +static unsigned char *bolttab; +static unsigned char *inusetab; + +static spinlock_t ps3_bolttab_lock = SPIN_LOCK_UNLOCKED; + +#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \ + _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) +static void _debug_dump_hpte(unsigned long pa, unsigned long va, + unsigned long group, unsigned long bitmap, hpte_t lhpte, int psize, + unsigned long slot, const char* func, int line) +{ + DBG("%s:%d: pa = %lxh\n", func, line, pa); + DBG("%s:%d: lpar = %lxh\n", func, line, + ps3_mm_phys_to_lpar(pa)); + DBG("%s:%d: va = %lxh\n", func, line, va); + DBG("%s:%d: group = %lxh\n", func, line, group); + DBG("%s:%d: bitmap = %lxh\n", func, line, bitmap); + DBG("%s:%d: hpte.v = %lxh\n", func, line, lhpte.v); + DBG("%s:%d: hpte.r = %lxh\n", func, line, lhpte.r); + DBG("%s:%d: psize = %xh\n", func, line, psize); + DBG("%s:%d: slot = %lxh\n", func, line, slot); +} + +static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va, + unsigned long pa, unsigned long rflags, unsigned long vflags, int psize) +{ + unsigned long slot; + hpte_t lhpte; + int secondary = 0; + unsigned long result; + unsigned long bitmap; + unsigned long flags; + unsigned long p_pteg, s_pteg, b_index, b_mask, cb, ci; + + vflags &= ~HPTE_V_SECONDARY; /* this bit is ignored */ + + lhpte.v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID; + lhpte.r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags; + + p_pteg = hpte_group / HPTES_PER_GROUP; + s_pteg = ~p_pteg & htab_hash_mask; + + spin_lock_irqsave(&ps3_bolttab_lock, flags); + + BUG_ON(bolttab[p_pteg] == 0xff && bolttab[s_pteg] == 0xff); + + bitmap = (inusetab[p_pteg] << 8) | inusetab[s_pteg]; + + if (bitmap == 0xffff) { + /* + * PTEG is full. Search for victim. + */ + bitmap &= ~((bolttab[p_pteg] << 8) | bolttab[s_pteg]); + do { + ci = mftb() & 15; + cb = 0x8000UL >> ci; + } while ((cb & bitmap) == 0); + } else { + /* + * search free slot in hardware order + * [primary] 0, 2, 4, 6, 1, 3, 5, 7 + * [secondary] 0, 2, 4, 6, 1, 3, 5, 7 + */ + for (ci = 0; ci < HPTES_PER_GROUP; ci += 2) { + cb = 0x8000UL >> ci; + if ((cb & bitmap) == 0) + goto found; + } + for (ci = 1; ci < HPTES_PER_GROUP; ci += 2) { + cb = 0x8000UL >> ci; + if ((cb & bitmap) == 0) + goto found; + } + for (ci = HPTES_PER_GROUP; ci < HPTES_PER_GROUP*2; ci += 2) { + cb = 0x8000UL >> ci; + if ((cb & bitmap) == 0) + goto found; + } + for (ci = HPTES_PER_GROUP+1; ci < HPTES_PER_GROUP*2; ci += 2) { + cb = 0x8000UL >> ci; + if ((cb & bitmap) == 0) + goto found; + } + } + +found: + if (ci < HPTES_PER_GROUP) { + slot = p_pteg * HPTES_PER_GROUP + ci; + } else { + slot = s_pteg * HPTES_PER_GROUP + (ci & 7); + /* lhpte.dw0.dw0.h = 1; */ + vflags |= HPTE_V_SECONDARY; + lhpte.v |= HPTE_V_SECONDARY; + } + + result = lv1_write_htab_entry(0, slot, lhpte.v, lhpte.r); + + if (result) { + debug_dump_hpte(pa, va, hpte_group, bitmap, lhpte, psize, slot); + BUG(); + } + + /* + * If used slot is not in primary HPTE group, + * the slot should be in secondary HPTE group. + */ + + if ((hpte_group ^ slot) & ~(HPTES_PER_GROUP - 1)) { + secondary = 1; + b_index = s_pteg; + } else { + secondary = 0; + b_index = p_pteg; + } + + b_mask = (lhpte.v & HPTE_V_BOLTED) ? 1 << 7 : 0 << 7; + bolttab[b_index] |= b_mask >> (slot & 7); + b_mask = 1 << 7; + inusetab[b_index] |= b_mask >> (slot & 7); + spin_unlock_irqrestore(&ps3_bolttab_lock, flags); + + return (slot & 7) | (secondary << 3); +} + +static long ps3_hpte_remove(unsigned long hpte_group) +{ + panic("ps3_hpte_remove() not implemented"); + return 0; +} + +static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, + unsigned long va, int psize, int local) +{ + unsigned long flags; + unsigned long result; + unsigned long pteg, bit; + unsigned long hpte_v, want_v; + + want_v = hpte_encode_v(va, psize); + + spin_lock_irqsave(&ps3_bolttab_lock, flags); + + hpte_v = htab[slot].v; + if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) { + spin_unlock_irqrestore(&ps3_bolttab_lock, flags); + + /* ps3_hpte_insert() will be used to update PTE */ + return -1; + } + + result = lv1_write_htab_entry(0, slot, 0, 0); + + if (result) { + DBG("%s: va=%lx slot=%lx psize=%d result = %ld (0x%lx)\n", + __func__, va, slot, psize, result, result); + BUG(); + } + + pteg = slot / HPTES_PER_GROUP; + bit = slot % HPTES_PER_GROUP; + inusetab[pteg] &= ~(0x80 >> bit); + + spin_unlock_irqrestore(&ps3_bolttab_lock, flags); + + /* ps3_hpte_insert() will be used to update PTE */ + return -1; +} + +static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, + int psize) +{ + panic("ps3_hpte_updateboltedpp() not implemented"); +} + +static void ps3_hpte_invalidate(unsigned long slot, unsigned long va, + int psize, int local) +{ + unsigned long flags; + unsigned long result; + unsigned long pteg, bit; + + spin_lock_irqsave(&ps3_bolttab_lock, flags); + result = lv1_write_htab_entry(0, slot, 0, 0); + + if (result) { + DBG("%s: va=%lx slot=%lx psize=%d result = %ld (0x%lx)\n", + __func__, va, slot, psize, result, result); + BUG(); + } + + pteg = slot / HPTES_PER_GROUP; + bit = slot % HPTES_PER_GROUP; + inusetab[pteg] &= ~(0x80 >> bit); + spin_unlock_irqrestore(&ps3_bolttab_lock, flags); +} + +static void ps3_hpte_clear(void) +{ + lv1_unmap_htab(htab_addr); +} + +void __init ps3_hpte_init(unsigned long htab_size) +{ + long bitmap_size; + + DBG(" -> %s:%d\n", __func__, __LINE__); + + ppc_md.hpte_invalidate = ps3_hpte_invalidate; + ppc_md.hpte_updatepp = ps3_hpte_updatepp; + ppc_md.hpte_updateboltedpp = ps3_hpte_updateboltedpp; + ppc_md.hpte_insert = ps3_hpte_insert; + ppc_md.hpte_remove = ps3_hpte_remove; + ppc_md.hpte_clear_all = ps3_hpte_clear; + + ppc64_pft_size = __ilog2(htab_size); + + bitmap_size = htab_size / sizeof(hpte_t) / 8; + + bolttab = __va(lmb_alloc(bitmap_size, 1)); + inusetab = __va(lmb_alloc(bitmap_size, 1)); + + memset(bolttab, 0, bitmap_size); + memset(inusetab, 0, bitmap_size); + + DBG(" <- %s:%d\n", __func__, __LINE__); +} + +void __init ps3_map_htab(void) +{ + long result; + unsigned long htab_size = (1UL << ppc64_pft_size); + + result = lv1_map_htab(0, &htab_addr); + + htab = (hpte_t *)__ioremap(htab_addr, htab_size, PAGE_READONLY_X); + + DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__, + htab_addr, (unsigned long)htab); +} -- cgit v1.2.3 From 6e74b38a7ffa6b69f287ae629aae91e725916e6f Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:55 +0100 Subject: [POWERPC] ps3: add repository support Adds support for the PS3 repository. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/repository.c | 840 ++++++++++++++++++++++++++++++++ 1 file changed, 840 insertions(+) create mode 100644 arch/powerpc/platforms/ps3/repository.c (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c new file mode 100644 index 00000000000..273a0d621bd --- /dev/null +++ b/arch/powerpc/platforms/ps3/repository.c @@ -0,0 +1,840 @@ +/* + * PS3 repository routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 + +enum ps3_vendor_id { + PS3_VENDOR_ID_NONE = 0, + PS3_VENDOR_ID_SONY = 0x8000000000000000UL, +}; + +enum ps3_lpar_id { + PS3_LPAR_ID_CURRENT = 0, + PS3_LPAR_ID_PME = 1, +}; + +#define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__) +static void _dump_field(const char *hdr, u64 n, const char* func, int line) +{ +#if defined(DEBUG) + char s[16]; + const char *const in = (const char *)&n; + unsigned int i; + + for (i = 0; i < 8; i++) + s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.'; + s[i] = 0; + + pr_debug("%s:%d: %s%016lx : %s\n", func, line, hdr, n, s); +#endif +} + +#define dump_node_name(_a, _b, _c, _d, _e) \ + _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__) +static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3, + u64 n4, const char* func, int line) +{ + pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); + _dump_field("n1: ", n1, func, line); + _dump_field("n2: ", n2, func, line); + _dump_field("n3: ", n3, func, line); + _dump_field("n4: ", n4, func, line); +} + +#define dump_node(_a, _b, _c, _d, _e, _f, _g) \ + _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) +static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, + u64 v1, u64 v2, const char* func, int line) +{ + pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); + _dump_field("n1: ", n1, func, line); + _dump_field("n2: ", n2, func, line); + _dump_field("n3: ", n3, func, line); + _dump_field("n4: ", n4, func, line); + pr_debug("%s:%d: v1: %016lx\n", func, line, v1); + pr_debug("%s:%d: v2: %016lx\n", func, line, v2); +} + +/** + * make_first_field - Make the first field of a repository node name. + * @text: Text portion of the field. + * @index: Numeric index portion of the field. Use zero for 'don't care'. + * + * This routine sets the vendor id to zero (non-vendor specific). + * Returns field value. + */ + +static u64 make_first_field(const char *text, u64 index) +{ + u64 n; + + strncpy((char *)&n, text, 8); + return PS3_VENDOR_ID_NONE + (n >> 32) + index; +} + +/** + * make_field - Make subsequent fields of a repository node name. + * @text: Text portion of the field. Use "" for 'don't care'. + * @index: Numeric index portion of the field. Use zero for 'don't care'. + * + * Returns field value. + */ + +static u64 make_field(const char *text, u64 index) +{ + u64 n; + + strncpy((char *)&n, text, 8); + return n + index; +} + +/** + * read_node - Read a repository node from raw fields. + * @n1: First field of node name. + * @n2: Second field of node name. Use zero for 'don't care'. + * @n3: Third field of node name. Use zero for 'don't care'. + * @n4: Fourth field of node name. Use zero for 'don't care'. + * @v1: First repository value (high word). + * @v2: Second repository value (low word). Optional parameter, use zero + * for 'don't care'. + */ + +static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, + u64 *_v1, u64 *_v2) +{ + int result; + u64 v1; + u64 v2; + + if (lpar_id == PS3_LPAR_ID_CURRENT) { + u64 id; + lv1_get_logical_partition_id(&id); + lpar_id = id; + } + + result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1, + &v2); + + if (result) { + pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n", + __func__, __LINE__, ps3_result(result)); + dump_node_name(lpar_id, n1, n2, n3, n4); + return result; + } + + dump_node(lpar_id, n1, n2, n3, n4, v1, v2); + + if (_v1) + *_v1 = v1; + if (_v2) + *_v2 = v2; + + if (v1 && !_v1) + pr_debug("%s:%d: warning: discarding non-zero v1: %016lx\n", + __func__, __LINE__, v1); + if (v2 && !_v2) + pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n", + __func__, __LINE__, v2); + + return result; +} + +int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, + u64 *value) +{ + return read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field(bus_str, 0), + 0, 0, + value, 0); +} + +int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id) +{ + int result; + u64 v1; + u64 v2; /* unused */ + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("id", 0), + 0, 0, + &v1, &v2); + *bus_id = v1; + return result; +} + +int ps3_repository_read_bus_type(unsigned int bus_index, + enum ps3_bus_type *bus_type) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("type", 0), + 0, 0, + &v1, 0); + *bus_type = v1; + return result; +} + +int ps3_repository_read_bus_num_dev(unsigned int bus_index, + unsigned int *num_dev) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("num_dev", 0), + 0, 0, + &v1, 0); + *num_dev = v1; + return result; +} + +int ps3_repository_read_dev_str(unsigned int bus_index, + unsigned int dev_index, const char *dev_str, u64 *value) +{ + return read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field(dev_str, 0), + 0, + value, 0); +} + +int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, + unsigned int *dev_id) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field("id", 0), + 0, + &v1, 0); + *dev_id = v1; + return result; +} + +int ps3_repository_read_dev_type(unsigned int bus_index, + unsigned int dev_index, enum ps3_dev_type *dev_type) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field("type", 0), + 0, + &v1, 0); + *dev_type = v1; + return result; +} + +int ps3_repository_read_dev_intr(unsigned int bus_index, + unsigned int dev_index, unsigned int intr_index, + unsigned int *intr_type, unsigned int* interrupt_id) +{ + int result; + u64 v1; + u64 v2; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field("intr", intr_index), + 0, + &v1, &v2); + *intr_type = v1; + *interrupt_id = v2; + return result; +} + +int ps3_repository_read_dev_reg_type(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field("reg", reg_index), + make_field("type", 0), + &v1, 0); + *reg_type = v1; + return result; +} + +int ps3_repository_read_dev_reg_addr(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len) +{ + return read_node(PS3_LPAR_ID_PME, + make_first_field("bus", bus_index), + make_field("dev", dev_index), + make_field("reg", reg_index), + make_field("data", 0), + bus_addr, len); +} + +int ps3_repository_read_dev_reg(unsigned int bus_index, + unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type, + u64 *bus_addr, u64 *len) +{ + int result = ps3_repository_read_dev_reg_type(bus_index, dev_index, + reg_index, reg_type); + return result ? result + : ps3_repository_read_dev_reg_addr(bus_index, dev_index, + reg_index, bus_addr, len); +} + +#if defined(DEBUG) +int ps3_repository_dump_resource_info(unsigned int bus_index, + unsigned int dev_index) +{ + int result = 0; + unsigned int res_index; + + pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__, + bus_index, dev_index); + + for (res_index = 0; res_index < 10; res_index++) { + enum ps3_interrupt_type intr_type; + unsigned int interrupt_id; + + result = ps3_repository_read_dev_intr(bus_index, dev_index, + res_index, &intr_type, &interrupt_id); + + if (result) { + if (result != LV1_NO_ENTRY) + pr_debug("%s:%d ps3_repository_read_dev_intr" + " (%u:%u) failed\n", __func__, __LINE__, + bus_index, dev_index); + break; + } + + pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n", + __func__, __LINE__, bus_index, dev_index, intr_type, + interrupt_id); + } + + for (res_index = 0; res_index < 10; res_index++) { + enum ps3_region_type reg_type; + u64 bus_addr; + u64 len; + + result = ps3_repository_read_dev_reg(bus_index, dev_index, + res_index, ®_type, &bus_addr, &len); + + if (result) { + if (result != LV1_NO_ENTRY) + pr_debug("%s:%d ps3_repository_read_dev_reg" + " (%u:%u) failed\n", __func__, __LINE__, + bus_index, dev_index); + break; + } + + pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n", + __func__, __LINE__, bus_index, dev_index, reg_type, + bus_addr, len); + } + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +static int dump_device_info(unsigned int bus_index, unsigned int num_dev) +{ + int result = 0; + unsigned int dev_index; + + pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index); + + for (dev_index = 0; dev_index < num_dev; dev_index++) { + enum ps3_dev_type dev_type; + unsigned int dev_id; + + result = ps3_repository_read_dev_type(bus_index, dev_index, + &dev_type); + + if (result) { + pr_debug("%s:%d ps3_repository_read_dev_type" + " (%u:%u) failed\n", __func__, __LINE__, + bus_index, dev_index); + break; + } + + result = ps3_repository_read_dev_id(bus_index, dev_index, + &dev_id); + + if (result) { + pr_debug("%s:%d ps3_repository_read_dev_id" + " (%u:%u) failed\n", __func__, __LINE__, + bus_index, dev_index); + continue; + } + + pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, + __LINE__, bus_index, dev_index, dev_type, dev_id); + + ps3_repository_dump_resource_info(bus_index, dev_index); + } + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +int ps3_repository_dump_bus_info(void) +{ + int result = 0; + unsigned int bus_index; + + pr_debug(" -> %s:%d\n", __func__, __LINE__); + + for (bus_index = 0; bus_index < 10; bus_index++) { + enum ps3_bus_type bus_type; + unsigned int bus_id; + unsigned int num_dev; + + result = ps3_repository_read_bus_type(bus_index, &bus_type); + + if (result) { + pr_debug("%s:%d read_bus_type(%u) failed\n", + __func__, __LINE__, bus_index); + break; + } + + result = ps3_repository_read_bus_id(bus_index, &bus_id); + + if (result) { + pr_debug("%s:%d read_bus_id(%u) failed\n", + __func__, __LINE__, bus_index); + continue; + } + + if (bus_index != bus_id) + pr_debug("%s:%d bus_index != bus_id\n", + __func__, __LINE__); + + result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); + + if (result) { + pr_debug("%s:%d read_bus_num_dev(%u) failed\n", + __func__, __LINE__, bus_index); + continue; + } + + pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", + __func__, __LINE__, bus_index, bus_type, bus_id, + num_dev); + + dump_device_info(bus_index, num_dev); + } + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} +#endif /* defined(DEBUG) */ + +static int find_device(unsigned int bus_index, unsigned int num_dev, + unsigned int start_dev_index, enum ps3_dev_type dev_type, + struct ps3_repository_device *dev) +{ + int result = 0; + unsigned int dev_index; + + pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type); + + dev->dev_index = UINT_MAX; + + for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) { + enum ps3_dev_type x; + + result = ps3_repository_read_dev_type(bus_index, dev_index, + &x); + + if (result) { + pr_debug("%s:%d read_dev_type failed\n", + __func__, __LINE__); + return result; + } + + if (x == dev_type) + break; + } + + BUG_ON(dev_index == num_dev); + + pr_debug("%s:%d: found dev_type %u at dev_index %u\n", + __func__, __LINE__, dev_type, dev_index); + + result = ps3_repository_read_dev_id(bus_index, dev_index, + &dev->did.dev_id); + + if (result) { + pr_debug("%s:%d read_dev_id failed\n", + __func__, __LINE__); + return result; + } + + dev->dev_index = dev_index; + + pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__, + dev->did.dev_id); + + return result; +} + +int ps3_repository_find_device (enum ps3_bus_type bus_type, + enum ps3_dev_type dev_type, + const struct ps3_repository_device *start_dev, + struct ps3_repository_device *dev) +{ + int result = 0; + unsigned int bus_index; + unsigned int num_dev; + + pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__, + bus_type, dev_type); + + dev->bus_index = UINT_MAX; + + for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10; + bus_index++) { + enum ps3_bus_type x; + + result = ps3_repository_read_bus_type(bus_index, &x); + + if (result) { + pr_debug("%s:%d read_bus_type failed\n", + __func__, __LINE__); + return result; + } + if (x == bus_type) + break; + } + + BUG_ON(bus_index == 10); + + pr_debug("%s:%d: found bus_type %u at bus_index %u\n", + __func__, __LINE__, bus_type, bus_index); + + result = ps3_repository_read_bus_num_dev(bus_index, &num_dev); + + if (result) { + pr_debug("%s:%d read_bus_num_dev failed\n", + __func__, __LINE__); + return result; + } + + result = find_device(bus_index, num_dev, start_dev + ? start_dev->dev_index + 1 : 0, dev_type, dev); + + if (result) { + pr_debug("%s:%d get_did failed\n", __func__, __LINE__); + return result; + } + + result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id); + + if (result) { + pr_debug("%s:%d read_bus_id failed\n", + __func__, __LINE__); + return result; + } + + dev->bus_index = bus_index; + + pr_debug("%s:%d found: bus_id %u, dev_id %u\n", + __func__, __LINE__, dev->did.bus_id, dev->did.dev_id); + + return result; +} + +int ps3_repository_find_interrupt(const struct ps3_repository_device *dev, + enum ps3_interrupt_type intr_type, unsigned int *interrupt_id) +{ + int result = 0; + unsigned int res_index; + + pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type); + + *interrupt_id = UINT_MAX; + + for (res_index = 0; res_index < 10; res_index++) { + enum ps3_interrupt_type t; + unsigned int id; + + result = ps3_repository_read_dev_intr(dev->bus_index, + dev->dev_index, res_index, &t, &id); + + if (result) { + pr_debug("%s:%d read_dev_intr failed\n", + __func__, __LINE__); + return result; + } + + if (t == intr_type) { + *interrupt_id = id; + break; + } + } + + BUG_ON(res_index == 10); + + pr_debug("%s:%d: found intr_type %u at res_index %u\n", + __func__, __LINE__, intr_type, res_index); + + return result; +} + +int ps3_repository_find_region(const struct ps3_repository_device *dev, + enum ps3_region_type reg_type, u64 *bus_addr, u64 *len) +{ + int result = 0; + unsigned int res_index; + + pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type); + + *bus_addr = *len = 0; + + for (res_index = 0; res_index < 10; res_index++) { + enum ps3_region_type t; + u64 a; + u64 l; + + result = ps3_repository_read_dev_reg(dev->bus_index, + dev->dev_index, res_index, &t, &a, &l); + + if (result) { + pr_debug("%s:%d read_dev_reg failed\n", + __func__, __LINE__); + return result; + } + + if (t == reg_type) { + *bus_addr = a; + *len = l; + break; + } + } + + BUG_ON(res_index == 10); + + pr_debug("%s:%d: found reg_type %u at res_index %u\n", + __func__, __LINE__, reg_type, res_index); + + return result; +} + +int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) +{ + return read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("pu", 0), + ppe_id, + make_field("rm_size", 0), + rm_size, 0); +} + +int ps3_repository_read_region_total(u64 *region_total) +{ + return read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("rgntotal", 0), + 0, 0, + region_total, 0); +} + +/** + * ps3_repository_read_mm_info - Read mm info for single pu system. + * @rm_base: Real mode memory base address. + * @rm_size: Real mode memory size. + * @region_total: Maximum memory region size. + */ + +int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total) +{ + int result; + u64 ppe_id; + + lv1_get_logical_ppe_id(&ppe_id); + *rm_base = 0; + result = ps3_repository_read_rm_size(ppe_id, rm_size); + return result ? result + : ps3_repository_read_region_total(region_total); +} + +/** + * ps3_repository_read_num_spu_reserved - Number of physical spus reserved. + * @num_spu: Number of physical spus. + */ + +int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("spun", 0), + 0, 0, + &v1, 0); + *num_spu_reserved = v1; + return result; +} + +/** + * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations. + * @num_resource_id: Number of spu resource ids. + */ + +int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("spursvn", 0), + 0, 0, + &v1, 0); + *num_resource_id = v1; + return result; +} + +/** + * ps3_repository_read_spu_resource_id - spu resource reservation id value. + * @res_index: Resource reservation index. + * @resource_type: Resource reservation type. + * @resource_id: Resource reservation id. + */ + +int ps3_repository_read_spu_resource_id(unsigned int res_index, + enum ps3_spu_resource_type* resource_type, unsigned int *resource_id) +{ + int result; + u64 v1; + u64 v2; + + result = read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("spursv", 0), + res_index, + 0, + &v1, &v2); + *resource_type = v1; + *resource_id = v2; + return result; +} + +int ps3_repository_read_boot_dat_address(u64 *address) +{ + return read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("boot_dat", 0), + make_field("address", 0), + 0, + address, 0); +} + +int ps3_repository_read_boot_dat_size(unsigned int *size) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_CURRENT, + make_first_field("bi", 0), + make_field("boot_dat", 0), + make_field("size", 0), + 0, + &v1, 0); + *size = v1; + return result; +} + +/** + * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area. + * address: lpar address of cell_ext_os_area + * @size: size of cell_ext_os_area + */ + +int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size) +{ + int result; + + *size = 0; + result = ps3_repository_read_boot_dat_address(lpar_addr); + return result ? result + : ps3_repository_read_boot_dat_size(size); +} + +int ps3_repository_read_num_be(unsigned int *num_be) +{ + int result; + u64 v1; + + result = read_node(PS3_LPAR_ID_PME, + make_first_field("ben", 0), + 0, + 0, + 0, + &v1, 0); + *num_be = v1; + return result; +} + +int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id) +{ + return read_node(PS3_LPAR_ID_PME, + make_first_field("be", be_index), + 0, + 0, + 0, + node_id, 0); +} + +int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq) +{ + return read_node(PS3_LPAR_ID_PME, + make_first_field("be", 0), + node_id, + make_field("clock", 0), + 0, + tb_freq, 0); +} + +int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) +{ + int result; + u64 node_id; + + *tb_freq = 0; + result = ps3_repository_read_be_node_id(0, &node_id); + return result ? result + : ps3_repository_read_tb_freq(node_id, tb_freq); +} -- cgit v1.2.3 From 2832a81df7f3cb7e7f912a256c156ddbd3450265 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:56 +0100 Subject: [POWERPC] ps3: add interrupt support Adds routines to interface with the PS3 interrupt services. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/interrupt.c | 575 +++++++++++++++++++++++++++++++++ 1 file changed, 575 insertions(+) create mode 100644 arch/powerpc/platforms/ps3/interrupt.c (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c new file mode 100644 index 00000000000..056c1e4141b --- /dev/null +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -0,0 +1,575 @@ +/* + * PS3 interrupt routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +#if defined(DEBUG) +#define DBG(fmt...) udbg_printf(fmt) +#else +#define DBG(fmt...) do{if(0)printk(fmt);}while(0) +#endif + +/** + * ps3_alloc_io_irq - Assign a virq to a system bus device. + * interrupt_id: The device interrupt id read from the system repository. + * @virq: The assigned Linux virq. + * + * An io irq represents a non-virtualized device interrupt. interrupt_id + * coresponds to the interrupt number of the interrupt controller. + */ + +int ps3_alloc_io_irq(unsigned int interrupt_id, unsigned int *virq) +{ + int result; + unsigned long outlet; + + result = lv1_construct_io_irq_outlet(interrupt_id, &outlet); + + if (result) { + pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; + } + + *virq = irq_create_mapping(NULL, outlet); + + pr_debug("%s:%d: interrupt_id %u => outlet %lu, virq %u\n", + __func__, __LINE__, interrupt_id, outlet, *virq); + + return 0; +} + +int ps3_free_io_irq(unsigned int virq) +{ + int result; + + result = lv1_destruct_io_irq_outlet(virq_to_hw(virq)); + + if (!result) + pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); + + irq_dispose_mapping(virq); + + return result; +} + +/** + * ps3_alloc_event_irq - Allocate a virq for use with a system event. + * @virq: The assigned Linux virq. + * + * The virq can be used with lv1_connect_interrupt_event_receive_port() to + * arrange to receive events, or with ps3_send_event_locally() to signal + * events. + */ + +int ps3_alloc_event_irq(unsigned int *virq) +{ + int result; + unsigned long outlet; + + result = lv1_construct_event_receive_port(&outlet); + + if (result) { + pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n", + __func__, __LINE__, ps3_result(result)); + *virq = NO_IRQ; + return result; + } + + *virq = irq_create_mapping(NULL, outlet); + + pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, outlet, + *virq); + + return 0; +} + +int ps3_free_event_irq(unsigned int virq) +{ + int result; + + pr_debug(" -> %s:%d\n", __func__, __LINE__); + + result = lv1_destruct_event_receive_port(virq_to_hw(virq)); + + if (result) + pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n", + __func__, __LINE__, ps3_result(result)); + + irq_dispose_mapping(virq); + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +int ps3_send_event_locally(unsigned int virq) +{ + return lv1_send_event_locally(virq_to_hw(virq)); +} + +/** + * ps3_connect_event_irq - Assign a virq to a system bus device. + * @did: The HV device identifier read from the system repository. + * @interrupt_id: The device interrupt id read from the system repository. + * @virq: The assigned Linux virq. + * + * An event irq represents a virtual device interrupt. The interrupt_id + * coresponds to the software interrupt number. + */ + +int ps3_connect_event_irq(const struct ps3_device_id *did, + unsigned int interrupt_id, unsigned int *virq) +{ + int result; + + result = ps3_alloc_event_irq(virq); + + if (result) + return result; + + result = lv1_connect_interrupt_event_receive_port(did->bus_id, + did->dev_id, virq_to_hw(*virq), interrupt_id); + + if (result) { + pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port" + " failed: %s\n", __func__, __LINE__, + ps3_result(result)); + ps3_free_event_irq(*virq); + *virq = NO_IRQ; + return result; + } + + pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, + interrupt_id, *virq); + + return 0; +} + +int ps3_disconnect_event_irq(const struct ps3_device_id *did, + unsigned int interrupt_id, unsigned int virq) +{ + int result; + + pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__, + interrupt_id, virq); + + result = lv1_disconnect_interrupt_event_receive_port(did->bus_id, + did->dev_id, virq_to_hw(virq), interrupt_id); + + if (result) + pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port" + " failed: %s\n", __func__, __LINE__, + ps3_result(result)); + + ps3_free_event_irq(virq); + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +/** + * ps3_alloc_vuart_irq - Configure the system virtual uart virq. + * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap. + * @virq: The assigned Linux virq. + * + * The system supports only a single virtual uart, so multiple calls without + * freeing the interrupt will return a wrong state error. + */ + +int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq) +{ + int result; + unsigned long outlet; + unsigned long lpar_addr; + + BUG_ON(!is_kernel_addr((unsigned long)virt_addr_bmp)); + + lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp)); + + result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet); + + if (result) { + pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; + } + + *virq = irq_create_mapping(NULL, outlet); + + pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, + outlet, *virq); + + return 0; +} + +int ps3_free_vuart_irq(unsigned int virq) +{ + int result; + + result = lv1_deconfigure_virtual_uart_irq(); + + if (result) { + pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; + } + + irq_dispose_mapping(virq); + + return result; +} + +/** + * ps3_alloc_spe_irq - Configure an spe virq. + * @spe_id: The spe_id returned from lv1_construct_logical_spe(). + * @class: The spe interrupt class {0,1,2}. + * @virq: The assigned Linux virq. + * + */ + +int ps3_alloc_spe_irq(unsigned long spe_id, unsigned int class, + unsigned int *virq) +{ + int result; + unsigned long outlet; + + BUG_ON(class > 2); + + result = lv1_get_spe_irq_outlet(spe_id, class, &outlet); + + if (result) { + pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; + } + + *virq = irq_create_mapping(NULL, outlet); + + pr_debug("%s:%d: spe_id %lu, class %u, outlet %lu, virq %u\n", + __func__, __LINE__, spe_id, class, outlet, *virq); + + return 0; +} + +int ps3_free_spe_irq(unsigned int virq) +{ + irq_dispose_mapping(virq); + return 0; +} + +#define PS3_INVALID_OUTLET ((irq_hw_number_t)-1) +#define PS3_PLUG_MAX 63 + +/** + * struct bmp - a per cpu irq status and mask bitmap structure + * @status: 256 bit status bitmap indexed by plug + * @unused_1: + * @mask: 256 bit mask bitmap indexed by plug + * @unused_2: + * @lock: + * @ipi_debug_brk_mask: + * + * The HV mantains per SMT thread mappings of HV outlet to HV plug on + * behalf of the guest. These mappings are implemented as 256 bit guest + * supplied bitmaps indexed by plug number. The address of the bitmaps are + * registered with the HV through lv1_configure_irq_state_bitmap(). + * + * The HV supports 256 plugs per thread, assigned as {0..255}, for a total + * of 512 plugs supported on a processor. To simplify the logic this + * implementation equates HV plug value to linux virq value, constrains each + * interrupt to have a system wide unique plug number, and limits the range + * of the plug values to map into the first dword of the bitmaps. This + * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note + * that there is no constraint on how many in this set an individual thread + * can aquire. + */ + +struct bmp { + struct { + unsigned long status; + unsigned long unused_1[3]; + unsigned long mask; + unsigned long unused_2[3]; + } __attribute__ ((packed)); + spinlock_t lock; + unsigned long ipi_debug_brk_mask; +}; + +/** + * struct private - a per cpu data structure + * @node: HV node id + * @cpu: HV thread id + * @bmp: an HV bmp structure + */ + +struct private { + unsigned long node; + unsigned int cpu; + struct bmp bmp; +}; + +#if defined(DEBUG) +static void _dump_64_bmp(const char *header, const unsigned long *p, unsigned cpu, + const char* func, int line) +{ + pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n", + func, line, header, cpu, + *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff, + *p & 0xffff); +} + +static void __attribute__ ((unused)) _dump_256_bmp(const char *header, + const unsigned long *p, unsigned cpu, const char* func, int line) +{ + pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n", + func, line, header, cpu, p[0], p[1], p[2], p[3]); +} + +#define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__) +static void _dump_bmp(struct private* pd, const char* func, int line) +{ + unsigned long flags; + + spin_lock_irqsave(&pd->bmp.lock, flags); + _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line); + _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); + spin_unlock_irqrestore(&pd->bmp.lock, flags); +} + +#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__) +static void __attribute__ ((unused)) _dump_mask(struct private* pd, + const char* func, int line) +{ + unsigned long flags; + + spin_lock_irqsave(&pd->bmp.lock, flags); + _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line); + spin_unlock_irqrestore(&pd->bmp.lock, flags); +} +#else +static void dump_bmp(struct private* pd) {}; +#endif /* defined(DEBUG) */ + +static void chip_mask(unsigned int virq) +{ + unsigned long flags; + struct private *pd = get_irq_chip_data(virq); + + pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); + + BUG_ON(virq < NUM_ISA_INTERRUPTS); + BUG_ON(virq > PS3_PLUG_MAX); + + spin_lock_irqsave(&pd->bmp.lock, flags); + pd->bmp.mask &= ~(0x8000000000000000UL >> virq); + spin_unlock_irqrestore(&pd->bmp.lock, flags); + + lv1_did_update_interrupt_mask(pd->node, pd->cpu); +} + +static void chip_unmask(unsigned int virq) +{ + unsigned long flags; + struct private *pd = get_irq_chip_data(virq); + + pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq); + + BUG_ON(virq < NUM_ISA_INTERRUPTS); + BUG_ON(virq > PS3_PLUG_MAX); + + spin_lock_irqsave(&pd->bmp.lock, flags); + pd->bmp.mask |= (0x8000000000000000UL >> virq); + spin_unlock_irqrestore(&pd->bmp.lock, flags); + + lv1_did_update_interrupt_mask(pd->node, pd->cpu); +} + +static void chip_eoi(unsigned int virq) +{ + lv1_end_of_interrupt(virq); +} + +static struct irq_chip irq_chip = { + .typename = "ps3", + .mask = chip_mask, + .unmask = chip_unmask, + .eoi = chip_eoi, +}; + +static void host_unmap(struct irq_host *h, unsigned int virq) +{ + int result; + + pr_debug("%s:%d: virq %d\n", __func__, __LINE__, virq); + + lv1_disconnect_irq_plug(virq); + + result = set_irq_chip_data(virq, NULL); + BUG_ON(result); +} + +static DEFINE_PER_CPU(struct private, private); + +static int host_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t hwirq) +{ + int result; + unsigned int cpu; + + pr_debug(" -> %s:%d\n", __func__, __LINE__); + pr_debug("%s:%d: hwirq %lu => virq %u\n", __func__, __LINE__, hwirq, + virq); + + /* bind this virq to a cpu */ + + preempt_disable(); + cpu = smp_processor_id(); + result = lv1_connect_irq_plug(virq, hwirq); + preempt_enable(); + + if (result) { + pr_info("%s:%d: lv1_connect_irq_plug failed:" + " %s\n", __func__, __LINE__, ps3_result(result)); + return -EPERM; + } + + result = set_irq_chip_data(virq, &per_cpu(private, cpu)); + BUG_ON(result); + + set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq); + + pr_debug(" <- %s:%d\n", __func__, __LINE__); + return result; +} + +static struct irq_host_ops host_ops = { + .map = host_map, + .unmap = host_unmap, +}; + +void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) +{ + struct private *pd = &per_cpu(private, cpu); + + pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq; + + pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__, + cpu, virq, pd->bmp.ipi_debug_brk_mask); +} + +static int bmp_get_and_clear_status_bit(struct bmp *m) +{ + unsigned long flags; + unsigned int bit; + unsigned long x; + + spin_lock_irqsave(&m->lock, flags); + + /* check for ipi break first to stop this cpu ASAP */ + + if (m->status & m->ipi_debug_brk_mask) { + m->status &= ~m->ipi_debug_brk_mask; + spin_unlock_irqrestore(&m->lock, flags); + return __ilog2(m->ipi_debug_brk_mask); + } + + x = (m->status & m->mask); + + for (bit = NUM_ISA_INTERRUPTS, x <<= bit; x; bit++, x <<= 1) + if (x & 0x8000000000000000UL) { + m->status &= ~(0x8000000000000000UL >> bit); + spin_unlock_irqrestore(&m->lock, flags); + return bit; + } + + spin_unlock_irqrestore(&m->lock, flags); + + pr_debug("%s:%d: not found\n", __func__, __LINE__); + return -1; +} + +unsigned int ps3_get_irq(void) +{ + int plug; + + struct private *pd = &__get_cpu_var(private); + + plug = bmp_get_and_clear_status_bit(&pd->bmp); + + if (plug < 1) { + pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__, + pd->cpu); + dump_bmp(&per_cpu(private, 0)); + dump_bmp(&per_cpu(private, 1)); + return NO_IRQ; + } + +#if defined(DEBUG) + if (plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX) { + dump_bmp(&per_cpu(private, 0)); + dump_bmp(&per_cpu(private, 1)); + BUG(); + } +#endif + return plug; +} + +void __init ps3_init_IRQ(void) +{ + int result; + unsigned long node; + unsigned cpu; + struct irq_host *host; + + lv1_get_logical_ppe_id(&node); + + host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &host_ops, + PS3_INVALID_OUTLET); + irq_set_default_host(host); + irq_set_virq_count(PS3_PLUG_MAX + 1); + + for_each_possible_cpu(cpu) { + struct private *pd = &per_cpu(private, cpu); + + pd->node = node; + pd->cpu = cpu; + spin_lock_init(&pd->bmp.lock); + + result = lv1_configure_irq_state_bitmap(node, cpu, + ps3_mm_phys_to_lpar(__pa(&pd->bmp.status))); + + if (result) + pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:" + " %s\n", __func__, __LINE__, + ps3_result(result)); + } + + ppc_md.get_irq = ps3_get_irq; +} -- cgit v1.2.3 From 261efc3f178c8c5b55d76208aee1f39ce247f723 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:57 +0100 Subject: [POWERPC] ps3: add lpar addressing Adds some needed bits for a config option PS3_USE_LPAR_ADDR that disables the PS3 lpar address translation mechanism. This is a currently needed workaround for limitations in the design of the generic cell spu support. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index f023719f645..451bfcd5502 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -29,4 +29,15 @@ config PS3_DYNAMIC_DMA This support is mainly for Linux kernel development. If unsure, say N. +config PS3_USE_LPAR_ADDR + depends on PPC_PS3 && EXPERIMENTAL + bool "PS3 use lpar address space" + default y + help + This option is solely for experimentation by experts. Disables + translation of lpar addresses. SPE support currently won't work + without this set to y. + + If you have any doubt, choose the default y. + endmenu -- cgit v1.2.3 From 00a3e2e93cd3ce73ab2d200fff22a62548da06d6 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:58 +0100 Subject: [POWERPC] ps3: add OS params support Adds support for early access to the parameter data from the PS3 'Other OS' flash memory area. The parameter data mainly holds user preferences like static ip address. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/Makefile | 2 +- arch/powerpc/platforms/ps3/os-area.c | 259 +++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/ps3/os-area.c (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile index 8d6c72c6ea7..6eb69778636 100644 --- a/arch/powerpc/platforms/ps3/Makefile +++ b/arch/powerpc/platforms/ps3/Makefile @@ -1,2 +1,2 @@ obj-y += setup.o mm.o smp.o time.o hvcall.o htab.o repository.o -obj-y += interrupt.o exports.o +obj-y += interrupt.o exports.o os-area.o diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c new file mode 100644 index 00000000000..58358305dc1 --- /dev/null +++ b/arch/powerpc/platforms/ps3/os-area.c @@ -0,0 +1,259 @@ +/* + * PS3 'Other OS' area data. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 "platform.h" + +enum { + OS_AREA_SEGMENT_SIZE = 0X200, +}; + +enum { + HEADER_LDR_FORMAT_RAW = 0, + HEADER_LDR_FORMAT_GZIP = 1, +}; + +/** + * struct os_area_header - os area header segment. + * @magic_num: Always 'cell_ext_os_area'. + * @hdr_version: Header format version number. + * @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. + * + * Note that the docs refer to area offsets. These are offsets in units of + * segments from the start of the os area (top of the header). These are + * better thought of as segment numbers. The os area of the os area is + * reserved for the os image. + */ + +struct os_area_header { + s8 magic_num[16]; + u32 hdr_version; + u32 os_area_offset; + u32 ldr_area_offset; + u32 _reserved_1; + u32 ldr_format; + u32 ldr_size; + u32 _reserved_2[6]; +} __attribute__ ((packed)); + +enum { + PARAM_BOOT_FLAG_GAME_OS = 0, + PARAM_BOOT_FLAG_OTHER_OS = 1, +}; + +enum { + PARAM_AV_MULTI_OUT_NTSC = 0, + PARAM_AV_MULTI_OUT_PAL_RGB = 1, + PARAM_AV_MULTI_OUT_PAL_YCBCR = 2, + PARAM_AV_MULTI_OUT_SECAM = 3, +}; + +enum { + PARAM_CTRL_BUTTON_O_IS_YES = 0, + PARAM_CTRL_BUTTON_X_IS_YES = 1, +}; + +/** + * struct os_area_params - os area params segment. + * @boot_flag: User preference of operating system, PARAM_BOOT_FLAG flag. + * @num_params: Number of params in this (params) segment. + * @rtc_diff: Difference in seconds between 1970 and the ps3 rtc value. + * @av_multi_out: User preference of AV output, PARAM_AV_MULTI_OUT flag. + * @ctrl_button: User preference of controller button config, PARAM_CTRL_BUTTON + * flag. + * @static_ip_addr: User preference of static IP address. + * @network_mask: User preference of static network mask. + * @default_gateway: User preference of static default gateway. + * @dns_primary: User preference of static primary dns server. + * @dns_secondary: User preference of static secondary dns server. + * + * User preference of zero for static_ip_addr means use dhcp. + */ + +struct os_area_params { + u32 boot_flag; + u32 _reserved_1[3]; + u32 num_params; + u32 _reserved_2[3]; + /* param 0 */ + s64 rtc_diff; + u8 av_multi_out; + u8 ctrl_button; + u8 _reserved_3[6]; + /* param 1 */ + u8 static_ip_addr[4]; + u8 network_mask[4]; + u8 default_gateway[4]; + u8 _reserved_4[4]; + /* param 2 */ + u8 dns_primary[4]; + u8 dns_secondary[4]; + u8 _reserved_5[8]; +} __attribute__ ((packed)); + +/** + * struct saved_params - Static working copies of data from the 'Other OS' area. + * + * 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 { + /* 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; + +#define dump_header(_a) _dump_header(_a, __func__, __LINE__) +static void _dump_header(const struct os_area_header __iomem *h, const char* func, + int 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, + h->hdr_version); + 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, + h->ldr_format); + pr_debug("%s:%d: h.ldr_size: %xh\n", func, line, + h->ldr_size); +} + +#define dump_params(_a) _dump_params(_a, __func__, __LINE__) +static void _dump_params(const struct os_area_params __iomem *p, const char* func, + int line) +{ + pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag); + pr_debug("%s:%d: p.num_params: %u\n", func, line, p->num_params); + pr_debug("%s:%d: p.rtc_diff %ld\n", func, line, p->rtc_diff); + pr_debug("%s:%d: p.av_multi_out %u\n", func, line, p->av_multi_out); + pr_debug("%s:%d: p.ctrl_button: %u\n", func, line, p->ctrl_button); + pr_debug("%s:%d: p.static_ip_addr: %u.%u.%u.%u\n", func, line, + p->static_ip_addr[0], p->static_ip_addr[1], + p->static_ip_addr[2], p->static_ip_addr[3]); + pr_debug("%s:%d: p.network_mask: %u.%u.%u.%u\n", func, line, + p->network_mask[0], p->network_mask[1], + p->network_mask[2], p->network_mask[3]); + pr_debug("%s:%d: p.default_gateway: %u.%u.%u.%u\n", func, line, + p->default_gateway[0], p->default_gateway[1], + p->default_gateway[2], p->default_gateway[3]); + pr_debug("%s:%d: p.dns_primary: %u.%u.%u.%u\n", func, line, + p->dns_primary[0], p->dns_primary[1], + p->dns_primary[2], p->dns_primary[3]); + pr_debug("%s:%d: p.dns_secondary: %u.%u.%u.%u\n", func, line, + p->dns_secondary[0], p->dns_secondary[1], + p->dns_secondary[2], p->dns_secondary[3]); +} + +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__); + return -1; + } + + if (header->hdr_version < 1) { + pr_debug("%s:%d hdr_version failed\n", __func__, __LINE__); + return -1; + } + + if (header->os_area_offset > header->ldr_area_offset) { + pr_debug("%s:%d offsets failed\n", __func__, __LINE__); + return -1; + } + + return 0; +} + +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; + + 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 result; + } + + header = (struct os_area_header *)__va(lpar_addr); + params = (struct os_area_params *)__va(lpar_addr + OS_AREA_SEGMENT_SIZE); + + result = verify_header(header); + + if (result) { + pr_debug("%s:%d verify_header failed\n", __func__, __LINE__); + dump_header(header); + return -EIO; + } + + dump_header(header); + dump_params(params); + + saved_params.rtc_diff = params->rtc_diff; + saved_params.av_multi_out = params->av_multi_out; + 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); + + return result; +} + +/** + * ps3_os_area_rtc_diff - Returns the ps3 rtc diff value. + * + * 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. + */ + +u64 ps3_os_area_rtc_diff(void) +{ + return saved_params.rtc_diff ? saved_params.rtc_diff : 946684800UL; +} -- cgit v1.2.3 From de91a53429952875740692d1de36ae70d4cf81da Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:46:59 +0100 Subject: [POWERPC] ps3: add spu support Adds spu support for the PS3 platform. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/ps3/Makefile | 2 + arch/powerpc/platforms/ps3/platform.h | 8 + arch/powerpc/platforms/ps3/spu.c | 613 ++++++++++++++++++++++++++++++++++ 3 files changed, 623 insertions(+) create mode 100644 arch/powerpc/platforms/ps3/spu.c (limited to 'arch') diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile index 6eb69778636..3757cfabc8c 100644 --- a/arch/powerpc/platforms/ps3/Makefile +++ b/arch/powerpc/platforms/ps3/Makefile @@ -1,2 +1,4 @@ obj-y += setup.o mm.o smp.o time.o hvcall.o htab.o repository.o obj-y += interrupt.o exports.o os-area.o + +obj-$(CONFIG_SPU_BASE) += spu.o diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index d9948df6ccd..23b111bea9d 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -57,4 +57,12 @@ int ps3_set_rtc_time(struct rtc_time *time); int __init ps3_os_area_init(void); u64 ps3_os_area_rtc_diff(void); +/* spu */ + +#if defined(CONFIG_SPU_BASE) +void ps3_spu_set_platform (void); +#else +static inline void ps3_spu_set_platform (void) {} +#endif + #endif diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c new file mode 100644 index 00000000000..644532c3b7c --- /dev/null +++ b/arch/powerpc/platforms/ps3/spu.c @@ -0,0 +1,613 @@ +/* + * PS3 Platform spu routines. + * + * Copyright (C) 2006 Sony Computer Entertainment Inc. + * Copyright 2006 Sony Corp. + * + * 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; version 2 of the License. + * + * 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 + +/* spu_management_ops */ + +/** + * enum spe_type - Type of spe to create. + * @spe_type_logical: Standard logical spe. + * + * For use with lv1_construct_logical_spe(). The current HV does not support + * any types other than those listed. + */ + +enum spe_type { + SPE_TYPE_LOGICAL = 0, +}; + +/** + * struct spe_shadow - logical spe shadow register area. + * + * Read-only shadow of spe registers. + */ + +struct spe_shadow { + u8 padding_0000[0x0140]; + u64 int_status_class0_RW; /* 0x0140 */ + u64 int_status_class1_RW; /* 0x0148 */ + u64 int_status_class2_RW; /* 0x0150 */ + u8 padding_0158[0x0610-0x0158]; + u64 mfc_dsisr_RW; /* 0x0610 */ + u8 padding_0618[0x0620-0x0618]; + u64 mfc_dar_RW; /* 0x0620 */ + u8 padding_0628[0x0800-0x0628]; + u64 mfc_dsipr_R; /* 0x0800 */ + u8 padding_0808[0x0810-0x0808]; + u64 mfc_lscrr_R; /* 0x0810 */ + u8 padding_0818[0x0c00-0x0818]; + u64 mfc_cer_R; /* 0x0c00 */ + u8 padding_0c08[0x0f00-0x0c08]; + u64 spe_execution_status; /* 0x0f00 */ + u8 padding_0f08[0x1000-0x0f08]; +} __attribute__ ((packed)); + + +/** + * enum spe_ex_state - Logical spe execution state. + * @spe_ex_state_unexecutable: Uninitialized. + * @spe_ex_state_executable: Enabled, not ready. + * @spe_ex_state_executed: Ready for use. + * + * The execution state (status) of the logical spe as reported in + * struct spe_shadow:spe_execution_status. + */ + +enum spe_ex_state { + SPE_EX_STATE_UNEXECUTABLE = 0, + SPE_EX_STATE_EXECUTABLE = 2, + SPE_EX_STATE_EXECUTED = 3, +}; + +/** + * struct priv1_cache - Cached values of priv1 registers. + * @masks[]: Array of cached spe interrupt masks, indexed by class. + * @sr1: Cached mfc_sr1 register. + * @tclass_id: Cached mfc_tclass_id register. + */ + +struct priv1_cache { + u64 masks[3]; + u64 sr1; + u64 tclass_id; +}; + +/** + * struct spu_pdata - Platform state variables. + * @spe_id: HV spe id returned by lv1_construct_logical_spe(). + * @resource_id: HV spe resource id returned by + * ps3_repository_read_spe_resource_id(). + * @priv2_addr: lpar address of spe priv2 area returned by + * lv1_construct_logical_spe(). + * @shadow_addr: lpar address of spe register shadow area returned by + * lv1_construct_logical_spe(). + * @shadow: Virtual (ioremap) address of spe register shadow area. + * @cache: Cached values of priv1 registers. + */ + +struct spu_pdata { + u64 spe_id; + u64 resource_id; + u64 priv2_addr; + u64 shadow_addr; + struct spe_shadow __iomem *shadow; + struct priv1_cache cache; +}; + +static struct spu_pdata *spu_pdata(struct spu *spu) +{ + return spu->pdata; +} + +#define dump_areas(_a, _b, _c, _d, _e) \ + _dump_areas(_a, _b, _c, _d, _e, __func__, __LINE__) +static void _dump_areas(unsigned int spe_id, unsigned long priv2, + unsigned long problem, unsigned long ls, unsigned long shadow, + const char* func, int line) +{ + pr_debug("%s:%d: spe_id: %xh (%u)\n", func, line, spe_id, spe_id); + pr_debug("%s:%d: priv2: %lxh\n", func, line, priv2); + pr_debug("%s:%d: problem: %lxh\n", func, line, problem); + pr_debug("%s:%d: ls: %lxh\n", func, line, ls); + pr_debug("%s:%d: shadow: %lxh\n", func, line, shadow); +} + +static unsigned long get_vas_id(void) +{ + unsigned long id; + + lv1_get_logical_ppe_id(&id); + lv1_get_virtual_address_space_id_of_ppe(id, &id); + + return id; +} + +static int __init construct_spu(struct spu *spu) +{ + int result; + unsigned long unused; + + result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT, + PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL, + &spu_pdata(spu)->priv2_addr, &spu->problem_phys, + &spu->local_store_phys, &unused, + &spu_pdata(spu)->shadow_addr, + &spu_pdata(spu)->spe_id); + + if (result) { + pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n", + __func__, __LINE__, ps3_result(result)); + return result; + } + + return result; +} + +static int __init add_spu_pages(unsigned long start_addr, unsigned long size) +{ + int result; + unsigned long start_pfn; + unsigned long nr_pages; + struct pglist_data *pgdata; + struct zone *zone; + + BUG_ON(!mem_init_done); + + start_pfn = start_addr >> PAGE_SHIFT; + nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + + pgdata = NODE_DATA(0); + zone = pgdata->node_zones; + + result = __add_pages(zone, start_pfn, nr_pages); + + if (result) + pr_debug("%s:%d: __add_pages failed: (%d)\n", + __func__, __LINE__, result); + + return result; +} + +static void spu_unmap(struct spu *spu) +{ + iounmap(spu->priv2); + iounmap(spu->problem); + iounmap((__force u8 __iomem *)spu->local_store); + iounmap(spu_pdata(spu)->shadow); +} + +static int __init setup_areas(struct spu *spu) +{ + struct table {char* name; unsigned long addr; unsigned long size;}; + int result; + + /* setup pages */ + + result = add_spu_pages(spu->local_store_phys, LS_SIZE); + if (result) + goto fail_add; + + result = add_spu_pages(spu->problem_phys, sizeof(struct spu_problem)); + if (result) + goto fail_add; + + /* ioremap */ + + spu_pdata(spu)->shadow = __ioremap( + spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), + PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED); + if (!spu_pdata(spu)->shadow) { + pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); + goto fail_ioremap; + } + + spu->local_store = ioremap(spu->local_store_phys, LS_SIZE); + if (!spu->local_store) { + pr_debug("%s:%d: ioremap local_store failed\n", + __func__, __LINE__); + goto fail_ioremap; + } + + spu->problem = ioremap(spu->problem_phys, + sizeof(struct spu_problem)); + if (!spu->problem) { + pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); + goto fail_ioremap; + } + + spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, + sizeof(struct spu_priv2)); + if (!spu->priv2) { + pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); + goto fail_ioremap; + } + + dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr, + spu->problem_phys, spu->local_store_phys, + spu_pdata(spu)->shadow_addr); + dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2, + (unsigned long)spu->problem, (unsigned long)spu->local_store, + (unsigned long)spu_pdata(spu)->shadow); + + return 0; + +fail_ioremap: + spu_unmap(spu); +fail_add: + return result; +} + +static int __init setup_interrupts(struct spu *spu) +{ + int result; + + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 0, + &spu->irqs[0]); + + if (result) + goto fail_alloc_0; + + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 1, + &spu->irqs[1]); + + if (result) + goto fail_alloc_1; + + result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 2, + &spu->irqs[2]); + + if (result) + goto fail_alloc_2; + + return result; + +fail_alloc_2: + ps3_free_spe_irq(spu->irqs[1]); +fail_alloc_1: + ps3_free_spe_irq(spu->irqs[0]); +fail_alloc_0: + spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; + return result; +} + +static int __init enable_spu(struct spu *spu) +{ + int result; + + result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id, + spu_pdata(spu)->resource_id); + + if (result) { + pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n", + __func__, __LINE__, ps3_result(result)); + goto fail_enable; + } + + result = setup_areas(spu); + + if (result) + goto fail_areas; + + result = setup_interrupts(spu); + + if (result) + goto fail_interrupts; + + return 0; + +fail_interrupts: + spu_unmap(spu); +fail_areas: + lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); +fail_enable: + return result; +} + +static int ps3_destroy_spu(struct spu *spu) +{ + int result; + + pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number); + + result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); + BUG_ON(result); + + ps3_free_spe_irq(spu->irqs[2]); + ps3_free_spe_irq(spu->irqs[1]); + ps3_free_spe_irq(spu->irqs[0]); + + spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; + + spu_unmap(spu); + + result = lv1_destruct_logical_spe(spu_pdata(spu)->spe_id); + BUG_ON(result); + + kfree(spu->pdata); + spu->pdata = NULL; + + return 0; +} + +static int __init ps3_create_spu(struct spu *spu, void *data) +{ + int result; + + pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number); + + spu->pdata = kzalloc(sizeof(struct spu_pdata), + GFP_KERNEL); + + if (!spu->pdata) { + result = -ENOMEM; + goto fail_malloc; + } + + spu_pdata(spu)->resource_id = (unsigned long)data; + + /* Init cached reg values to HV defaults. */ + + spu_pdata(spu)->cache.sr1 = 0x33; + + result = construct_spu(spu); + + if (result) + goto fail_construct; + + /* For now, just go ahead and enable it. */ + + result = enable_spu(spu); + + if (result) + goto fail_enable; + + /* Make sure the spu is in SPE_EX_STATE_EXECUTED. */ + + /* need something better here!!! */ + while (in_be64(&spu_pdata(spu)->shadow->spe_execution_status) + != SPE_EX_STATE_EXECUTED) + (void)0; + + return result; + +fail_enable: +fail_construct: + ps3_destroy_spu(spu); +fail_malloc: + return result; +} + +static int __init ps3_enumerate_spus(int (*fn)(void *data)) +{ + int result; + unsigned int num_resource_id; + unsigned int i; + + result = ps3_repository_read_num_spu_resource_id(&num_resource_id); + + pr_debug("%s:%d: num_resource_id %u\n", __func__, __LINE__, + num_resource_id); + + /* + * For now, just create logical spus equal to the number + * of physical spus reserved for the partition. + */ + + for (i = 0; i < num_resource_id; i++) { + enum ps3_spu_resource_type resource_type; + unsigned int resource_id; + + result = ps3_repository_read_spu_resource_id(i, + &resource_type, &resource_id); + + if (result) + break; + + if (resource_type == PS3_SPU_RESOURCE_TYPE_EXCLUSIVE) { + result = fn((void*)(unsigned long)resource_id); + + if (result) + break; + } + } + + if (result) + printk(KERN_WARNING "%s:%d: Error initializing spus\n", + __func__, __LINE__); + + return result; +} + +const struct spu_management_ops spu_management_ps3_ops = { + .enumerate_spus = ps3_enumerate_spus, + .create_spu = ps3_create_spu, + .destroy_spu = ps3_destroy_spu, +}; + +/* spu_priv1_ops */ + +static void int_mask_and(struct spu *spu, int class, u64 mask) +{ + u64 old_mask; + + /* are these serialized by caller??? */ + old_mask = spu_int_mask_get(spu, class); + spu_int_mask_set(spu, class, old_mask & mask); +} + +static void int_mask_or(struct spu *spu, int class, u64 mask) +{ + u64 old_mask; + + old_mask = spu_int_mask_get(spu, class); + spu_int_mask_set(spu, class, old_mask | mask); +} + +static void int_mask_set(struct spu *spu, int class, u64 mask) +{ + spu_pdata(spu)->cache.masks[class] = mask; + lv1_set_spe_interrupt_mask(spu_pdata(spu)->spe_id, class, + spu_pdata(spu)->cache.masks[class]); +} + +static u64 int_mask_get(struct spu *spu, int class) +{ + return spu_pdata(spu)->cache.masks[class]; +} + +static void int_stat_clear(struct spu *spu, int class, u64 stat) +{ + /* Note that MFC_DSISR will be cleared when class1[MF] is set. */ + + lv1_clear_spe_interrupt_status(spu_pdata(spu)->spe_id, class, + stat, 0); +} + +static u64 int_stat_get(struct spu *spu, int class) +{ + u64 stat; + + lv1_get_spe_interrupt_status(spu_pdata(spu)->spe_id, class, &stat); + return stat; +} + +static void cpu_affinity_set(struct spu *spu, int cpu) +{ + /* No support. */ +} + +static u64 mfc_dar_get(struct spu *spu) +{ + return in_be64(&spu_pdata(spu)->shadow->mfc_dar_RW); +} + +static void mfc_dsisr_set(struct spu *spu, u64 dsisr) +{ + /* Nothing to do, cleared in int_stat_clear(). */ +} + +static u64 mfc_dsisr_get(struct spu *spu) +{ + return in_be64(&spu_pdata(spu)->shadow->mfc_dsisr_RW); +} + +static void mfc_sdr_setup(struct spu *spu) +{ + /* Nothing to do. */ +} + +static void mfc_sr1_set(struct spu *spu, u64 sr1) +{ + /* Check bits allowed by HV. */ + + static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK + | MFC_STATE1_PROBLEM_STATE_MASK); + + BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed)); + + spu_pdata(spu)->cache.sr1 = sr1; + lv1_set_spe_privilege_state_area_1_register( + spu_pdata(spu)->spe_id, + offsetof(struct spu_priv1, mfc_sr1_RW), + spu_pdata(spu)->cache.sr1); +} + +static u64 mfc_sr1_get(struct spu *spu) +{ + return spu_pdata(spu)->cache.sr1; +} + +static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) +{ + spu_pdata(spu)->cache.tclass_id = tclass_id; + lv1_set_spe_privilege_state_area_1_register( + spu_pdata(spu)->spe_id, + offsetof(struct spu_priv1, mfc_tclass_id_RW), + spu_pdata(spu)->cache.tclass_id); +} + +static u64 mfc_tclass_id_get(struct spu *spu) +{ + return spu_pdata(spu)->cache.tclass_id; +} + +static void tlb_invalidate(struct spu *spu) +{ + /* Nothing to do. */ +} + +static void resource_allocation_groupID_set(struct spu *spu, u64 id) +{ + /* No support. */ +} + +static u64 resource_allocation_groupID_get(struct spu *spu) +{ + return 0; /* No support. */ +} + +static void resource_allocation_enable_set(struct spu *spu, u64 enable) +{ + /* No support. */ +} + +static u64 resource_allocation_enable_get(struct spu *spu) +{ + return 0; /* No support. */ +} + +const struct spu_priv1_ops spu_priv1_ps3_ops = { + .int_mask_and = int_mask_and, + .int_mask_or = int_mask_or, + .int_mask_set = int_mask_set, + .int_mask_get = int_mask_get, + .int_stat_clear = int_stat_clear, + .int_stat_get = int_stat_get, + .cpu_affinity_set = cpu_affinity_set, + .mfc_dar_get = mfc_dar_get, + .mfc_dsisr_set = mfc_dsisr_set, + .mfc_dsisr_get = mfc_dsisr_get, + .mfc_sdr_setup = mfc_sdr_setup, + .mfc_sr1_set = mfc_sr1_set, + .mfc_sr1_get = mfc_sr1_get, + .mfc_tclass_id_set = mfc_tclass_id_set, + .mfc_tclass_id_get = mfc_tclass_id_get, + .tlb_invalidate = tlb_invalidate, + .resource_allocation_groupID_set = resource_allocation_groupID_set, + .resource_allocation_groupID_get = resource_allocation_groupID_get, + .resource_allocation_enable_set = resource_allocation_enable_set, + .resource_allocation_enable_get = resource_allocation_enable_get, +}; + +void ps3_spu_set_platform(void) +{ + spu_priv1_ops = &spu_priv1_ps3_ops; + spu_management_ops = &spu_management_ps3_ops; +} -- cgit v1.2.3 From 797c7b56d28e800947c66d1c324a6bfc83289b7a Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Thu, 23 Nov 2006 00:47:01 +0100 Subject: [POWERPC] ps3: add ps3_defconfig Adds a ps3_defconfig for the PS3 game console. Signed-off-by: Geoff Levand Signed-off-by: Arnd Bergmann --- arch/powerpc/configs/ps3_defconfig | 837 +++++++++++++++++++++++++++++++++++++ 1 file changed, 837 insertions(+) create mode 100644 arch/powerpc/configs/ps3_defconfig (limited to 'arch') diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig new file mode 100644 index 00000000000..f2d888e014a --- /dev/null +++ b/arch/powerpc/configs/ps3_defconfig @@ -0,0 +1,837 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc6 +# Tue Nov 21 19:38:53 2006 +# +CONFIG_PPC64=y +CONFIG_64BIT=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_COMPAT=y +CONFIG_SYSVIPC_COMPAT=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +# CONFIG_PPC_UDBG_16550 is not set +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +# CONFIG_DEFAULT_UIMAGE is not set + +# +# Processor support +# +# CONFIG_POWER4_ONLY is not set +CONFIG_POWER3=y +CONFIG_POWER4=y +CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +# CONFIG_PPC_OF_PLATFORM_PCI is not set +CONFIG_ALTIVEC=y +CONFIG_PPC_STD_MMU=y +CONFIG_VIRT_CPU_ACCOUNTING=y +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_KALLSYMS_EXTRA_PASS=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y +CONFIG_STOP_MACHINE=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Platform support +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_EMBEDDED6xx is not set +# CONFIG_APUS is not set +# CONFIG_PPC_PSERIES is not set +# CONFIG_PPC_ISERIES is not set +# CONFIG_PPC_PMAC is not set +# CONFIG_PPC_MAPLE is not set +# CONFIG_PPC_PASEMI is not set +CONFIG_PPC_CELL=y +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_IBM_CELL_BLADE is not set +CONFIG_PPC_PS3=y +# CONFIG_U3_DART is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_WANT_EARLY_SERIAL is not set +# CONFIG_MPIC is not set + +# +# Cell Broadband Engine options +# +CONFIG_SPU_FS=y +CONFIG_SPU_BASE=y +# CONFIG_CBE_RAS is not set + +# +# PS3 Platform Options +# +CONFIG_PS3_HTAB_SIZE=20 +CONFIG_PS3_DYNAMIC_DMA=y +CONFIG_PS3_USE_LPAR_ADDR=y + +# +# Kernel options +# +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_BKL is not set +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_FORCE_MAX_ZONEORDER=9 +# CONFIG_IOMMU_VMERGE is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_IRQ_ALL_CPUS is not set +# CONFIG_NUMA is not set +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +# CONFIG_FLATMEM_MANUAL is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_MEMORY_HOTPLUG=y +CONFIG_MEMORY_HOTPLUG_SPARSE=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_RESOURCES_64BIT=y +CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_PPC_64K_PAGES=y +# CONFIG_SCHED_SMT is not set +CONFIG_PROC_DEVICETREE=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="root=/dev/nfs rw ip=dhcp" +# CONFIG_PM is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +CONFIG_KERNEL_START=0xc000000000000000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +# CONFIG_PACKET is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +CONFIG_GEN_RTC=y +# CONFIG_GEN_RTC_X is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set +# CONFIG_KPROBES is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +CONFIG_DEBUG_LIST=y +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUG_STACKOVERFLOW is not set +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUGGER is not set +CONFIG_IRQSTACKS=y +# CONFIG_BOOTX_TEXT is not set +CONFIG_PPC_EARLY_DEBUG=y +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set -- cgit v1.2.3 From 1c72db14fe77c2aa2c18be0fa2594f54d7413147 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 23 Nov 2006 00:47:02 +0100 Subject: [POWERPC] update cell_defconfig for ps3 support In the common cell kernel, I want to have ps3 enabled to find potential bugs at compile-time. Also enable SPU disassembly in xmon. Signed-off-by: Arnd Bergmann --- arch/powerpc/configs/cell_defconfig | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 3d6a2f10a7d..a98c982c73a 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Wed Oct 4 15:30:50 2006 +# Linux kernel version: 2.6.19-rc6 +# Wed Nov 22 15:33:04 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -32,6 +32,10 @@ CONFIG_AUDIT_ARCH=y CONFIG_POWER3=y CONFIG_POWER4=y CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +CONFIG_PPC_DCR_MMIO=y +CONFIG_PPC_DCR=y +CONFIG_PPC_OF_PLATFORM_PCI=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y CONFIG_VIRT_CPU_ACCOUNTING=y @@ -67,7 +71,7 @@ CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -131,6 +135,7 @@ CONFIG_PPC_CELL=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_PPC_PS3=y # CONFIG_U3_DART is not set CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERROR_LOGGING is not set @@ -139,6 +144,8 @@ CONFIG_RTAS_FLASH=y CONFIG_MMIO_NVRAM=y # CONFIG_PPC_MPC106 is not set # CONFIG_PPC_970_NAP is not set +CONFIG_PPC_INDIRECT_IO=y +CONFIG_GENERIC_IOMAP=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=y CONFIG_CPU_FREQ_DEBUG=y @@ -153,7 +160,7 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # CONFIG_CPU_FREQ_PMAC64 is not set # CONFIG_WANT_EARLY_SERIAL is not set -# CONFIG_MPIC is not set +CONFIG_MPIC=y # # Cell Broadband Engine options @@ -164,6 +171,13 @@ CONFIG_CBE_RAS=y CONFIG_CBE_THERM=m CONFIG_CBE_CPUFREQ=m +# +# PS3 Platform Options +# +CONFIG_PS3_HTAB_SIZE=20 +# CONFIG_PS3_DYNAMIC_DMA is not set +CONFIG_PS3_USE_LPAR_ADDR=y + # # Kernel options # @@ -180,13 +194,14 @@ CONFIG_BINFMT_MISC=m CONFIG_FORCE_MAX_ZONEORDER=9 # CONFIG_IOMMU_VMERGE is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_KEXEC=y +# CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set CONFIG_IRQ_ALL_CPUS=y CONFIG_NUMA=y CONFIG_NODES_SHIFT=4 CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_FLATMEM_MANUAL is not set @@ -203,6 +218,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y CONFIG_ARCH_MEMORY_PROBE=y +CONFIG_NODES_SPAN_OTHER_NODES=y CONFIG_PPC_64K_PAGES=y CONFIG_SCHED_SMT=y CONFIG_PROC_DEVICETREE=y @@ -221,7 +237,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y CONFIG_PCIEPORTBUS=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -294,7 +309,6 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_SIT is not set CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y @@ -1157,6 +1171,7 @@ CONFIG_DEBUG_FS=y CONFIG_DEBUGGER=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y +CONFIG_XMON_DISASSEMBLY=y CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set @@ -1174,7 +1189,7 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=m CONFIG_CRYPTO_HASH=y -# CONFIG_CRYPTO_MANAGER is not set +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -- cgit v1.2.3 From fecb352f6bb86564b24ecbf7e5bfec09346b9327 Mon Sep 17 00:00:00 2001 From: Mike Wolf Date: Tue, 21 Nov 2006 14:41:54 -0600 Subject: [POWERPC] powerpc: Make 970MP detectable by oprofile Change the oprofile_cpu_type in cputables.c to be ppc64/970MP. Oprofile needs to distinquish the MP from other 970 processors so it can add some new counters specific to the 970MP. Signed-off-by: Mike Wolf Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 911ac442f44..0b01faa3e7e 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -225,7 +225,7 @@ static struct cpu_spec cpu_specs[] = { .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970MP, .cpu_restore = __restore_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970", + .oprofile_cpu_type = "ppc64/970MP", .oprofile_type = PPC_OPROFILE_POWER4, .platform = "ppc970", }, -- cgit v1.2.3 From 7839af3354c9ed86336a0b40032007919393f3ed Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Fri, 17 Nov 2006 17:08:37 +0100 Subject: [POWERPC] Compile a zImage.chrp if PPC_EFIKA seleted Signed-off-by: Nicolas DET Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 4a6f0f054b7..22e90168723 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -156,6 +156,7 @@ image-$(CONFIG_PPC_PSERIES) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.pseries image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp +image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac image-$(CONFIG_DEFAULT_UIMAGE) += uImage -- cgit v1.2.3 From aa668d6aac63f5fc02aa63bf25ff36d12510e050 Mon Sep 17 00:00:00 2001 From: Nicolas DET Date: Fri, 17 Nov 2006 16:03:20 +0100 Subject: [POWERPC] Fix compile issue for Efika platform This patch fixes a compile issue for the Efika platform recently introduced by API changes. Signed-off-by: Nicolas DET Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/efika/Makefile | 2 +- arch/powerpc/platforms/efika/setup.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/efika/Makefile b/arch/powerpc/platforms/efika/Makefile index 17b2a781fba..56d44044023 100644 --- a/arch/powerpc/platforms/efika/Makefile +++ b/arch/powerpc/platforms/efika/Makefile @@ -1 +1 @@ -obj-y += setup.o mpc52xx.o pci.o +obj-y += setup.o pci.o diff --git a/arch/powerpc/platforms/efika/setup.c b/arch/powerpc/platforms/efika/setup.c index 3bc1b5fe0ce..110c980ed1e 100644 --- a/arch/powerpc/platforms/efika/setup.c +++ b/arch/powerpc/platforms/efika/setup.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "efika.h" -- cgit v1.2.3 From bd2e5f829e772787ea4d986d72ddf57f50878649 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Mon, 27 Nov 2006 19:18:52 +0100 Subject: [POWERPC] spufs: return an error in spu_create is isolated create isnt supported This changes the spu_create system call to return an error (-ENODEV) if and isolated spu context is requested on hardware that doesn't support isolated mode. Tested on systemsim with and without isolation support Signed-off-by: Jeremy Kerr Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/spufs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index a3ca06bd0ca..c7d010749a1 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -323,6 +323,10 @@ static int spufs_create_context(struct inode *inode, == SPU_CREATE_ISOLATE) goto out_unlock; + ret = -ENODEV; + if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) + goto out_unlock; + ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); if (ret) goto out_unlock; -- cgit v1.2.3 From c2b2226c7e46549c26fd5f5f40122536bc91ba0d Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2006 19:18:53 +0100 Subject: [POWERPC] spufs: always send sigtrap on breakpoint Currently, we only send a sigtrap if the current task is being ptraced. This is somewhat inconsistant, and it breaks utrace support in fedora. Removing the check should do the right thing in all cases. Cc: Ulrich Weigand Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/spufs/run.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 1be4e3339d8..1acc2ffef8c 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -350,12 +350,10 @@ out2: (status >> SPU_STOP_STATUS_SHIFT != 0x2104))))) ret = status; - if (unlikely(current->ptrace & PT_PTRACED)) { - if ((status & SPU_STATUS_STOPPED_BY_STOP) - && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { - force_sig(SIGTRAP, current); - ret = -ERESTARTSYS; - } + if ((status & SPU_STATUS_STOPPED_BY_STOP) + && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { + force_sig(SIGTRAP, current); + ret = -ERESTARTSYS; } out: -- cgit v1.2.3 From da06aa08d9f23e4f970d9a25a6e52f9a7736bfa2 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 27 Nov 2006 19:18:54 +0100 Subject: [POWERPC] spufs: we should only execute init_spu_base on cell Signed-off-by: Stephen Rothwell Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/spu_base.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 841ed359802..bd7bffc3ddd 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -663,6 +663,9 @@ static int __init init_spu_base(void) { int i, ret; + if (!spu_management_ops) + return 0; + /* create sysdev class for spus */ ret = sysdev_class_register(&spu_sysdev_class); if (ret) -- cgit v1.2.3 From e055595d3e5f5233374211bc6893e5d16976df99 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2006 19:18:55 +0100 Subject: [POWERPC] cell: fix building without spufs It may be desireable to build a kernel for cell without spufs, e.g. as the initial kboot kernel. This requires that the SPU specific parts of the core dump and the xmon code depend on CONFIG_SPU_BASE instead of CONFIG_PPC_CELL. Signed-off-by: Arnd Bergmann --- arch/powerpc/xmon/Makefile | 2 +- arch/powerpc/xmon/xmon.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile index 69303575d3d..51d97588e76 100644 --- a/arch/powerpc/xmon/Makefile +++ b/arch/powerpc/xmon/Makefile @@ -8,5 +8,5 @@ obj-y += xmon.o setjmp.o start.o nonstdio.o ifdef CONFIG_XMON_DISASSEMBLY obj-y += ppc-dis.o ppc-opc.o -obj-$(CONFIG_PPC_CELL) += spu-dis.o spu-opc.o +obj-$(CONFIG_SPU_BASE) += spu-dis.o spu-opc.o endif diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1cf90c8ac34..dc8a3760a98 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -213,7 +213,7 @@ Commands:\n\ p call a procedure\n\ r print registers\n\ s single step\n" -#ifdef CONFIG_PPC_CELL +#ifdef CONFIG_SPU_BASE " ss stop execution on all spus\n\ sr restore execution on stopped spus\n\ sf # dump spu fields for spu # (in hex)\n\ @@ -2654,7 +2654,7 @@ void __init xmon_setup(void) debugger(NULL); } -#ifdef CONFIG_PPC_CELL +#ifdef CONFIG_SPU_BASE struct spu_info { struct spu *spu; @@ -2907,7 +2907,7 @@ static int do_spu_cmd(void) return 0; } -#else /* ! CONFIG_PPC_CELL */ +#else /* ! CONFIG_SPU_BASE */ static int do_spu_cmd(void) { return -1; -- cgit v1.2.3 From eb30c72026500f9efa9bb23ab2393d6a9e36c5e1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 27 Nov 2006 19:18:56 +0100 Subject: [POWERPC] ps3: Missed renames of CONFIG_PS3 to CONFIG_PPC_PS3 When renaming CONFIG_PS3 to CONFIG_PPC_PS3, a few occurrences have been missed. I also fixed up the alignment in arch/powerpc/platforms/Makefile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 56caf4fbd73..52984a803e7 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -5,7 +5,7 @@ ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif endif -obj-$(CONFIG_PPC_EFIKA) += efika/ +obj-$(CONFIG_PPC_EFIKA) += efika/ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_83xx) += 83xx/ @@ -14,7 +14,7 @@ obj-$(CONFIG_PPC_86xx) += 86xx/ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ -obj-$(CONFIG_PPC_PASEMI) += pasemi/ +obj-$(CONFIG_PPC_PASEMI) += pasemi/ obj-$(CONFIG_PPC_CELL) += cell/ -obj-$(CONFIG_PS3) += ps3/ +obj-$(CONFIG_PPC_PS3) += ps3/ obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ -- cgit v1.2.3 From e22ba7e38144c1cccac5024cfd6ec88bb64d3e1f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2006 19:18:57 +0100 Subject: [POWERPC] ps3: multiplatform build fixes A few code paths need to check whether or not they are running on the PS3's LV1 hypervisor before making hcalls. This introduces a new firmware feature bit for this, FW_FEATURE_PS3_LV1. Now when both PS3 and IBM_CELL_BLADE are enabled, but not PSERIES, FW_FEATURE_PS3_LV1 and FW_FEATURE_LPAR get enabled at compile time, which is a bug. The same problem can also happen for (PPC_ISERIES && !PPC_PSERIES && PPC_SOMETHING_ELSE). In order to solve this, I introduce a new CONFIG_PPC_NATIVE option that is set when at least one platform is selected that can run without a hypervisor and then turns the firmware feature check into a run-time option. The new cell oprofile support that was recently merged does not work on hypervisor based platforms like the PS3, therefore make it depend on PPC_CELL_NATIVE instead of PPC_CELL. This may change if we get oprofile support for PS3. Signed-off-by: Arnd Bergmann --- arch/powerpc/Kconfig | 26 +++++++++++++++++++++----- arch/powerpc/mm/Makefile | 2 +- arch/powerpc/oprofile/Makefile | 2 +- arch/powerpc/oprofile/common.c | 2 +- arch/powerpc/platforms/ps3/mm.c | 4 ++++ arch/powerpc/platforms/ps3/setup.c | 2 +- 6 files changed, 29 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c0146a40c6f..c04b7138e1a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -390,6 +390,7 @@ config PPC_PSERIES select PPC_RTAS select RTAS_ERROR_LOGGING select PPC_UDBG_16550 + select PPC_NATIVE default y config PPC_ISERIES @@ -406,6 +407,7 @@ config PPC_CHRP select PPC_RTAS select PPC_MPC106 select PPC_UDBG_16550 + select PPC_NATIVE default y config PPC_EFIKA @@ -414,6 +416,7 @@ config PPC_EFIKA select PPC_RTAS select RTAS_PROC select PPC_MPC52xx + select PPC_NATIVE default y config PPC_PMAC @@ -422,6 +425,7 @@ config PPC_PMAC select MPIC select PPC_INDIRECT_PCI if PPC32 select PPC_MPC106 if PPC32 + select PPC_NATIVE default y config PPC_PMAC64 @@ -441,6 +445,7 @@ config PPC_PREP select PPC_I8259 select PPC_INDIRECT_PCI select PPC_UDBG_16550 + select PPC_NATIVE default y config PPC_MAPLE @@ -452,6 +457,7 @@ config PPC_MAPLE select GENERIC_TBSYNC select PPC_UDBG_16550 select PPC_970_NAP + select PPC_NATIVE default n help This option enables support for the Maple 970FX Evaluation Board. @@ -464,6 +470,7 @@ config PPC_PASEMI select MPIC select PPC_UDBG_16550 select GENERIC_TBSYNC + select PPC_NATIVE help This option enables support for PA Semi's PWRficient line of SoC processors, including PA6T-1682M @@ -478,6 +485,7 @@ config PPC_CELL_NATIVE select PPC_DCR_MMIO select PPC_OF_PLATFORM_PCI select PPC_INDIRECT_IO + select PPC_NATIVE select MPIC default n @@ -490,11 +498,6 @@ config PPC_IBM_CELL_BLADE select PPC_UDBG_16550 select UDBG_RTAS_CONSOLE -config UDBG_RTAS_CONSOLE - bool "RTAS based debug console" - depends on PPC_RTAS - default n - config PPC_PS3 bool "Sony PS3" depends on PPC_MULTIPLATFORM && PPC64 @@ -503,6 +506,19 @@ config PPC_PS3 This option enables support for the Sony PS3 game console and other platforms using the PS3 hypervisor. +config PPC_NATIVE + bool + depends on PPC_MULTIPLATFORM + help + Support for running natively on the hardware, i.e. without + a hypervisor. This option is not user-selectable but should + be selected by all platforms that need it. + +config UDBG_RTAS_CONSOLE + bool "RTAS based debug console" + depends on PPC_RTAS + default n + config XICS depends on PPC_PSERIES bool diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 93441e7a292..38a81967ca0 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile @@ -8,7 +8,7 @@ endif obj-y := fault.o mem.o lmb.o obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o -hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o +hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \ hash_utils_64.o hash_low_64.o tlb_64.o \ slb_low.o slb.o stab.o mmap.o imalloc.o \ diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile index 51c510fed7f..4ccef2d5530 100644 --- a/arch/powerpc/oprofile/Makefile +++ b/arch/powerpc/oprofile/Makefile @@ -11,7 +11,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) oprofile-y := $(DRIVER_OBJS) common.o backtrace.o -oprofile-$(CONFIG_PPC_CELL) += op_model_cell.o +oprofile-$(CONFIG_PPC_CELL_NATIVE) += op_model_cell.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o oprofile-$(CONFIG_6xx) += op_model_7450.o diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c index 7a423437977..b6d82390b6a 100644 --- a/arch/powerpc/oprofile/common.c +++ b/arch/powerpc/oprofile/common.c @@ -147,7 +147,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) switch (cur_cpu_spec->oprofile_type) { #ifdef CONFIG_PPC64 -#ifdef CONFIG_PPC_CELL +#ifdef CONFIG_PPC_CELL_NATIVE case PPC_OPROFILE_CELL: model = &op_model_cell; break; diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index a57f7036dd1..49c0d010d49 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -293,6 +294,9 @@ static int __init ps3_mm_add_memory(void) unsigned long start_pfn; unsigned long nr_pages; + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return 0; + BUG_ON(!mem_init_done); start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index c1f6de50654..d8b5cadbe80 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -108,7 +108,7 @@ static int __init ps3_probe(void) if (!of_flat_dt_is_compatible(dt_root, "PS3")) return 0; - powerpc_firmware_features |= FW_FEATURE_LPAR; + powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; ps3_os_area_init(); ps3_mm_init(); -- cgit v1.2.3 From 4ec64d5686112e9c5a9f1eeeb0eeedd54fb07d69 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2006 19:18:58 +0100 Subject: [POWERPC] ps3: add a default zImage target It's currently not possible to build the default zImage target if PS3 is the only selected platform. This is a hack to fall back to building the pseries style zImage, so the build is successful. This will probably change in the future, if someone writes a PS3 specific boot wrapper. Signed-off-by: Arnd Bergmann --- arch/powerpc/boot/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 22e90168723..b320562c03b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -155,6 +155,7 @@ $(obj)/uImage: vmlinux $(wrapperbits) image-$(CONFIG_PPC_PSERIES) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.pseries image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries +image-$(CONFIG_PPC_PS3) += zImage.pseries image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac -- cgit v1.2.3 From 369cf4b940d0d92d33f39a2df11102f3e2df0e0a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 27 Nov 2006 19:18:59 +0100 Subject: [POWERPC] fix missing #include in sys_ppc32.c sys_mmap is declared in asm/syscalls.h Signed-off-by: Arnd Bergmann --- arch/powerpc/kernel/sys_ppc32.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index d15c33e9595..03a2a2f30d6 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c @@ -51,6 +51,7 @@ #include #include #include +#include /* readdir & getdents */ #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -- cgit v1.2.3 From a5715d6dfc85e002bfad68bb2858cf5a248e2060 Mon Sep 17 00:00:00 2001 From: Mohan Kumar M Date: Fri, 17 Nov 2006 17:42:24 +0530 Subject: [POWERPC] pSeries/kexec: Fix for interrupt distribution This allows any secondary CPU thread also to become boot cpu for POWER5. The patch is required to solve kdump boot issue when the kdump kernel is booted with parameter "maxcpus=1". XICS init code tries to match the current boot cpu id with "reg" property in each CPU node in the device tree. But CPU node is created only for primary thread CPU ids and "reg" property only reflects primary CPU ids. So when a kernel is booted on a secondary cpu thread above condition will never meet and the default distribution server is left as zero. This leads to route the interrupts to CPU 0, but which is not online at this time. We use ibm,ppc-interrupt-server#s to check for both primary and secondary CPU ids. Accordingly default distribution server value is initialized from "ibm,ppc-interrupt-gserver#s" property. We loop through ibm,ppc-interrupt-gserver#s property to find the global distribution server from the last entry that matches with boot cpuid. Signed-off-by: Mohan Kumar M Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/xics.c | 68 +++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index d071abe78ab..b5b2b1103de 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -656,13 +656,38 @@ static void __init xics_setup_8259_cascade(void) set_irq_chained_handler(cascade, pseries_8259_cascade); } +static struct device_node *cpuid_to_of_node(int cpu) +{ + struct device_node *np; + u32 hcpuid = get_hard_smp_processor_id(cpu); + + for_each_node_by_type(np, "cpu") { + int i, len; + const u32 *intserv; + + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + + if (!intserv) + intserv = get_property(np, "reg", &len); + + i = len / sizeof(u32); + + while (i--) + if (intserv[i] == hcpuid) + return np; + } + + return NULL; +} + void __init xics_init_IRQ(void) { - int i; + int i, j; struct device_node *np; u32 ilen, indx = 0; - const u32 *ireg; + const u32 *ireg, *isize; int found = 0; + u32 hcpuid; ppc64_boot_msg(0x20, "XICS Init"); @@ -683,26 +708,31 @@ void __init xics_init_IRQ(void) xics_init_host(); /* Find the server numbers for the boot cpu. */ - for (np = of_find_node_by_type(NULL, "cpu"); - np; - np = of_find_node_by_type(np, "cpu")) { - ireg = get_property(np, "reg", &ilen); - if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { - ireg = get_property(np, - "ibm,ppc-interrupt-gserver#s", &ilen); - i = ilen / sizeof(int); - if (ireg && i > 0) { - default_server = ireg[0]; - /* take last element */ - default_distrib_server = ireg[i-1]; - } - ireg = get_property(np, + np = cpuid_to_of_node(boot_cpuid); + BUG_ON(!np); + ireg = get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); + if (!ireg) + goto skip_gserver_check; + i = ilen / sizeof(int); + hcpuid = get_hard_smp_processor_id(boot_cpuid); + + /* Global interrupt distribution server is specified in the last + * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last + * entry fom this property for current boot cpu id and use it as + * default distribution server + */ + for (j = 0; j < i; j += 2) { + if (ireg[j] == hcpuid) { + default_server = hcpuid; + default_distrib_server = ireg[j+1]; + + isize = get_property(np, "ibm,interrupt-server#-size", NULL); - if (ireg) - interrupt_server_size = *ireg; - break; + if (isize) + interrupt_server_size = *isize; } } +skip_gserver_check: of_node_put(np); if (firmware_has_feature(FW_FEATURE_LPAR)) -- cgit v1.2.3 From 28f9ec349ae47c91768b7bc5607db4442c818e11 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Mon, 20 Nov 2006 16:32:39 +0300 Subject: [POWERPC] Add of_platform support for ROM devices This adds support for flash device descriptions to the OF device tree. It's inspired by and partially borrowed from Sergei's patch "[RFC] Adding MTD to device tree.patch". Signed-off-by: Vitaly Wool Signed-off-by: Sergei Shtylyov Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/rom.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 arch/powerpc/sysdev/rom.c (limited to 'arch') diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index bae874626fc..ee7c6d48af7 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ +obj-$(CONFIG_MTD) += rom.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c new file mode 100644 index 00000000000..bf5b3f10e6c --- /dev/null +++ b/arch/powerpc/sysdev/rom.c @@ -0,0 +1,31 @@ +/* + * ROM device registration + * + * (C) 2006 MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include + +static int __init powerpc_flash_init(void) +{ + struct device_node *node = NULL; + + /* + * Register all the devices which type is "rom" + */ + while ((node = of_find_node_by_type(node, "rom")) != NULL) { + if (node->name == NULL) { + printk(KERN_WARNING "powerpc_flash_init: found 'rom' " + "device, but with no name, skipping...\n"); + continue; + } + of_platform_device_create(node, node->name, NULL); + } + return 0; +} + +arch_initcall(powerpc_flash_init); -- cgit v1.2.3 From 06f2138e61d4f5dce82207236767e0759bbd45cc Mon Sep 17 00:00:00 2001 From: Rutger Nijlunsing Date: Sun, 26 Nov 2006 21:08:38 +0100 Subject: [POWERPC] Add files build to .gitignore Mostly taken from corresponding Makefile's make-clean rule. Tested by (cross)compiling for $ARCH PPC and POWERPC and checking output of git-status. Signed-off-by: Rutger Nijlunsing Signed-off-by: Paul Mackerras --- arch/powerpc/.gitignore | 1 + arch/powerpc/boot/.gitignore | 8 +++++++- arch/ppc/.gitignore | 1 + arch/ppc/boot/images/.gitignore | 6 ++++++ arch/ppc/boot/lib/.gitignore | 3 +++ arch/ppc/boot/utils/.gitignore | 3 +++ 6 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/.gitignore create mode 100644 arch/ppc/.gitignore create mode 100644 arch/ppc/boot/images/.gitignore create mode 100644 arch/ppc/boot/lib/.gitignore create mode 100644 arch/ppc/boot/utils/.gitignore (limited to 'arch') diff --git a/arch/powerpc/.gitignore b/arch/powerpc/.gitignore new file mode 100644 index 00000000000..a1a869c8c84 --- /dev/null +++ b/arch/powerpc/.gitignore @@ -0,0 +1 @@ +include diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore index 590e72f06d5..0734b2fc1d9 100644 --- a/arch/powerpc/boot/.gitignore +++ b/arch/powerpc/boot/.gitignore @@ -19,9 +19,15 @@ kernel-vmlinux.strip.gz mktree uImage zImage -zImage.vmode +zImage.chrp +zImage.coff zImage.coff.lds zImage.lds +zImage.miboot +zImage.pmac +zImage.pseries +zImage.sandpoint +zImage.vmode zconf.h zlib.h zutil.h diff --git a/arch/ppc/.gitignore b/arch/ppc/.gitignore new file mode 100644 index 00000000000..a1a869c8c84 --- /dev/null +++ b/arch/ppc/.gitignore @@ -0,0 +1 @@ +include diff --git a/arch/ppc/boot/images/.gitignore b/arch/ppc/boot/images/.gitignore new file mode 100644 index 00000000000..21c2dc5b6b7 --- /dev/null +++ b/arch/ppc/boot/images/.gitignore @@ -0,0 +1,6 @@ +sImage +vmapus +vmlinux* +miboot* +zImage* +uImage diff --git a/arch/ppc/boot/lib/.gitignore b/arch/ppc/boot/lib/.gitignore new file mode 100644 index 00000000000..1629a616775 --- /dev/null +++ b/arch/ppc/boot/lib/.gitignore @@ -0,0 +1,3 @@ +inffast.c +inflate.c +inftrees.c diff --git a/arch/ppc/boot/utils/.gitignore b/arch/ppc/boot/utils/.gitignore new file mode 100644 index 00000000000..bbdfb3b9c53 --- /dev/null +++ b/arch/ppc/boot/utils/.gitignore @@ -0,0 +1,3 @@ +mkprep +mkbugboot +mktree -- cgit v1.2.3 From c705677e1c69012adea3bc51b54e9c7170d1cbee Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 27 Nov 2006 14:59:50 +1100 Subject: [POWERPC] iSeries: Eliminate "exceeds stub group size" warnings Commit 3ccfc65c5004e5fe5cfbffe43b8acc686680b53e missed the same fixes for legacy iSeries specific code, so make some more symbols no longer global. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/entry_64.S | 4 +++- arch/powerpc/kernel/head_64.S | 10 ++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index ec754c92ba9..1a3d4de197d 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S @@ -97,7 +97,9 @@ BEGIN_FW_FTR_SECTION cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ andi. r10,r12,MSR_PR /* from kernel */ crand 4*cr0+eq,4*cr1+eq,4*cr0+eq - beq hardware_interrupt_entry + bne 2f + b hardware_interrupt_entry +2: END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) #endif mfmsr r11 diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 8cdff5a1f3e..71b1fe58e9e 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -825,7 +825,7 @@ system_reset_iSeries: cmpwi 0,r23,0 beq iSeries_secondary_smp_loop /* Loop until told to go */ - bne .__secondary_start /* Loop until told to go */ + bne __secondary_start /* Loop until told to go */ iSeries_secondary_smp_loop: /* Let the Hypervisor know we are alive */ /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ @@ -846,7 +846,6 @@ iSeries_secondary_smp_loop: b 1b /* If SMP not configured, secondaries * loop forever */ - .globl decrementer_iSeries_masked decrementer_iSeries_masked: /* We may not have a valid TOC pointer in here. */ li r11,1 @@ -857,7 +856,6 @@ decrementer_iSeries_masked: mtspr SPRN_DEC,r12 /* fall through */ - .globl hardware_interrupt_iSeries_masked hardware_interrupt_iSeries_masked: mtcrf 0x80,r9 /* Restore regs */ ld r12,PACALPPACAPTR(r13) @@ -1604,7 +1602,7 @@ _GLOBAL(generic_secondary_smp_init) ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD - b .__secondary_start + b __secondary_start #endif #ifdef CONFIG_PPC_ISERIES @@ -1873,7 +1871,7 @@ _GLOBAL(pmac_secondary_start) ld r1,PACAEMERGSP(r13) subi r1,r1,STACK_FRAME_OVERHEAD - b .__secondary_start + b __secondary_start #endif /* CONFIG_PPC_PMAC */ @@ -1890,7 +1888,7 @@ _GLOBAL(pmac_secondary_start) * r13 = paca virtual address * SPRG3 = paca virtual address */ -_GLOBAL(__secondary_start) +__secondary_start: /* Set thread priority to MEDIUM */ HMT_MEDIUM -- cgit v1.2.3 From f5b2eb026949e7c3988074529854609921675cff Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 27 Nov 2006 17:17:02 +1100 Subject: [POWERPC] iSeries: allow CONFIG_CMDLINE It doesn't hurt to have this enabled on legacy iSeries and will mean it is available for a combined build. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c04b7138e1a..836caf1e943 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -852,7 +852,6 @@ source "arch/powerpc/platforms/prep/Kconfig" config CMDLINE_BOOL bool "Default bootloader kernel arguments" - depends on !PPC_ISERIES config CMDLINE string "Initial kernel command string" -- cgit v1.2.3 From 39d074b2e4b89c914c00dfd9987672e2dea92f19 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:23 -0700 Subject: [POWERPC] Move MPC52xx PIC driver into arch/powerpc/platforms/52xx No other chips use this device, it belongs in a 52xx-specific path. Signed-off-by: Grant Likely Signed-off-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/52xx/Makefile | 6 + arch/powerpc/platforms/52xx/mpc52xx_pic.c | 538 ++++++++++++++++++++++++++++++ arch/powerpc/platforms/Makefile | 1 + arch/powerpc/sysdev/Makefile | 1 - arch/powerpc/sysdev/mpc52xx_pic.c | 538 ------------------------------ 5 files changed, 545 insertions(+), 539 deletions(-) create mode 100644 arch/powerpc/platforms/52xx/Makefile create mode 100644 arch/powerpc/platforms/52xx/mpc52xx_pic.c delete mode 100644 arch/powerpc/sysdev/mpc52xx_pic.c (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile new file mode 100644 index 00000000000..e1b02f1a189 --- /dev/null +++ b/arch/powerpc/platforms/52xx/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for 52xx based boards +# +ifeq ($(CONFIG_PPC_MERGE),y) +obj-y += mpc52xx_pic.o +endif diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c new file mode 100644 index 00000000000..6df51f04b8f --- /dev/null +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -0,0 +1,538 @@ +/* + * + * Programmable Interrupt Controller functions for the Freescale MPC52xx. + * + * Copyright (C) 2006 bplan GmbH + * + * Based on the code from the 2.4 kernel by + * Dale Farnsworth and Kent Borg. + * + * Copyright (C) 2004 Sylvain Munaut + * Copyright (C) 2003 Montavista Software, Inc + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* + * +*/ + +static struct mpc52xx_intr __iomem *intr; +static struct mpc52xx_sdma __iomem *sdma; +static struct irq_host *mpc52xx_irqhost = NULL; + +static unsigned char mpc52xx_map_senses[4] = { + IRQ_TYPE_LEVEL_HIGH, + IRQ_TYPE_EDGE_RISING, + IRQ_TYPE_EDGE_FALLING, + IRQ_TYPE_LEVEL_LOW, +}; + +/* + * +*/ + +static inline void io_be_setbit(u32 __iomem * addr, int bitno) +{ + out_be32(addr, in_be32(addr) | (1 << bitno)); +} + +static inline void io_be_clrbit(u32 __iomem * addr, int bitno) +{ + out_be32(addr, in_be32(addr) & ~(1 << bitno)); +} + +/* + * IRQ[0-3] interrupt irq_chip +*/ + +static void mpc52xx_extirq_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->ctrl, 11 - l2irq); +} + +static void mpc52xx_extirq_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->ctrl, 11 - l2irq); +} + +static void mpc52xx_extirq_ack(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->ctrl, 27 - l2irq); +} + +static struct irq_chip mpc52xx_extirq_irqchip = { + .typename = " MPC52xx IRQ[0-3] ", + .mask = mpc52xx_extirq_mask, + .unmask = mpc52xx_extirq_unmask, + .ack = mpc52xx_extirq_ack, +}; + +/* + * Main interrupt irq_chip +*/ + +static void mpc52xx_main_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->main_mask, 15 - l2irq); +} + +static void mpc52xx_main_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->main_mask, 15 - l2irq); +} + +static struct irq_chip mpc52xx_main_irqchip = { + .typename = "MPC52xx Main", + .mask = mpc52xx_main_mask, + .mask_ack = mpc52xx_main_mask, + .unmask = mpc52xx_main_unmask, +}; + +/* + * Peripherals interrupt irq_chip +*/ + +static void mpc52xx_periph_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&intr->per_mask, 31 - l2irq); +} + +static void mpc52xx_periph_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&intr->per_mask, 31 - l2irq); +} + +static struct irq_chip mpc52xx_periph_irqchip = { + .typename = "MPC52xx Peripherals", + .mask = mpc52xx_periph_mask, + .mask_ack = mpc52xx_periph_mask, + .unmask = mpc52xx_periph_unmask, +}; + +/* + * SDMA interrupt irq_chip +*/ + +static void mpc52xx_sdma_mask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_setbit(&sdma->IntMask, l2irq); +} + +static void mpc52xx_sdma_unmask(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + io_be_clrbit(&sdma->IntMask, l2irq); +} + +static void mpc52xx_sdma_ack(unsigned int virq) +{ + int irq; + int l2irq; + + irq = irq_map[virq].hwirq; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); + + out_be32(&sdma->IntPend, 1 << l2irq); +} + +static struct irq_chip mpc52xx_sdma_irqchip = { + .typename = "MPC52xx SDMA", + .mask = mpc52xx_sdma_mask, + .unmask = mpc52xx_sdma_unmask, + .ack = mpc52xx_sdma_ack, +}; + +/* + * irq_host +*/ + +static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node) +{ + pr_debug("%s: node=%p\n", __func__, node); + return mpc52xx_irqhost->host_data == node; +} + +static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, + u32 * intspec, unsigned int intsize, + irq_hw_number_t * out_hwirq, + unsigned int *out_flags) +{ + int intrvect_l1; + int intrvect_l2; + int intrvect_type; + int intrvect_linux; + + if (intsize != 3) + return -1; + + intrvect_l1 = (int)intspec[0]; + intrvect_l2 = (int)intspec[1]; + intrvect_type = (int)intspec[2]; + + intrvect_linux = + (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; + intrvect_linux |= + (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK; + + pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1, + intrvect_l2); + + *out_hwirq = intrvect_linux; + *out_flags = mpc52xx_map_senses[intrvect_type]; + + return 0; +} + +/* + * this function retrieves the correct IRQ type out + * of the MPC regs + * Only externals IRQs needs this +*/ +static int mpc52xx_irqx_gettype(int irq) +{ + int type; + u32 ctrl_reg; + + ctrl_reg = in_be32(&intr->ctrl); + type = (ctrl_reg >> (22 - irq * 2)) & 0x3; + + return mpc52xx_map_senses[type]; +} + +static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, + irq_hw_number_t irq) +{ + int l1irq; + int l2irq; + struct irq_chip *good_irqchip; + void *good_handle; + int type; + + l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET; + l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; + + /* + * Most of ours IRQs will be level low + * Only external IRQs on some platform may be others + */ + type = IRQ_TYPE_LEVEL_LOW; + + switch (l1irq) { + case MPC52xx_IRQ_L1_CRIT: + pr_debug("%s: Critical. l2=%x\n", __func__, l2irq); + + BUG_ON(l2irq != 0); + + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + break; + + case MPC52xx_IRQ_L1_MAIN: + pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq); + + if ((l2irq >= 1) && (l2irq <= 3)) { + type = mpc52xx_irqx_gettype(l2irq); + good_irqchip = &mpc52xx_extirq_irqchip; + } else { + good_irqchip = &mpc52xx_main_irqchip; + } + break; + + case MPC52xx_IRQ_L1_PERP: + pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_periph_irqchip; + break; + + case MPC52xx_IRQ_L1_SDMA: + pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq); + good_irqchip = &mpc52xx_sdma_irqchip; + break; + + default: + pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq); + printk(KERN_ERR "Unknow IRQ!\n"); + return -EINVAL; + } + + switch (type) { + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_EDGE_RISING: + good_handle = handle_edge_irq; + break; + default: + good_handle = handle_level_irq; + } + + set_irq_chip_and_handler(virq, good_irqchip, good_handle); + + pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq, + (int)irq, type); + + return 0; +} + +static struct irq_host_ops mpc52xx_irqhost_ops = { + .match = mpc52xx_irqhost_match, + .xlate = mpc52xx_irqhost_xlate, + .map = mpc52xx_irqhost_map, +}; + +/* + * init (public) +*/ + +void __init mpc52xx_init_irq(void) +{ + struct device_node *picnode = NULL; + int picnode_regsize; + u32 picnode_regoffset; + + struct device_node *sdmanode = NULL; + int sdmanode_regsize; + u32 sdmanode_regoffset; + + u64 size64; + int flags; + + u32 intr_ctrl; + + picnode = of_find_compatible_node(NULL, "interrupt-controller", + "mpc5200-pic"); + if (picnode == NULL) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to find the interrupt controller " + "in the OpenFirmware device tree\n"); + goto end; + } + + sdmanode = of_find_compatible_node(NULL, "dma-controller", + "mpc5200-bestcomm"); + if (sdmanode == NULL) { + printk(KERN_ERR "MPC52xx PIC" + "Unable to find the Bestcomm DMA controller device " + "in the OpenFirmware device tree\n"); + goto end; + } + + /* Retrieve PIC ressources */ + picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags); + if (picnode_regoffset == 0) { + printk(KERN_ERR "MPC52xx PIC" + "Unable to get the interrupt controller address\n"); + goto end; + } + + picnode_regoffset = + of_translate_address(picnode, (u32 *) picnode_regoffset); + picnode_regsize = (int)size64; + + /* Retrieve SDMA ressources */ + sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags); + if (sdmanode_regoffset == 0) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to get the Bestcomm DMA controller address\n"); + goto end; + } + + sdmanode_regoffset = + of_translate_address(sdmanode, (u32 *) sdmanode_regoffset); + sdmanode_regsize = (int)size64; + + /* Remap the necessary zones */ + intr = ioremap(picnode_regoffset, picnode_regsize); + if (intr == NULL) { + printk(KERN_ERR "MPC52xx PIC: " + "Unable to ioremap interrupt controller registers!\n"); + goto end; + } + + sdma = ioremap(sdmanode_regoffset, sdmanode_regsize); + if (sdma == NULL) { + iounmap(intr); + printk(KERN_ERR "MPC52xx PIC: " + "Unable to ioremap Bestcomm DMA registers!\n"); + goto end; + } + + printk(KERN_INFO "MPC52xx PIC: MPC52xx PIC Remapped at 0x%8.8x\n", + picnode_regoffset); + printk(KERN_INFO "MPC52xx PIC: MPC52xx SDMA Remapped at 0x%8.8x\n", + sdmanode_regoffset); + + /* Disable all interrupt sources. */ + out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ + out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ + out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */ + out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */ + intr_ctrl = in_be32(&intr->ctrl); + intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */ + intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */ + 0x00001000 | /* MEE master external enable */ + 0x00000000 | /* 0 means disable IRQ 0-3 */ + 0x00000001; /* CEb route critical normally */ + out_be32(&intr->ctrl, intr_ctrl); + + /* Zero a bunch of the priority settings. */ + out_be32(&intr->per_pri1, 0); + out_be32(&intr->per_pri2, 0); + out_be32(&intr->per_pri3, 0); + out_be32(&intr->main_pri1, 0); + out_be32(&intr->main_pri2, 0); + + /* + * As last step, add an irq host to translate the real + * hw irq information provided by the ofw to linux virq + */ + + mpc52xx_irqhost = + irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTHWIRQ, + &mpc52xx_irqhost_ops, -1); + + if (mpc52xx_irqhost) { + mpc52xx_irqhost->host_data = picnode; + printk(KERN_INFO "MPC52xx PIC is up and running!\n"); + } else { + printk(KERN_ERR + "MPC52xx PIC: Unable to allocate the IRQ host\n"); + } + +end: + of_node_put(picnode); + of_node_put(sdmanode); +} + +/* + * get_irq (public) +*/ +unsigned int mpc52xx_get_irq(void) +{ + u32 status; + int irq = NO_IRQ_IGNORE; + + status = in_be32(&intr->enc_status); + if (status & 0x00000400) { /* critical */ + irq = (status >> 8) & 0x3; + if (irq == 2) /* high priority peripheral */ + goto peripheral; + irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else if (status & 0x00200000) { /* main */ + irq = (status >> 16) & 0x1f; + if (irq == 4) /* low priority peripheral */ + goto peripheral; + irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else if (status & 0x20000000) { /* peripheral */ + peripheral: + irq = (status >> 24) & 0x1f; + if (irq == 0) { /* bestcomm */ + status = in_be32(&sdma->IntPend); + irq = ffs(status) - 1; + irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } else + irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) & + MPC52xx_IRQ_L1_MASK; + } + + pr_debug("%s: irq=%x. virq=%d\n", __func__, irq, + irq_linear_revmap(mpc52xx_irqhost, irq)); + + return irq_linear_revmap(mpc52xx_irqhost, irq); +} + diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 52984a803e7..468c5fdde93 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -8,6 +8,7 @@ endif obj-$(CONFIG_PPC_EFIKA) += efika/ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ +obj-$(CONFIG_PPC_MPC52xx) += 52xx/ obj-$(CONFIG_PPC_83xx) += 83xx/ obj-$(CONFIG_PPC_85xx) += 85xx/ obj-$(CONFIG_PPC_86xx) += 86xx/ diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index ee7c6d48af7..6cc34597a62 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_MTD) += rom.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_83xx) += ipic.o -obj-$(CONFIG_PPC_MPC52xx) += mpc52xx_pic.o endif # Temporary hack until we have migrated to asm-powerpc diff --git a/arch/powerpc/sysdev/mpc52xx_pic.c b/arch/powerpc/sysdev/mpc52xx_pic.c deleted file mode 100644 index 6df51f04b8f..00000000000 --- a/arch/powerpc/sysdev/mpc52xx_pic.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * - * Programmable Interrupt Controller functions for the Freescale MPC52xx. - * - * Copyright (C) 2006 bplan GmbH - * - * Based on the code from the 2.4 kernel by - * Dale Farnsworth and Kent Borg. - * - * Copyright (C) 2004 Sylvain Munaut - * Copyright (C) 2003 Montavista Software, Inc - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -/* - * -*/ - -static struct mpc52xx_intr __iomem *intr; -static struct mpc52xx_sdma __iomem *sdma; -static struct irq_host *mpc52xx_irqhost = NULL; - -static unsigned char mpc52xx_map_senses[4] = { - IRQ_TYPE_LEVEL_HIGH, - IRQ_TYPE_EDGE_RISING, - IRQ_TYPE_EDGE_FALLING, - IRQ_TYPE_LEVEL_LOW, -}; - -/* - * -*/ - -static inline void io_be_setbit(u32 __iomem * addr, int bitno) -{ - out_be32(addr, in_be32(addr) | (1 << bitno)); -} - -static inline void io_be_clrbit(u32 __iomem * addr, int bitno) -{ - out_be32(addr, in_be32(addr) & ~(1 << bitno)); -} - -/* - * IRQ[0-3] interrupt irq_chip -*/ - -static void mpc52xx_extirq_mask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_clrbit(&intr->ctrl, 11 - l2irq); -} - -static void mpc52xx_extirq_unmask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_setbit(&intr->ctrl, 11 - l2irq); -} - -static void mpc52xx_extirq_ack(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_setbit(&intr->ctrl, 27 - l2irq); -} - -static struct irq_chip mpc52xx_extirq_irqchip = { - .typename = " MPC52xx IRQ[0-3] ", - .mask = mpc52xx_extirq_mask, - .unmask = mpc52xx_extirq_unmask, - .ack = mpc52xx_extirq_ack, -}; - -/* - * Main interrupt irq_chip -*/ - -static void mpc52xx_main_mask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_setbit(&intr->main_mask, 15 - l2irq); -} - -static void mpc52xx_main_unmask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_clrbit(&intr->main_mask, 15 - l2irq); -} - -static struct irq_chip mpc52xx_main_irqchip = { - .typename = "MPC52xx Main", - .mask = mpc52xx_main_mask, - .mask_ack = mpc52xx_main_mask, - .unmask = mpc52xx_main_unmask, -}; - -/* - * Peripherals interrupt irq_chip -*/ - -static void mpc52xx_periph_mask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_setbit(&intr->per_mask, 31 - l2irq); -} - -static void mpc52xx_periph_unmask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_clrbit(&intr->per_mask, 31 - l2irq); -} - -static struct irq_chip mpc52xx_periph_irqchip = { - .typename = "MPC52xx Peripherals", - .mask = mpc52xx_periph_mask, - .mask_ack = mpc52xx_periph_mask, - .unmask = mpc52xx_periph_unmask, -}; - -/* - * SDMA interrupt irq_chip -*/ - -static void mpc52xx_sdma_mask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_setbit(&sdma->IntMask, l2irq); -} - -static void mpc52xx_sdma_unmask(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - io_be_clrbit(&sdma->IntMask, l2irq); -} - -static void mpc52xx_sdma_ack(unsigned int virq) -{ - int irq; - int l2irq; - - irq = irq_map[virq].hwirq; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - - out_be32(&sdma->IntPend, 1 << l2irq); -} - -static struct irq_chip mpc52xx_sdma_irqchip = { - .typename = "MPC52xx SDMA", - .mask = mpc52xx_sdma_mask, - .unmask = mpc52xx_sdma_unmask, - .ack = mpc52xx_sdma_ack, -}; - -/* - * irq_host -*/ - -static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node) -{ - pr_debug("%s: node=%p\n", __func__, node); - return mpc52xx_irqhost->host_data == node; -} - -static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct, - u32 * intspec, unsigned int intsize, - irq_hw_number_t * out_hwirq, - unsigned int *out_flags) -{ - int intrvect_l1; - int intrvect_l2; - int intrvect_type; - int intrvect_linux; - - if (intsize != 3) - return -1; - - intrvect_l1 = (int)intspec[0]; - intrvect_l2 = (int)intspec[1]; - intrvect_type = (int)intspec[2]; - - intrvect_linux = - (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; - intrvect_linux |= - (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK; - - pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1, - intrvect_l2); - - *out_hwirq = intrvect_linux; - *out_flags = mpc52xx_map_senses[intrvect_type]; - - return 0; -} - -/* - * this function retrieves the correct IRQ type out - * of the MPC regs - * Only externals IRQs needs this -*/ -static int mpc52xx_irqx_gettype(int irq) -{ - int type; - u32 ctrl_reg; - - ctrl_reg = in_be32(&intr->ctrl); - type = (ctrl_reg >> (22 - irq * 2)) & 0x3; - - return mpc52xx_map_senses[type]; -} - -static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t irq) -{ - int l1irq; - int l2irq; - struct irq_chip *good_irqchip; - void *good_handle; - int type; - - l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET; - l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET; - - /* - * Most of ours IRQs will be level low - * Only external IRQs on some platform may be others - */ - type = IRQ_TYPE_LEVEL_LOW; - - switch (l1irq) { - case MPC52xx_IRQ_L1_CRIT: - pr_debug("%s: Critical. l2=%x\n", __func__, l2irq); - - BUG_ON(l2irq != 0); - - type = mpc52xx_irqx_gettype(l2irq); - good_irqchip = &mpc52xx_extirq_irqchip; - break; - - case MPC52xx_IRQ_L1_MAIN: - pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq); - - if ((l2irq >= 1) && (l2irq <= 3)) { - type = mpc52xx_irqx_gettype(l2irq); - good_irqchip = &mpc52xx_extirq_irqchip; - } else { - good_irqchip = &mpc52xx_main_irqchip; - } - break; - - case MPC52xx_IRQ_L1_PERP: - pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq); - good_irqchip = &mpc52xx_periph_irqchip; - break; - - case MPC52xx_IRQ_L1_SDMA: - pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq); - good_irqchip = &mpc52xx_sdma_irqchip; - break; - - default: - pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq); - printk(KERN_ERR "Unknow IRQ!\n"); - return -EINVAL; - } - - switch (type) { - case IRQ_TYPE_EDGE_FALLING: - case IRQ_TYPE_EDGE_RISING: - good_handle = handle_edge_irq; - break; - default: - good_handle = handle_level_irq; - } - - set_irq_chip_and_handler(virq, good_irqchip, good_handle); - - pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq, - (int)irq, type); - - return 0; -} - -static struct irq_host_ops mpc52xx_irqhost_ops = { - .match = mpc52xx_irqhost_match, - .xlate = mpc52xx_irqhost_xlate, - .map = mpc52xx_irqhost_map, -}; - -/* - * init (public) -*/ - -void __init mpc52xx_init_irq(void) -{ - struct device_node *picnode = NULL; - int picnode_regsize; - u32 picnode_regoffset; - - struct device_node *sdmanode = NULL; - int sdmanode_regsize; - u32 sdmanode_regoffset; - - u64 size64; - int flags; - - u32 intr_ctrl; - - picnode = of_find_compatible_node(NULL, "interrupt-controller", - "mpc5200-pic"); - if (picnode == NULL) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to find the interrupt controller " - "in the OpenFirmware device tree\n"); - goto end; - } - - sdmanode = of_find_compatible_node(NULL, "dma-controller", - "mpc5200-bestcomm"); - if (sdmanode == NULL) { - printk(KERN_ERR "MPC52xx PIC" - "Unable to find the Bestcomm DMA controller device " - "in the OpenFirmware device tree\n"); - goto end; - } - - /* Retrieve PIC ressources */ - picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags); - if (picnode_regoffset == 0) { - printk(KERN_ERR "MPC52xx PIC" - "Unable to get the interrupt controller address\n"); - goto end; - } - - picnode_regoffset = - of_translate_address(picnode, (u32 *) picnode_regoffset); - picnode_regsize = (int)size64; - - /* Retrieve SDMA ressources */ - sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags); - if (sdmanode_regoffset == 0) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to get the Bestcomm DMA controller address\n"); - goto end; - } - - sdmanode_regoffset = - of_translate_address(sdmanode, (u32 *) sdmanode_regoffset); - sdmanode_regsize = (int)size64; - - /* Remap the necessary zones */ - intr = ioremap(picnode_regoffset, picnode_regsize); - if (intr == NULL) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to ioremap interrupt controller registers!\n"); - goto end; - } - - sdma = ioremap(sdmanode_regoffset, sdmanode_regsize); - if (sdma == NULL) { - iounmap(intr); - printk(KERN_ERR "MPC52xx PIC: " - "Unable to ioremap Bestcomm DMA registers!\n"); - goto end; - } - - printk(KERN_INFO "MPC52xx PIC: MPC52xx PIC Remapped at 0x%8.8x\n", - picnode_regoffset); - printk(KERN_INFO "MPC52xx PIC: MPC52xx SDMA Remapped at 0x%8.8x\n", - sdmanode_regoffset); - - /* Disable all interrupt sources. */ - out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ - out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */ - out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */ - out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */ - intr_ctrl = in_be32(&intr->ctrl); - intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */ - intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */ - 0x00001000 | /* MEE master external enable */ - 0x00000000 | /* 0 means disable IRQ 0-3 */ - 0x00000001; /* CEb route critical normally */ - out_be32(&intr->ctrl, intr_ctrl); - - /* Zero a bunch of the priority settings. */ - out_be32(&intr->per_pri1, 0); - out_be32(&intr->per_pri2, 0); - out_be32(&intr->per_pri3, 0); - out_be32(&intr->main_pri1, 0); - out_be32(&intr->main_pri2, 0); - - /* - * As last step, add an irq host to translate the real - * hw irq information provided by the ofw to linux virq - */ - - mpc52xx_irqhost = - irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTHWIRQ, - &mpc52xx_irqhost_ops, -1); - - if (mpc52xx_irqhost) { - mpc52xx_irqhost->host_data = picnode; - printk(KERN_INFO "MPC52xx PIC is up and running!\n"); - } else { - printk(KERN_ERR - "MPC52xx PIC: Unable to allocate the IRQ host\n"); - } - -end: - of_node_put(picnode); - of_node_put(sdmanode); -} - -/* - * get_irq (public) -*/ -unsigned int mpc52xx_get_irq(void) -{ - u32 status; - int irq = NO_IRQ_IGNORE; - - status = in_be32(&intr->enc_status); - if (status & 0x00000400) { /* critical */ - irq = (status >> 8) & 0x3; - if (irq == 2) /* high priority peripheral */ - goto peripheral; - irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) & - MPC52xx_IRQ_L1_MASK; - } else if (status & 0x00200000) { /* main */ - irq = (status >> 16) & 0x1f; - if (irq == 4) /* low priority peripheral */ - goto peripheral; - irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) & - MPC52xx_IRQ_L1_MASK; - } else if (status & 0x20000000) { /* peripheral */ - peripheral: - irq = (status >> 24) & 0x1f; - if (irq == 0) { /* bestcomm */ - status = in_be32(&sdma->IntPend); - irq = ffs(status) - 1; - irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) & - MPC52xx_IRQ_L1_MASK; - } else - irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) & - MPC52xx_IRQ_L1_MASK; - } - - pr_debug("%s: irq=%x. virq=%d\n", __func__, irq, - irq_linear_revmap(mpc52xx_irqhost, irq)); - - return irq_linear_revmap(mpc52xx_irqhost, irq); -} - -- cgit v1.2.3 From d4150248fc769c7a69c61cb9d95dfac14950d8cf Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:24 -0700 Subject: [POWERPC] Put mpc52xx support file in platforms/52xx platforms/embedded6xx is probably going away, and 52xx boards need some extra support the 52xx interrupt controller and DMA engine anyway. It makes sense to group all the 52xx bits into a single path. Signed-off-by: Grant Likely Signed-off-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 4 ++++ arch/powerpc/platforms/embedded6xx/Kconfig | 12 ------------ 2 files changed, 4 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 836caf1e943..a6bc221ad1b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -410,6 +410,10 @@ config PPC_CHRP select PPC_NATIVE default y +config PPC_MPC52xx + bool + default n + config PPC_EFIKA bool "bPlan Efika 5k2. MPC5200B based computer" depends on PPC_MULTIPLATFORM && PPC32 diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 234a861870a..910d50a8333 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -146,15 +146,6 @@ config PQ2FADS Select PQ2FADS if you wish to configure for a Freescale PQ2FADS board (-VR or -ZU). -config LITE5200 - bool "Freescale LITE5200 / (IceCube)" - select PPC_MPC52xx - help - Support for the LITE5200 dev board for the MPC5200 from Freescale. - This is for the LITE5200 version 2.0 board. Don't know if it changes - much but it's only been tested on this board version. I think this - board is also known as IceCube. - config EV64360 bool "Marvell-EV64360BP" help @@ -172,9 +163,6 @@ config TQM8xxL depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L) default y -config PPC_MPC52xx - bool - config 8260 bool "CPM2 Support" if WILLOW depends on 6xx -- cgit v1.2.3 From b9cf5d8e2edc503977be090eff45ef81555dcb1d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:25 -0700 Subject: [POWERPC] Move Efika support files into platforms/52xx The Efika board isn't different enough from other 52xx based boards to justify a separate platform. This patch merges it with the support code for all other 52xx based boards. Signed-off-by: Grant Likely Acked-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/52xx/Makefile | 2 + arch/powerpc/platforms/52xx/efika-pci.c | 119 ++++++++++++++++++++++++ arch/powerpc/platforms/52xx/efika-setup.c | 150 ++++++++++++++++++++++++++++++ arch/powerpc/platforms/52xx/efika.h | 19 ++++ arch/powerpc/platforms/Makefile | 1 - arch/powerpc/platforms/efika/Makefile | 1 - arch/powerpc/platforms/efika/efika.h | 19 ---- arch/powerpc/platforms/efika/pci.c | 119 ------------------------ arch/powerpc/platforms/efika/setup.c | 150 ------------------------------ 9 files changed, 290 insertions(+), 290 deletions(-) create mode 100644 arch/powerpc/platforms/52xx/efika-pci.c create mode 100644 arch/powerpc/platforms/52xx/efika-setup.c create mode 100644 arch/powerpc/platforms/52xx/efika.h delete mode 100644 arch/powerpc/platforms/efika/Makefile delete mode 100644 arch/powerpc/platforms/efika/efika.h delete mode 100644 arch/powerpc/platforms/efika/pci.c delete mode 100644 arch/powerpc/platforms/efika/setup.c (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index e1b02f1a189..1c9c122123d 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile @@ -4,3 +4,5 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y += mpc52xx_pic.o endif + +obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o diff --git a/arch/powerpc/platforms/52xx/efika-pci.c b/arch/powerpc/platforms/52xx/efika-pci.c new file mode 100644 index 00000000000..62e05b2a922 --- /dev/null +++ b/arch/powerpc/platforms/52xx/efika-pci.c @@ -0,0 +1,119 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "efika.h" + +#ifdef CONFIG_PCI +/* + * Access functions for PCI config space using RTAS calls. + */ +static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 * val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int ret = -1; + int rval; + + rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); + *val = ret; + return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static int rtas_write_config(struct pci_bus *bus, unsigned int devfn, + int offset, int len, u32 val) +{ + struct pci_controller *hose = bus->sysdata; + unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) + | (((bus->number - hose->first_busno) & 0xff) << 16) + | (hose->index << 24); + int rval; + + rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, + addr, len, val); + return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops rtas_pci_ops = { + rtas_read_config, + rtas_write_config +}; + +void __init efika_pcisetup(void) +{ + const int *bus_range; + int len; + struct pci_controller *hose; + struct device_node *root; + struct device_node *pcictrl; + + root = of_find_node_by_path("/"); + if (root == NULL) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Unable to find the root node\n"); + return; + } + + for (pcictrl = NULL;;) { + pcictrl = of_get_next_child(root, pcictrl); + if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) + break; + } + + of_node_put(root); + + if (pcictrl == NULL) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Unable to find the PCI bridge node\n"); + return; + } + + bus_range = get_property(pcictrl, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Can't get bus-range for %s\n", pcictrl->full_name); + return; + } + + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", + bus_range[0]); + else + printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s\n", pcictrl->full_name); + printk("\n"); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk(KERN_WARNING EFIKA_PLATFORM_NAME + ": Can't allocate PCI controller structure for %s\n", + pcictrl->full_name); + return; + } + + hose->arch_data = of_node_get(pcictrl); + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + hose->ops = &rtas_pci_ops; + + pci_process_bridge_OF_ranges(hose, pcictrl, 0); +} + +#else +void __init efika_pcisetup(void) +{} +#endif diff --git a/arch/powerpc/platforms/52xx/efika-setup.c b/arch/powerpc/platforms/52xx/efika-setup.c new file mode 100644 index 00000000000..110c980ed1e --- /dev/null +++ b/arch/powerpc/platforms/52xx/efika-setup.c @@ -0,0 +1,150 @@ +/* + * + * Efika 5K2 platform setup + * Some code really inspired from the lite5200b platform. + * + * Copyright (C) 2006 bplan GmbH + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "efika.h" + +static void efika_show_cpuinfo(struct seq_file *m) +{ + struct device_node *root; + const char *revision = NULL; + const char *codegendescription = NULL; + const char *codegenvendor = NULL; + + root = of_find_node_by_path("/"); + if (root) { + revision = get_property(root, "revision", NULL); + codegendescription = + get_property(root, "CODEGEN,description", NULL); + codegenvendor = get_property(root, "CODEGEN,vendor", NULL); + + of_node_put(root); + } + + if (codegendescription) + seq_printf(m, "machine\t\t: %s\n", codegendescription); + else + seq_printf(m, "machine\t\t: Efika\n"); + + if (revision) + seq_printf(m, "revision\t: %s\n", revision); + + if (codegenvendor) + seq_printf(m, "vendor\t\t: %s\n", codegenvendor); + + of_node_put(root); +} + +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(); + + if (ppc_md.progress) + ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0); +} + +static void __init efika_init(void) +{ + struct device_node *np; + struct device_node *cnp = NULL; + const u32 *base; + + /* Find every child of the SOC node and add it to of_platform */ + np = of_find_node_by_name(NULL, "builtin"); + if (np) { + char name[BUS_ID_SIZE]; + while ((cnp = of_get_next_child(np, cnp))) { + strcpy(name, cnp->name); + + base = get_property(cnp, "reg", NULL); + if (base == NULL) + continue; + + snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base); + of_platform_device_create(cnp, name, NULL); + + printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name); + } + } + + if (ppc_md.progress) + ppc_md.progress(" Have fun with your Efika! ", 0x7777); +} + +static int __init efika_probe(void) +{ + char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), + "model", NULL); + + if (model == NULL) + return 0; + if (strcmp(model, "EFIKA5K2")) + return 0; + + ISA_DMA_THRESHOLD = ~0L; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + return 1; +} + +define_machine(efika) +{ + .name = EFIKA_PLATFORM_NAME, + .probe = efika_probe, + .setup_arch = efika_setup_arch, + .init = efika_init, + .show_cpuinfo = efika_show_cpuinfo, + .init_IRQ = mpc52xx_init_irq, + .get_irq = mpc52xx_get_irq, + .restart = rtas_restart, + .power_off = rtas_power_off, + .halt = rtas_halt, + .set_rtc_time = rtas_set_rtc_time, + .get_rtc_time = rtas_get_rtc_time, + .progress = rtas_progress, + .get_boot_time = rtas_get_boot_time, + .calibrate_decr = generic_calibrate_decr, + .phys_mem_access_prot = pci_phys_mem_access_prot, +}; diff --git a/arch/powerpc/platforms/52xx/efika.h b/arch/powerpc/platforms/52xx/efika.h new file mode 100644 index 00000000000..2f060fd097d --- /dev/null +++ b/arch/powerpc/platforms/52xx/efika.h @@ -0,0 +1,19 @@ +/* + * Efika 5K2 platform setup - Header file + * + * Copyright (C) 2006 bplan GmbH + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#ifndef __ARCH_POWERPC_EFIKA__ +#define __ARCH_POWERPC_EFIKA__ + +#define EFIKA_PLATFORM_NAME "Efika" + +extern void __init efika_pcisetup(void); + +#endif diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index 468c5fdde93..44d95eaf22e 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile @@ -5,7 +5,6 @@ ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_PPC_PMAC) += powermac/ endif endif -obj-$(CONFIG_PPC_EFIKA) += efika/ obj-$(CONFIG_PPC_CHRP) += chrp/ obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_MPC52xx) += 52xx/ diff --git a/arch/powerpc/platforms/efika/Makefile b/arch/powerpc/platforms/efika/Makefile deleted file mode 100644 index 56d44044023..00000000000 --- a/arch/powerpc/platforms/efika/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y += setup.o pci.o diff --git a/arch/powerpc/platforms/efika/efika.h b/arch/powerpc/platforms/efika/efika.h deleted file mode 100644 index 2f060fd097d..00000000000 --- a/arch/powerpc/platforms/efika/efika.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Efika 5K2 platform setup - Header file - * - * Copyright (C) 2006 bplan GmbH - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#ifndef __ARCH_POWERPC_EFIKA__ -#define __ARCH_POWERPC_EFIKA__ - -#define EFIKA_PLATFORM_NAME "Efika" - -extern void __init efika_pcisetup(void); - -#endif diff --git a/arch/powerpc/platforms/efika/pci.c b/arch/powerpc/platforms/efika/pci.c deleted file mode 100644 index 62e05b2a922..00000000000 --- a/arch/powerpc/platforms/efika/pci.c +++ /dev/null @@ -1,119 +0,0 @@ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "efika.h" - -#ifdef CONFIG_PCI -/* - * Access functions for PCI config space using RTAS calls. - */ -static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset, - int len, u32 * val) -{ - struct pci_controller *hose = bus->sysdata; - unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) - | (((bus->number - hose->first_busno) & 0xff) << 16) - | (hose->index << 24); - int ret = -1; - int rval; - - rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len); - *val = ret; - return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -} - -static int rtas_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose = bus->sysdata; - unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8) - | (((bus->number - hose->first_busno) & 0xff) << 16) - | (hose->index << 24); - int rval; - - rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL, - addr, len, val); - return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops rtas_pci_ops = { - rtas_read_config, - rtas_write_config -}; - -void __init efika_pcisetup(void) -{ - const int *bus_range; - int len; - struct pci_controller *hose; - struct device_node *root; - struct device_node *pcictrl; - - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Unable to find the root node\n"); - return; - } - - for (pcictrl = NULL;;) { - pcictrl = of_get_next_child(root, pcictrl); - if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) - break; - } - - of_node_put(root); - - if (pcictrl == NULL) { - printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Unable to find the PCI bridge node\n"); - return; - } - - bus_range = get_property(pcictrl, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't get bus-range for %s\n", pcictrl->full_name); - return; - } - - if (bus_range[1] == bus_range[0]) - printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", - bus_range[0]); - else - printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", - bus_range[0], bus_range[1]); - printk(" controlled by %s\n", pcictrl->full_name); - printk("\n"); - - hose = pcibios_alloc_controller(); - if (!hose) { - printk(KERN_WARNING EFIKA_PLATFORM_NAME - ": Can't allocate PCI controller structure for %s\n", - pcictrl->full_name); - return; - } - - hose->arch_data = of_node_get(pcictrl); - hose->first_busno = bus_range[0]; - hose->last_busno = bus_range[1]; - hose->ops = &rtas_pci_ops; - - pci_process_bridge_OF_ranges(hose, pcictrl, 0); -} - -#else -void __init efika_pcisetup(void) -{} -#endif diff --git a/arch/powerpc/platforms/efika/setup.c b/arch/powerpc/platforms/efika/setup.c deleted file mode 100644 index 110c980ed1e..00000000000 --- a/arch/powerpc/platforms/efika/setup.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Efika 5K2 platform setup - * Some code really inspired from the lite5200b platform. - * - * Copyright (C) 2006 bplan GmbH - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "efika.h" - -static void efika_show_cpuinfo(struct seq_file *m) -{ - struct device_node *root; - const char *revision = NULL; - const char *codegendescription = NULL; - const char *codegenvendor = NULL; - - root = of_find_node_by_path("/"); - if (root) { - revision = get_property(root, "revision", NULL); - codegendescription = - get_property(root, "CODEGEN,description", NULL); - codegenvendor = get_property(root, "CODEGEN,vendor", NULL); - - of_node_put(root); - } - - if (codegendescription) - seq_printf(m, "machine\t\t: %s\n", codegendescription); - else - seq_printf(m, "machine\t\t: Efika\n"); - - if (revision) - seq_printf(m, "revision\t: %s\n", revision); - - if (codegenvendor) - seq_printf(m, "vendor\t\t: %s\n", codegenvendor); - - of_node_put(root); -} - -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(); - - if (ppc_md.progress) - ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0); -} - -static void __init efika_init(void) -{ - struct device_node *np; - struct device_node *cnp = NULL; - const u32 *base; - - /* Find every child of the SOC node and add it to of_platform */ - np = of_find_node_by_name(NULL, "builtin"); - if (np) { - char name[BUS_ID_SIZE]; - while ((cnp = of_get_next_child(np, cnp))) { - strcpy(name, cnp->name); - - base = get_property(cnp, "reg", NULL); - if (base == NULL) - continue; - - snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base); - of_platform_device_create(cnp, name, NULL); - - printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name); - } - } - - if (ppc_md.progress) - ppc_md.progress(" Have fun with your Efika! ", 0x7777); -} - -static int __init efika_probe(void) -{ - char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), - "model", NULL); - - if (model == NULL) - return 0; - if (strcmp(model, "EFIKA5K2")) - return 0; - - ISA_DMA_THRESHOLD = ~0L; - DMA_MODE_READ = 0x44; - DMA_MODE_WRITE = 0x48; - - return 1; -} - -define_machine(efika) -{ - .name = EFIKA_PLATFORM_NAME, - .probe = efika_probe, - .setup_arch = efika_setup_arch, - .init = efika_init, - .show_cpuinfo = efika_show_cpuinfo, - .init_IRQ = mpc52xx_init_irq, - .get_irq = mpc52xx_get_irq, - .restart = rtas_restart, - .power_off = rtas_power_off, - .halt = rtas_halt, - .set_rtc_time = rtas_set_rtc_time, - .get_rtc_time = rtas_get_rtc_time, - .progress = rtas_progress, - .get_boot_time = rtas_get_boot_time, - .calibrate_decr = generic_calibrate_decr, - .phys_mem_access_prot = pci_phys_mem_access_prot, -}; -- cgit v1.2.3 From e65fdfd6ca447353ad1b4c0a0d20df55f3f6f233 Mon Sep 17 00:00:00 2001 From: Sylvain Munaut Date: Mon, 27 Nov 2006 14:16:26 -0700 Subject: [POWERPC] Separate IRQ config / register set from main header There is no need to expose these settings outside the scope of the interrupt controller code itself. Signed-off-by: Sylvain Munaut Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/52xx/mpc52xx_pic.c | 1 + arch/powerpc/platforms/52xx/mpc52xx_pic.h | 53 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 arch/powerpc/platforms/52xx/mpc52xx_pic.h (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 6df51f04b8f..504154fdf6a 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -33,6 +33,7 @@ #include #include #include +#include "mpc52xx_pic.h" /* * diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.h b/arch/powerpc/platforms/52xx/mpc52xx_pic.h new file mode 100644 index 00000000000..1a26bcdb304 --- /dev/null +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.h @@ -0,0 +1,53 @@ +/* + * Header file for Freescale MPC52xx Interrupt controller + * + * Copyright (C) 2004-2005 Sylvain Munaut + * Copyright (C) 2003 MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef __POWERPC_SYSDEV_MPC52xx_PIC_H__ +#define __POWERPC_SYSDEV_MPC52xx_PIC_H__ + +#include + + +/* HW IRQ mapping */ +#define MPC52xx_IRQ_L1_CRIT (0) +#define MPC52xx_IRQ_L1_MAIN (1) +#define MPC52xx_IRQ_L1_PERP (2) +#define MPC52xx_IRQ_L1_SDMA (3) + +#define MPC52xx_IRQ_L1_OFFSET (6) +#define MPC52xx_IRQ_L1_MASK (0x00c0) + +#define MPC52xx_IRQ_L2_OFFSET (0) +#define MPC52xx_IRQ_L2_MASK (0x003f) + +#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0) + + +/* Interrupt controller Register set */ +struct mpc52xx_intr { + u32 per_mask; /* INTR + 0x00 */ + u32 per_pri1; /* INTR + 0x04 */ + u32 per_pri2; /* INTR + 0x08 */ + u32 per_pri3; /* INTR + 0x0c */ + u32 ctrl; /* INTR + 0x10 */ + u32 main_mask; /* INTR + 0x14 */ + u32 main_pri1; /* INTR + 0x18 */ + u32 main_pri2; /* INTR + 0x1c */ + u32 reserved1; /* INTR + 0x20 */ + u32 enc_status; /* INTR + 0x24 */ + u32 crit_status; /* INTR + 0x28 */ + u32 main_status; /* INTR + 0x2c */ + u32 per_status; /* INTR + 0x30 */ + u32 reserved2; /* INTR + 0x34 */ + u32 per_error; /* INTR + 0x38 */ +}; + +#endif /* __POWERPC_SYSDEV_MPC52xx_PIC_H__ */ + -- cgit v1.2.3 From 6065170cf75c64267f6edec5fd359ce8444bd13d Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:27 -0700 Subject: [POWERPC] Add common routines for 52xx support in arch/powerpc Adds utility routines used by 52xx device drivers and board support code. Main functionality is to add device nodes to the of_platform_bus, retrieve the IPB bus frequency, and find+ioremap device registers. Signed-off-by: Grant Likely Signed-off-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/52xx/Makefile | 2 +- arch/powerpc/platforms/52xx/mpc52xx_common.c | 124 +++++++++++++++++++++++++++ arch/powerpc/platforms/52xx/mpc52xx_pic.c | 110 +++++------------------- 3 files changed, 147 insertions(+), 89 deletions(-) create mode 100644 arch/powerpc/platforms/52xx/mpc52xx_common.c (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index 1c9c122123d..b8f27a86406 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile @@ -2,7 +2,7 @@ # Makefile for 52xx based boards # ifeq ($(CONFIG_PPC_MERGE),y) -obj-y += mpc52xx_pic.o +obj-y += mpc52xx_pic.o mpc52xx_common.o endif obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c new file mode 100644 index 00000000000..05b21444127 --- /dev/null +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -0,0 +1,124 @@ +/* + * + * Utility functions for the Freescale MPC52xx. + * + * Copyright (C) 2006 Sylvain Munaut + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + * + */ + +#undef DEBUG + +#include + +#include +#include +#include +#include + + +void __iomem * +mpc52xx_find_and_map(const char *compatible) +{ + struct device_node *ofn; + const u32 *regaddr_p; + u64 regaddr64, size64; + + ofn = of_find_compatible_node(NULL, NULL, compatible); + if (!ofn) + return NULL; + + regaddr_p = of_get_address(ofn, 0, &size64, NULL); + if (!regaddr_p) { + of_node_put(ofn); + return NULL; + } + + regaddr64 = of_translate_address(ofn, regaddr_p); + + of_node_put(ofn); + + return ioremap((u32)regaddr64, (u32)size64); +} + + +/** + * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device + * @node: device node + * + * Returns IPB bus frequency, or 0 if the bus frequency cannot be found. + */ +unsigned int +mpc52xx_find_ipb_freq(struct device_node *node) +{ + struct device_node *np; + const unsigned int *p_ipb_freq = NULL; + + of_node_get(node); + while (node) { + p_ipb_freq = get_property(node, "bus-frequency", NULL); + if (p_ipb_freq) + break; + + np = of_get_parent(node); + of_node_put(node); + node = np; + } + if (node) + of_node_put(node); + + return p_ipb_freq ? *p_ipb_freq : 0; +} + + +void __init +mpc52xx_setup_cpu(void) +{ + struct mpc52xx_cdm __iomem *cdm; + struct mpc52xx_xlb __iomem *xlb; + + /* Map zones */ + cdm = mpc52xx_find_and_map("mpc52xx-cdm"); + xlb = mpc52xx_find_and_map("mpc52xx-xlb"); + + if (!cdm || !xlb) { + printk(KERN_ERR __FILE__ ": " + "Error while mapping CDM/XLB during mpc52xx_setup_cpu. " + "Expect some abnormal behavior\n"); + goto unmap_regs; + } + + /* Use internal 48 Mhz */ + out_8(&cdm->ext_48mhz_en, 0x00); + out_8(&cdm->fd_enable, 0x01); + if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */ + out_be16(&cdm->fd_counters, 0x0001); + else + out_be16(&cdm->fd_counters, 0x5555); + + /* Configure the XLB Arbiter priorities */ + out_be32(&xlb->master_pri_enable, 0xff); + out_be32(&xlb->master_priority, 0x11111111); + + /* Disable XLB pipelining */ + /* (cfr errate 292. We could do this only just before ATA PIO + transaction and re-enable it afterwards ...) */ + out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS); + + /* Unmap zones */ +unmap_regs: + if (cdm) iounmap(cdm); + if (xlb) iounmap(xlb); +} + +static int __init +mpc52xx_declare_of_platform_devices(void) +{ + /* Find every child of the SOC node and add it to of_platform */ + return of_platform_bus_probe(NULL, NULL, NULL); +} + +device_initcall(mpc52xx_declare_of_platform_devices); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c index 504154fdf6a..cd91a6c3aaf 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c @@ -54,12 +54,12 @@ static unsigned char mpc52xx_map_senses[4] = { * */ -static inline void io_be_setbit(u32 __iomem * addr, int bitno) +static inline void io_be_setbit(u32 __iomem *addr, int bitno) { out_be32(addr, in_be32(addr) | (1 << bitno)); } -static inline void io_be_clrbit(u32 __iomem * addr, int bitno) +static inline void io_be_clrbit(u32 __iomem *addr, int bitno) { out_be32(addr, in_be32(addr) & ~(1 << bitno)); } @@ -104,7 +104,7 @@ static void mpc52xx_extirq_ack(unsigned int virq) pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq); - io_be_setbit(&intr->ctrl, 27 - l2irq); + io_be_setbit(&intr->ctrl, 27-l2irq); } static struct irq_chip mpc52xx_extirq_irqchip = { @@ -379,81 +379,21 @@ static struct irq_host_ops mpc52xx_irqhost_ops = { void __init mpc52xx_init_irq(void) { - struct device_node *picnode = NULL; - int picnode_regsize; - u32 picnode_regoffset; - - struct device_node *sdmanode = NULL; - int sdmanode_regsize; - u32 sdmanode_regoffset; - - u64 size64; - int flags; - u32 intr_ctrl; - - picnode = of_find_compatible_node(NULL, "interrupt-controller", - "mpc5200-pic"); - if (picnode == NULL) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to find the interrupt controller " - "in the OpenFirmware device tree\n"); - goto end; - } - - sdmanode = of_find_compatible_node(NULL, "dma-controller", - "mpc5200-bestcomm"); - if (sdmanode == NULL) { - printk(KERN_ERR "MPC52xx PIC" - "Unable to find the Bestcomm DMA controller device " - "in the OpenFirmware device tree\n"); - goto end; - } - - /* Retrieve PIC ressources */ - picnode_regoffset = (u32) of_get_address(picnode, 0, &size64, &flags); - if (picnode_regoffset == 0) { - printk(KERN_ERR "MPC52xx PIC" - "Unable to get the interrupt controller address\n"); - goto end; - } - - picnode_regoffset = - of_translate_address(picnode, (u32 *) picnode_regoffset); - picnode_regsize = (int)size64; - - /* Retrieve SDMA ressources */ - sdmanode_regoffset = (u32) of_get_address(sdmanode, 0, &size64, &flags); - if (sdmanode_regoffset == 0) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to get the Bestcomm DMA controller address\n"); - goto end; - } - - sdmanode_regoffset = - of_translate_address(sdmanode, (u32 *) sdmanode_regoffset); - sdmanode_regsize = (int)size64; + struct device_node *picnode; /* Remap the necessary zones */ - intr = ioremap(picnode_regoffset, picnode_regsize); - if (intr == NULL) { - printk(KERN_ERR "MPC52xx PIC: " - "Unable to ioremap interrupt controller registers!\n"); - goto end; - } + picnode = of_find_compatible_node(NULL, NULL, "mpc52xx-pic"); - sdma = ioremap(sdmanode_regoffset, sdmanode_regsize); - if (sdma == NULL) { - iounmap(intr); - printk(KERN_ERR "MPC52xx PIC: " - "Unable to ioremap Bestcomm DMA registers!\n"); - goto end; - } + intr = mpc52xx_find_and_map("mpc52xx-pic"); + if (!intr) + panic(__FILE__ ": find_and_map failed on 'mpc52xx-pic'. " + "Check node !"); - printk(KERN_INFO "MPC52xx PIC: MPC52xx PIC Remapped at 0x%8.8x\n", - picnode_regoffset); - printk(KERN_INFO "MPC52xx PIC: MPC52xx SDMA Remapped at 0x%8.8x\n", - sdmanode_regoffset); + sdma = mpc52xx_find_and_map("mpc52xx-bestcomm"); + if (!sdma) + panic(__FILE__ ": find_and_map failed on 'mpc52xx-bestcomm'. " + "Check node !"); /* Disable all interrupt sources. */ out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */ @@ -480,21 +420,15 @@ void __init mpc52xx_init_irq(void) * hw irq information provided by the ofw to linux virq */ - mpc52xx_irqhost = - irq_alloc_host(IRQ_HOST_MAP_LINEAR, MPC52xx_IRQ_HIGHTESTHWIRQ, - &mpc52xx_irqhost_ops, -1); + mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, + MPC52xx_IRQ_HIGHTESTHWIRQ, + &mpc52xx_irqhost_ops, -1); - if (mpc52xx_irqhost) { - mpc52xx_irqhost->host_data = picnode; - printk(KERN_INFO "MPC52xx PIC is up and running!\n"); - } else { - printk(KERN_ERR - "MPC52xx PIC: Unable to allocate the IRQ host\n"); - } + if (!mpc52xx_irqhost) + panic(__FILE__ ": Cannot allocate the IRQ host\n"); -end: - of_node_put(picnode); - of_node_put(sdmanode); + mpc52xx_irqhost->host_data = picnode; + printk(KERN_INFO "MPC52xx PIC is up and running!\n"); } /* @@ -526,9 +460,10 @@ unsigned int mpc52xx_get_irq(void) irq = ffs(status) - 1; irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; - } else + } else { irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK; + } } pr_debug("%s: irq=%x. virq=%d\n", __func__, irq, @@ -536,4 +471,3 @@ unsigned int mpc52xx_get_irq(void) return irq_linear_revmap(mpc52xx_irqhost, irq); } - -- cgit v1.2.3 From 6b64253139a20b7db1f701a9117bc5174eb878bc Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:28 -0700 Subject: [POWERPC] Add lite5200 board support to arch/powerpc Signed-off-by: Grant Likely Acked-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 6 ++ arch/powerpc/platforms/52xx/Makefile | 3 +- arch/powerpc/platforms/52xx/lite5200.c | 162 +++++++++++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/52xx/lite5200.c (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a6bc221ad1b..7b63ede083f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -423,6 +423,12 @@ config PPC_EFIKA select PPC_NATIVE default y +config PPC_LITE5200 + bool "Freescale Lite5200 Eval Board" + depends on PPC_MULTIPLATFORM && PPC32 + select PPC_MPC52xx + default n + config PPC_PMAC bool "Apple PowerMac based machines" depends on PPC_MULTIPLATFORM diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile index b8f27a86406..a46184a0c75 100644 --- a/arch/powerpc/platforms/52xx/Makefile +++ b/arch/powerpc/platforms/52xx/Makefile @@ -5,4 +5,5 @@ ifeq ($(CONFIG_PPC_MERGE),y) obj-y += mpc52xx_pic.o mpc52xx_common.o endif -obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o +obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o +obj-$(CONFIG_PPC_LITE5200) += lite5200.o diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c new file mode 100644 index 00000000000..a375c15b431 --- /dev/null +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -0,0 +1,162 @@ +/* + * Freescale Lite5200 board support + * + * Written by: Grant Likely + * + * Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved. + * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved. + * + * Description: + * 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. + */ + +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* ************************************************************************ + * + * Setup the architecture + * + */ + +static void __init +lite52xx_setup_cpu(void) +{ + struct mpc52xx_gpio __iomem *gpio; + u32 port_config; + + /* Map zones */ + gpio = mpc52xx_find_and_map("mpc52xx-gpio"); + if (!gpio) { + printk(KERN_ERR __FILE__ ": " + "Error while mapping GPIO register for port config. " + "Expect some abnormal behavior\n"); + goto error; + } + + /* Set port config */ + port_config = in_be32(&gpio->port_config); + + port_config &= ~0x00800000; /* 48Mhz internal, pin is GPIO */ + + port_config &= ~0x00007000; /* USB port : Differential mode */ + port_config |= 0x00001000; /* USB 1 only */ + + port_config &= ~0x03000000; /* ATA CS is on csb_4/5 */ + port_config |= 0x01000000; + + pr_debug("port_config: old:%x new:%x\n", + in_be32(&gpio->port_config), port_config); + out_be32(&gpio->port_config, port_config); + + /* Unmap zone */ +error: + iounmap(gpio); +} + +static void __init lite52xx_setup_arch(void) +{ + struct device_node *np; + + if (ppc_md.progress) + ppc_md.progress("lite52xx_setup_arch()", 0); + + np = of_find_node_by_type(NULL, "cpu"); + if (np) { + unsigned int *fp = + (int *)get_property(np, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(np); + } + + /* CPU & Port mux setup */ + mpc52xx_setup_cpu(); /* Generic */ + lite52xx_setup_cpu(); /* Platorm specific */ + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +} + +void lite52xx_show_cpuinfo(struct seq_file *m) +{ + struct device_node* np = of_find_all_nodes(NULL); + const char *model = NULL; + + if (np) + model = get_property(np, "model", NULL); + + seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "machine\t\t: %s\n", model ? model : "unknown"); + + of_node_put(np); +} + +/* + * Called very early, MMU is off, device-tree isn't unflattened + */ +static int __init lite52xx_probe(void) +{ + unsigned long node = of_get_flat_dt_root(); + const char *model = of_get_flat_dt_prop(node, "model", NULL); + + if (!of_flat_dt_is_compatible(node, "lite52xx")) + return 0; + pr_debug("%s board w/ mpc52xx found\n", model ? model : "unknown"); + + return 1; +} + +define_machine(lite52xx) { + .name = "lite52xx", + .probe = lite52xx_probe, + .setup_arch = lite52xx_setup_arch, + .init_IRQ = mpc52xx_init_irq, + .get_irq = mpc52xx_get_irq, + .show_cpuinfo = lite52xx_show_cpuinfo, + .calibrate_decr = generic_calibrate_decr, +}; -- cgit v1.2.3 From c6d4d657c2f11fe3b33dd8303f57a8b8d55323d6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:29 -0700 Subject: [POWERPC] Add device trees for lite5200 and lite5200b eval boards Signed-off-by: Grant Likely Acked-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/boot/dts/lite5200.dts | 313 +++++++++++++++++++++++++++++++++++ arch/powerpc/boot/dts/lite5200b.dts | 318 ++++++++++++++++++++++++++++++++++++ 2 files changed, 631 insertions(+) create mode 100644 arch/powerpc/boot/dts/lite5200.dts create mode 100644 arch/powerpc/boot/dts/lite5200b.dts (limited to 'arch') diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts new file mode 100644 index 00000000000..8bc0d259796 --- /dev/null +++ b/arch/powerpc/boot/dts/lite5200.dts @@ -0,0 +1,313 @@ +/* + * Lite5200 board Device Tree Source + * + * Copyright 2006 Secret Lab Technologies Ltd. + * Grant Likely + * + * 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. + */ + +/ { + model = "Lite5200"; + compatible = "lite5200\0lite52xx\0mpc5200\0mpc52xx"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; + i-cache-line-size = <20>; + d-cache-size = <4000>; // L1, 16K + i-cache-size = <4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + 32-bit; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 04000000>; // 64MB + }; + + soc5200@f0000000 { + #interrupt-cells = <3>; + device_type = "soc"; + ranges = <0 f0000000 f0010000>; + reg = ; + bus-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "mpc5200-cdm\0mpc52xx-cdm"; + reg = <200 38>; + }; + + pic@500 { + // 5200 interrupts are encoded into two levels; + linux,phandle = <500>; + interrupt-controller; + #interrupt-cells = <3>; + device_type = "interrupt-controller"; + compatible = "mpc5200-pic\0mpc52xx-pic"; + reg = <500 80>; + built-in; + }; + + gpt@600 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <600 10>; + interrupts = <1 9 0>; + interrupt-parent = <500>; + }; + + gpt@610 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <610 10>; + interrupts = <1 a 0>; + interrupt-parent = <500>; + }; + + gpt@620 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <620 10>; + interrupts = <1 b 0>; + interrupt-parent = <500>; + }; + + gpt@630 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <630 10>; + interrupts = <1 c 0>; + interrupt-parent = <500>; + }; + + gpt@640 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <640 10>; + interrupts = <1 d 0>; + interrupt-parent = <500>; + }; + + gpt@650 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <650 10>; + interrupts = <1 e 0>; + interrupt-parent = <500>; + }; + + gpt@660 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <660 10>; + interrupts = <1 f 0>; + interrupt-parent = <500>; + }; + + gpt@670 { // General Purpose Timer + compatible = "mpc5200-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <670 10>; + interrupts = <1 10 0>; + interrupt-parent = <500>; + }; + + rtc@800 { // Real time clock + compatible = "mpc5200-rtc\0mpc52xx-rtc"; + device_type = "rtc"; + reg = <800 100>; + interrupts = <1 5 0 1 6 0>; + interrupt-parent = <500>; + }; + + mscan@900 { + device_type = "mscan"; + compatible = "mpc5200-mscan\0mpc52xx-mscan"; + interrupts = <2 11 0>; + interrupt-parent = <500>; + reg = <900 80>; + }; + + mscan@980 { + device_type = "mscan"; + compatible = "mpc5200-mscan\0mpc52xx-mscan"; + interrupts = <1 12 0>; + interrupt-parent = <500>; + reg = <980 80>; + }; + + gpio@b00 { + compatible = "mpc5200-gpio\0mpc52xx-gpio"; + reg = ; + interrupts = <1 7 0>; + interrupt-parent = <500>; + }; + + gpio-wkup@b00 { + compatible = "mpc5200-gpio-wkup\0mpc52xx-gpio-wkup"; + reg = ; + interrupts = <1 8 0 0 3 0>; + interrupt-parent = <500>; + }; + + pci@0d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "mpc5200-pci\0mpc52xx-pci"; + reg = ; + interrupt-map-mask = ; + interrupt-map = ; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 a 0>; + interrupt-parent = <500>; + bus-range = <0 0>; + ranges = <42000000 0 80000000 80000000 0 20000000 + 02000000 0 a0000000 a0000000 0 10000000 + 01000000 0 00000000 b0000000 0 01000000>; + }; + + spi@f00 { + device_type = "spi"; + compatible = "mpc5200-spi\0mpc52xx-spi"; + reg = ; + interrupts = <2 d 0 2 e 0>; + interrupt-parent = <500>; + }; + + usb@1000 { + device_type = "usb-ohci-be"; + compatible = "mpc5200-ohci\0mpc52xx-ohci\0ohci-be"; + reg = <1000 ff>; + interrupts = <2 6 0>; + interrupt-parent = <500>; + }; + + bestcomm@1200 { + device_type = "dma-controller"; + compatible = "mpc5200-bestcomm\0mpc52xx-bestcomm"; + reg = <1200 80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 a 0 3 b 0 + 3 c 0 3 d 0 3 e 0 3 f 0>; + interrupt-parent = <500>; + }; + + xlb@1f00 { + compatible = "mpc5200-xlb\0mpc52xx-xlb"; + reg = <1f00 100>; + }; + + serial@2000 { // PSC1 + device_type = "serial"; + compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart"; + port-number = <0>; // Logical port assignment + reg = <2000 100>; + interrupts = <2 1 0>; + interrupt-parent = <500>; + }; + + // PSC2 in spi mode example + spi@2200 { // PSC2 + device_type = "spi"; + compatible = "mpc5200-psc-spi\0mpc52xx-psc-spi"; + reg = <2200 100>; + interrupts = <2 2 0>; + interrupt-parent = <500>; + }; + + // PSC3 in CODEC mode example + i2s@2400 { // PSC3 + device_type = "i2s"; + compatible = "mpc5200-psc-i2s\0mpc52xx-psc-i2s"; + reg = <2400 100>; + interrupts = <2 3 0>; + interrupt-parent = <500>; + }; + + // PSC4 unconfigured + //serial@2600 { // PSC4 + // device_type = "serial"; + // compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart"; + // reg = <2600 100>; + // interrupts = <2 b 0>; + // interrupt-parent = <500>; + //}; + + // PSC5 unconfigured + //serial@2800 { // PSC5 + // device_type = "serial"; + // compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart"; + // reg = <2800 100>; + // interrupts = <2 c 0>; + // interrupt-parent = <500>; + //}; + + // PSC6 in AC97 mode example + ac97@2c00 { // PSC6 + device_type = "ac97"; + compatible = "mpc5200-psc-ac97\0mpc52xx-psc-ac97"; + reg = <2c00 100>; + interrupts = <2 4 0>; + interrupt-parent = <500>; + }; + + ethernet@3000 { + device_type = "network"; + compatible = "mpc5200-fec\0mpc52xx-fec"; + reg = <3000 800>; + mac-address = [ 02 03 04 05 06 07 ]; // Bad! + interrupts = <2 5 0>; + interrupt-parent = <500>; + }; + + ata@3a00 { + device_type = "ata"; + compatible = "mpc5200-ata\0mpc52xx-ata"; + reg = <3a00 100>; + interrupts = <2 7 0>; + interrupt-parent = <500>; + }; + + i2c@3d00 { + device_type = "i2c"; + compatible = "mpc5200-i2c\0mpc52xx-i2c"; + reg = <3d00 40>; + interrupts = <2 f 0>; + interrupt-parent = <500>; + }; + + i2c@3d40 { + device_type = "i2c"; + compatible = "mpc5200-i2c\0mpc52xx-i2c"; + reg = <3d40 40>; + interrupts = <2 10 0>; + interrupt-parent = <500>; + }; + sram@8000 { + device_type = "sram"; + compatible = "mpc5200-sram\0mpc52xx-sram\0sram"; + reg = <8000 4000>; + }; + }; +}; diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts new file mode 100644 index 00000000000..81cb76418a7 --- /dev/null +++ b/arch/powerpc/boot/dts/lite5200b.dts @@ -0,0 +1,318 @@ +/* + * Lite5200B board Device Tree Source + * + * Copyright 2006 Secret Lab Technologies Ltd. + * Grant Likely + * + * 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. + */ + +/ { + model = "Lite5200b"; + compatible = "lite5200b\0lite52xx\0mpc5200b\0mpc52xx"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,5200@0 { + device_type = "cpu"; + reg = <0>; + d-cache-line-size = <20>; + i-cache-line-size = <20>; + d-cache-size = <4000>; // L1, 16K + i-cache-size = <4000>; // L1, 16K + timebase-frequency = <0>; // from bootloader + bus-frequency = <0>; // from bootloader + clock-frequency = <0>; // from bootloader + 32-bit; + }; + }; + + memory { + device_type = "memory"; + reg = <00000000 10000000>; // 256MB + }; + + soc5200@f0000000 { + #interrupt-cells = <3>; + device_type = "soc"; + ranges = <0 f0000000 f0010000>; + reg = ; + bus-frequency = <0>; // from bootloader + + cdm@200 { + compatible = "mpc5200b-cdm\0mpc52xx-cdm"; + reg = <200 38>; + }; + + pic@500 { + // 5200 interrupts are encoded into two levels; + linux,phandle = <500>; + interrupt-controller; + #interrupt-cells = <3>; + device_type = "interrupt-controller"; + compatible = "mpc5200b-pic\0mpc52xx-pic"; + reg = <500 80>; + built-in; + }; + + gpt@600 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <600 10>; + interrupts = <1 9 0>; + interrupt-parent = <500>; + }; + + gpt@610 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <610 10>; + interrupts = <1 a 0>; + interrupt-parent = <500>; + }; + + gpt@620 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <620 10>; + interrupts = <1 b 0>; + interrupt-parent = <500>; + }; + + gpt@630 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <630 10>; + interrupts = <1 c 0>; + interrupt-parent = <500>; + }; + + gpt@640 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <640 10>; + interrupts = <1 d 0>; + interrupt-parent = <500>; + }; + + gpt@650 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <650 10>; + interrupts = <1 e 0>; + interrupt-parent = <500>; + }; + + gpt@660 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <660 10>; + interrupts = <1 f 0>; + interrupt-parent = <500>; + }; + + gpt@670 { // General Purpose Timer + compatible = "mpc5200b-gpt\0mpc52xx-gpt"; + device_type = "gpt"; + reg = <670 10>; + interrupts = <1 10 0>; + interrupt-parent = <500>; + }; + + rtc@800 { // Real time clock + compatible = "mpc5200b-rtc\0mpc52xx-rtc"; + device_type = "rtc"; + reg = <800 100>; + interrupts = <1 5 0 1 6 0>; + interrupt-parent = <500>; + }; + + mscan@900 { + device_type = "mscan"; + compatible = "mpc5200b-mscan\0mpc52xx-mscan"; + interrupts = <2 11 0>; + interrupt-parent = <500>; + reg = <900 80>; + }; + + mscan@980 { + device_type = "mscan"; + compatible = "mpc5200b-mscan\0mpc52xx-mscan"; + interrupts = <1 12 0>; + interrupt-parent = <500>; + reg = <980 80>; + }; + + gpio@b00 { + compatible = "mpc5200b-gpio\0mpc52xx-gpio"; + reg = ; + interrupts = <1 7 0>; + interrupt-parent = <500>; + }; + + gpio-wkup@b00 { + compatible = "mpc5200b-gpio-wkup\0mpc52xx-gpio-wkup"; + reg = ; + interrupts = <1 8 0 0 3 0>; + interrupt-parent = <500>; + }; + + pci@0d00 { + #interrupt-cells = <1>; + #size-cells = <2>; + #address-cells = <3>; + device_type = "pci"; + compatible = "mpc5200b-pci\0mpc52xx-pci"; + reg = ; + interrupt-map-mask = ; + interrupt-map = ; + clock-frequency = <0>; // From boot loader + interrupts = <2 8 0 2 9 0 2 a 0>; + interrupt-parent = <500>; + bus-range = <0 0>; + ranges = <42000000 0 80000000 80000000 0 20000000 + 02000000 0 a0000000 a0000000 0 10000000 + 01000000 0 00000000 b0000000 0 01000000>; + }; + + spi@f00 { + device_type = "spi"; + compatible = "mpc5200b-spi\0mpc52xx-spi"; + reg = ; + interrupts = <2 d 0 2 e 0>; + interrupt-parent = <500>; + }; + + usb@1000 { + device_type = "usb-ohci-be"; + compatible = "mpc5200b-ohci\0mpc52xx-ohci\0ohci-be"; + reg = <1000 ff>; + interrupts = <2 6 0>; + interrupt-parent = <500>; + }; + + bestcomm@1200 { + device_type = "dma-controller"; + compatible = "mpc5200b-bestcomm\0mpc52xx-bestcomm"; + reg = <1200 80>; + interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 + 3 4 0 3 5 0 3 6 0 3 7 0 + 3 8 0 3 9 0 3 a 0 3 b 0 + 3 c 0 3 d 0 3 e 0 3 f 0>; + interrupt-parent = <500>; + }; + + xlb@1f00 { + compatible = "mpc5200b-xlb\0mpc52xx-xlb"; + reg = <1f00 100>; + }; + + serial@2000 { // PSC1 + device_type = "serial"; + compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart"; + port-number = <0>; // Logical port assignment + reg = <2000 100>; + interrupts = <2 1 0>; + interrupt-parent = <500>; + }; + + // PSC2 in spi mode example + spi@2200 { // PSC2 + device_type = "spi"; + compatible = "mpc5200b-psc-spi\0mpc52xx-psc-spi"; + reg = <2200 100>; + interrupts = <2 2 0>; + interrupt-parent = <500>; + }; + + // PSC3 in CODEC mode example + i2s@2400 { // PSC3 + device_type = "i2s"; + compatible = "mpc5200b-psc-i2s\0mpc52xx-psc-i2s"; + reg = <2400 100>; + interrupts = <2 3 0>; + interrupt-parent = <500>; + }; + + // PSC4 unconfigured + //serial@2600 { // PSC4 + // device_type = "serial"; + // compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart"; + // reg = <2600 100>; + // interrupts = <2 b 0>; + // interrupt-parent = <500>; + //}; + + // PSC5 unconfigured + //serial@2800 { // PSC5 + // device_type = "serial"; + // compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart"; + // reg = <2800 100>; + // interrupts = <2 c 0>; + // interrupt-parent = <500>; + //}; + + // PSC6 in AC97 mode example + ac97@2c00 { // PSC6 + device_type = "ac97"; + compatible = "mpc5200b-psc-ac97\0mpc52xx-psc-ac97"; + reg = <2c00 100>; + interrupts = <2 4 0>; + interrupt-parent = <500>; + }; + + ethernet@3000 { + device_type = "network"; + compatible = "mpc5200b-fec\0mpc52xx-fec"; + reg = <3000 800>; + mac-address = [ 02 03 04 05 06 07 ]; // Bad! + interrupts = <2 5 0>; + interrupt-parent = <500>; + }; + + ata@3a00 { + device_type = "ata"; + compatible = "mpc5200b-ata\0mpc52xx-ata"; + reg = <3a00 100>; + interrupts = <2 7 0>; + interrupt-parent = <500>; + }; + + i2c@3d00 { + device_type = "i2c"; + compatible = "mpc5200b-i2c\0mpc52xx-i2c"; + reg = <3d00 40>; + interrupts = <2 f 0>; + interrupt-parent = <500>; + }; + + i2c@3d40 { + device_type = "i2c"; + compatible = "mpc5200b-i2c\0mpc52xx-i2c"; + reg = <3d40 40>; + interrupts = <2 10 0>; + interrupt-parent = <500>; + }; + sram@8000 { + device_type = "sram"; + compatible = "mpc5200b-sram\0mpc52xx-sram\0sram"; + reg = <8000 4000>; + }; + }; +}; -- cgit v1.2.3 From ede8edb35b95c78c890b15fdb6cedcb3f42f4769 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 27 Nov 2006 14:16:30 -0700 Subject: [POWERPC] defconfig for lite5200 board Signed-off-by: Grant Likely Acked-by: Sylvain Munaut Signed-off-by: Paul Mackerras --- arch/powerpc/configs/lite5200_defconfig | 931 ++++++++++++++++++++++++++++++++ 1 file changed, 931 insertions(+) create mode 100644 arch/powerpc/configs/lite5200_defconfig (limited to 'arch') diff --git a/arch/powerpc/configs/lite5200_defconfig b/arch/powerpc/configs/lite5200_defconfig new file mode 100644 index 00000000000..ee7655776d4 --- /dev/null +++ b/arch/powerpc/configs/lite5200_defconfig @@ -0,0 +1,931 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc6 +# Mon Nov 27 11:08:20 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +# CONFIG_PPC_UDBG_16550 is not set +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +# CONFIG_DEFAULT_UIMAGE is not set + +# +# Processor support +# +CONFIG_CLASSIC32=y +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Platform support +# +CONFIG_PPC_MULTIPLATFORM=y +# CONFIG_EMBEDDED6xx is not set +# CONFIG_APUS is not set +# CONFIG_PPC_CHRP is not set +CONFIG_PPC_MPC52xx=y +# CONFIG_PPC_EFIKA is not set +CONFIG_PPC_LITE5200=y +# CONFIG_PPC_PMAC is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_WANT_EARLY_SERIAL is not set +# CONFIG_MPIC is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +# CONFIG_KEXEC is not set +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_SYSFS_DEPRECATED is not set +# CONFIG_SOFTWARE_SUSPEND is not set +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_INDIRECT_PCI is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_PROC_FS is not set + +# +# SCSI support type (disk, tape, CD-ROM) +# +# CONFIG_BLK_DEV_SD is not set +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +CONFIG_PATA_MPC52xx=y +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set +# CONFIG_QLA3XXX is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_MPC52xx=y +CONFIG_SERIAL_MPC52xx_CONSOLE=y +CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600 +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_PLIST=y + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUGGER is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set -- cgit v1.2.3 From 4468f01dc7cfd1998845cd66a0cdb1f3ef9740f0 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Mon, 27 Nov 2006 21:21:29 -0600 Subject: [POWERPC] Fix OF pci flags parsing For PCI devices with only io ports, of_bus_pci_get_flags() will fall through and still mark the resource as IORESOURCE_MEM. Signed-off-by: Olof Johansson Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_parse.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 346fb7bf9a0..0dfbe1cd28e 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -160,9 +160,11 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr) switch((w >> 24) & 0x03) { case 0x01: flags |= IORESOURCE_IO; + break; case 0x02: /* 32 bits */ case 0x03: /* 64 bits */ flags |= IORESOURCE_MEM; + break; } if (w & 0x40000000) flags |= IORESOURCE_PREFETCH; -- cgit v1.2.3 From dc0f80aa6a6c128cf90adefb5b7deddfb56d937b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 28 Nov 2006 12:31:53 +0100 Subject: [POWERPC] Clean images in arch/powerpc/boot Add a rule to clean up the various generated image files in arch/powerpc/boot. Signed-off-by: Geert Uytterhoeven Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index b320562c03b..4a831ae95a9 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -179,3 +179,4 @@ install: $(CONFIGURE) $(image-y) clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz) clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz) +clean-files += $(image-) -- cgit v1.2.3 From 0efbc18a753f7d6dbe832e014bc80e2b4c12bece Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 29 Nov 2006 22:31:47 +1100 Subject: [POWERPC] Tell firmware we can handle POWER6 compatible mode This adds the "logical" PVR value used by POWER6 in "compatible" mode to the list of PVR values that the kernel tells firmware it is able to handle. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 396109a537c..46cf32670dd 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -643,6 +643,7 @@ static void __init early_cmdline_parse(void) static unsigned char ibm_architecture_vec[] = { W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */ W(0xffff0000), W(0x003e0000), /* POWER6 */ + W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */ W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */ 5 - 1, /* 5 option vectors */ -- cgit v1.2.3 From ec59cf710bcf638a895f2ad90cafb1493b95953e Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Wed, 29 Nov 2006 12:05:22 -0600 Subject: [POWERPC] Change ppc64_defconfig to use AUTOFS_V4 not V3 Defconfig ppc64 kernels running under late-model distros may hang in the automounter rc.d script, which seems to be expecting autofs version 4. This patch uses the newer autofs. Signed-off-by: Linas Vepstas Signed-off-by: Paul Mackerras --- arch/powerpc/configs/ppc64_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index be11df7c11a..1c009651f92 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -1386,8 +1386,8 @@ CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS4_FS=m # CONFIG_FUSE_FS is not set # -- cgit v1.2.3 From bbb681779012fae778c0a53081bbb19cf43bca4e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 30 Nov 2006 11:44:09 +1100 Subject: [POWERPC] Allow xmon to build on legacy iSeries xmon still does not run on iSeries, but this allows us to build a combined kernel that includes it. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig.debug | 2 +- arch/powerpc/xmon/xmon.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index ff16063d67f..5cce9048ce0 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -77,7 +77,7 @@ config KGDB_CONSOLE config XMON bool "Include xmon kernel debugger" - depends on DEBUGGER && !PPC_ISERIES + depends on DEBUGGER help Include in-kernel hooks for the xmon kernel monitor/debugger. Unless you are intending to debug the kernel, say N here. diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dc8a3760a98..a34ed49e035 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -44,6 +44,7 @@ #ifdef CONFIG_PPC64 #include #include +#include #endif #include "nonstdio.h" @@ -2580,6 +2581,10 @@ void dump_segments(void) void xmon_init(int enable) { +#ifdef CONFIG_PPC_ISERIES + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return; +#endif if (enable) { __debugger = xmon; __debugger_ipi = xmon_ipi; @@ -2617,6 +2622,10 @@ static struct sysrq_key_op sysrq_xmon_op = static int __init setup_xmon_sysrq(void) { +#ifdef CONFIG_PPC_ISERIES + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return 0; +#endif register_sysrq_key('x', &sysrq_xmon_op); return 0; } -- cgit v1.2.3 From 80814be40e1f0e7e6fc00fdfe0af16268670e0b4 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 30 Nov 2006 11:45:14 +1100 Subject: [POWERPC] Allow CONFIG_BOOTX_TEXT on iSeries and therefore combined builds. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig.debug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 5cce9048ce0..f0e51edde02 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -125,7 +125,7 @@ config BDI_SWITCH config BOOTX_TEXT bool "Support for early boot text console (BootX or OpenFirmware only)" - depends PPC_OF && !PPC_ISERIES + depends PPC_OF help Say Y here to see progress messages from the boot firmware in text mode. Requires either BootX or Open Firmware. -- cgit v1.2.3 From 0470466dbafd1db0815bb884d26a6be431e19f96 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 30 Nov 2006 11:46:22 +1100 Subject: [POWERPC] Fix cputable.h for combined build Remove CPU_FTR_16M_PAGE from the cupfeatures mask at runtime on iSeries. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/mm/hash_utils_64.c | 2 +- arch/powerpc/platforms/iseries/setup.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 1915661c2c8..c0d2a694fa3 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -277,7 +277,7 @@ static void __init htab_init_page_sizes(void) * Not in the device-tree, let's fallback on known size * list for 16M capable GP & GR */ - if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries)) + if (cpu_has_feature(CPU_FTR_16M_PAGE)) memcpy(mmu_psize_defs, mmu_psize_defaults_gp, sizeof(mmu_psize_defaults_gp)); found: diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 1796644ec7d..bdf2afbb60c 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c @@ -643,6 +643,8 @@ static int __init iseries_probe(void) return 0; hpte_init_iSeries(); + /* iSeries does not support 16M pages */ + cur_cpu_spec->cpu_features &= ~CPU_FTR_16M_PAGE; return 1; } -- cgit v1.2.3 From 4eab0e65bd3c9d3065f54e7477fec79c5e939ed6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 30 Nov 2006 16:53:11 +1100 Subject: [POWERPC] iSeries: stop dt_mod.o being rebuilt unnecessarily Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/iseries/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index dee4eb4d8be..13ac3015d91 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile @@ -1,5 +1,7 @@ EXTRA_CFLAGS += -mno-minimal-toc +extra-y += dt.o + 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 @@ -7,5 +9,9 @@ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_VIOPATH) += viopath.o obj-$(CONFIG_MODULES) += ksyms.o +quiet_cmd_dt_strings = DT_STR $@ + cmd_dt_strings = $(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings \ + $< $@ + $(obj)/dt_mod.o: $(obj)/dt.o - @$(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings $(obj)/dt.o $(obj)/dt_mod.o + $(call if_changed,dt_strings) -- cgit v1.2.3 From e73aedba562d1e7777287043afb8e46131ed402e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 30 Nov 2006 16:55:04 +1100 Subject: [POWERPC] iSeries: don't build head_64.o unnecessarily Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index f9ce5d798de..4fe53d08ab8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -76,7 +76,7 @@ obj-y += iomap.o endif ifeq ($(CONFIG_PPC_ISERIES),y) -$(obj)/head_64.o: $(obj)/lparmap.s +extra-y += lparmap.s AFLAGS_head_64.o += -I$(obj) endif -- cgit v1.2.3 From 57933f8fbedba686659b947659418734615611e9 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 1 Dec 2006 12:57:05 -0600 Subject: [POWERPC] Add the e300c3 core to the CPU table. This core is used in Freescale's 831x chips. Signed-off-by: Scott Wood Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/cputable.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 0b01faa3e7e..9d1614c3ce6 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -840,6 +840,17 @@ static struct cpu_spec cpu_specs[] = { .cpu_setup = __setup_cpu_603, .platform = "ppc603", }, + { /* e300c3 on 83xx */ + .pvr_mask = 0x7fff0000, + .pvr_value = 0x00850000, + .cpu_name = "e300c3", + .cpu_features = CPU_FTRS_E300, + .cpu_user_features = COMMON_USER, + .icache_bsize = 32, + .dcache_bsize = 32, + .cpu_setup = __setup_cpu_603, + .platform = "ppc603", + }, { /* default match, we assume split I/D cache & TB (non-601)... */ .pvr_mask = 0x00000000, .pvr_value = 0x00000000, -- cgit v1.2.3 From 04d76b937bdf60a8c9ac34e222e3ca977ab9ddc8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 1 Dec 2006 22:53:48 +0100 Subject: [POWERPC] Linkstation / kurobox support Support for the Kurobox(HG)/LinkStation-I NAS systems by Buffalo Technology, should be also applicable to the PPC TeraStation family. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Kumar Gala Signed-off-by: Paul Mackerras --- arch/powerpc/boot/dts/kuroboxHG.dts | 148 ++ arch/powerpc/configs/linkstation_defconfig | 1583 ++++++++++++++++++++++ arch/powerpc/platforms/embedded6xx/Kconfig | 18 +- arch/powerpc/platforms/embedded6xx/Makefile | 1 + arch/powerpc/platforms/embedded6xx/linkstation.c | 211 +++ arch/powerpc/platforms/embedded6xx/ls_uart.c | 131 ++ 6 files changed, 2089 insertions(+), 3 deletions(-) create mode 100644 arch/powerpc/boot/dts/kuroboxHG.dts create mode 100644 arch/powerpc/configs/linkstation_defconfig create mode 100644 arch/powerpc/platforms/embedded6xx/linkstation.c create mode 100644 arch/powerpc/platforms/embedded6xx/ls_uart.c (limited to 'arch') diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts new file mode 100644 index 00000000000..d06b0b01889 --- /dev/null +++ b/arch/powerpc/boot/dts/kuroboxHG.dts @@ -0,0 +1,148 @@ +/* + * Device Tree Souce for Buffalo KuroboxHG + * + * Choose CONFIG_LINKSTATION to build a kernel for KuroboxHG, or use + * the default configuration linkstation_defconfig. + * + * Based on sandpoint.dts + * + * 2006 (c) G. Liakhovetski + * + * This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + +XXXX add flash parts, rtc, ?? + +build with: "dtc -f -I dts -O dtb -o kuroboxHG.dtb -V 16 kuroboxHG.dts" + + + */ + +/ { + linux,phandle = <1000>; + model = "KuroboxHG"; + compatible = "linkstation"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + linux,phandle = <2000>; + #cpus = <1>; + #address-cells = <1>; + #size-cells = <0>; + + PowerPC,603e { /* Really 8241 */ + linux,phandle = <2100>; + linux,boot-cpu; + device_type = "cpu"; + reg = <0>; + clock-frequency = ; /* Fixed by bootwrapper */ + timebase-frequency = <1F04000>; /* Fixed by bootwrapper */ + bus-frequency = <0>; /* From bootloader */ + /* Following required by dtc but not used */ + i-cache-line-size = <0>; + d-cache-line-size = <0>; + i-cache-size = <4000>; + d-cache-size = <4000>; + }; + }; + + memory { + linux,phandle = <3000>; + device_type = "memory"; + reg = <00000000 08000000>; + }; + + soc10x { /* AFAICT need to make soc for 8245's uarts to be defined */ + linux,phandle = <4000>; + #address-cells = <1>; + #size-cells = <1>; + #interrupt-cells = <2>; + device_type = "soc"; + compatible = "mpc10x"; + store-gathering = <0>; /* 0 == off, !0 == on */ + reg = <80000000 00100000>; + ranges = <80000000 80000000 70000000 /* pci mem space */ + fc000000 fc000000 00100000 /* EUMB */ + fe000000 fe000000 00c00000 /* pci i/o space */ + fec00000 fec00000 00300000 /* pci cfg regs */ + fef00000 fef00000 00100000>; /* pci iack */ + + i2c@80003000 { + linux,phandle = <4300>; + device_type = "i2c"; + compatible = "fsl-i2c"; + reg = <80003000 1000>; + interrupts = <5 2>; + interrupt-parent = <4400>; + }; + + serial@80004500 { + linux,phandle = <4511>; + device_type = "serial"; + compatible = "ns16550"; + reg = <80004500 8>; + clock-frequency = <7c044a8>; + current-speed = <2580>; + interrupts = <9 2>; + interrupt-parent = <4400>; + }; + + serial@80004600 { + linux,phandle = <4512>; + device_type = "serial"; + compatible = "ns16550"; + reg = <80004600 8>; + clock-frequency = <7c044a8>; + current-speed = ; + interrupts = ; + interrupt-parent = <4400>; + }; + + pic@80040000 { + linux,phandle = <4400>; + #interrupt-cells = <2>; + #address-cells = <0>; + device_type = "open-pic"; + compatible = "chrp,open-pic"; + interrupt-controller; + reg = <80040000 40000>; + built-in; + }; + + pci@fec00000 { + linux,phandle = <4500>; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + device_type = "pci"; + compatible = "mpc10x-pci"; + reg = ; + ranges = <01000000 0 0 fe000000 0 00c00000 + 02000000 0 80000000 80000000 0 70000000>; + bus-range = <0 ff>; + clock-frequency = <7f28155>; + interrupt-parent = <4400>; + interrupt-map-mask = ; + interrupt-map = < + /* IDSEL 0x11 - IRQ0 ETH */ + 5800 0 0 1 4400 0 1 + 5800 0 0 2 4400 1 1 + 5800 0 0 3 4400 2 1 + 5800 0 0 4 4400 3 1 + /* IDSEL 0x12 - IRQ1 IDE0 */ + 6000 0 0 1 4400 1 1 + 6000 0 0 2 4400 2 1 + 6000 0 0 3 4400 3 1 + 6000 0 0 4 4400 0 1 + /* IDSEL 0x14 - IRQ3 USB2.0 */ + 7000 0 0 1 4400 3 1 + 7000 0 0 2 4400 3 1 + 7000 0 0 3 4400 3 1 + 7000 0 0 4 4400 3 1 + >; + }; + }; +}; diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig new file mode 100644 index 00000000000..23fd210eb56 --- /dev/null +++ b/arch/powerpc/configs/linkstation_defconfig @@ -0,0 +1,1583 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc4 +# Wed Nov 15 20:36:30 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_IRQ_PER_CPU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_AUDIT_ARCH=y +# CONFIG_DEFAULT_UIMAGE is not set + +# +# Processor support +# +CONFIG_CLASSIC32=y +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_PPC_86xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_PPC_DCR_NATIVE is not set +# CONFIG_PPC_DCR_MMIO is not set +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_SMP is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="-kuroboxHG" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Platform support +# +# CONFIG_PPC_MULTIPLATFORM is not set +CONFIG_EMBEDDED6xx=y +# CONFIG_APUS is not set +# CONFIG_PPC_CELL is not set +# CONFIG_PPC_CELL_NATIVE is not set +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_PPC_INDIRECT_IO is not set +# CONFIG_GENERIC_IOMAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +CONFIG_LINKSTATION=y +# CONFIG_MPC7448HPC2 is not set +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_EV64360 is not set +CONFIG_PPC_GEN550=y +CONFIG_MPC10X_BRIDGE=y +CONFIG_MPC10X_OPENPIC=y +# CONFIG_MPC10X_STORE_GATHERING is not set +# CONFIG_WANT_EARLY_SERIAL is not set +CONFIG_MPIC=y + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_MPIC_WEIRD is not set +# CONFIG_PPC_I8259 is not set +CONFIG_PPC_INDIRECT_PCI=y +CONFIG_FSL_SOC=y +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PCIEPORTBUS is not set +# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +CONFIG_NETFILTER_XT_MATCH_ESP=m +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_POLICY is not set +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=m +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set +# CONFIG_IP_NF_SIP is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_IPRANGE=m +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_AH is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=m +CONFIG_IEEE80211_DEBUG=y +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +CONFIG_IEEE80211_SOFTMAC_DEBUG=y +CONFIG_WIRELESS_EXT=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +CONFIG_MTD_MAP_BANK_WIDTH_1=y +# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xffc00000 +CONFIG_MTD_PHYSMAP_LEN=0x400000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +CONFIG_ATA=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +# CONFIG_PATA_PDC2027X is not set +CONFIG_PATA_SIL680=y +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_R8169=y +# CONFIG_R8169_NAPI is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_HOSTAP is not set +# CONFIG_BCM43XX is not set +# CONFIG_ZD1211RW is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +CONFIG_NETCONSOLE=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_RX is not set +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NET_POLL_CONTROLLER=y + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_INPUT_MISC=y +CONFIG_INPUT_UINPUT=m + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_MPC=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +CONFIG_SENSORS_EEPROM=m +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_M41T00 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_CONSOLE=y +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_AIRCABLE is not set +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ARK3116 is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_FTDI_SIO=y +# CONFIG_USB_SERIAL_FUNSOFT is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_KLSI is not set +# CONFIG_USB_SERIAL_KOBIL_SCT is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set +# CONFIG_USB_SERIAL_MOS7840 is not set +# CONFIG_USB_SERIAL_NAVMAN is not set +# CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OPTION is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set + +# +# RTC drivers +# +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_PLIST=y + +# +# Instrumentation Support +# +CONFIG_PROFILING=y +CONFIG_OPROFILE=m + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FORCED_INLINING=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_DEBUGGER is not set +# CONFIG_BDI_SWITCH is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +# CONFIG_PPC_EARLY_DEBUG is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_MANAGER=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_TWOFISH_COMMON=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig index 910d50a8333..ddbe398fbd4 100644 --- a/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/arch/powerpc/platforms/embedded6xx/Kconfig @@ -74,6 +74,18 @@ config SANDPOINT Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). +config LINKSTATION + bool "Linkstation / Kurobox(HG) from Buffalo" + select MPIC + select FSL_SOC + select PPC_UDBG_16550 if SERIAL_8250 + help + Select LINKSTATION if configuring for one of PPC- (MPC8241) + based NAS systems from Buffalo Technology. So far only + KuroboxHG has been tested. In the future classical Kurobox, + Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based + Terastation systems should be supported too. + config MPC7448HPC2 bool "Freescale MPC7448HPC2(Taiga)" select TSI108_BRIDGE @@ -196,7 +208,7 @@ config PPC_GEN550 depends on SANDPOINT || SPRUCE || PPLUS || \ PRPMC750 || PRPMC800 || LOPEC || \ (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \ - 83xx + 83xx || LINKSTATION default y config FORCE @@ -270,13 +282,13 @@ config EPIC_SERIAL_MODE config MPC10X_BRIDGE bool - depends on POWERPMC250 || LOPEC || SANDPOINT + depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION select PPC_INDIRECT_PCI default y config MPC10X_OPENPIC bool - depends on POWERPMC250 || LOPEC || SANDPOINT + depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION default y config MPC10X_STORE_GATHERING diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile index fa499fe5929..d3d11a3cd65 100644 --- a/arch/powerpc/platforms/embedded6xx/Makefile +++ b/arch/powerpc/platforms/embedded6xx/Makefile @@ -2,3 +2,4 @@ # Makefile for the 6xx/7xx/7xxxx linux kernel. # obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o +obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c new file mode 100644 index 00000000000..61599d919ea --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/linkstation.c @@ -0,0 +1,211 @@ +/* + * Board setup routines for the Buffalo Linkstation / Kurobox Platform. + * + * Copyright (C) 2006 G. Liakhovetski (g.liakhovetski@gmx.de) + * + * Based on sandpoint.c by Mark A. Greer + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of + * any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static struct mtd_partition linkstation_physmap_partitions[] = { + { + .name = "mtd_firmimg", + .offset = 0x000000, + .size = 0x300000, + }, + { + .name = "mtd_bootcode", + .offset = 0x300000, + .size = 0x070000, + }, + { + .name = "mtd_status", + .offset = 0x370000, + .size = 0x010000, + }, + { + .name = "mtd_conf", + .offset = 0x380000, + .size = 0x080000, + }, + { + .name = "mtd_allflash", + .offset = 0x000000, + .size = 0x400000, + }, + { + .name = "mtd_data", + .offset = 0x310000, + .size = 0x0f0000, + }, +}; + +static int __init add_bridge(struct device_node *dev) +{ + int len; + struct pci_controller *hose; + int *bus_range; + + printk("Adding PCI host bridge %s\n", dev->full_name); + + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) + printk(KERN_WARNING "Can't get bus-range for %s, assume" + " bus 0\n", dev->full_name); + + hose = pcibios_alloc_controller(); + if (hose == NULL) + return -ENOMEM; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + hose->arch_data = dev; + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, 1); + + return 0; +} + +static void __init linkstation_setup_arch(void) +{ + struct device_node *np; +#ifdef CONFIG_MTD_PHYSMAP + physmap_set_partitions(linkstation_physmap_partitions, + ARRAY_SIZE(linkstation_physmap_partitions)); +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + + /* Lookup PCI host bridges */ + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) + add_bridge(np); + + printk(KERN_INFO "BUFFALO Network Attached Storage Series\n"); + printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n"); +} + +/* + * Interrupt setup and service. Interrrupts on the linkstation come + * from the four PCI slots plus onboard 8241 devices: I2C, DUART. + */ +static void __init linkstation_init_IRQ(void) +{ + struct mpic *mpic; + struct device_node *dnp; + void *prop; + int size; + phys_addr_t paddr; + + dnp = of_find_node_by_type(NULL, "open-pic"); + if (dnp == NULL) + return; + + prop = (struct device_node *)get_property(dnp, "reg", &size); + paddr = (phys_addr_t)of_translate_address(dnp, prop); + + mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC "); + BUG_ON(mpic == NULL); + + /* PCI IRQs */ + mpic_assign_isu(mpic, 0, paddr + 0x10200); + + /* I2C */ + mpic_assign_isu(mpic, 1, paddr + 0x11000); + + /* ttyS0, ttyS1 */ + mpic_assign_isu(mpic, 2, paddr + 0x11100); + + mpic_init(mpic); +} + +extern void avr_uart_configure(void); +extern void avr_uart_send(const char); + +static void linkstation_restart(char *cmd) +{ + local_irq_disable(); + + /* Reset system via AVR */ + avr_uart_configure(); + /* Send reboot command */ + avr_uart_send('C'); + + for(;;) /* Spin until reset happens */ + avr_uart_send('G'); /* "kick" */ +} + +static void linkstation_power_off(void) +{ + local_irq_disable(); + + /* Power down system via AVR */ + avr_uart_configure(); + /* send shutdown command */ + avr_uart_send('E'); + + for(;;) /* Spin until power-off happens */ + avr_uart_send('G'); /* "kick" */ + /* NOTREACHED */ +} + +static void linkstation_halt(void) +{ + linkstation_power_off(); + /* NOTREACHED */ +} + +static void linkstation_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Buffalo Technology\n"); + seq_printf(m, "machine\t\t: Linkstation I/Kurobox(HG)\n"); +} + +static int __init linkstation_probe(void) +{ + unsigned long root; + + root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "linkstation")) + return 0; + return 1; +} + +define_machine(linkstation){ + .name = "Buffalo Linkstation", + .probe = linkstation_probe, + .setup_arch = linkstation_setup_arch, + .init_IRQ = linkstation_init_IRQ, + .show_cpuinfo = linkstation_show_cpuinfo, + .get_irq = mpic_get_irq, + .restart = linkstation_restart, + .power_off = linkstation_power_off, + .halt = linkstation_halt, + .calibrate_decr = generic_calibrate_decr, +}; diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c new file mode 100644 index 00000000000..31bcdae8482 --- /dev/null +++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void __iomem *avr_addr; +static unsigned long avr_clock; + +static struct work_struct wd_work; + +static void wd_stop(void *unused) +{ + const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"; + int i = 0, rescue = 8; + int len = strlen(string); + + while (rescue--) { + int j; + char lsr = in_8(avr_addr + UART_LSR); + + if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) { + for (j = 0; j < 16 && i < len; j++, i++) + out_8(avr_addr + UART_TX, string[i]); + if (i == len) { + /* Read "OK" back: 4ms for the last "KKKK" + plus a couple bytes back */ + msleep(7); + printk("linkstation: disarming the AVR watchdog: "); + while (in_8(avr_addr + UART_LSR) & UART_LSR_DR) + printk("%c", in_8(avr_addr + UART_RX)); + break; + } + } + msleep(17); + } + printk("\n"); +} + +#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600) + +void avr_uart_configure(void) +{ + unsigned char cval = UART_LCR_WLEN8; + unsigned int quot = AVR_QUOT(avr_clock); + + if (!avr_addr || !avr_clock) + return; + + out_8(avr_addr + UART_LCR, cval); /* initialise UART */ + out_8(avr_addr + UART_MCR, 0); + out_8(avr_addr + UART_IER, 0); + + cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR; + + out_8(avr_addr + UART_LCR, cval); /* Set character format */ + + out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ + out_8(avr_addr + UART_DLL, quot & 0xff); /* LS of divisor */ + out_8(avr_addr + UART_DLM, quot >> 8); /* MS of divisor */ + out_8(avr_addr + UART_LCR, cval); /* reset DLAB */ + out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */ +} + +void avr_uart_send(const char c) +{ + if (!avr_addr || !avr_clock) + return; + + out_8(avr_addr + UART_TX, c); + out_8(avr_addr + UART_TX, c); + out_8(avr_addr + UART_TX, c); + out_8(avr_addr + UART_TX, c); +} + +static void __init ls_uart_init(void) +{ + local_irq_disable(); + +#ifndef CONFIG_SERIAL_8250 + out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */ + out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO | + UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); /* clear FIFOs */ + out_8(avr_addr + UART_FCR, 0); + out_8(avr_addr + UART_IER, 0); + + /* Clear up interrupts */ + (void) in_8(avr_addr + UART_LSR); + (void) in_8(avr_addr + UART_RX); + (void) in_8(avr_addr + UART_IIR); + (void) in_8(avr_addr + UART_MSR); +#endif + avr_uart_configure(); + + local_irq_enable(); +} + +static int __init ls_uarts_init(void) +{ + struct device_node *avr; + phys_addr_t phys_addr; + int len; + + avr = of_find_node_by_path("/soc10x/serial@80004500"); + if (!avr) + return -EINVAL; + + avr_clock = *(u32*)get_property(avr, "clock-frequency", &len); + phys_addr = ((u32*)get_property(avr, "reg", &len))[0]; + + if (!avr_clock || !phys_addr) + return -EINVAL; + + avr_addr = ioremap(phys_addr, 32); + if (!avr_addr) + return -EFAULT; + + ls_uart_init(); + + INIT_WORK(&wd_work, wd_stop, NULL); + schedule_work(&wd_work); + + return 0; +} + +late_initcall(ls_uarts_init); -- cgit v1.2.3 From f8485350c22b25f5b9804d89cb8fdf6626d0f5cb Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Sat, 2 Dec 2006 13:26:57 +0200 Subject: [POWERPC] Replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc. Signed-off-by: Yan Burman Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/ibmebus.c | 3 +-- arch/powerpc/kernel/pci_64.c | 3 +-- arch/powerpc/kernel/rtas_flash.c | 4 +--- arch/powerpc/kernel/smp-tbsync.c | 3 +-- arch/powerpc/platforms/iseries/iommu.c | 4 +--- arch/powerpc/platforms/iseries/viopath.c | 3 +-- arch/powerpc/platforms/pseries/reconfig.c | 3 +-- arch/powerpc/sysdev/qe_lib/ucc_fast.c | 4 +--- arch/powerpc/sysdev/qe_lib/ucc_slow.c | 4 +--- 9 files changed, 9 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 8e515797de6..82bd2f10770 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -214,11 +214,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node( return NULL; } - dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); + dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); if (!dev) { return NULL; } - memset(dev, 0, sizeof(struct ibmebus_dev)); dev->ofdev.node = of_node_get(dn); diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index afee470de92..6fa9a0a5c8d 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -330,7 +330,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, struct pci_dev *dev; const char *type; - dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); if (!dev) return NULL; type = get_property(node, "device_type", NULL); @@ -339,7 +339,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, DBG(" create device, devfn: %x, type: %s\n", devfn, type); - memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = node; dev->dev.parent = bus->bridge; diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 6f6fc977cb3..b9561d30051 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -681,14 +681,12 @@ static int initialize_flash_pde_data(const char *rtas_call_name, int *status; int token; - dp->data = kmalloc(buf_size, GFP_KERNEL); + dp->data = kzalloc(buf_size, GFP_KERNEL); if (dp->data == NULL) { remove_flash_pde(dp); return -ENOMEM; } - memset(dp->data, 0, buf_size); - /* * This code assumes that the status int is the first member of the * struct diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index e1970f83f14..bc892e69b4f 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -116,8 +116,7 @@ void __devinit smp_generic_give_timebase(void) printk("Synchronizing timebase\n"); /* if this fails then this kernel won't work anyway... */ - tbsync = kmalloc( sizeof(*tbsync), GFP_KERNEL ); - memset( tbsync, 0, sizeof(*tbsync) ); + tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); mb(); running = 1; diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index ee0a4e42e4f..d7a756d5135 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -115,12 +115,10 @@ void iommu_table_getparms_iSeries(unsigned long busno, { struct iommu_table_cb *parms; - parms = kmalloc(sizeof(*parms), GFP_KERNEL); + parms = kzalloc(sizeof(*parms), GFP_KERNEL); if (parms == NULL) panic("PCI_DMA: TCE Table Allocation failed."); - memset(parms, 0, sizeof(*parms)); - parms->itc_busno = busno; parms->itc_slotno = slotno; parms->itc_virtbus = virtbus; diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c index 04e07e5da0c..84e7ee2c086 100644 --- a/arch/powerpc/platforms/iseries/viopath.c +++ b/arch/powerpc/platforms/iseries/viopath.c @@ -119,10 +119,9 @@ static int proc_viopath_show(struct seq_file *m, void *v) struct device_node *node; const char *sysid; - buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL); + buf = kzalloc(HW_PAGE_SIZE, GFP_KERNEL); if (!buf) return 0; - memset(buf, 0, HW_PAGE_SIZE); handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE, DMA_FROM_DEVICE); diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 1773103354b..4ad33e41b00 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -268,11 +268,10 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length static struct property *new_property(const char *name, const int length, const unsigned char *value, struct property *last) { - struct property *new = kmalloc(sizeof(*new), GFP_KERNEL); + struct property *new = kzalloc(sizeof(*new), GFP_KERNEL); if (!new) return NULL; - memset(new, 0, sizeof(*new)); if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL))) goto cleanup; diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c index 75fa3104a43..e657559bea9 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c @@ -216,14 +216,12 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc return -EINVAL; } - uccf = (struct ucc_fast_private *) - kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); + uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); if (!uccf) { uccf_err ("ucc_fast_init: No memory for UCC slow data structure!"); return -ENOMEM; } - memset(uccf, 0, sizeof(struct ucc_fast_private)); /* Fill fast UCC structure */ uccf->uf_info = uf_info; diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c index a49da6b73ec..47b56203f47 100644 --- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c +++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c @@ -168,14 +168,12 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc return -EINVAL; } - uccs = (struct ucc_slow_private *) - kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); + uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); if (!uccs) { uccs_err ("ucc_slow_init: No memory for UCC slow data structure!"); return -ENOMEM; } - memset(uccs, 0, sizeof(struct ucc_slow_private)); /* Fill slow UCC structure */ uccs->us_info = us_info; -- cgit v1.2.3 From 872455e2ca12843e3dd16ebde1ce02dccc4bf99f Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 3 Dec 2006 20:52:27 +0300 Subject: [POWERPC] Fix debug printks for 32-bit resources in the PCI code Cure the damage done by the former PCI debug printks fix for the case of 64-bit resources (commit 685143ac1f7a579a3fac9c7f2ac8f82e95af6864) which broke it for the plain vanilla 32-bit resources... Signed-off-by: Sergei Shtylyov Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index b08238f3050..2f54cd81dea 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -100,7 +100,7 @@ pcibios_fixup_resources(struct pci_dev *dev) continue; if (res->end == 0xffffffff) { DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", - pci_name(dev), i, res->start, res->end); + pci_name(dev), i, (u64)res->start, (u64)res->end); res->end -= res->start; res->start = 0; res->flags |= IORESOURCE_UNSET; @@ -116,11 +116,9 @@ pcibios_fixup_resources(struct pci_dev *dev) if (offset != 0) { res->start += offset; res->end += offset; -#ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", - i, res->flags, pci_name(dev), - res->start - offset, res->start); -#endif + DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", + i, res->flags, pci_name(dev), + (u64)res->start - offset, (u64)res->start); } } @@ -256,7 +254,7 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + (u64)res->start, (u64)res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -307,7 +305,7 @@ reparent_resources(struct resource *parent, struct resource *res) for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", - p->name, p->start, p->end, res->name); + p->name, (u64)p->start, (u64)p->end, res->name); } return 0; } @@ -363,7 +361,7 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) } if (request_resource(pr, res)) { DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", - res->start, res->end); + (u64)res->start, (u64)res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); @@ -481,14 +479,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) struct resource *pr, *r = &dev->resource[idx]; DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", - pci_name(dev), idx, r->start, r->end, r->flags); + pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", - pr, pr->start, pr->end, pr->flags); + pr, (u64)pr->start, (u64)pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; r->end -= r->start; @@ -961,7 +959,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res->flags = IORESOURCE_IO; res->start = ranges[2]; DBG("PCI: IO 0x%llx -> 0x%llx\n", - res->start, res->start + size - 1); + (u64)res->start, (u64)res->start + size - 1); break; case 2: /* memory space */ memno = 0; @@ -983,7 +981,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res->flags |= IORESOURCE_PREFETCH; res->start = ranges[na+2]; DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, - res->start, res->start + size - 1); + (u64)res->start, (u64)res->start + size - 1); } break; } -- cgit v1.2.3 From c019d49b69237f195b1a31d90facf738a371841f Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Mon, 4 Dec 2006 09:09:08 +0100 Subject: [ARM] 3972/1: AT91: Update board.h Replace the 'is_b' variable with 'slot_b' in at91_mmc_data. Also add the new 'chipselect' variable for CF/PCMCIA and 'bus_width_16' variable for NAND. This (and previous patches) will unfortunately break the current MMC, USB Gadget and PCMCIA drivers. Updates and fixes for those drivers will be submitted to the various subsystem maintainers. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- arch/arm/mach-at91rm9200/board-carmeva.c | 2 +- arch/arm/mach-at91rm9200/board-csb337.c | 2 +- arch/arm/mach-at91rm9200/board-dk.c | 2 +- arch/arm/mach-at91rm9200/board-eb9200.c | 2 +- arch/arm/mach-at91rm9200/board-ek.c | 2 +- arch/arm/mach-at91rm9200/board-kb9202.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91rm9200/board-carmeva.c index 5cd68e6001e..654f0379550 100644 --- a/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/arch/arm/mach-at91rm9200/board-carmeva.c @@ -88,7 +88,7 @@ static struct at91_udc_data __initdata carmeva_udc_data = { // }; static struct at91_mmc_data __initdata carmeva_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, .det_pin = AT91_PIN_PB10, .wp_pin = AT91_PIN_PC14, diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91rm9200/board-csb337.c index 8eeae491ce7..b8bb8052607 100644 --- a/arch/arm/mach-at91rm9200/board-csb337.c +++ b/arch/arm/mach-at91rm9200/board-csb337.c @@ -99,7 +99,7 @@ static struct at91_cf_data __initdata csb337_cf_data = { static struct at91_mmc_data __initdata csb337_mmc_data = { .det_pin = AT91_PIN_PD5, - .is_b = 0, + .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PD6, }; diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91rm9200/board-dk.c index 314e1f769ea..7522bf91bce 100644 --- a/arch/arm/mach-at91rm9200/board-dk.c +++ b/arch/arm/mach-at91rm9200/board-dk.c @@ -95,7 +95,7 @@ static struct at91_cf_data __initdata dk_cf_data = { }; static struct at91_mmc_data __initdata dk_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91rm9200/board-eb9200.c index 65e867ba2df..80b72cf7264 100644 --- a/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/arch/arm/mach-at91rm9200/board-eb9200.c @@ -87,7 +87,7 @@ static struct at91_cf_data __initdata eb9200_cf_data = { }; static struct at91_mmc_data __initdata eb9200_mmc_data = { - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91rm9200/board-ek.c index 9fcfa066635..c4fdb415f20 100644 --- a/arch/arm/mach-at91rm9200/board-ek.c +++ b/arch/arm/mach-at91rm9200/board-ek.c @@ -89,7 +89,7 @@ static struct at91_udc_data __initdata ek_udc_data = { static struct at91_mmc_data __initdata ek_mmc_data = { .det_pin = AT91_PIN_PB27, - .is_b = 0, + .slot_b = 0, .wire4 = 1, .wp_pin = AT91_PIN_PA17, }; diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91rm9200/board-kb9202.c index 35a954a44b1..759d8191854 100644 --- a/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/arch/arm/mach-at91rm9200/board-kb9202.c @@ -84,7 +84,7 @@ static struct at91_udc_data __initdata kb9202_udc_data = { static struct at91_mmc_data __initdata kb9202_mmc_data = { .det_pin = AT91_PIN_PB2, - .is_b = 0, + .slot_b = 0, .wire4 = 1, }; -- cgit v1.2.3 From 26916264c17b5af8a3eaaf83b128f85cf1107cff Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 4 Dec 2006 15:39:47 +0100 Subject: [S390] remove salipl memory detection. The SALIPL entry point has an needless memory detection routine as we later check the memory size again. The SALIPL code also uses diagnose 0x060 if we are running under VM, but this diagnose is not compatible with the 64 bit addressing mode. The solution is to get rid of this code and rely on the memory detection in the startup code. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head.S | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 0cf59bb7a85..8f8c802f1bc 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S @@ -418,24 +418,6 @@ start: .gotr: l %r10,.tbl # EBCDIC to ASCII table tr 0(240,%r8),0(%r10) - stidp __LC_CPUID # Are we running on VM maybe - cli __LC_CPUID,0xff - bnz .test - .long 0x83300060 # diag 3,0,x'0060' - storage size - b .done -.test: - mvc 0x68(8),.pgmnw # set up pgm check handler - l %r2,.fourmeg - lr %r3,%r2 - bctr %r3,%r0 # 4M-1 -.loop: iske %r0,%r3 - ar %r3,%r2 -.pgmx: - sr %r3,%r2 - la %r3,1(%r3) -.done: - l %r1,.memsize - st %r3,ARCH_OFFSET(%r1) slr %r0,%r0 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) @@ -443,9 +425,6 @@ start: .tbl: .long _ebcasc # translate table .cmd: .long COMMAND_LINE # address of command line buffer .parm: .long PARMAREA -.memsize: .long memory_size -.fourmeg: .long 0x00400000 # 4M -.pgmnw: .long 0x00080000,.pgmx .lowcase: .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f -- cgit v1.2.3 From feb5babead7f8058f0108ec59c3e7c2df666bd67 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:39:52 +0100 Subject: [S390] Remove unused GENERIC_BUST_SPINLOCK from Kconfig. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 245b81bc715..5b04c4095c8 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -33,9 +33,6 @@ config GENERIC_CALIBRATE_DELAY config GENERIC_TIME def_bool y -config GENERIC_BUST_SPINLOCK - bool - mainmenu "Linux Kernel Configuration" config S390 -- cgit v1.2.3 From 03a4d2087644f5477d9a9742e75a329f23b279e6 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 4 Dec 2006 15:39:58 +0100 Subject: [S390] Add ipl/reipl loadparm attribute. If multiple kernel images are installed on one DASD, the loadparm can be used to select the boot configuration. This patch introduces the following two new sysfs attributes: /sys/firmware/ipl/loadparm: shows loadparm of current system (ro) /sys/firmware/reipl/ccw/loadparm: loadparm used for next reboot (rw) Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 1f5e782b3d0..36f0d3004f9 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -13,12 +13,20 @@ #include #include #include +#include #include #include #include #include +#include #define IPL_PARM_BLOCK_VERSION 0 +#define LOADPARM_LEN 8 + +extern char s390_readinfo_sccb[]; +#define SCCB_VALID (*((__u16*)&s390_readinfo_sccb[6]) == 0x0010) +#define SCCB_LOADPARM (&s390_readinfo_sccb[24]) +#define SCCB_FLAG (s390_readinfo_sccb[91]) enum ipl_type { IPL_TYPE_NONE = 1, @@ -289,9 +297,25 @@ static struct attribute_group ipl_fcp_attr_group = { /* CCW ipl device attributes */ +static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page) +{ + char loadparm[LOADPARM_LEN + 1] = {}; + + if (!SCCB_VALID) + return sprintf(page, "#unknown#\n"); + memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); + EBCASC(loadparm, LOADPARM_LEN); + strstrip(loadparm); + return sprintf(page, "%s\n", loadparm); +} + +static struct subsys_attribute sys_ipl_ccw_loadparm_attr = + __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL); + static struct attribute *ipl_ccw_attrs[] = { &sys_ipl_type_attr.attr, &sys_ipl_device_attr.attr, + &sys_ipl_ccw_loadparm_attr.attr, NULL, }; @@ -348,8 +372,57 @@ static struct attribute_group reipl_fcp_attr_group = { DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", reipl_block_ccw->ipl_info.ccw.devno); +static void reipl_get_ascii_loadparm(char *loadparm) +{ + memcpy(loadparm, &reipl_block_ccw->ipl_info.ccw.load_param, + LOADPARM_LEN); + EBCASC(loadparm, LOADPARM_LEN); + loadparm[LOADPARM_LEN] = 0; + strstrip(loadparm); +} + +static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) +{ + char buf[LOADPARM_LEN + 1]; + + reipl_get_ascii_loadparm(buf); + return sprintf(page, "%s\n", buf); +} + +static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys, + const char *buf, size_t len) +{ + int i, lp_len; + + /* ignore trailing newline */ + lp_len = len; + if ((len > 0) && (buf[len - 1] == '\n')) + lp_len--; + /* loadparm can have max 8 characters and must not start with a blank */ + if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' '))) + return -EINVAL; + /* loadparm can only contain "a-z,A-Z,0-9,SP,." */ + for (i = 0; i < lp_len; i++) { + if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') || + (buf[i] == '.')) + continue; + return -EINVAL; + } + /* initialize loadparm with blanks */ + memset(&reipl_block_ccw->ipl_info.ccw.load_param, ' ', LOADPARM_LEN); + /* copy and convert to ebcdic */ + memcpy(&reipl_block_ccw->ipl_info.ccw.load_param, buf, lp_len); + ASCEBC(reipl_block_ccw->ipl_info.ccw.load_param, LOADPARM_LEN); + return len; +} + +static struct subsys_attribute sys_reipl_ccw_loadparm_attr = + __ATTR(loadparm, 0644, reipl_ccw_loadparm_show, + reipl_ccw_loadparm_store); + static struct attribute *reipl_ccw_attrs[] = { &sys_reipl_ccw_device_attr.attr, + &sys_reipl_ccw_loadparm_attr.attr, NULL, }; @@ -571,11 +644,14 @@ void do_reipl(void) { struct ccw_dev_id devid; static char buf[100]; + char loadparm[LOADPARM_LEN + 1]; switch (reipl_type) { case IPL_TYPE_CCW: + reipl_get_ascii_loadparm(loadparm); printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n", reipl_block_ccw->ipl_info.ccw.devno); + printk(KERN_EMERG "loadparm = '%s'\n", loadparm); break; case IPL_TYPE_FCP: printk(KERN_EMERG "reboot on fcp device:\n"); @@ -592,7 +668,12 @@ void do_reipl(void) reipl_ccw_dev(&devid); break; case IPL_METHOD_CCW_VM: - sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno); + if (strlen(loadparm) == 0) + sprintf(buf, "IPL %X", + reipl_block_ccw->ipl_info.ccw.devno); + else + sprintf(buf, "IPL %X LOADPARM '%s'", + reipl_block_ccw->ipl_info.ccw.devno, loadparm); cpcmd(buf, NULL, 0, NULL); break; case IPL_METHOD_CCW_DIAG: @@ -746,6 +827,17 @@ static int __init reipl_ccw_init(void) reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw); reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; + /* check if read scp info worked and set loadparm */ + if (SCCB_VALID) + memcpy(reipl_block_ccw->ipl_info.ccw.load_param, + SCCB_LOADPARM, LOADPARM_LEN); + else + /* read scp info failed: set empty loadparm (EBCDIC blanks) */ + memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, + LOADPARM_LEN); + /* FIXME: check for diag308_set_works when enabling diag ccw reipl */ + if (!MACHINE_IS_VM) + sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO; if (ipl_get_type() == IPL_TYPE_CCW) reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; reipl_capabilities |= IPL_TYPE_CCW; @@ -827,13 +919,11 @@ static int __init dump_ccw_init(void) return 0; } -extern char s390_readinfo_sccb[]; - static int __init dump_fcp_init(void) { int rc; - if(!(s390_readinfo_sccb[91] & 0x2)) + if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) return 0; /* LDIPL DUMP is not installed */ if (!diag308_set_works) return 0; -- cgit v1.2.3 From 3902e47628dcaf79b2c7a6a59f6978d968eff288 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 4 Dec 2006 15:40:05 +0100 Subject: [S390] No panic for failed reboot If reboot fails (e.g. because wrong devno has been specified by the user), we should just stop all cpus, but should not trigger a kernel panic. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 36f0d3004f9..60ba1454bfe 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -697,7 +697,8 @@ void do_reipl(void) diag308(DIAG308_IPL, NULL); break; } - panic("reipl failed!\n"); + printk(KERN_EMERG "reboot failed!\n"); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); } static void do_dump(void) -- cgit v1.2.3 From 5986b0e845bc52a53ff3cafd74d341e81c95658d Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Mon, 4 Dec 2006 15:40:13 +0100 Subject: [S390] Use diag instead of ccw reipl. Since the diag 308 reipl method is superior to the ccw method, we should use it whenever it is possible. We can do that, if the user has not specified a new reipl ccw device and the system has been ipled from a ccw device. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 60ba1454bfe..ec127826f22 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -664,6 +664,8 @@ void do_reipl(void) switch (reipl_method) { case IPL_METHOD_CCW_CIO: devid.devno = reipl_block_ccw->ipl_info.ccw.devno; + if (ipl_get_type() == IPL_TYPE_CCW && devid.devno == ipl_devno) + diag308(DIAG308_IPL, NULL); devid.ssid = 0; reipl_ccw_dev(&devid); break; -- cgit v1.2.3 From 6b4044bdd158aa9ad07b3f68d1c7598036d3ee58 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:20 +0100 Subject: [S390] extmem unbalanced spin_lock. segment save will exit with a lock held if the passed segment doesn't exist. Any subsequent call to segment_save will lead to a deadlock. Fix this and give up the lock before returning. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/extmem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 226275d5c4f..077af540494 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -563,8 +563,9 @@ segment_save(char *name) seg = segment_by_name (name); if (seg == NULL) { - PRINT_ERR ("could not find segment %s in segment_save, please report to linux390@de.ibm.com\n",name); - return; + PRINT_ERR("could not find segment %s in segment_save, please " + "report to linux390@de.ibm.com\n", name); + goto out; } startpfn = seg->start_addr >> PAGE_SHIFT; -- cgit v1.2.3 From 15e9b586e0bd3692e2a21c5be178810d9d32214e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:26 +0100 Subject: [S390] Reset infrastructure for re-IPL. In case of re-IPL and diag308 doesn't work we have to reset all devices manually and wait synchronously that each reset finished. This patch adds the necessary infrastucture and the first exploiter of it. Subsystems that need to add a function that needs to be called at re-IPL may register/unregister this function via struct reset_call { struct reset_call *next; void (*fn)(void); }; void register_reset_call(struct reset_call *reset); void unregister_reset_call(struct reset_call *reset); When the registered function get called the context is: - all cpus beside the current one are stopped - all machine checks and interrupts are disabled - prefixing is disabled - a default machine check handler is available for use The registered functions may not take any locks are sleep. For the common I/O layer part of this patch: Introduce a reset_call css_reset that does the following: - clear all subchannels - perform a rchp on all channel paths and wait for the resulting machine checks This replaces the calls to clear_all_subchannels() and cio_reset_channel_paths() for kexec and ccw reipl. reipl_ccw_dev() now uses reipl_find_schid() to determine the subchannel id for a given device id. Also remove cio_reset_channel_paths() and friends since they are not needed anymore. Signed-off-by: Heiko Carstens Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/ipl.c | 54 ++++++++++++++++++++++++++++++++++++ arch/s390/kernel/machine_kexec.c | 9 ++---- arch/s390/kernel/reipl.S | 17 ++---------- arch/s390/kernel/reipl64.S | 16 ++++------- arch/s390/kernel/relocate_kernel.S | 5 +--- arch/s390/kernel/relocate_kernel64.S | 5 +--- arch/s390/kernel/reset.S | 48 ++++++++++++++++++++++++++++++++ 8 files changed, 115 insertions(+), 41 deletions(-) create mode 100644 arch/s390/kernel/reset.S (limited to 'arch') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index aa978978d3d..a81881c9b29 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -4,7 +4,7 @@ EXTRA_AFLAGS := -traditional -obj-y := bitmap.o traps.o time.o process.o \ +obj-y := bitmap.o traps.o time.o process.o reset.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index ec127826f22..77f4aff630f 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -19,6 +19,7 @@ #include #include #include +#include #define IPL_PARM_BLOCK_VERSION 0 #define LOADPARM_LEN 8 @@ -1024,3 +1025,56 @@ static int __init s390_ipl_init(void) } __initcall(s390_ipl_init); + +static LIST_HEAD(rcall); +static DEFINE_MUTEX(rcall_mutex); + +void register_reset_call(struct reset_call *reset) +{ + mutex_lock(&rcall_mutex); + list_add(&reset->list, &rcall); + mutex_unlock(&rcall_mutex); +} +EXPORT_SYMBOL_GPL(register_reset_call); + +void unregister_reset_call(struct reset_call *reset) +{ + mutex_lock(&rcall_mutex); + list_del(&reset->list); + mutex_unlock(&rcall_mutex); +} +EXPORT_SYMBOL_GPL(unregister_reset_call); + +static void do_reset_calls(void) +{ + struct reset_call *reset; + + list_for_each_entry(reset, &rcall, list) + reset->fn(); +} + +extern void reset_mcck_handler(void); + +void s390_reset_system(void) +{ + struct _lowcore *lc; + + /* Disable all interrupts/machine checks */ + __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); + + /* Stack for interrupt/machine check handler */ + lc = (struct _lowcore *)(unsigned long) store_prefix(); + lc->panic_stack = S390_lowcore.panic_stack; + + /* Disable prefixing */ + set_prefix(0); + + /* Disable lowcore protection */ + __ctl_clear_bit(0,28); + + /* Set new machine check handler */ + S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; + S390_lowcore.mcck_new_psw.addr = + PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; + do_reset_calls(); +} diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 60b1ea9f946..202bf1fdfe3 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -22,6 +22,7 @@ #include #include #include +#include static void kexec_halt_all_cpus(void *); @@ -62,12 +63,6 @@ machine_shutdown(void) NORET_TYPE void machine_kexec(struct kimage *image) { - clear_all_subchannels(); - cio_reset_channel_paths(); - - /* Disable lowcore protection */ - ctl_clear_bit(0,28); - on_each_cpu(kexec_halt_all_cpus, image, 0, 0); for (;;); } @@ -98,6 +93,8 @@ kexec_halt_all_cpus(void *kernel_image) cpu_relax(); } + s390_reset_system(); + image = (struct kimage *) kernel_image; data_mover = (relocate_kernel_t) (page_to_pfn(image->control_code_page) << PAGE_SHIFT); diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 0340477f3b0..f9434d42ce9 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S @@ -11,19 +11,10 @@ .globl do_reipl_asm do_reipl_asm: basr %r13,0 .Lpg0: lpsw .Lnewpsw-.Lpg0(%r13) - - # switch off lowcore protection - -.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13) - stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13) - ni .Lctlsave1-.Lpg0(%r13),0xef - lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13) - - # do store status of all registers +.Lpg1: # do store status of all registers stm %r0,%r15,__LC_GPREGS_SAVE_AREA stctl %c0,%c15,__LC_CREGS_SAVE_AREA - mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13) stam %a0,%a15,__LC_AREGS_SAVE_AREA stpx __LC_PREFIX_SAVE_AREA stckc .Lclkcmp-.Lpg0(%r13) @@ -56,8 +47,7 @@ do_reipl_asm: basr %r13,0 .L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 jz .L003 bas %r14,.Ldisab-.Lpg0(%r13) -.L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID +.L003: st %r1,__LC_SUBCHANNEL_ID lpsw 0 sigp 0,0,0(6) .Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) @@ -65,9 +55,6 @@ do_reipl_asm: basr %r13,0 .align 8 .Lclkcmp: .quad 0x0000000000000000 .Lall: .long 0xff000000 -.Lnull: .long 0x00000000 -.Lctlsave1: .long 0x00000000 -.Lctlsave2: .long 0x00000000 .align 8 .Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 .Lpcnew: .long 0x00080000,0x80000000+.Lecs diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S index de7435054f7..f18ef260ca2 100644 --- a/arch/s390/kernel/reipl64.S +++ b/arch/s390/kernel/reipl64.S @@ -10,10 +10,10 @@ #include .globl do_reipl_asm do_reipl_asm: basr %r13,0 +.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) +.Lpg1: # do store status of all registers - # do store status of all registers - -.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13) + stg %r1,.Lregsave-.Lpg0(%r13) lghi %r1,0x1000 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1) lg %r0,.Lregsave-.Lpg0(%r13) @@ -27,11 +27,7 @@ do_reipl_asm: basr %r13,0 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1) stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1) - lpswe .Lnewpsw-.Lpg0(%r13) -.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13) - stctg %c0,%c0,.Lregsave-.Lpg0(%r13) - ni .Lregsave+4-.Lpg0(%r13),0xef - lctlg %c0,%c0,.Lregsave-.Lpg0(%r13) + lctlg %c6,%c6,.Lall-.Lpg0(%r13) lgr %r1,%r2 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) stsch .Lschib-.Lpg0(%r13) @@ -56,8 +52,7 @@ do_reipl_asm: basr %r13,0 .L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 jz .L003 bas %r14,.Ldisab-.Lpg0(%r13) -.L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID +.L003: st %r1,__LC_SUBCHANNEL_ID lhi %r1,0 # mode 0 = esa slr %r0,%r0 # set cpuid to zero sigp %r1,%r0,0x12 # switch to esa mode @@ -70,7 +65,6 @@ do_reipl_asm: basr %r13,0 .Lclkcmp: .quad 0x0000000000000000 .Lall: .quad 0x00000000ff000000 .Lregsave: .quad 0x0000000000000000 -.Lnull: .long 0x0000000000000000 .align 16 /* * These addresses have to be 31 bit otherwise diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S index f9899ff2e5b..3b456b80bce 100644 --- a/arch/s390/kernel/relocate_kernel.S +++ b/arch/s390/kernel/relocate_kernel.S @@ -26,8 +26,7 @@ relocate_kernel: basr %r13,0 # base address .base: - stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external) - spx zero64-.base(%r13) # absolute addressing mode + stnsm sys_msk-.base(%r13),0xfb # disable DAT stctl %c0,%c15,ctlregs-.base(%r13) stm %r0,%r15,gprregs-.base(%r13) la %r1,load_psw-.base(%r13) @@ -97,8 +96,6 @@ lpsw 0 # hopefully start new kernel... .align 8 - zero64: - .quad 0 load_psw: .long 0x00080000,0x80000000 sys_msk: diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S index 4fb443042d9..1f9ea2067b5 100644 --- a/arch/s390/kernel/relocate_kernel64.S +++ b/arch/s390/kernel/relocate_kernel64.S @@ -27,8 +27,7 @@ relocate_kernel: basr %r13,0 # base address .base: - stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs - spx zero64-.base(%r13) # absolute addressing mode + stnsm sys_msk-.base(%r13),0xfb # disable DAT stctg %c0,%c15,ctlregs-.base(%r13) stmg %r0,%r15,gprregs-.base(%r13) lghi %r0,3 @@ -100,8 +99,6 @@ lpsw 0 # hopefully start new kernel... .align 8 - zero64: - .quad 0 load_psw: .long 0x00080000,0x80000000 sys_msk: diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S new file mode 100644 index 00000000000..be8688c0665 --- /dev/null +++ b/arch/s390/kernel/reset.S @@ -0,0 +1,48 @@ +/* + * arch/s390/kernel/reset.S + * + * Copyright (C) IBM Corp. 2006 + * Author(s): Heiko Carstens + */ + +#include +#include + +#ifdef CONFIG_64BIT + + .globl reset_mcck_handler +reset_mcck_handler: + basr %r13,0 +0: lg %r15,__LC_PANIC_STACK # load panic stack + aghi %r15,-STACK_FRAME_OVERHEAD + lg %r1,s390_reset_mcck_handler-0b(%r13) + ltgr %r1,%r1 + jz 1f + basr %r14,%r1 +1: la %r1,4095 + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) + lpswe __LC_MCK_OLD_PSW + + .globl s390_reset_mcck_handler +s390_reset_mcck_handler: + .quad 0 + +#else /* CONFIG_64BIT */ + + .globl reset_mcck_handler +reset_mcck_handler: + basr %r13,0 +0: l %r15,__LC_PANIC_STACK # load panic stack + ahi %r15,-STACK_FRAME_OVERHEAD + l %r1,s390_reset_mcck_handler-0b(%r13) + ltr %r1,%r1 + jz 1f + basr %r14,%r1 +1: lm %r0,%r15,__LC_GPREGS_SAVE_AREA + lpsw __LC_MCK_OLD_PSW + + .globl s390_reset_mcck_handler +s390_reset_mcck_handler: + .long 0 + +#endif /* CONFIG_64BIT */ -- cgit v1.2.3 From 740b5706b9c4b3767f597b3ea76654c6f2a800b2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:30 +0100 Subject: [S390] cpcmd <-> __cpcmd calling issues In case of reipl cpcmd gets called when all other cpus are not running anymore. To prevent deadlocks change __cpcmd so that it doesn't take any locks and call cpcmd or __cpcmd, whatever is correct in the current context. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/cpcmd.c | 18 +++++++++++------- arch/s390/kernel/ipl.c | 10 +++++----- arch/s390/kernel/setup.c | 10 +++++----- 3 files changed, 21 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 1eae74e72f9..a5972f1541f 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c @@ -21,14 +21,15 @@ static DEFINE_SPINLOCK(cpcmd_lock); static char cpcmd_buf[241]; /* - * the caller of __cpcmd has to ensure that the response buffer is below 2 GB + * __cpcmd has some restrictions over cpcmd + * - the response buffer must reside below 2GB (if any) + * - __cpcmd is unlocked and therefore not SMP-safe */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) { - unsigned long flags, cmdlen; + unsigned cmdlen; int return_code, return_len; - spin_lock_irqsave(&cpcmd_lock, flags); cmdlen = strlen(cmd); BUG_ON(cmdlen > 240); memcpy(cpcmd_buf, cmd, cmdlen); @@ -74,7 +75,6 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) : "+d" (reg3) : "d" (reg2) : "cc"); return_code = (int) reg3; } - spin_unlock_irqrestore(&cpcmd_lock, flags); if (response_code != NULL) *response_code = return_code; return return_len; @@ -82,15 +82,18 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) EXPORT_SYMBOL(__cpcmd); -#ifdef CONFIG_64BIT int cpcmd(const char *cmd, char *response, int rlen, int *response_code) { char *lowbuf; int len; + unsigned long flags; if ((rlen == 0) || (response == NULL) - || !((unsigned long)response >> 31)) + || !((unsigned long)response >> 31)) { + spin_lock_irqsave(&cpcmd_lock, flags); len = __cpcmd(cmd, response, rlen, response_code); + spin_unlock_irqrestore(&cpcmd_lock, flags); + } else { lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); if (!lowbuf) { @@ -98,7 +101,9 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code) "cpcmd: could not allocate response buffer\n"); return -ENOMEM; } + spin_lock_irqsave(&cpcmd_lock, flags); len = __cpcmd(cmd, lowbuf, rlen, response_code); + spin_unlock_irqrestore(&cpcmd_lock, flags); memcpy(response, lowbuf, rlen); kfree(lowbuf); } @@ -106,4 +111,3 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code) } EXPORT_SYMBOL(cpcmd); -#endif /* CONFIG_64BIT */ diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 77f4aff630f..101b003cfab 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -677,7 +677,7 @@ void do_reipl(void) else sprintf(buf, "IPL %X LOADPARM '%s'", reipl_block_ccw->ipl_info.ccw.devno, loadparm); - cpcmd(buf, NULL, 0, NULL); + __cpcmd(buf, NULL, 0, NULL); break; case IPL_METHOD_CCW_DIAG: diag308(DIAG308_SET, reipl_block_ccw); @@ -691,12 +691,12 @@ void do_reipl(void) diag308(DIAG308_IPL, NULL); break; case IPL_METHOD_FCP_RO_VM: - cpcmd("IPL", NULL, 0, NULL); + __cpcmd("IPL", NULL, 0, NULL); break; case IPL_METHOD_NONE: default: if (MACHINE_IS_VM) - cpcmd("IPL", NULL, 0, NULL); + __cpcmd("IPL", NULL, 0, NULL); diag308(DIAG308_IPL, NULL); break; } @@ -732,9 +732,9 @@ static void do_dump(void) case IPL_METHOD_CCW_VM: dump_smp_stop_all(); sprintf(buf, "STORE STATUS"); - cpcmd(buf, NULL, 0, NULL); + __cpcmd(buf, NULL, 0, NULL); sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); - cpcmd(buf, NULL, 0, NULL); + __cpcmd(buf, NULL, 0, NULL); break; case IPL_METHOD_CCW_DIAG: diag308(DIAG308_SET, dump_block_ccw); diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2aa13e8e000..9bbef0c6558 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -229,11 +229,11 @@ static void __init conmode_default(void) char *ptr; if (MACHINE_IS_VM) { - __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); + cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); console_devno = simple_strtoul(query_buffer + 5, NULL, 16); ptr = strstr(query_buffer, "SUBCHANNEL ="); console_irq = simple_strtoul(ptr + 13, NULL, 16); - __cpcmd("QUERY TERM", query_buffer, 1024, NULL); + cpcmd("QUERY TERM", query_buffer, 1024, NULL); ptr = strstr(query_buffer, "CONMODE"); /* * Set the conmode to 3215 so that the device recognition @@ -242,7 +242,7 @@ static void __init conmode_default(void) * 3215 and the 3270 driver will try to access the console * device (3215 as console and 3270 as normal tty). */ - __cpcmd("TERM CONMODE 3215", NULL, 0, NULL); + cpcmd("TERM CONMODE 3215", NULL, 0, NULL); if (ptr == NULL) { #if defined(CONFIG_SCLP_CONSOLE) SET_CONSOLE_SCLP; @@ -299,14 +299,14 @@ static void do_machine_restart_nonsmp(char * __unused) static void do_machine_halt_nonsmp(void) { if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) - cpcmd(vmhalt_cmd, NULL, 0, NULL); + __cpcmd(vmhalt_cmd, NULL, 0, NULL); signal_processor(smp_processor_id(), sigp_stop_and_store_status); } static void do_machine_power_off_nonsmp(void) { if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) - cpcmd(vmpoff_cmd, NULL, 0, NULL); + __cpcmd(vmpoff_cmd, NULL, 0, NULL); signal_processor(smp_processor_id(), sigp_stop_and_store_status); } -- cgit v1.2.3 From c6b5b847a7cf11f131c43fe0041443ec11697fc7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:33 +0100 Subject: [S390] cpu shutdown rework Let one master cpu kill all other cpus instead of sending an external interrupt to all other cpus so they can kill themselves. Simplifies reipl/shutdown functions a lot. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ipl.c | 24 +-------- arch/s390/kernel/machine_kexec.c | 65 ++++++------------------ arch/s390/kernel/smp.c | 104 ++++++++++++--------------------------- 3 files changed, 49 insertions(+), 144 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 101b003cfab..a36bea1188d 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -576,23 +576,6 @@ static struct subsys_attribute dump_type_attr = static decl_subsys(dump, NULL, NULL); -#ifdef CONFIG_SMP -static void dump_smp_stop_all(void) -{ - int cpu; - preempt_disable(); - for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) - continue; - while (signal_processor(cpu, sigp_stop) == sigp_busy) - udelay(10); - } - preempt_enable(); -} -#else -#define dump_smp_stop_all() do { } while (0) -#endif - /* * Shutdown actions section */ @@ -724,13 +707,13 @@ static void do_dump(void) switch (dump_method) { case IPL_METHOD_CCW_CIO: - dump_smp_stop_all(); + smp_send_stop(); devid.devno = dump_block_ccw->ipl_info.ccw.devno; devid.ssid = 0; reipl_ccw_dev(&devid); break; case IPL_METHOD_CCW_VM: - dump_smp_stop_all(); + smp_send_stop(); sprintf(buf, "STORE STATUS"); __cpcmd(buf, NULL, 0, NULL); sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); @@ -1059,9 +1042,6 @@ void s390_reset_system(void) { struct _lowcore *lc; - /* Disable all interrupts/machine checks */ - __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); - /* Stack for interrupt/machine check handler */ lc = (struct _lowcore *)(unsigned long) store_prefix(); lc->panic_stack = S390_lowcore.panic_stack; diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 202bf1fdfe3..def5caf8f72 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -1,15 +1,10 @@ /* * arch/s390/kernel/machine_kexec.c * - * (C) Copyright IBM Corp. 2005 + * Copyright IBM Corp. 2005,2006 * - * Author(s): Rolf Adelsberger - * - */ - -/* - * s390_machine_kexec.c - handle the transition of Linux booting another kernel - * on the S390 architecture. + * Author(s): Rolf Adelsberger, + * Heiko Carstens */ #include @@ -24,81 +19,53 @@ #include #include -static void kexec_halt_all_cpus(void *); - -typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long); +typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long); extern const unsigned char relocate_kernel[]; extern const unsigned long long relocate_kernel_len; -int -machine_kexec_prepare(struct kimage *image) +int machine_kexec_prepare(struct kimage *image) { - unsigned long reboot_code_buffer; + void *reboot_code_buffer; /* We don't support anything but the default image type for now. */ if (image->type != KEXEC_TYPE_DEFAULT) return -EINVAL; /* Get the destination where the assembler code should be copied to.*/ - reboot_code_buffer = page_to_pfn(image->control_code_page)<control_code_page); /* Then copy it */ - memcpy((void *) reboot_code_buffer, relocate_kernel, - relocate_kernel_len); + memcpy(reboot_code_buffer, relocate_kernel, relocate_kernel_len); return 0; } -void -machine_kexec_cleanup(struct kimage *image) +void machine_kexec_cleanup(struct kimage *image) { } -void -machine_shutdown(void) +void machine_shutdown(void) { printk(KERN_INFO "kexec: machine_shutdown called\n"); } -NORET_TYPE void -machine_kexec(struct kimage *image) -{ - on_each_cpu(kexec_halt_all_cpus, image, 0, 0); - for (;;); -} - extern void pfault_fini(void); -static void -kexec_halt_all_cpus(void *kernel_image) +void machine_kexec(struct kimage *image) { - static atomic_t cpuid = ATOMIC_INIT(-1); - int cpu; - struct kimage *image; relocate_kernel_t data_mover; + preempt_disable(); #ifdef CONFIG_PFAULT if (MACHINE_IS_VM) pfault_fini(); #endif - - if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1) - signal_processor(smp_processor_id(), sigp_stop); - - /* Wait for all other cpus to enter stopped state */ - for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) - continue; - while (!smp_cpu_not_running(cpu)) - cpu_relax(); - } - + smp_send_stop(); s390_reset_system(); - image = (struct kimage *) kernel_image; - data_mover = (relocate_kernel_t) - (page_to_pfn(image->control_code_page) << PAGE_SHIFT); + data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); /* Call the moving routine */ - (*data_mover) (&image->head, image->start); + (*data_mover)(&image->head, image->start); + for (;;); } diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 62822245f9b..b549a43ed08 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -230,18 +230,37 @@ static inline void do_store_status(void) } } +static inline void do_wait_for_stop(void) +{ + int cpu; + + /* Wait for all other cpus to enter stopped state */ + for_each_online_cpu(cpu) { + if (cpu == smp_processor_id()) + continue; + while(!smp_cpu_not_running(cpu)) + cpu_relax(); + } +} + /* * this function sends a 'stop' sigp to all other CPUs in the system. * it goes straight through. */ void smp_send_stop(void) { + /* Disable all interrupts/machine checks */ + __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); + /* write magic number to zero page (absolute 0) */ lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; /* stop other processors. */ do_send_stop(); + /* wait until other processors are stopped */ + do_wait_for_stop(); + /* store status of other processors. */ do_store_status(); } @@ -250,88 +269,28 @@ void smp_send_stop(void) * Reboot, halt and power_off routines for SMP. */ -static void do_machine_restart(void * __unused) -{ - int cpu; - static atomic_t cpuid = ATOMIC_INIT(-1); - - if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1) - signal_processor(smp_processor_id(), sigp_stop); - - /* Wait for all other cpus to enter stopped state */ - for_each_online_cpu(cpu) { - if (cpu == smp_processor_id()) - continue; - while(!smp_cpu_not_running(cpu)) - cpu_relax(); - } - - /* Store status of other cpus. */ - do_store_status(); - - /* - * Finally call reipl. Because we waited for all other - * cpus to enter this function we know that they do - * not hold any s390irq-locks (the cpus have been - * interrupted by an external interrupt and s390irq - * locks are always held disabled). - */ - do_reipl(); -} - void machine_restart_smp(char * __unused) { - on_each_cpu(do_machine_restart, NULL, 0, 0); -} - -static void do_wait_for_stop(void) -{ - unsigned long cr[16]; - - __ctl_store(cr, 0, 15); - cr[0] &= ~0xffff; - cr[6] = 0; - __ctl_load(cr, 0, 15); - for (;;) - enabled_wait(); -} - -static void do_machine_halt(void * __unused) -{ - static atomic_t cpuid = ATOMIC_INIT(-1); - - if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) { - smp_send_stop(); - if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) - cpcmd(vmhalt_cmd, NULL, 0, NULL); - signal_processor(smp_processor_id(), - sigp_stop_and_store_status); - } - do_wait_for_stop(); + smp_send_stop(); + do_reipl(); } void machine_halt_smp(void) { - on_each_cpu(do_machine_halt, NULL, 0, 0); -} - -static void do_machine_power_off(void * __unused) -{ - static atomic_t cpuid = ATOMIC_INIT(-1); - - if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) { - smp_send_stop(); - if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) - cpcmd(vmpoff_cmd, NULL, 0, NULL); - signal_processor(smp_processor_id(), - sigp_stop_and_store_status); - } - do_wait_for_stop(); + smp_send_stop(); + if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) + __cpcmd(vmhalt_cmd, NULL, 0, NULL); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); + for (;;); } void machine_power_off_smp(void) { - on_each_cpu(do_machine_power_off, NULL, 0, 0); + smp_send_stop(); + if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) + __cpcmd(vmpoff_cmd, NULL, 0, NULL); + signal_processor(smp_processor_id(), sigp_stop_and_store_status); + for (;;); } /* @@ -860,4 +819,3 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_get_cpu); EXPORT_SYMBOL(smp_put_cpu); - -- cgit v1.2.3 From baf2aeb3d9e286add823bcaea5442ad4ee34f6e4 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:36 +0100 Subject: [S390] Misaligned wait PSW at memory detection. If the memory detection code would ever reach the point where it would load the wait psw, it would generate a specification exception and the system would crash at ipl time. This is because of a misaligned wait psw. It needs to be on a double word boundary instead of a word boundary. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head31.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 0a2c929486a..adb082aeada 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -131,10 +131,11 @@ startup_continue: .long init_thread_union .Lpmask: .byte 0 -.align 8 + .align 8 .Lpcext:.long 0x00080000,0x80000000 .Lcr: .long 0x00 # place holder for cr0 + .align 8 .Lwaitsclp: .long 0x010a0000,0x80000000 + .Lsclph .Lrcp: -- cgit v1.2.3 From 36a2bd425d9b3ba2a40b0653e08d17702c78558e Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:38 +0100 Subject: [S390] Cleanup memory_chunk array usage. Need this at yet another file and don't want to add yet another extern... Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head31.S | 2 +- arch/s390/kernel/setup.c | 7 ++----- arch/s390/mm/extmem.c | 11 ++++------- 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index adb082aeada..9817c327aab 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -157,7 +157,7 @@ startup_continue: slr %r4,%r4 # set start of chunk to zero slr %r5,%r5 # set end of chunk to zero slr %r6,%r6 # set access code to zero - la %r10, MEMORY_CHUNKS # number of chunks + la %r10,MEMORY_CHUNKS # number of chunks .Lloop: tprot 0(%r5),0 # test protection of first byte ipm %r7 diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 9bbef0c6558..b1a8ad967f9 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -64,11 +64,8 @@ unsigned int console_devno = -1; unsigned int console_irq = -1; unsigned long memory_size = 0; unsigned long machine_flags = 0; -struct { - unsigned long addr, size, type; -} memory_chunk[MEMORY_CHUNKS] = { { 0 } }; -#define CHUNK_READ_WRITE 0 -#define CHUNK_READ_ONLY 1 + +struct mem_chunk memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 077af540494..375c2c4f6b7 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -14,12 +14,13 @@ #include #include #include +#include #include #include #include #include #include -#include +#include #define DCSS_DEBUG /* Debug messages on/off */ @@ -82,10 +83,6 @@ static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", "EW/EN-MIXED" }; -extern struct { - unsigned long addr, size, type; -} memory_chunk[MEMORY_CHUNKS]; - /* * Create the 8 bytes, ebcdic VM segment name from * an ascii name. @@ -249,8 +246,8 @@ segment_overlaps_storage(struct dcss_segment *seg) { int i; - for (i=0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - if (memory_chunk[i].type != 0) + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { + if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) continue; -- cgit v1.2.3 From 29b08d2bae854f66d3cfd5f57aaf2e7c2c7fce32 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:40 +0100 Subject: [S390] pfault code cleanup. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/machine_kexec.c | 8 +------- arch/s390/kernel/smp.c | 13 +++---------- arch/s390/kernel/traps.c | 25 +------------------------ arch/s390/mm/fault.c | 28 +++++++++++++++++++++++++--- 4 files changed, 30 insertions(+), 44 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index def5caf8f72..f6d9bcc0f75 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -49,18 +49,12 @@ void machine_shutdown(void) printk(KERN_INFO "kexec: machine_shutdown called\n"); } -extern void pfault_fini(void); - void machine_kexec(struct kimage *image) { relocate_kernel_t data_mover; - preempt_disable(); -#ifdef CONFIG_PFAULT - if (MACHINE_IS_VM) - pfault_fini(); -#endif smp_send_stop(); + pfault_fini(); s390_reset_system(); data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b549a43ed08..19090f7d4f5 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -460,8 +460,6 @@ __init smp_count_cpus(void) */ extern void init_cpu_timer(void); extern void init_cpu_vtimer(void); -extern int pfault_init(void); -extern void pfault_fini(void); int __devinit start_secondary(void *cpuvoid) { @@ -473,11 +471,9 @@ int __devinit start_secondary(void *cpuvoid) #ifdef CONFIG_VIRT_TIMER init_cpu_vtimer(); #endif -#ifdef CONFIG_PFAULT /* Enable pfault pseudo page faults on this cpu. */ - if (MACHINE_IS_VM) - pfault_init(); -#endif + pfault_init(); + /* Mark this cpu as online */ cpu_set(smp_processor_id(), cpu_online_map); /* Switch on interrupts */ @@ -667,11 +663,8 @@ __cpu_disable(void) } cpu_clear(cpu, cpu_online_map); -#ifdef CONFIG_PFAULT /* Disable pfault pseudo page faults on this cpu. */ - if (MACHINE_IS_VM) - pfault_fini(); -#endif + pfault_fini(); memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals)); memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals)); diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 92ecffbc8d8..475dbb88443 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -58,12 +58,6 @@ int sysctl_userprocess_debug = 0; extern pgm_check_handler_t do_protection_exception; extern pgm_check_handler_t do_dat_exception; -#ifdef CONFIG_PFAULT -extern int pfault_init(void); -extern void pfault_fini(void); -extern void pfault_interrupt(__u16 error_code); -static ext_int_info_t ext_int_pfault; -#endif extern pgm_check_handler_t do_monitor_call; #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) @@ -739,22 +733,5 @@ void __init trap_init(void) pgm_check_table[0x1C] = &space_switch_exception; pgm_check_table[0x1D] = &hfp_sqrt_exception; pgm_check_table[0x40] = &do_monitor_call; - - if (MACHINE_IS_VM) { -#ifdef CONFIG_PFAULT - /* - * Try to get pfault pseudo page faults going. - */ - if (register_early_external_interrupt(0x2603, pfault_interrupt, - &ext_int_pfault) != 0) - panic("Couldn't request external interrupt 0x2603"); - - if (pfault_init() == 0) - return; - - /* Tough luck, no pfault. */ - unregister_early_external_interrupt(0x2603, pfault_interrupt, - &ext_int_pfault); -#endif - } + pfault_irq_init(); } diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 1c323bbfda9..cd85e34d870 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifndef CONFIG_64BIT #define __FAIL_ADDR_MASK 0x7ffff000 @@ -394,6 +395,7 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code) /* * 'pfault' pseudo page faults routines. */ +static ext_int_info_t ext_int_pfault; static int pfault_disable = 0; static int __init nopfault(char *str) @@ -422,7 +424,7 @@ int pfault_init(void) __PF_RES_FIELD }; int rc; - if (pfault_disable) + if (!MACHINE_IS_VM || pfault_disable) return -1; asm volatile( " diag %1,%0,0x258\n" @@ -440,7 +442,7 @@ void pfault_fini(void) pfault_refbk_t refbk = { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL }; - if (pfault_disable) + if (!MACHINE_IS_VM || pfault_disable) return; __ctl_clear_bit(0,9); asm volatile( @@ -500,5 +502,25 @@ pfault_interrupt(__u16 error_code) set_tsk_need_resched(tsk); } } -#endif +void __init pfault_irq_init(void) +{ + if (!MACHINE_IS_VM) + return; + + /* + * Try to get pfault pseudo page faults going. + */ + if (register_early_external_interrupt(0x2603, pfault_interrupt, + &ext_int_pfault) != 0) + panic("Couldn't request external interrupt 0x2603"); + + if (pfault_init() == 0) + return; + + /* Tough luck, no pfault. */ + pfault_disable = 1; + unregister_early_external_interrupt(0x2603, pfault_interrupt, + &ext_int_pfault); +} +#endif -- cgit v1.2.3 From d57de5a36791cb1b7285649c62f183b0d3505f7d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:42 +0100 Subject: [S390] Use diag260 for memory size detection. Avoid the tprot loop if diag260 works and reports that there are no holes in memory. The tprot instruction can lead to a significant delay in the ipl process if the virtual guest has a lot of memory and the host is under memory pressure. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head64.S | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 42f54d48244..cc6dbc57eb9 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -70,7 +70,22 @@ startup_continue: sgr %r5,%r5 # set src,length and pad to zero mvcle %r2,%r4,0 # clear mem jo .-4 # branch back, if not finish + # set program check new psw mask + mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) + larl %r1,.Lslowmemdetect # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + lghi %r1,0xc + diag %r0,%r1,0x260 # get memory size of virtual machine + cgr %r0,%r1 # different? -> old detection routine + jne .Lslowmemdetect + aghi %r1,1 # size is one more than end + larl %r2,memory_chunk + stg %r1,8(%r2) # store size of chunk + larl %r2,memory_size + stg %r1,0(%r2) # set memory size + j .Ldonemem +.Lslowmemdetect: l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word .Lservicecall: stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts @@ -139,8 +154,6 @@ startup_continue: .int 0x100000 .Lfchunk: - # set program check new psw mask - mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # # find memory chunks. -- cgit v1.2.3 From 59f35d53fde3987d071ea1c9bf1c9ba29fcb69fe Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Mon, 4 Dec 2006 15:40:45 +0100 Subject: [S390] Add dynamic size check for usercopy functions. Use a wrapper for copy_to/from_user to chose the best usercopy method. The mvcos instruction is better for sizes greater than 256 bytes, if mvcos is not available a page table walk is better for sizes greater than 1024 bytes. Also removed the redundant copy_to/from_user_std_small functions. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/lib/Makefile | 2 +- arch/s390/lib/uaccess_mvcos.c | 27 ++++++-- arch/s390/lib/uaccess_pt.c | 153 ++++++++++++++++++++++++++++++++++++++++++ arch/s390/lib/uaccess_std.c | 67 +++++------------- 4 files changed, 190 insertions(+), 59 deletions(-) create mode 100644 arch/s390/lib/uaccess_pt.c (limited to 'arch') diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index b0cfa6c4883..b5f94cf3bde 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile @@ -4,7 +4,7 @@ EXTRA_AFLAGS := -traditional -lib-y += delay.o string.o uaccess_std.o +lib-y += delay.o string.o uaccess_std.o uaccess_pt.o lib-$(CONFIG_32BIT) += div64.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 121b2935a42..f9a23d57eb7 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c @@ -27,6 +27,9 @@ #define SLR "slgr" #endif +extern size_t copy_from_user_std(size_t, const void __user *, void *); +extern size_t copy_to_user_std(size_t, void __user *, const void *); + size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) { register unsigned long reg0 asm("0") = 0x81UL; @@ -66,6 +69,13 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) return size; } +size_t copy_from_user_mvcos_check(size_t size, const void __user *ptr, void *x) +{ + if (size <= 256) + return copy_from_user_std(size, ptr, x); + return copy_from_user_mvcos(size, ptr, x); +} + size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) { register unsigned long reg0 asm("0") = 0x810000UL; @@ -95,6 +105,13 @@ size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) return size; } +size_t copy_to_user_mvcos_check(size_t size, void __user *ptr, const void *x) +{ + if (size <= 256) + return copy_to_user_std(size, ptr, x); + return copy_to_user_mvcos(size, ptr, x); +} + size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from) { register unsigned long reg0 asm("0") = 0x810081UL; @@ -145,18 +162,16 @@ size_t clear_user_mvcos(size_t size, void __user *to) return size; } -extern size_t copy_from_user_std_small(size_t, const void __user *, void *); -extern size_t copy_to_user_std_small(size_t, void __user *, const void *); extern size_t strnlen_user_std(size_t, const char __user *); extern size_t strncpy_from_user_std(size_t, const char __user *, char *); extern int futex_atomic_op(int, int __user *, int, int *); extern int futex_atomic_cmpxchg(int __user *, int, int); struct uaccess_ops uaccess_mvcos = { - .copy_from_user = copy_from_user_mvcos, - .copy_from_user_small = copy_from_user_std_small, - .copy_to_user = copy_to_user_mvcos, - .copy_to_user_small = copy_to_user_std_small, + .copy_from_user = copy_from_user_mvcos_check, + .copy_from_user_small = copy_from_user_std, + .copy_to_user = copy_to_user_mvcos_check, + .copy_to_user_small = copy_to_user_std, .copy_in_user = copy_in_user_mvcos, .clear_user = clear_user_mvcos, .strnlen_user = strnlen_user_std, diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c new file mode 100644 index 00000000000..8741bdc0929 --- /dev/null +++ b/arch/s390/lib/uaccess_pt.c @@ -0,0 +1,153 @@ +/* + * arch/s390/lib/uaccess_pt.c + * + * User access functions based on page table walks. + * + * Copyright IBM Corp. 2006 + * Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com) + */ + +#include +#include +#include +#include + +static inline int __handle_fault(struct mm_struct *mm, unsigned long address, + int write_access) +{ + struct vm_area_struct *vma; + int ret = -EFAULT; + + down_read(&mm->mmap_sem); + vma = find_vma(mm, address); + if (unlikely(!vma)) + goto out; + if (unlikely(vma->vm_start > address)) { + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto out; + if (expand_stack(vma, address)) + goto out; + } + + if (!write_access) { + /* page not present, check vm flags */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + goto out; + } else { + if (!(vma->vm_flags & VM_WRITE)) + goto out; + } + +survive: + switch (handle_mm_fault(mm, vma, address, write_access)) { + case VM_FAULT_MINOR: + current->min_flt++; + break; + case VM_FAULT_MAJOR: + current->maj_flt++; + break; + case VM_FAULT_SIGBUS: + goto out_sigbus; + case VM_FAULT_OOM: + goto out_of_memory; + default: + BUG(); + } + ret = 0; +out: + up_read(&mm->mmap_sem); + return ret; + +out_of_memory: + up_read(&mm->mmap_sem); + if (current->pid == 1) { + yield(); + goto survive; + } + printk("VM: killing process %s\n", current->comm); + return ret; + +out_sigbus: + up_read(&mm->mmap_sem); + current->thread.prot_addr = address; + current->thread.trap_no = 0x11; + force_sig(SIGBUS, current); + return ret; +} + +static inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, + size_t n, int write_user) +{ + struct mm_struct *mm = current->mm; + unsigned long offset, pfn, done, size; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + void *from, *to; + + done = 0; +retry: + spin_lock(&mm->page_table_lock); + do { + pgd = pgd_offset(mm, uaddr); + if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) + goto fault; + + pmd = pmd_offset(pgd, uaddr); + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) + goto fault; + + pte = pte_offset_map(pmd, uaddr); + if (!pte || !pte_present(*pte) || + (write_user && !pte_write(*pte))) + goto fault; + + pfn = pte_pfn(*pte); + if (!pfn_valid(pfn)) + goto out; + + offset = uaddr & (PAGE_SIZE - 1); + size = min(n - done, PAGE_SIZE - offset); + if (write_user) { + to = (void *)((pfn << PAGE_SHIFT) + offset); + from = kptr + done; + } else { + from = (void *)((pfn << PAGE_SHIFT) + offset); + to = kptr + done; + } + memcpy(to, from, size); + done += size; + uaddr += size; + } while (done < n); +out: + spin_unlock(&mm->page_table_lock); + return n - done; +fault: + spin_unlock(&mm->page_table_lock); + if (__handle_fault(mm, uaddr, write_user)) + return n - done; + goto retry; +} + +size_t copy_from_user_pt(size_t n, const void __user *from, void *to) +{ + size_t rc; + + if (segment_eq(get_fs(), KERNEL_DS)) { + memcpy(to, (void __kernel __force *) from, n); + return 0; + } + rc = __user_copy_pt((unsigned long) from, to, n, 0); + if (unlikely(rc)) + memset(to + n - rc, 0, rc); + return rc; +} + +size_t copy_to_user_pt(size_t n, void __user *to, const void *from) +{ + if (segment_eq(get_fs(), KERNEL_DS)) { + memcpy((void __kernel __force *) to, from, n); + return 0; + } + return __user_copy_pt((unsigned long) to, (void *) from, n, 1); +} diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index f44f0078b35..2d549ed2e11 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -28,6 +28,9 @@ #define SLR "slgr" #endif +extern size_t copy_from_user_pt(size_t n, const void __user *from, void *to); +extern size_t copy_to_user_pt(size_t n, void __user *to, const void *from); + size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) { unsigned long tmp1, tmp2; @@ -69,34 +72,11 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) return size; } -size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) +size_t copy_from_user_std_check(size_t size, const void __user *ptr, void *x) { - unsigned long tmp1, tmp2; - - tmp1 = 0UL; - asm volatile( - "0: mvcp 0(%0,%2),0(%1),%3\n" - " "SLR" %0,%0\n" - " j 5f\n" - "1: la %4,255(%1)\n" /* %4 = ptr + 255 */ - " "LHI" %3,-4096\n" - " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ - " "SLR" %4,%1\n" - " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" - "2: mvcp 0(%4,%2),0(%1),%3\n" - " "SLR" %0,%4\n" - " "ALR" %2,%4\n" - "3:"LHI" %4,-1\n" - " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,4f\n" - " xc 0(1,%2),0(%2)\n" - "4: ex %4,0(%3)\n" - "5:\n" - EX_TABLE(0b,1b) EX_TABLE(2b,3b) - : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); - return size; + if (size <= 1024) + return copy_from_user_std(size, ptr, x); + return copy_from_user_pt(size, ptr, x); } size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) @@ -130,28 +110,11 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) return size; } -size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x) +size_t copy_to_user_std_check(size_t size, void __user *ptr, const void *x) { - unsigned long tmp1, tmp2; - - tmp1 = 0UL; - asm volatile( - "0: mvcs 0(%0,%1),0(%2),%3\n" - " "SLR" %0,%0\n" - " j 3f\n" - "1: la %4,255(%1)\n" /* ptr + 255 */ - " "LHI" %3,-4096\n" - " nr %4,%3\n" /* (ptr + 255) & -4096UL */ - " "SLR" %4,%1\n" - " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 3f\n" - "2: mvcs 0(%4,%1),0(%2),%3\n" - " "SLR" %0,%4\n" - "3:\n" - EX_TABLE(0b,1b) EX_TABLE(2b,3b) - : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) - : : "cc", "memory"); - return size; + if (size <= 1024) + return copy_to_user_std(size, ptr, x); + return copy_to_user_pt(size, ptr, x); } size_t copy_in_user_std(size_t size, void __user *to, const void __user *from) @@ -343,10 +306,10 @@ int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval) } struct uaccess_ops uaccess_std = { - .copy_from_user = copy_from_user_std, - .copy_from_user_small = copy_from_user_std_small, - .copy_to_user = copy_to_user_std, - .copy_to_user_small = copy_to_user_std_small, + .copy_from_user = copy_from_user_std_check, + .copy_from_user_small = copy_from_user_std, + .copy_to_user = copy_to_user_std_check, + .copy_to_user_small = copy_to_user_std, .copy_in_user = copy_in_user_std, .clear_user = clear_user_std, .strnlen_user = strnlen_user_std, -- cgit v1.2.3 From 236257eee99a35d67d3feab0769bded83efdc3ec Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:47 +0100 Subject: [S390] lockdep: show held locks when showing a stackdump Follow i386/x86_64: lockdep can be used to print held locks when printing a backtrace. This can be useful when debugging things like 'scheduling while atomic' asserts. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/traps.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 475dbb88443..3cbb0dcf1f1 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c @@ -129,7 +129,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) } } -void show_trace(struct task_struct *task, unsigned long * stack) +void show_trace(struct task_struct *task, unsigned long *stack) { register unsigned long __r15 asm ("15"); unsigned long sp; @@ -151,6 +151,9 @@ void show_trace(struct task_struct *task, unsigned long * stack) __show_trace(sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); printk("\n"); + if (!task) + task = current; + debug_show_held_locks(task); } void show_stack(struct task_struct *task, unsigned long *sp) -- cgit v1.2.3 From 1681cedaee9f8dcb59d499a9277bc3a190a2378d Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Mon, 4 Dec 2006 15:40:49 +0100 Subject: [S390] set KBUILD_IMAGE. Set KBUILD_IMAGE to a sane value. This enables "make rpm" Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/Makefile | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 5deb9f7544a..6598e526857 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -35,6 +35,9 @@ cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) +#KBUILD_IMAGE is necessary for make rpm +KBUILD_IMAGE :=arch/s390/boot/image + # # Prevent tail-call optimizations, to get clearer backtraces: # -- cgit v1.2.3 From 09252e77ed13b1b412329825bad5797fbdd5a5c8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:51 +0100 Subject: [S390] Convert extmem spin_lock into a mutex. There's no need to have a spin_lock here, but need sleepable context for vmem_map. Therefore convert the spin_lock into a mutex. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/extmem.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 375c2c4f6b7..9e9bc48463a 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -78,7 +78,7 @@ struct dcss_segment { int segcnt; }; -static DEFINE_SPINLOCK(dcss_lock); +static DEFINE_MUTEX(dcss_lock); static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", "EW/EN-MIXED" }; @@ -114,7 +114,7 @@ segment_by_name (char *name) struct list_head *l; struct dcss_segment *tmp, *retval = NULL; - assert_spin_locked(&dcss_lock); + BUG_ON(!mutex_is_locked(&dcss_lock)); dcss_mkname (name, dcss_name); list_for_each (l, &dcss_list) { tmp = list_entry (l, struct dcss_segment, list); @@ -269,7 +269,7 @@ segment_overlaps_others (struct dcss_segment *seg) struct list_head *l; struct dcss_segment *tmp; - assert_spin_locked(&dcss_lock); + BUG_ON(!mutex_is_locked(&dcss_lock)); list_for_each(l, &dcss_list) { tmp = list_entry(l, struct dcss_segment, list); if ((tmp->start_addr >> 20) > (seg->end >> 20)) @@ -426,7 +426,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, if (!MACHINE_IS_VM) return -ENOSYS; - spin_lock (&dcss_lock); + mutex_lock(&dcss_lock); seg = segment_by_name (name); if (seg == NULL) rc = __segment_load (name, do_nonshared, addr, end); @@ -441,7 +441,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, rc = -EPERM; } } - spin_unlock (&dcss_lock); + mutex_unlock(&dcss_lock); return rc; } @@ -464,7 +464,7 @@ segment_modify_shared (char *name, int do_nonshared) unsigned long dummy; int dcss_command, rc, diag_cc; - spin_lock (&dcss_lock); + mutex_lock(&dcss_lock); seg = segment_by_name (name); if (seg == NULL) { rc = -EINVAL; @@ -505,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared) &dummy, &dummy); kfree(seg); out_unlock: - spin_unlock(&dcss_lock); + mutex_unlock(&dcss_lock); return rc; } @@ -523,7 +523,7 @@ segment_unload(char *name) if (!MACHINE_IS_VM) return; - spin_lock(&dcss_lock); + mutex_lock(&dcss_lock); seg = segment_by_name (name); if (seg == NULL) { PRINT_ERR ("could not find segment %s in segment_unload, " @@ -537,7 +537,7 @@ segment_unload(char *name) kfree(seg); } out_unlock: - spin_unlock(&dcss_lock); + mutex_unlock(&dcss_lock); } /* @@ -556,7 +556,7 @@ segment_save(char *name) if (!MACHINE_IS_VM) return; - spin_lock(&dcss_lock); + mutex_lock(&dcss_lock); seg = segment_by_name (name); if (seg == NULL) { @@ -589,7 +589,7 @@ segment_save(char *name) goto out; } out: - spin_unlock(&dcss_lock); + mutex_unlock(&dcss_lock); } EXPORT_SYMBOL(segment_load); -- cgit v1.2.3 From 8b62bc9642300471737bc3b77b2a4a2ead46dedb Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:40:56 +0100 Subject: [S390] Memory detection fixes. VMALLOC_END on 31bit should be 0x8000000UL instead of 0x7fffffffL. The page mask which is used to make sure memory_end is on 4MB/2MB boundary is wrong and not needed. Therefore remove it. Make sure a vmalloc area does also exist and work on (future) machines with 4TB and more memory. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head31.S | 3 --- arch/s390/kernel/head64.S | 4 ---- arch/s390/kernel/setup.c | 49 +++++++++++++++++++++++++++++++---------------- 3 files changed, 32 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 9817c327aab..4388b3309e0 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -177,8 +177,6 @@ startup_continue: st %r0,4(%r3) # store size of chunk st %r6,8(%r3) # store type of chunk la %r3,12(%r3) - l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size - st %r5,0(%r4) # store last end to memory size ahi %r10,-1 # update chunk number .Lchkloop: lr %r6,%r7 # set access code to last cc @@ -293,7 +291,6 @@ startup_continue: .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte .Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c -.Lmemsize:.long memory_size .Lmchunk:.long memory_chunk .Lmflags:.long machine_flags .Lbss_bgn: .long __bss_start diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index cc6dbc57eb9..c526279e112 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -81,8 +81,6 @@ startup_continue: aghi %r1,1 # size is one more than end larl %r2,memory_chunk stg %r1,8(%r2) # store size of chunk - larl %r2,memory_size - stg %r1,0(%r2) # set memory size j .Ldonemem .Lslowmemdetect: @@ -188,8 +186,6 @@ startup_continue: stg %r0,8(%r3) # store size of chunk st %r6,20(%r3) # store type of chunk la %r3,24(%r3) - larl %r8,memory_size - stg %r5,0(%r8) # store memory size ahi %r10,-1 # update chunk number .Lchkloop: lr %r6,%r7 # set access code to last cc diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b1a8ad967f9..b928fecdc74 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -62,7 +62,6 @@ EXPORT_SYMBOL_GPL(uaccess); unsigned int console_mode = 0; unsigned int console_devno = -1; unsigned int console_irq = -1; -unsigned long memory_size = 0; unsigned long machine_flags = 0; struct mem_chunk memory_chunk[MEMORY_CHUNKS]; @@ -486,6 +485,37 @@ setup_resources(void) } } +static void __init setup_memory_end(void) +{ + unsigned long real_size, memory_size; + unsigned long max_mem, max_phys; + int i; + + memory_size = real_size = 0; + max_phys = VMALLOC_END - VMALLOC_MIN_SIZE; + memory_end &= PAGE_MASK; + + max_mem = memory_end ? min(max_phys, memory_end) : max_phys; + + for (i = 0; i < MEMORY_CHUNKS; i++) { + struct mem_chunk *chunk = &memory_chunk[i]; + + real_size = max(real_size, chunk->addr + chunk->size); + if (chunk->addr >= max_mem) { + memset(chunk, 0, sizeof(*chunk)); + continue; + } + if (chunk->addr + chunk->size > max_mem) + chunk->size = max_mem - chunk->addr; + memory_size = max(memory_size, chunk->addr + chunk->size); + } + if (!memory_end) + memory_end = memory_size; + if (real_size > memory_end) + printk("More memory detected than supported. Unused: %luk\n", + (real_size - memory_end) >> 10); +} + static void __init setup_memory(void) { @@ -642,8 +672,6 @@ setup_arch(char **cmdline_p) init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - memory_end = memory_size; - if (MACHINE_HAS_MVCOS) memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); else @@ -651,20 +679,7 @@ setup_arch(char **cmdline_p) parse_early_param(); -#ifndef CONFIG_64BIT - memory_end &= ~0x400000UL; - - /* - * We need some free virtual space to be able to do vmalloc. - * On a machine with 2GB memory we make sure that we have at - * least 128 MB free space for vmalloc. - */ - if (memory_end > 1920*1024*1024) - memory_end = 1920*1024*1024; -#else /* CONFIG_64BIT */ - memory_end &= ~0x200000UL; -#endif /* CONFIG_64BIT */ - + setup_memory_end(); setup_memory(); setup_resources(); setup_lowcore(); -- cgit v1.2.3 From 74f8f557fd0c6f32e17e78c9ef508ca66ef37d3a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 4 Dec 2006 15:41:10 +0100 Subject: [S390] Don't use small stacks when lockdep is used. The lock dependency validator adds a bunch of extra stack frames to the stack, which can cause stack overflows. Especially seen on 31 bit where the small stack is only 4k. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 5b04c4095c8..583d9ff0a57 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -178,7 +178,7 @@ config PACK_STACK config SMALL_STACK bool "Use 4kb/8kb for kernel stack instead of 8kb/16kb" - depends on PACK_STACK + depends on PACK_STACK && !LOCKDEP help If you say Y here and the compiler supports the -mkernel-backchain option the kernel will use a smaller kernel stack size. For 31 bit -- cgit v1.2.3 From 6869e940c2244554ad8858f8c4f07bf7e2fd5e3d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 4 Dec 2006 16:40:58 +1000 Subject: [PATCH] m68knommu: formatting cleanup in Kconfig Formatting and a spelling cleanup in m68knommu Kconfig. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/Kconfig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index c1bc22c6d0d..aa70dde5422 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -173,7 +173,7 @@ config CLOCK_DIV On many SoC style CPUs the master CPU clock is also used to drive on-chip peripherals. The clock that is distributed to these peripherals is sometimes a fixed ratio of the master clock - frequency. If so then set this to the divider ration of the + frequency. If so then set this to the divider ratio of the master clock to the peripheral clock. If not sure then select 1. config OLDMASK @@ -192,7 +192,7 @@ config PILOT3 Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII. config XCOPILOT_BUGS - bool " (X)Copilot support" + bool "(X)Copilot support" depends on PILOT3 help Support the bugs of Xcopilot. @@ -216,20 +216,20 @@ config DRAGEN2 Support for the DragenEngine II board. config DIRECT_IO_ACCESS - bool " Allow user to access IO directly" + bool "Allow user to access IO directly" depends on (UCSIMM || UCDIMM || DRAGEN2) help Disable the CPU internal registers protection in user mode, to allow a user application to read/write them. config INIT_LCD - bool " Initialize LCD" + bool "Initialize LCD" depends on (UCSIMM || UCDIMM || DRAGEN2) help Initialize the LCD controller of the 68x328 processor. config MEMORY_RESERVE - int " Memory reservation (MiB)" + int "Memory reservation (MiB)" depends on (UCSIMM || UCDIMM) help Reserve certain memory regions on 68x328 based boards. @@ -409,7 +409,7 @@ config MOD5272 Support for the Netburner MOD-5272 board. config ROMFS_FROM_ROM - bool " ROMFS image not RAM resident" + bool "ROMFS image not RAM resident" depends on (NETtel || SNAPGEAR) help The ROMfs filesystem will stay resident in the FLASH/ROM, not be -- cgit v1.2.3 From 1b9552af943f54336333c9a6e02f5ed9f18e0bcc Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 4 Dec 2006 17:26:44 +1000 Subject: [PATCH] m68knommu: fix compile when CONFIG_BLK_DEV_INITRD=n This patch fixes the following compile error with CONFIG_BLK_DEV_INITRD=n and -Werror-implicit-function-declaration: ... CC arch/m68knommu/kernel/setup.o /home/bunk/linux/kernel-2.6/linux-2.6.18-rc5-mm1/arch/m68knommu/kernel/setup.c: In function 'setup_arch': /home/bunk/linux/kernel-2.6/linux-2.6.18-rc5-mm1/arch/m68knommu/kernel/setup.c:268: error: implicit declaration of function 'paging_init' make[2]: *** [arch/m68knommu/kernel/setup.o] Error 1 Signed-off-by: Adrian Bunk Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/setup.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c index 7b21959eaea..9cf2e4d1fc7 100644 --- a/arch/m68knommu/kernel/setup.c +++ b/arch/m68knommu/kernel/setup.c @@ -36,10 +36,7 @@ #include #include #include - -#ifdef CONFIG_BLK_DEV_INITRD #include -#endif unsigned long memory_start; unsigned long memory_end; -- cgit v1.2.3 From 19127e2bf94e7b427530b64af417185221b69508 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 4 Dec 2006 17:26:55 +1000 Subject: [PATCH] m68knommu: add printk level for oops dumps Specify printk level in m68knommu oops dump code. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/process.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index c18a8330695..941955dc3b7 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -290,7 +290,7 @@ void dump(struct pt_regs *fp) unsigned char *tp; int i; - printk(KERN_EMERG "\nCURRENT PROCESS:\n\n"); + printk(KERN_EMERG "\n" KERN_EMERG "CURRENT PROCESS:\n" KERN_EMERG "\n"); printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid); if (current->mm) { @@ -301,7 +301,8 @@ void dump(struct pt_regs *fp) (int) current->mm->end_data, (int) current->mm->end_data, (int) current->mm->brk); - printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n\n", + printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n" + KERN_EMERG "\n", (int) current->mm->start_stack, (int)(((unsigned long) current) + THREAD_SIZE)); } @@ -312,36 +313,35 @@ void dump(struct pt_regs *fp) fp->d0, fp->d1, fp->d2, fp->d3); printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", fp->d4, fp->d5, fp->a0, fp->a1); - printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %08x\n", (unsigned int) rdusp(), - (unsigned int) fp); + printk(KERN_EMERG "\n" KERN_EMERG "USP: %08x TRAPFRAME: %08x\n", + (unsigned int) rdusp(), (unsigned int) fp); - printk(KERN_EMERG "\nCODE:"); + printk(KERN_EMERG "\n" KERN_EMERG "CODE:"); tp = ((unsigned char *) fp->pc) - 0x20; for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { if ((i % 0x10) == 0) - printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); - printk(KERN_EMERG "%08x ", (int) *sp++); + printk("\n" KERN_EMERG "%08x: ", (int) (tp + i)); + printk("%08x ", (int) *sp++); } - printk(KERN_EMERG "\n"); + printk("\n" KERN_EMERG "\n"); - printk(KERN_EMERG "\nKERNEL STACK:"); + printk(KERN_EMERG "KERNEL STACK:"); tp = ((unsigned char *) fp) - 0x40; for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { if ((i % 0x10) == 0) - printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); - printk(KERN_EMERG "%08x ", (int) *sp++); + printk("\n" KERN_EMERG "%08x: ", (int) (tp + i)); + printk("%08x ", (int) *sp++); } - printk(KERN_EMERG "\n"); - printk(KERN_EMERG "\n"); + printk("\n" KERN_EMERG "\n"); - printk(KERN_EMERG "\nUSER STACK:"); + printk(KERN_EMERG "USER STACK:"); tp = (unsigned char *) (rdusp() - 0x10); for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) { if ((i % 0x10) == 0) - printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); - printk(KERN_EMERG "%08x ", (int) *sp++); + printk("\n" KERN_EMERG "%08x: ", (int) (tp + i)); + printk("%08x ", (int) *sp++); } - printk(KERN_EMERG "\n\n"); + printk("\n" KERN_EMERG "\n"); } /* -- cgit v1.2.3 From 329237c12b94911dfad128e2588b0b7ae9c516e7 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 4 Dec 2006 17:27:09 +1000 Subject: [PATCH] m68knommu: add printk level for stack dump Specify printk level in m68knommu stack dump code. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/traps.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c index 17649d2543e..9129b3a5258 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c @@ -127,11 +127,12 @@ void show_stack(struct task_struct *task, unsigned long *stack) if (stack + 1 > endstack) break; if (i % 8 == 0) - printk(KERN_EMERG "\n "); - printk(KERN_EMERG " %08lx", *stack++); + printk("\n" KERN_EMERG " "); + printk(" %08lx", *stack++); } + printk("\n"); - printk(KERN_EMERG "\nCall Trace:"); + printk(KERN_EMERG "Call Trace:"); i = 0; while (stack + 1 <= endstack) { addr = *stack++; @@ -146,12 +147,12 @@ void show_stack(struct task_struct *task, unsigned long *stack) if (((addr >= (unsigned long) &_start) && (addr <= (unsigned long) &_etext))) { if (i % 4 == 0) - printk(KERN_EMERG "\n "); - printk(KERN_EMERG " [<%08lx>]", addr); + printk("\n" KERN_EMERG " "); + printk(" [<%08lx>]", addr); i++; } } - printk(KERN_EMERG "\n"); + printk("\n"); } void bad_super_trap(struct frame *fp) -- cgit v1.2.3 From 1bddcc50c27c8ca39a62a1d37e3928707be8f850 Mon Sep 17 00:00:00 2001 From: David Wu Date: Mon, 4 Dec 2006 17:27:22 +1000 Subject: [PATCH] m68knommu: add SHM support It turns out SHMAT, SHMDT, SHMGET and SHMCTL support in sys_ipc() for m68knommu in 2.6 kernel(uClinux-dist-20060803 release) is missing. (copied from m68k sources, report by David Wu ) Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/kernel/sys_m68k.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c index c3494b8447d..3265b2d734d 100644 --- a/arch/m68knommu/kernel/sys_m68k.c +++ b/arch/m68knommu/kernel/sys_m68k.c @@ -137,7 +137,7 @@ asmlinkage int old_select(struct sel_arg_struct *arg) asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth) { - int version; + int version, ret; version = call >> 16; /* hack for backward compatibility */ call &= 0xffff; @@ -190,6 +190,27 @@ asmlinkage int sys_ipc (uint call, int first, int second, default: return -EINVAL; } + if (call <= SHMCTL) + switch (call) { + case SHMAT: + switch (version) { + default: { + ulong raddr; + ret = do_shmat (first, ptr, second, &raddr); + if (ret) + return ret; + return put_user (raddr, (ulong __user *) third); + } + } + case SHMDT: + return sys_shmdt (ptr); + case SHMGET: + return sys_shmget (first, second, third); + case SHMCTL: + return sys_shmctl (first, second, ptr); + default: + return -ENOSYS; + } return -EINVAL; } -- cgit v1.2.3 From 552984050958fc0f51bff38948d0bf4d31ea2b03 Mon Sep 17 00:00:00 2001 From: Michael Broughton Date: Mon, 4 Dec 2006 17:27:29 +1000 Subject: [PATCH] m68knommu: auto detect memory size on M5208EVB board Here is a small patch to automatically detect the DRAM size on m520x. It was generated against 2.6.17-uc0, and tested on an Intec 5208 dev board. Signed-off-by: Michael Broughton Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/platform/5307/head.S | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch') diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S index f2edb6498cd..b9aa0ca29bf 100644 --- a/arch/m68knommu/platform/5307/head.S +++ b/arch/m68knommu/platform/5307/head.S @@ -64,6 +64,26 @@ negl %d0 /* negate bits */ .endm +#elif defined(CONFIG_M520x) +.macro GET_MEM_SIZE + clrl %d0 + movel MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */ + andl #0x1f, %d2 /* Get only the chip select size */ + beq 3f /* Check if it is enabled */ + addql #1, %d2 /* Form exponent */ + moveql #1, %d0 + lsll %d2, %d0 /* 2 ^ exponent */ +3: + movel MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */ + andl #0x1f, %d2 /* Get only the chip select size */ + beq 4f /* Check if it is enabled */ + addql #1, %d2 /* Form exponent */ + moveql #1, %d1 + lsll %d2, %d1 /* 2 ^ exponent */ + addl %d1, %d0 /* Total size of SDRAM in d0 */ +4: +.endm + #else #error "ERROR: I don't know how to probe your boards memory size?" #endif -- cgit v1.2.3 From d773c660973560970a6b3697cb280ddc5389447d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 4 Dec 2006 17:27:42 +1000 Subject: [PATCH] m68knommu: remove __rom_end from 68360 startup code Remove use of __rom_end symbol all together. This helps clean out the miscellaneous symbols lying around in the m68knommu linker script. Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/platform/68360/head-ram.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68knommu/platform/68360/head-ram.S b/arch/m68knommu/platform/68360/head-ram.S index 2ea51479f13..2ef06242398 100644 --- a/arch/m68knommu/platform/68360/head-ram.S +++ b/arch/m68knommu/platform/68360/head-ram.S @@ -25,6 +25,7 @@ .global _periph_base #define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) +#define ROMEND (CONFIG_ROMBASE + CONFIG_ROMSIZE) #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) @@ -175,7 +176,7 @@ configure_chip_select_0: move.l %d0, BR0 configure_chip_select_1: - move.l #__rom_end, %d0 + move.l #ROMEND, %d0 subi.l #__rom_start, %d0 subq.l #0x01, %d0 eori.l #SIM_OR_MASK, %d0 -- cgit v1.2.3 From 05e4396651ca1cac51d8da9ff4992741c9dc1e39 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 7 Nov 2006 18:02:44 +0900 Subject: [MIPS] Use SYSVIPC_COMPAT to fix various problems on N32 N32 SysV IPC system calls should use 32-bit compatible code. arch/mips/kernel/linux32.c have similar compatible code for O32, but ipc/compat.c seems more complete. We can use it for both N32 and O32. This patch should fix these problems (and other possible problems): http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=1149188824.6986.6.camel%40diimka-laptop http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=44C6B829.8050508%40caviumnetworks.com Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 5 + arch/mips/kernel/linux32.c | 578 ++--------------------------------------- arch/mips/kernel/scall64-n32.S | 14 +- 3 files changed, 35 insertions(+), 562 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 27f83e64296..2308c8ef021 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1940,6 +1940,11 @@ config COMPAT depends on MIPS32_COMPAT default y +config SYSVIPC_COMPAT + bool + depends on COMPAT && SYSVIPC + default y + config MIPS32_O32 bool "Kernel support for o32 binaries" depends on MIPS32_COMPAT diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 7a3ebbeba1f..b061c9aa630 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -382,531 +382,6 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, return ret; } -struct msgbuf32 { s32 mtype; char mtext[1]; }; - -struct ipc_perm32 -{ - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; -}; - -struct ipc64_perm32 { - key_t key; - __compat_uid_t uid; - __compat_gid_t gid; - __compat_uid_t cuid; - __compat_gid_t cgid; - compat_mode_t mode; - unsigned short seq; - unsigned short __pad1; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct semid_ds32 { - struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */ - compat_time_t sem_otime; /* last semop time */ - compat_time_t sem_ctime; /* last change time */ - u32 sem_base; /* ptr to first semaphore in array */ - u32 sem_pending; /* pending operations to be processed */ - u32 sem_pending_last; /* last pending operation */ - u32 undo; /* undo requests on this array */ - unsigned short sem_nsems; /* no. of semaphores in array */ -}; - -struct semid64_ds32 { - struct ipc64_perm32 sem_perm; - compat_time_t sem_otime; - compat_time_t sem_ctime; - unsigned int sem_nsems; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct msqid_ds32 -{ - struct ipc_perm32 msg_perm; - u32 msg_first; - u32 msg_last; - compat_time_t msg_stime; - compat_time_t msg_rtime; - compat_time_t msg_ctime; - u32 wwait; - u32 rwait; - unsigned short msg_cbytes; - unsigned short msg_qnum; - unsigned short msg_qbytes; - compat_ipc_pid_t msg_lspid; - compat_ipc_pid_t msg_lrpid; -}; - -struct msqid64_ds32 { - struct ipc64_perm32 msg_perm; - compat_time_t msg_stime; - unsigned int __unused1; - compat_time_t msg_rtime; - unsigned int __unused2; - compat_time_t msg_ctime; - unsigned int __unused3; - unsigned int msg_cbytes; - unsigned int msg_qnum; - unsigned int msg_qbytes; - compat_pid_t msg_lspid; - compat_pid_t msg_lrpid; - unsigned int __unused4; - unsigned int __unused5; -}; - -struct shmid_ds32 { - struct ipc_perm32 shm_perm; - int shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_ipc_pid_t shm_cpid; - compat_ipc_pid_t shm_lpid; - unsigned short shm_nattch; -}; - -struct shmid64_ds32 { - struct ipc64_perm32 shm_perm; - compat_size_t shm_segsz; - compat_time_t shm_atime; - compat_time_t shm_dtime; - compat_time_t shm_ctime; - compat_pid_t shm_cpid; - compat_pid_t shm_lpid; - unsigned int shm_nattch; - unsigned int __unused1; - unsigned int __unused2; -}; - -struct ipc_kludge32 { - u32 msgp; - s32 msgtyp; -}; - -static int -do_sys32_semctl(int first, int second, int third, void __user *uptr) -{ - union semun fourth; - u32 pad; - int err, err2; - struct semid64_ds s; - mm_segment_t old_fs; - - if (!uptr) - return -EINVAL; - err = -EFAULT; - if (get_user (pad, (u32 __user *)uptr)) - return err; - if ((third & ~IPC_64) == SETVAL) - fourth.val = (int)pad; - else - fourth.__pad = (void __user *)A(pad); - switch (third & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case IPC_SET: - case SEM_INFO: - case GETVAL: - case GETPID: - case GETNCNT: - case GETZCNT: - case GETALL: - case SETVAL: - case SETALL: - err = sys_semctl (first, second, third, fourth); - break; - - case IPC_STAT: - case SEM_STAT: - fourth.__pad = (struct semid64_ds __user *)&s; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_semctl(first, second, third | IPC_64, fourth); - set_fs(old_fs); - - if (third & IPC_64) { - struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp64->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems); - } else { - struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad); - - if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key); - err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid); - err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid); - err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid); - err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid); - err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode); - err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq); - err2 |= __put_user(s.sem_otime, &usp32->sem_otime); - err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime); - err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems); - } - if (err2) - err = -EFAULT; - break; - - default: - err = - EINVAL; - break; - } - - return err; -} - -static int -do_sys32_msgsnd (int first, int second, int third, void __user *uptr) -{ - struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (second < 0) - return -EINVAL; - p = kmalloc (second + sizeof (struct msgbuf) - + 4, GFP_USER); - if (!p) - return -ENOMEM; - err = get_user (p->mtype, &up->mtype); - if (err) - goto out; - err |= __copy_from_user (p->mtext, &up->mtext, second); - if (err) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third); - set_fs (old_fs); -out: - kfree (p); - - return err; -} - -static int -do_sys32_msgrcv (int first, int second, int msgtyp, int third, - int version, void __user *uptr) -{ - struct msgbuf32 __user *up; - struct msgbuf *p; - mm_segment_t old_fs; - int err; - - if (!version) { - struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr; - struct ipc_kludge32 ipck; - - err = -EINVAL; - if (!uptr) - goto out; - err = -EFAULT; - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32))) - goto out; - uptr = (void __user *)AA(ipck.msgp); - msgtyp = ipck.msgtyp; - } - - if (second < 0) - return -EINVAL; - err = -ENOMEM; - p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER); - if (!p) - goto out; - old_fs = get_fs (); - set_fs (KERNEL_DS); - err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third); - set_fs (old_fs); - if (err < 0) - goto free_then_out; - up = (struct msgbuf32 __user *)uptr; - if (put_user (p->mtype, &up->mtype) || - __copy_to_user (&up->mtext, p->mtext, err)) - err = -EFAULT; -free_then_out: - kfree (p); -out: - return err; -} - -static int -do_sys32_msgctl (int first, int second, void __user *uptr) -{ - int err = -EINVAL, err2; - struct msqid64_ds m; - struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr; - struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr; - mm_segment_t old_fs; - - switch (second & ~IPC_64) { - case IPC_INFO: - case IPC_RMID: - case MSG_INFO: - err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr); - break; - - case IPC_SET: - if (second & IPC_64) { - if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up64->msg_qbytes); - } else { - if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid); - err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid); - err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode); - err |= __get_user(m.msg_qbytes, &up32->msg_qbytes); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - break; - - case IPC_STAT: - case MSG_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m); - set_fs(old_fs); - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up64->msg_stime); - err2 |= __put_user(m.msg_rtime, &up64->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up64->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up64->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up64->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid); - if (err2) - err = -EFAULT; - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key); - err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid); - err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid); - err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid); - err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid); - err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode); - err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq); - err2 |= __put_user(m.msg_stime, &up32->msg_stime); - err2 |= __put_user(m.msg_rtime, &up32->msg_rtime); - err2 |= __put_user(m.msg_ctime, &up32->msg_ctime); - err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes); - err2 |= __put_user(m.msg_qnum, &up32->msg_qnum); - err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes); - err2 |= __put_user(m.msg_lspid, &up32->msg_lspid); - err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid); - if (err2) - err = -EFAULT; - } - break; - } - - return err; -} - -static int -do_sys32_shmat (int first, int second, int third, int version, void __user *uptr) -{ - unsigned long raddr; - u32 __user *uaddr = (u32 __user *)A((u32)third); - int err = -EINVAL; - - if (version == 1) - return err; - err = do_shmat (first, uptr, second, &raddr); - if (err) - return err; - err = put_user (raddr, uaddr); - return err; -} - -struct shm_info32 { - int used_ids; - u32 shm_tot, shm_rss, shm_swp; - u32 swap_attempts, swap_successes; -}; - -static int -do_sys32_shmctl (int first, int second, void __user *uptr) -{ - struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr; - struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr; - struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr; - int err = -EFAULT, err2; - struct shmid64_ds s64; - mm_segment_t old_fs; - struct shm_info si; - struct shmid_ds s; - - switch (second & ~IPC_64) { - case IPC_INFO: - second = IPC_INFO; /* So that we don't have to translate it */ - case IPC_RMID: - case SHM_LOCK: - case SHM_UNLOCK: - err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr); - break; - case IPC_SET: - if (second & IPC_64) { - err = get_user(s.shm_perm.uid, &up64->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode); - } else { - err = get_user(s.shm_perm.uid, &up32->shm_perm.uid); - err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid); - err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode); - } - if (err) - break; - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s); - set_fs(old_fs); - break; - - case IPC_STAT: - case SHM_STAT: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second | IPC_64, (void __user *) &s64); - set_fs(old_fs); - if (err < 0) - break; - if (second & IPC_64) { - if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up64->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid); - } else { - if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) { - err = -EFAULT; - break; - } - err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key); - err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid); - err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid); - err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid); - err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid); - err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode); - err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq); - err2 |= __put_user(s64.shm_atime, &up32->shm_atime); - err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime); - err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime); - err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz); - err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch); - err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid); - err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid); - } - if (err2) - err = -EFAULT; - break; - - case SHM_INFO: - old_fs = get_fs(); - set_fs(KERNEL_DS); - err = sys_shmctl(first, second, (void __user *)&si); - set_fs(old_fs); - if (err < 0) - break; - err2 = put_user(si.used_ids, &uip->used_ids); - err2 |= __put_user(si.shm_tot, &uip->shm_tot); - err2 |= __put_user(si.shm_rss, &uip->shm_rss); - err2 |= __put_user(si.shm_swp, &uip->shm_swp); - err2 |= __put_user(si.swap_attempts, &uip->swap_attempts); - err2 |= __put_user (si.swap_successes, &uip->swap_successes); - if (err2) - err = -EFAULT; - break; - - default: - err = -EINVAL; - break; - } - - return err; -} - -static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems, - const struct compat_timespec __user *timeout32) -{ - struct compat_timespec t32; - struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64)); - - if (copy_from_user(&t32, timeout32, sizeof(t32))) - return -EFAULT; - - if (put_user(t32.tv_sec, &t64->tv_sec) || - put_user(t32.tv_nsec, &t64->tv_nsec)) - return -EFAULT; - - return sys_semtimedop(semid, tsems, nsems, t64); -} - asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -918,48 +393,43 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) switch (call) { case SEMOP: /* struct sembuf is the same on 32 and 64bit :)) */ - err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - NULL); + err = sys_semtimedop(first, compat_ptr(ptr), second, NULL); break; case SEMTIMEDOP: - err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, - (const struct compat_timespec __user *)AA(fifth)); + err = compat_sys_semtimedop(first, compat_ptr(ptr), second, + compat_ptr(fifth)); break; case SEMGET: - err = sys_semget (first, second, third); + err = sys_semget(first, second, third); break; case SEMCTL: - err = do_sys32_semctl (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_semctl(first, second, third, compat_ptr(ptr)); break; - case MSGSND: - err = do_sys32_msgsnd (first, second, third, - (void __user *)AA(ptr)); + err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr)); break; case MSGRCV: - err = do_sys32_msgrcv (first, second, fifth, third, - version, (void __user *)AA(ptr)); + err = compat_sys_msgrcv(first, second, fifth, third, + version, compat_ptr(ptr)); break; case MSGGET: - err = sys_msgget ((key_t) first, second); + err = sys_msgget((key_t) first, second); break; case MSGCTL: - err = do_sys32_msgctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_msgctl(first, second, compat_ptr(ptr)); break; - case SHMAT: - err = do_sys32_shmat (first, second, third, - version, (void __user *)AA(ptr)); + err = compat_sys_shmat(first, second, third, version, + compat_ptr(ptr)); break; case SHMDT: - err = sys_shmdt ((char __user *)A(ptr)); + err = sys_shmdt(compat_ptr(ptr)); break; case SHMGET: - err = sys_shmget (first, (unsigned)second, third); + err = sys_shmget(first, (unsigned)second, third); break; case SHMCTL: - err = do_sys32_shmctl (first, second, (void __user *)AA(ptr)); + err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: err = -EINVAL; @@ -969,18 +439,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) return err; } -asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, - int shmflg, int32_t __user *addr) +#ifdef CONFIG_MIPS32_N32 +asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg) { - unsigned long raddr; - int err; - - err = do_shmat(shmid, shmaddr, shmflg, &raddr); - if (err) - return err; - - return put_user(raddr, addr); + /* compat_sys_semctl expects a pointer to union semun */ + u32 __user *uptr = compat_alloc_user_space(sizeof(u32)); + if (put_user(ptr_to_compat(arg.__pad), uptr)) + return -EFAULT; + return compat_sys_semctl(semid, semnum, cmd, uptr); } +#endif struct sysctl_args32 { diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 5b18f265d75..34567d81f94 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -149,8 +149,8 @@ EXPORT(sysn32_call_table) PTR sys_mincore PTR sys_madvise PTR sys_shmget - PTR sys32_shmat - PTR sys_shmctl /* 6030 */ + PTR sys_shmat + PTR compat_sys_shmctl /* 6030 */ PTR sys_dup PTR sys_dup2 PTR sys_pause @@ -184,12 +184,12 @@ EXPORT(sysn32_call_table) PTR sys32_newuname PTR sys_semget PTR sys_semop - PTR sys_semctl + PTR sysn32_semctl PTR sys_shmdt /* 6065 */ PTR sys_msgget - PTR sys_msgsnd - PTR sys_msgrcv - PTR sys_msgctl + PTR compat_sys_msgsnd + PTR compat_sys_msgrcv + PTR compat_sys_msgctl PTR compat_sys_fcntl /* 6070 */ PTR sys_flock PTR sys_fsync @@ -335,7 +335,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_fcntl64 PTR sys_set_tid_address PTR sys_restart_syscall - PTR sys_semtimedop /* 6215 */ + PTR compat_sys_semtimedop /* 6215 */ PTR sys_fadvise64_64 PTR compat_sys_statfs64 PTR compat_sys_fstatfs64 -- cgit v1.2.3 From 03dbd2e0b1dcb24d63f64aa234cce3a7fabed328 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Thu, 30 Nov 2006 13:45:32 +0000 Subject: [MIPS] SWARM: Fix a typo in #error directives This is a fix for a typo repeated several times in #error directives for invalid SiByte configurations. Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle --- arch/mips/sibyte/swarm/setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index ac342f5643c..defa1f1452a 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c @@ -43,7 +43,7 @@ #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) #include #else -#error invalid SiByte board configuation +#error invalid SiByte board configuration #endif #include #include @@ -53,7 +53,7 @@ extern void bcm1480_setup(void); #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) extern void sb1250_setup(void); #else -#error invalid SiByte board configuation +#error invalid SiByte board configuration #endif extern int xicor_probe(void); @@ -90,7 +90,7 @@ void __init plat_timer_setup(struct irqaction *irq) #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) sb1250_time_init(); #else -#error invalid SiByte board configuation +#error invalid SiByte board configuration #endif } @@ -111,7 +111,7 @@ void __init plat_mem_setup(void) #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) sb1250_setup(); #else -#error invalid SiByte board configuation +#error invalid SiByte board configuration #endif panic_timeout = 5; /* For debug. */ -- cgit v1.2.3 From 0bcdda0f3a87ed684d46841b6069409e39c4af65 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Mon, 4 Dec 2006 00:42:59 +0900 Subject: [MIPS] Unify csum_partial.S The 32-bit version and 64-bit version are almost equal. Unify them. This makes further improvements (for example, copying with parallel, supporting PREFETCH, etc.) easier. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib-32/Makefile | 2 +- arch/mips/lib-32/csum_partial.S | 240 ------------------------------------- arch/mips/lib-64/Makefile | 2 +- arch/mips/lib-64/csum_partial.S | 242 ------------------------------------- arch/mips/lib/Makefile | 4 +- arch/mips/lib/csum_partial.S | 258 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 262 insertions(+), 486 deletions(-) delete mode 100644 arch/mips/lib-32/csum_partial.S delete mode 100644 arch/mips/lib-64/csum_partial.S create mode 100644 arch/mips/lib/csum_partial.S (limited to 'arch') diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile index ad285786e74..dcd4d2ed2ac 100644 --- a/arch/mips/lib-32/Makefile +++ b/arch/mips/lib-32/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o memset.o watch.o +lib-y += memset.o watch.o obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o diff --git a/arch/mips/lib-32/csum_partial.S b/arch/mips/lib-32/csum_partial.S deleted file mode 100644 index ea257dbdcc4..00000000000 --- a/arch/mips/lib-32/csum_partial.S +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1998 Ralf Baechle - */ -#include -#include - -#define ADDC(sum,reg) \ - addu sum, reg; \ - sltu v1, sum, reg; \ - addu sum, v1 - -#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - -/* - * a0: source address - * a1: length of the area to checksum - * a2: partial checksum - */ - -#define src a0 -#define dest a1 -#define sum v0 - - .text - .set noreorder - -/* unknown src alignment and < 8 bytes to go */ -small_csumcpy: - move a1, t2 - - andi t0, a1, 4 - beqz t0, 1f - andi t0, a1, 2 - - /* Still a full word to go */ - ulw t1, (src) - addiu src, 4 - ADDC(sum, t1) - -1: move t1, zero - beqz t0, 1f - andi t0, a1, 1 - - /* Still a halfword to go */ - ulhu t1, (src) - addiu src, 2 - -1: beqz t0, 1f - sll t1, t1, 16 - - lbu t2, (src) - nop - -#ifdef __MIPSEB__ - sll t2, t2, 8 -#endif - or t1, t2 - -1: ADDC(sum, t1) - - /* fold checksum */ - sll v1, sum, 16 - addu sum, v1 - sltu v1, sum, v1 - srl sum, sum, 16 - addu sum, v1 - - /* odd buffer alignment? */ - beqz t7, 1f - nop - sll v1, sum, 8 - srl sum, sum, 8 - or sum, v1 - andi sum, 0xffff -1: - .set reorder - /* Add the passed partial csum. */ - ADDC(sum, a2) - jr ra - .set noreorder - -/* ------------------------------------------------------------------------- */ - - .align 5 -LEAF(csum_partial) - move sum, zero - move t7, zero - - sltiu t8, a1, 0x8 - bnez t8, small_csumcpy /* < 8 bytes to copy */ - move t2, a1 - - beqz a1, out - andi t7, src, 0x1 /* odd buffer? */ - -hword_align: - beqz t7, word_align - andi t8, src, 0x2 - - lbu t0, (src) - subu a1, a1, 0x1 -#ifdef __MIPSEL__ - sll t0, t0, 8 -#endif - ADDC(sum, t0) - addu src, src, 0x1 - andi t8, src, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a1, 56 - - lhu t0, (src) - subu a1, a1, 0x2 - ADDC(sum, t0) - sltiu t8, a1, 56 - addu src, src, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a1 - - andi t8, src, 0x4 - beqz t8, qword_align - andi t8, src, 0x8 - - lw t0, 0x00(src) - subu a1, a1, 0x4 - ADDC(sum, t0) - addu src, src, 0x4 - andi t8, src, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, src, 0x10 - - lw t0, 0x00(src) - lw t1, 0x04(src) - subu a1, a1, 0x8 - ADDC(sum, t0) - ADDC(sum, t1) - addu src, src, 0x8 - andi t8, src, 0x10 - -oword_align: - beqz t8, begin_movement - srl t8, a1, 0x7 - - lw t3, 0x08(src) - lw t4, 0x0c(src) - lw t0, 0x00(src) - lw t1, 0x04(src) - ADDC(sum, t3) - ADDC(sum, t4) - ADDC(sum, t0) - ADDC(sum, t1) - subu a1, a1, 0x10 - addu src, src, 0x10 - srl t8, a1, 0x7 - -begin_movement: - beqz t8, 1f - andi t2, a1, 0x40 - -move_128bytes: - CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4) - subu t8, t8, 0x01 - bnez t8, move_128bytes - addu src, src, 0x80 - -1: - beqz t2, 1f - andi t2, a1, 0x20 - -move_64bytes: - CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) - CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) - addu src, src, 0x40 - -1: - beqz t2, do_end_words - andi t8, a1, 0x1c - -move_32bytes: - CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) - andi t8, a1, 0x1c - addu src, src, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - srl t8, t8, 0x2 - -end_words: - lw t0, (src) - subu t8, t8, 0x1 - ADDC(sum, t0) - bnez t8, end_words - addu src, src, 0x4 - -maybe_end_cruft: - andi t2, a1, 0x3 - -small_memcpy: - j small_csumcpy; move a1, t2 - beqz t2, out - move a1, t2 - -end_bytes: - lb t0, (src) - subu a1, a1, 0x1 - bnez a2, end_bytes - addu src, src, 0x1 - -out: - jr ra - move v0, sum - END(csum_partial) diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile index ad285786e74..dcd4d2ed2ac 100644 --- a/arch/mips/lib-64/Makefile +++ b/arch/mips/lib-64/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o memset.o watch.o +lib-y += memset.o watch.o obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o diff --git a/arch/mips/lib-64/csum_partial.S b/arch/mips/lib-64/csum_partial.S deleted file mode 100644 index 25aba660cc9..00000000000 --- a/arch/mips/lib-64/csum_partial.S +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Quick'n'dirty IP checksum ... - * - * Copyright (C) 1998, 1999 Ralf Baechle - * Copyright (C) 1999 Silicon Graphics, Inc. - */ -#include -#include - -#define ADDC(sum,reg) \ - addu sum, reg; \ - sltu v1, sum, reg; \ - addu sum, v1 - -#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \ - lw t0, (offset + 0x00)(src); \ - lw t1, (offset + 0x04)(src); \ - lw t2, (offset + 0x08)(src); \ - lw t3, (offset + 0x0c)(src); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - lw t0, (offset + 0x10)(src); \ - lw t1, (offset + 0x14)(src); \ - lw t2, (offset + 0x18)(src); \ - lw t3, (offset + 0x1c)(src); \ - ADDC(sum, t0); \ - ADDC(sum, t1); \ - ADDC(sum, t2); \ - ADDC(sum, t3); \ - -/* - * a0: source address - * a1: length of the area to checksum - * a2: partial checksum - */ - -#define src a0 -#define sum v0 - - .text - .set noreorder - -/* unknown src alignment and < 8 bytes to go */ -small_csumcpy: - move a1, ta2 - - andi ta0, a1, 4 - beqz ta0, 1f - andi ta0, a1, 2 - - /* Still a full word to go */ - ulw ta1, (src) - daddiu src, 4 - ADDC(sum, ta1) - -1: move ta1, zero - beqz ta0, 1f - andi ta0, a1, 1 - - /* Still a halfword to go */ - ulhu ta1, (src) - daddiu src, 2 - -1: beqz ta0, 1f - sll ta1, ta1, 16 - - lbu ta2, (src) - nop - -#ifdef __MIPSEB__ - sll ta2, ta2, 8 -#endif - or ta1, ta2 - -1: ADDC(sum, ta1) - - /* fold checksum */ - sll v1, sum, 16 - addu sum, v1 - sltu v1, sum, v1 - srl sum, sum, 16 - addu sum, v1 - - /* odd buffer alignment? */ - beqz t3, 1f - nop - sll v1, sum, 8 - srl sum, sum, 8 - or sum, v1 - andi sum, 0xffff -1: - .set reorder - /* Add the passed partial csum. */ - ADDC(sum, a2) - jr ra - .set noreorder - -/* ------------------------------------------------------------------------- */ - - .align 5 -LEAF(csum_partial) - move sum, zero - move t3, zero - - sltiu t8, a1, 0x8 - bnez t8, small_csumcpy /* < 8 bytes to copy */ - move ta2, a1 - - beqz a1, out - andi t3, src, 0x1 /* odd buffer? */ - -hword_align: - beqz t3, word_align - andi t8, src, 0x2 - - lbu ta0, (src) - dsubu a1, a1, 0x1 -#ifdef __MIPSEL__ - sll ta0, ta0, 8 -#endif - ADDC(sum, ta0) - daddu src, src, 0x1 - andi t8, src, 0x2 - -word_align: - beqz t8, dword_align - sltiu t8, a1, 56 - - lhu ta0, (src) - dsubu a1, a1, 0x2 - ADDC(sum, ta0) - sltiu t8, a1, 56 - daddu src, src, 0x2 - -dword_align: - bnez t8, do_end_words - move t8, a1 - - andi t8, src, 0x4 - beqz t8, qword_align - andi t8, src, 0x8 - - lw ta0, 0x00(src) - dsubu a1, a1, 0x4 - ADDC(sum, ta0) - daddu src, src, 0x4 - andi t8, src, 0x8 - -qword_align: - beqz t8, oword_align - andi t8, src, 0x10 - - lw ta0, 0x00(src) - lw ta1, 0x04(src) - dsubu a1, a1, 0x8 - ADDC(sum, ta0) - ADDC(sum, ta1) - daddu src, src, 0x8 - andi t8, src, 0x10 - -oword_align: - beqz t8, begin_movement - dsrl t8, a1, 0x7 - - lw ta3, 0x08(src) - lw t0, 0x0c(src) - lw ta0, 0x00(src) - lw ta1, 0x04(src) - ADDC(sum, ta3) - ADDC(sum, t0) - ADDC(sum, ta0) - ADDC(sum, ta1) - dsubu a1, a1, 0x10 - daddu src, src, 0x10 - dsrl t8, a1, 0x7 - -begin_movement: - beqz t8, 1f - andi ta2, a1, 0x40 - -move_128bytes: - CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0) - CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0) - CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0) - CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0) - dsubu t8, t8, 0x01 - bnez t8, move_128bytes - daddu src, src, 0x80 - -1: - beqz ta2, 1f - andi ta2, a1, 0x20 - -move_64bytes: - CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0) - CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0) - daddu src, src, 0x40 - -1: - beqz ta2, do_end_words - andi t8, a1, 0x1c - -move_32bytes: - CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0) - andi t8, a1, 0x1c - daddu src, src, 0x20 - -do_end_words: - beqz t8, maybe_end_cruft - dsrl t8, t8, 0x2 - -end_words: - lw ta0, (src) - dsubu t8, t8, 0x1 - ADDC(sum, ta0) - bnez t8, end_words - daddu src, src, 0x4 - -maybe_end_cruft: - andi ta2, a1, 0x3 - -small_memcpy: - j small_csumcpy; move a1, ta2 /* XXX ??? */ - beqz t2, out - move a1, ta2 - -end_bytes: - lb ta0, (src) - dsubu a1, a1, 0x1 - bnez a2, end_bytes - daddu src, src, 0x1 - -out: - jr ra - move v0, sum - END(csum_partial) diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index b225543f530..888b61ea12f 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,8 +2,8 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \ - strnlen_user.o uncached.o +lib-y += csum_partial.o csum_partial_copy.o memcpy.o promlib.o \ + strlen_user.o strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S new file mode 100644 index 00000000000..15611d9df7a --- /dev/null +++ b/arch/mips/lib/csum_partial.S @@ -0,0 +1,258 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Quick'n'dirty IP checksum ... + * + * Copyright (C) 1998, 1999 Ralf Baechle + * Copyright (C) 1999 Silicon Graphics, Inc. + */ +#include +#include + +#ifdef CONFIG_64BIT +#define T0 ta0 +#define T1 ta1 +#define T2 ta2 +#define T3 ta3 +#define T4 t0 +#define T7 t3 +#else +#define T0 t0 +#define T1 t1 +#define T2 t2 +#define T3 t3 +#define T4 t4 +#define T7 t7 +#endif + +#define ADDC(sum,reg) \ + addu sum, reg; \ + sltu v1, sum, reg; \ + addu sum, v1 + +#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \ + lw _t0, (offset + 0x00)(src); \ + lw _t1, (offset + 0x04)(src); \ + lw _t2, (offset + 0x08)(src); \ + lw _t3, (offset + 0x0c)(src); \ + ADDC(sum, _t0); \ + ADDC(sum, _t1); \ + ADDC(sum, _t2); \ + ADDC(sum, _t3); \ + lw _t0, (offset + 0x10)(src); \ + lw _t1, (offset + 0x14)(src); \ + lw _t2, (offset + 0x18)(src); \ + lw _t3, (offset + 0x1c)(src); \ + ADDC(sum, _t0); \ + ADDC(sum, _t1); \ + ADDC(sum, _t2); \ + ADDC(sum, _t3); \ + +/* + * a0: source address + * a1: length of the area to checksum + * a2: partial checksum + */ + +#define src a0 +#define sum v0 + + .text + .set noreorder + +/* unknown src alignment and < 8 bytes to go */ +small_csumcpy: + move a1, T2 + + andi T0, a1, 4 + beqz T0, 1f + andi T0, a1, 2 + + /* Still a full word to go */ + ulw T1, (src) + PTR_ADDIU src, 4 + ADDC(sum, T1) + +1: move T1, zero + beqz T0, 1f + andi T0, a1, 1 + + /* Still a halfword to go */ + ulhu T1, (src) + PTR_ADDIU src, 2 + +1: beqz T0, 1f + sll T1, T1, 16 + + lbu T2, (src) + nop + +#ifdef __MIPSEB__ + sll T2, T2, 8 +#endif + or T1, T2 + +1: ADDC(sum, T1) + + /* fold checksum */ + sll v1, sum, 16 + addu sum, v1 + sltu v1, sum, v1 + srl sum, sum, 16 + addu sum, v1 + + /* odd buffer alignment? */ + beqz T7, 1f + nop + sll v1, sum, 8 + srl sum, sum, 8 + or sum, v1 + andi sum, 0xffff +1: + .set reorder + /* Add the passed partial csum. */ + ADDC(sum, a2) + jr ra + .set noreorder + +/* ------------------------------------------------------------------------- */ + + .align 5 +LEAF(csum_partial) + move sum, zero + move T7, zero + + sltiu t8, a1, 0x8 + bnez t8, small_csumcpy /* < 8 bytes to copy */ + move T2, a1 + + beqz a1, out + andi T7, src, 0x1 /* odd buffer? */ + +hword_align: + beqz T7, word_align + andi t8, src, 0x2 + + lbu T0, (src) + LONG_SUBU a1, a1, 0x1 +#ifdef __MIPSEL__ + sll T0, T0, 8 +#endif + ADDC(sum, T0) + PTR_ADDU src, src, 0x1 + andi t8, src, 0x2 + +word_align: + beqz t8, dword_align + sltiu t8, a1, 56 + + lhu T0, (src) + LONG_SUBU a1, a1, 0x2 + ADDC(sum, T0) + sltiu t8, a1, 56 + PTR_ADDU src, src, 0x2 + +dword_align: + bnez t8, do_end_words + move t8, a1 + + andi t8, src, 0x4 + beqz t8, qword_align + andi t8, src, 0x8 + + lw T0, 0x00(src) + LONG_SUBU a1, a1, 0x4 + ADDC(sum, T0) + PTR_ADDU src, src, 0x4 + andi t8, src, 0x8 + +qword_align: + beqz t8, oword_align + andi t8, src, 0x10 + + lw T0, 0x00(src) + lw T1, 0x04(src) + LONG_SUBU a1, a1, 0x8 + ADDC(sum, T0) + ADDC(sum, T1) + PTR_ADDU src, src, 0x8 + andi t8, src, 0x10 + +oword_align: + beqz t8, begin_movement + LONG_SRL t8, a1, 0x7 + + lw T3, 0x08(src) + lw T4, 0x0c(src) + lw T0, 0x00(src) + lw T1, 0x04(src) + ADDC(sum, T3) + ADDC(sum, T4) + ADDC(sum, T0) + ADDC(sum, T1) + LONG_SUBU a1, a1, 0x10 + PTR_ADDU src, src, 0x10 + LONG_SRL t8, a1, 0x7 + +begin_movement: + beqz t8, 1f + andi T2, a1, 0x40 + +move_128bytes: + CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x40, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x60, sum, T0, T1, T3, T4) + LONG_SUBU t8, t8, 0x01 + bnez t8, move_128bytes + PTR_ADDU src, src, 0x80 + +1: + beqz T2, 1f + andi T2, a1, 0x20 + +move_64bytes: + CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4) + PTR_ADDU src, src, 0x40 + +1: + beqz T2, do_end_words + andi t8, a1, 0x1c + +move_32bytes: + CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) + andi t8, a1, 0x1c + PTR_ADDU src, src, 0x20 + +do_end_words: + beqz t8, maybe_end_cruft + LONG_SRL t8, t8, 0x2 + +end_words: + lw T0, (src) + LONG_SUBU t8, t8, 0x1 + ADDC(sum, T0) + bnez t8, end_words + PTR_ADDU src, src, 0x4 + +maybe_end_cruft: + andi T2, a1, 0x3 + +small_memcpy: + j small_csumcpy; move a1, T2 /* XXX ??? */ + beqz t2, out + move a1, T2 + +end_bytes: + lb T0, (src) + LONG_SUBU a1, a1, 0x1 + bnez a2, end_bytes + PTR_ADDU src, src, 0x1 + +out: + jr ra + move v0, sum + END(csum_partial) -- cgit v1.2.3 From 08f57f7ffe5819e537301b1f1109fa4fc670bfff Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 3 Dec 2006 19:55:45 +0000 Subject: [MIPS] Alchemy: Automatically enable CONFIG_RESOURCES_64BIT for PCI configs. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2308c8ef021..3947e5daea3 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -16,6 +16,7 @@ config MIPS_MTX1 bool "4G Systems MTX-1 board" select DMA_NONCOHERENT select HW_HAS_PCI + select RESOURCES_64BIT if PCI select SOC_AU1500 select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -32,6 +33,7 @@ config MIPS_PB1000 select SOC_AU1000 select DMA_NONCOHERENT select HW_HAS_PCI + select RESOURCES_64BIT if PCI select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -41,6 +43,7 @@ config MIPS_PB1100 select SOC_AU1100 select DMA_NONCOHERENT select HW_HAS_PCI + select RESOURCES_64BIT if PCI select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -50,6 +53,7 @@ config MIPS_PB1500 select SOC_AU1500 select DMA_NONCOHERENT select HW_HAS_PCI + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -59,6 +63,7 @@ config MIPS_PB1550 select DMA_NONCOHERENT select HW_HAS_PCI select MIPS_DISABLE_OBSOLETE_IDE + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -67,6 +72,7 @@ config MIPS_PB1200 select SOC_AU1200 select DMA_NONCOHERENT select MIPS_DISABLE_OBSOLETE_IDE + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -75,6 +81,7 @@ config MIPS_DB1000 select SOC_AU1000 select DMA_NONCOHERENT select HW_HAS_PCI + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN @@ -91,6 +98,7 @@ config MIPS_DB1500 select DMA_NONCOHERENT select HW_HAS_PCI select MIPS_DISABLE_OBSOLETE_IDE + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN @@ -101,6 +109,7 @@ config MIPS_DB1550 select HW_HAS_PCI select DMA_NONCOHERENT select MIPS_DISABLE_OBSOLETE_IDE + select RESOURCES_64BIT if PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_LITTLE_ENDIAN -- cgit v1.2.3 From 0004a9dfeaa709a7f853487aba19932c9b1a87c8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 31 Oct 2006 03:45:07 +0000 Subject: [MIPS] Cleanup memory barriers for weakly ordered systems. Also the R4000 / R4600 LL/SC instructions imply a sync so no explicit sync needed. Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ++++ arch/mips/kernel/smp.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3947e5daea3..4d64960be03 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1277,6 +1277,7 @@ config CPU_RM9000 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select WEAK_ORDERING config CPU_SB1 bool "SB1" @@ -1285,6 +1286,7 @@ config CPU_SB1 select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM + select WEAK_ORDERING endchoice @@ -1345,6 +1347,8 @@ config SYS_HAS_CPU_RM9000 config SYS_HAS_CPU_SB1 bool +config WEAK_ORDERING + bool endmenu # diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 49db516789e..f2a8701e414 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -172,7 +172,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, spin_lock(&smp_call_lock); call_data = &data; - mb(); + smp_mb(); /* Send a message to all other CPUs and wait for them to respond */ for_each_online_cpu(i) @@ -204,7 +204,7 @@ void smp_call_function_interrupt(void) * Notify initiating CPU that I've grabbed the data and am * about to execute the function. */ - mb(); + smp_mb(); atomic_inc(&call_data->started); /* @@ -215,7 +215,7 @@ void smp_call_function_interrupt(void) irq_exit(); if (wait) { - mb(); + smp_mb(); atomic_inc(&call_data->finished); } } -- cgit v1.2.3 From 8a8944aab2e4b02550c29c45a0383dd4096dd989 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Mon, 4 Dec 2006 16:11:38 -0800 Subject: [POWERPC] ps3: add a default zImage target Add a powerpc make target that can be loaded by the ps3 bootloader (kboot) and set this as the default image to build for that platform. Until the compressed zImage wrapper is made, this arranges for a stripped vmlinux image to be built. Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/boot/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 4a831ae95a9..343dbcfdf08 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -149,13 +149,16 @@ $(obj)/zImage.miboot: vmlinux $(wrapperbits) $(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits) $(call cmd,wrap_initrd,miboot) +$(obj)/zImage.ps3: vmlinux + $(STRIP) -s -R .comment $< -o $@ + $(obj)/uImage: vmlinux $(wrapperbits) $(call cmd,wrap,uboot) image-$(CONFIG_PPC_PSERIES) += zImage.pseries image-$(CONFIG_PPC_MAPLE) += zImage.pseries image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries -image-$(CONFIG_PPC_PS3) += zImage.pseries +image-$(CONFIG_PPC_PS3) += zImage.ps3 image-$(CONFIG_PPC_CHRP) += zImage.chrp image-$(CONFIG_PPC_EFIKA) += zImage.chrp image-$(CONFIG_PPC_PMAC) += zImage.pmac -- cgit v1.2.3 From 650f3289f40e9c2789ecb22683d140a05448f71b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 4 Dec 2006 17:29:13 -0700 Subject: [POWERPC] Remove obsolete PPC_52xx and update CLASSIC32 comment The support for the 52xx-based systems is now included under CONFIG_CLASSIC32, since the 52xx chips have a 603e-based core. Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7b63ede083f..291c95ac4b3 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -112,7 +112,7 @@ choice default 6xx config CLASSIC32 - bool "6xx/7xx/74xx" + bool "52xx/6xx/7xx/74xx" select PPC_FPU select 6xx help @@ -121,16 +121,18 @@ config CLASSIC32 versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC embedded versions (403 and 405) and the high end 64 bit Power processors (POWER 3, POWER4, and IBM PPC970 also known as G5). + + This option is the catch-all for 6xx types, including some of the + embedded versions. Unless there is see an option for the specific + chip family you are using, you want this option. + + You do not want this if you are building a kernel for a 64 bit + IBM RS/6000 or an Apple G5, choose 6xx. + + If unsure, select this option - Unless you are building a kernel for one of the embedded processor - systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx. Note that the kernel runs in 32-bit mode even on 64-bit chips. -config PPC_52xx - bool "Freescale 52xx" - select 6xx - select PPC_FPU - config PPC_82xx bool "Freescale 82xx" select 6xx -- cgit v1.2.3 From d8594d639135b500bf6010f981ea854092d54030 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 4 Dec 2006 17:29:12 -0700 Subject: [POWERPC] Add missing EXPORTS for mpc52xx support Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/of_device.c | 1 + arch/powerpc/platforms/52xx/mpc52xx_common.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 5c653986afa..8a06724e029 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -122,6 +122,7 @@ void of_device_unregister(struct of_device *ofdev) } +EXPORT_SYMBOL(of_match_node); EXPORT_SYMBOL(of_match_device); EXPORT_SYMBOL(of_device_register); EXPORT_SYMBOL(of_device_unregister); diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c index 05b21444127..8331ff45777 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c @@ -43,6 +43,7 @@ mpc52xx_find_and_map(const char *compatible) return ioremap((u32)regaddr64, (u32)size64); } +EXPORT_SYMBOL(mpc52xx_find_and_map); /** @@ -72,6 +73,7 @@ mpc52xx_find_ipb_freq(struct device_node *node) return p_ipb_freq ? *p_ipb_freq : 0; } +EXPORT_SYMBOL(mpc52xx_find_ipb_freq); void __init -- cgit v1.2.3 From 6d5aefb8eaa38e44b5b8cf60c812aceafc02d924 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 5 Dec 2006 19:36:26 +0000 Subject: WorkQueue: Fix up arch-specific work items where possible Fix up arch-specific work items where possible to use the new work_struct and delayed_work structs. Three places that enqueue bits of their stack and then return have been marked with #error as this is not permitted. Signed-Off-By: David Howells --- arch/arm/common/sharpsl_pm.c | 22 +++++++++++----------- arch/arm/mach-omap1/board-h3.c | 3 ++- arch/arm/mach-omap1/board-nokia770.c | 6 +++--- arch/arm/mach-omap1/leds-osk.c | 4 ++-- arch/arm/mach-omap2/board-h4.c | 3 ++- arch/arm/mach-pxa/akita-ioexp.c | 6 +++--- arch/ia64/hp/sim/simserial.c | 4 ++-- arch/ia64/kernel/mca.c | 8 ++++---- arch/ia64/kernel/smpboot.c | 12 +++++++----- arch/mips/kernel/kspd.c | 4 ++-- arch/powerpc/platforms/embedded6xx/ls_uart.c | 4 ++-- arch/powerpc/platforms/powermac/backlight.c | 12 ++++++------ arch/ppc/8260_io/fcc_enet.c | 21 +++++++++++++-------- arch/ppc/8xx_io/fec.c | 21 +++++++++++++-------- arch/s390/appldata/appldata_base.c | 6 +++--- arch/um/drivers/chan_kern.c | 2 +- arch/um/drivers/mconsole_kern.c | 4 ++-- arch/um/drivers/net_kern.c | 1 + arch/um/drivers/port_kern.c | 4 ++-- 19 files changed, 81 insertions(+), 66 deletions(-) (limited to 'arch') diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 605dedf9679..b3599743093 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -60,16 +60,16 @@ static int sharpsl_ac_check(void); static int sharpsl_fatal_check(void); static int sharpsl_average_value(int ad); static void sharpsl_average_clear(void); -static void sharpsl_charge_toggle(void *private_); -static void sharpsl_battery_thread(void *private_); +static void sharpsl_charge_toggle(struct work_struct *private_); +static void sharpsl_battery_thread(struct work_struct *private_); /* * Variables */ struct sharpsl_pm_status sharpsl_pm; -DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); -DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); +DECLARE_DELAYED_WORK(toggle_charger, sharpsl_charge_toggle); +DECLARE_DELAYED_WORK(sharpsl_bat, sharpsl_battery_thread); DEFINE_LED_TRIGGER(sharpsl_charge_led_trigger); @@ -116,7 +116,7 @@ void sharpsl_battery_kick(void) EXPORT_SYMBOL(sharpsl_battery_kick); -static void sharpsl_battery_thread(void *private_) +static void sharpsl_battery_thread(struct work_struct *private_) { int voltage, percent, apm_status, i = 0; @@ -128,7 +128,7 @@ static void sharpsl_battery_thread(void *private_) /* Corgi cannot confirm when battery fully charged so periodically kick! */ if (!sharpsl_pm.machinfo->batfull_irq && (sharpsl_pm.charge_mode == CHRG_ON) && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); while(1) { voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); @@ -212,7 +212,7 @@ static void sharpsl_charge_off(void) sharpsl_pm_led(SHARPSL_LED_OFF); sharpsl_pm.charge_mode = CHRG_OFF; - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } static void sharpsl_charge_error(void) @@ -222,7 +222,7 @@ static void sharpsl_charge_error(void) sharpsl_pm.charge_mode = CHRG_ERROR; } -static void sharpsl_charge_toggle(void *private_) +static void sharpsl_charge_toggle(struct work_struct *private_) { dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); @@ -254,7 +254,7 @@ static void sharpsl_ac_timer(unsigned long data) else if (sharpsl_pm.charge_mode == CHRG_ON) sharpsl_charge_off(); - schedule_work(&sharpsl_bat); + schedule_delayed_work(&sharpsl_bat, 0); } @@ -279,10 +279,10 @@ static void sharpsl_chrg_full_timer(unsigned long data) sharpsl_charge_off(); } else if (sharpsl_pm.full_count < 2) { dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); - schedule_work(&toggle_charger); + schedule_delayed_work(&toggle_charger, 0); } else { sharpsl_charge_off(); sharpsl_pm.charge_mode = CHRG_DONE; diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index f225a083dee..9d2346fb68f 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c @@ -323,7 +323,8 @@ static int h3_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c index dbc555d209f..cbe909bad79 100644 --- a/arch/arm/mach-omap1/board-nokia770.c +++ b/arch/arm/mach-omap1/board-nokia770.c @@ -74,7 +74,7 @@ static struct omap_kp_platform_data nokia770_kp_data = { .rows = 8, .cols = 8, .keymap = nokia770_keymap, - .keymapsize = ARRAY_SIZE(nokia770_keymap) + .keymapsize = ARRAY_SIZE(nokia770_keymap), .delay = 4, }; @@ -191,7 +191,7 @@ static void nokia770_audio_pwr_up(void) printk("HP connected\n"); } -static void codec_delayed_power_down(void *arg) +static void codec_delayed_power_down(struct work_struct *work) { down(&audio_pwr_sem); if (audio_pwr_state == -1) @@ -200,7 +200,7 @@ static void codec_delayed_power_down(void *arg) up(&audio_pwr_sem); } -static DECLARE_WORK(codec_power_down_work, codec_delayed_power_down, NULL); +static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down); static void nokia770_audio_pwr_down(void) { diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c index 3b29e59b0e6..0cbf1b0071f 100644 --- a/arch/arm/mach-omap1/leds-osk.c +++ b/arch/arm/mach-omap1/leds-osk.c @@ -35,7 +35,7 @@ static u8 hw_led_state; static u8 tps_leds_change; -static void tps_work(void *unused) +static void tps_work(struct work_struct *unused) { for (;;) { u8 leds; @@ -61,7 +61,7 @@ static void tps_work(void *unused) } } -static DECLARE_WORK(work, tps_work, NULL); +static DECLARE_WORK(work, tps_work); #ifdef CONFIG_OMAP_OSK_MISTRAL diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 26a95a642ad..3b1ad1d981a 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c @@ -206,7 +206,8 @@ static int h4_transceiver_mode(struct device *dev, int mode) cancel_delayed_work(&irda_config->gpio_expa); PREPARE_WORK(&irda_config->gpio_expa, set_trans_mode, &mode); - schedule_work(&irda_config->gpio_expa); +#error this is not permitted - mode is an argument variable + schedule_delayed_work(&irda_config->gpio_expa, 0); return 0; } diff --git a/arch/arm/mach-pxa/akita-ioexp.c b/arch/arm/mach-pxa/akita-ioexp.c index 1b398742ab5..12d2fe0ceff 100644 --- a/arch/arm/mach-pxa/akita-ioexp.c +++ b/arch/arm/mach-pxa/akita-ioexp.c @@ -36,11 +36,11 @@ I2C_CLIENT_INSMOD; static int max7310_write(struct i2c_client *client, int address, int data); static struct i2c_client max7310_template; -static void akita_ioexp_work(void *private_); +static void akita_ioexp_work(struct work_struct *private_); static struct device *akita_ioexp_device; static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT; -DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL); +DECLARE_WORK(akita_ioexp, akita_ioexp_work); /* @@ -158,7 +158,7 @@ void akita_reset_ioexp(struct device *dev, unsigned char bit) EXPORT_SYMBOL(akita_set_ioexp); EXPORT_SYMBOL(akita_reset_ioexp); -static void akita_ioexp_work(void *private_) +static void akita_ioexp_work(struct work_struct *private_) { if (akita_ioexp_device) max7310_set_ouputs(akita_ioexp_device, ioexp_output_value); diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index caab986af70..b62f0c4d2c7 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -209,7 +209,7 @@ static void do_serial_bh(void) } #endif -static void do_softint(void *private_) +static void do_softint(struct work_struct *private_) { printk(KERN_ERR "simserial: do_softint called\n"); } @@ -698,7 +698,7 @@ static int get_async_struct(int line, struct async_struct **ret_info) info->flags = sstate->flags; info->xmit_fifo_size = sstate->xmit_fifo_size; info->line = line; - INIT_WORK(&info->work, do_softint, info); + INIT_WORK(&info->work, do_softint); info->state = sstate; if (sstate->info) { kfree(info); diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 7cfa63a98cb..6bedd97570c 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -678,7 +678,7 @@ ia64_mca_cmc_vector_enable (void *dummy) * disable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_disable_keventd(void *unused) +ia64_mca_cmc_vector_disable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_disable, NULL, 1, 0); } @@ -690,7 +690,7 @@ ia64_mca_cmc_vector_disable_keventd(void *unused) * enable the cmc interrupt vector. */ static void -ia64_mca_cmc_vector_enable_keventd(void *unused) +ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused) { on_each_cpu(ia64_mca_cmc_vector_enable, NULL, 1, 0); } @@ -1247,8 +1247,8 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, monarch_cpu = -1; } -static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd, NULL); -static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd, NULL); +static DECLARE_WORK(cmc_disable_work, ia64_mca_cmc_vector_disable_keventd); +static DECLARE_WORK(cmc_enable_work, ia64_mca_cmc_vector_enable_keventd); /* * ia64_mca_cmc_int_handler diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index f7d7f566814..b21ddecea94 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c @@ -463,15 +463,17 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) } struct create_idle { + struct work_struct work; struct task_struct *idle; struct completion done; int cpu; }; void -do_fork_idle(void *_c_idle) +do_fork_idle(struct work_struct *work) { - struct create_idle *c_idle = _c_idle; + struct create_idle *c_idle = + container_of(work, struct create_idle, work); c_idle->idle = fork_idle(c_idle->cpu); complete(&c_idle->done); @@ -482,10 +484,10 @@ do_boot_cpu (int sapicid, int cpu) { int timeout; struct create_idle c_idle = { + .work = __WORK_INITIALIZER(c_idle.work, do_fork_idle), .cpu = cpu, .done = COMPLETION_INITIALIZER(c_idle.done), }; - DECLARE_WORK(work, do_fork_idle, &c_idle); c_idle.idle = get_idle_for_cpu(cpu); if (c_idle.idle) { @@ -497,9 +499,9 @@ do_boot_cpu (int sapicid, int cpu) * We can't use kernel_thread since we must avoid to reschedule the child. */ if (!keventd_up() || current_is_keventd()) - work.func(work.data); + c_idle.work.func(&c_idle.work); else { - schedule_work(&work); + schedule_work(&c_idle.work); wait_for_completion(&c_idle.done); } diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index f06a144c788..2c82412b9ef 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -319,7 +319,7 @@ static void sp_cleanup(void) static int channel_open = 0; /* the work handler */ -static void sp_work(void *data) +static void sp_work(struct work_struct *unused) { if (!channel_open) { if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { @@ -354,7 +354,7 @@ static void startwork(int vpe) return; } - INIT_WORK(&work, sp_work, NULL); + INIT_WORK(&work, sp_work); queue_work(workqueue, &work); } else queue_work(workqueue, &work); diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c index 31bcdae8482..0e837762cc5 100644 --- a/arch/powerpc/platforms/embedded6xx/ls_uart.c +++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c @@ -14,7 +14,7 @@ static unsigned long avr_clock; static struct work_struct wd_work; -static void wd_stop(void *unused) +static void wd_stop(struct work_struct *unused) { const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK"; int i = 0, rescue = 8; @@ -122,7 +122,7 @@ static int __init ls_uarts_init(void) ls_uart_init(); - INIT_WORK(&wd_work, wd_stop, NULL); + INIT_WORK(&wd_work, wd_stop); schedule_work(&wd_work); return 0; diff --git a/arch/powerpc/platforms/powermac/backlight.c b/arch/powerpc/platforms/powermac/backlight.c index afa593a8544..c3a89414ddc 100644 --- a/arch/powerpc/platforms/powermac/backlight.c +++ b/arch/powerpc/platforms/powermac/backlight.c @@ -18,11 +18,11 @@ #define OLD_BACKLIGHT_MAX 15 -static void pmac_backlight_key_worker(void *data); -static void pmac_backlight_set_legacy_worker(void *data); +static void pmac_backlight_key_worker(struct work_struct *work); +static void pmac_backlight_set_legacy_worker(struct work_struct *work); -static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker, NULL); -static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker, NULL); +static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker); +static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker); /* Although these variables are used in interrupt context, it makes no sense to * protect them. No user is able to produce enough key events per second and @@ -94,7 +94,7 @@ int pmac_backlight_curve_lookup(struct fb_info *info, int value) return level; } -static void pmac_backlight_key_worker(void *data) +static void pmac_backlight_key_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; @@ -166,7 +166,7 @@ static int __pmac_backlight_set_legacy_brightness(int brightness) return error; } -static void pmac_backlight_set_legacy_worker(void *data) +static void pmac_backlight_set_legacy_worker(struct work_struct *work) { if (atomic_read(&kernel_backlight_disabled)) return; diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 2e1943e2781..709952c25f2 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -385,6 +385,7 @@ struct fcc_enet_private { phy_info_t *phy; struct work_struct phy_relink; struct work_struct phy_display_config; + struct net_device *dev; uint sequence_done; @@ -1391,10 +1392,11 @@ static phy_info_t *phy_info[] = { NULL }; -static void mii_display_status(void *data) +static void mii_display_status(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, phy_relink); + struct net_device *dev = fep->dev; uint s = fep->phy_status; if (!fep->link && !fep->old_link) { @@ -1428,10 +1430,12 @@ static void mii_display_status(void *data) printk(".\n"); } -static void mii_display_config(void *data) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = data; - volatile struct fcc_enet_private *fep = dev->priv; + volatile struct fcc_enet_private *fep = + container_of(work, struct fcc_enet_private, + phy_display_config); + struct net_device *dev = fep->dev; uint s = fep->phy_status; printk("%s: config: auto-negotiation ", dev->name); @@ -1758,8 +1762,9 @@ static int __init fec_enet_init(void) cep->phy_id_done = 0; cep->phy_addr = fip->fc_phyaddr; mii_queue(dev, mk_mii_read(MII_PHYSID1), mii_discover_phy); - INIT_WORK(&cep->phy_relink, mii_display_status, dev); - INIT_WORK(&cep->phy_display_config, mii_display_config, dev); + INIT_WORK(&cep->phy_relink, mii_display_status); + INIT_WORK(&cep->phy_display_config, mii_display_config); + cep->dev = dev; #endif /* CONFIG_USE_MDIO */ fip++; diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 2f9fa9e3d33..e6c28fb423b 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -173,6 +173,7 @@ struct fec_enet_private { uint phy_speed; phy_info_t *phy; struct work_struct phy_task; + struct net_device *dev; uint sequence_done; @@ -1263,10 +1264,11 @@ static void mii_display_status(struct net_device *dev) printk(".\n"); } -static void mii_display_config(void *priv) +static void mii_display_config(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; volatile uint *s = &(fep->phy_status); printk("%s: config: auto-negotiation ", dev->name); @@ -1295,10 +1297,11 @@ static void mii_display_config(void *priv) fep->sequence_done = 1; } -static void mii_relink(void *priv) +static void mii_relink(struct work_struct *work) { - struct net_device *dev = (struct net_device *)priv; - struct fec_enet_private *fep = dev->priv; + struct fec_enet_private *fep = + container_of(work, struct fec_enet_private, phy_task); + struct net_device *dev = fep->dev; int duplex; fep->link = (fep->phy_status & PHY_STAT_LINK) ? 1 : 0; @@ -1325,7 +1328,8 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_relink, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_relink); schedule_work(&fep->phy_task); } @@ -1333,7 +1337,8 @@ static void mii_queue_config(uint mii_reg, struct net_device *dev) { struct fec_enet_private *fep = dev->priv; - INIT_WORK(&fep->phy_task, mii_display_config, (void *)dev); + fep->dev = dev; + INIT_WORK(&fep->phy_task, mii_display_config); schedule_work(&fep->phy_task); } diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index af1e8fc7d98..67d5cf9cba8 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -92,8 +92,8 @@ static int appldata_timer_active; * Work queue */ static struct workqueue_struct *appldata_wq; -static void appldata_work_fn(void *data); -static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); +static void appldata_work_fn(struct work_struct *work); +static DECLARE_WORK(appldata_work, appldata_work_fn); /* @@ -125,7 +125,7 @@ static void appldata_timer_function(unsigned long data) * * call data gathering function for each (active) module */ -static void appldata_work_fn(void *data) +static void appldata_work_fn(struct work_struct *work) { struct list_head *lh; struct appldata_ops *ops; diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 3576b3cc505..7d4190e5565 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -638,7 +638,7 @@ int chan_out_fd(struct list_head *chans) return -1; } -void chan_interrupt(struct list_head *chans, struct work_struct *task, +void chan_interrupt(struct list_head *chans, struct delayed_work *task, struct tty_struct *tty, int irq) { struct list_head *ele, *next; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 7b172160fe0..96f0189327a 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -56,7 +56,7 @@ static struct notifier_block reboot_notifier = { static LIST_HEAD(mc_requests); -static void mc_work_proc(void *unused) +static void mc_work_proc(struct work_struct *unused) { struct mconsole_entry *req; unsigned long flags; @@ -72,7 +72,7 @@ static void mc_work_proc(void *unused) } } -static DECLARE_WORK(mconsole_work, mc_work_proc, NULL); +static DECLARE_WORK(mconsole_work, mc_work_proc); static irqreturn_t mconsole_interrupt(int irq, void *dev_id) { diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index ec9eb8bd943..286bc0b3207 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -99,6 +99,7 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id) * same device, since it tests for (dev->flags & IFF_UP). So * there's no harm in delaying the device shutdown. */ schedule_work(&close_work); +#error this is not permitted - close_work will go out of scope goto out; } reactivate_fd(lp->fd, UM_ETH_IRQ); diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index ce9f3733f73..6dfe632f1c1 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -132,7 +132,7 @@ static int port_accept(struct port_list *port) DECLARE_MUTEX(ports_sem); struct list_head ports = LIST_HEAD_INIT(ports); -void port_work_proc(void *unused) +void port_work_proc(struct work_struct *unused) { struct port_list *port; struct list_head *ele; @@ -150,7 +150,7 @@ void port_work_proc(void *unused) local_irq_restore(flags); } -DECLARE_WORK(port_work, port_work_proc, NULL); +DECLARE_WORK(port_work, port_work_proc); static irqreturn_t port_interrupt(int irq, void *data) { -- cgit v1.2.3 From 9d4436a6fbc8c5eccdfcb8f5884e0a7b4a57f6d2 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 5 Nov 2006 15:40:13 +0900 Subject: sh: Add support for SH7206 and SH7619 CPU subtypes. This implements initial support for the SH7206 (SH-2A) and SH7619 (SH-2) MMU-less CPUs. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 43 +++++- arch/sh/Makefile | 3 + arch/sh/boot/compressed/misc.c | 3 +- arch/sh/kernel/Makefile | 2 +- arch/sh/kernel/cpu/Makefile | 11 +- arch/sh/kernel/cpu/init.c | 2 + arch/sh/kernel/cpu/irq/imask.c | 5 +- arch/sh/kernel/cpu/irq/ipr.c | 16 ++ arch/sh/kernel/cpu/sh2/Makefile | 3 +- arch/sh/kernel/cpu/sh2/clock-sh7619.c | 81 ++++++++++ arch/sh/kernel/cpu/sh2/probe.c | 16 +- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 53 +++++++ arch/sh/kernel/cpu/sh2a/Makefile | 10 ++ arch/sh/kernel/cpu/sh2a/clock-sh7206.c | 85 +++++++++++ arch/sh/kernel/cpu/sh2a/probe.c | 39 +++++ arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 58 ++++++++ arch/sh/kernel/setup.c | 1 + arch/sh/kernel/signal.c | 10 +- arch/sh/kernel/timers/Makefile | 2 + arch/sh/kernel/timers/timer-cmt.c | 256 ++++++++++++++++++++++++++++++++ arch/sh/kernel/timers/timer-mtu2.c | 260 +++++++++++++++++++++++++++++++++ arch/sh/kernel/timers/timer.c | 6 + arch/sh/mm/Kconfig | 17 ++- arch/sh/mm/cache-sh2.c | 69 +++++---- arch/sh/tools/mach-types | 2 + 25 files changed, 1000 insertions(+), 53 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh2/clock-sh7619.c create mode 100644 arch/sh/kernel/cpu/sh2/setup-sh7619.c create mode 100644 arch/sh/kernel/cpu/sh2a/Makefile create mode 100644 arch/sh/kernel/cpu/sh2a/clock-sh7206.c create mode 100644 arch/sh/kernel/cpu/sh2a/probe.c create mode 100644 arch/sh/kernel/cpu/sh2a/setup-sh7206.c create mode 100644 arch/sh/kernel/timers/timer-cmt.c create mode 100644 arch/sh/kernel/timers/timer-mtu2.c (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index bffc7e17697..ba7a1501630 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -219,6 +219,20 @@ config SH_SHMIN help Select SHMIN if configuring for the SHMIN board. +config SH_7206_SOLUTION_ENGINE + bool "SolutionEngine7206" + select CPU_SUBTYPE_SH7206 + help + Select 7206 SolutionEngine if configuring for a Hitachi SH7206 + evaluation board. + +config SH_7619_SOLUTION_ENGINE + bool "SolutionEngine7619" + select CPU_SUBTYPE_SH7619 + help + Select 7619 SolutionEngine if configuring for a Hitachi SH7619 + evaluation board. + config SH_UNKNOWN bool "BareCPU" help @@ -364,10 +378,25 @@ depends on !GENERIC_TIME config SH_TMU bool "TMU timer support" + depends on CPU_SH3 || CPU_SH4 default y help This enables the use of the TMU as the system timer. +config SH_CMT + bool "CMT timer support" + depends on CPU_SH2 + default y + help + This enables the use of the CMT as the system timer. + +config SH_MTU2 + bool "MTU2 timer support" + depends on CPU_SH2A + default n + help + This enables the use of the MTU2 as the system timer. + endmenu source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" @@ -378,17 +407,25 @@ source "arch/sh/boards/renesas/r7780rp/Kconfig" config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" + default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 + default "31250000" if CPU_SUBTYPE_SH7619 + default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ + CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 || \ + CPU_SUBTYPE_SH7206 default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 default "60000000" if CPU_SUBTYPE_SH7751 - default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ - CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7705 - default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 default "66000000" if CPU_SUBTYPE_SH4_202 help This option is used to specify the peripheral clock frequency. This is necessary for determining the reference clock value on platforms lacking an RTC. +config SH_CLK_MD + int "CPU Mode Pin Setting" + depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 + help + MD2 - MD0 Setting. + menu "CPU Frequency scaling" source "drivers/cpufreq/Kconfig" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 26d62ff51a6..dc43984bd4b 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -109,6 +109,8 @@ machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev machdir-$(CONFIG_SH_LANDISK) := landisk machdir-$(CONFIG_SH_TITAN) := titan machdir-$(CONFIG_SH_SHMIN) := shmin +machdir-$(CONFIG_SH_7206_SOLUTION_ENGINE) := se/7206 +machdir-$(CONFIG_SH_7619_SOLUTION_ENGINE) := se/7619 machdir-$(CONFIG_SH_UNKNOWN) := unknown incdir-y := $(notdir $(machdir-y)) @@ -124,6 +126,7 @@ core-$(CONFIG_HD64465) += arch/sh/cchips/hd6446x/hd64465/ core-$(CONFIG_VOYAGERGX) += arch/sh/cchips/voyagergx/ cpuincdir-$(CONFIG_CPU_SH2) := cpu-sh2 +cpuincdir-$(CONFIG_CPU_SH2A) := cpu-sh2a cpuincdir-$(CONFIG_CPU_SH3) := cpu-sh3 cpuincdir-$(CONFIG_CPU_SH4) := cpu-sh4 diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index f2fed5ce5cc..35452d85b7f 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -12,6 +12,7 @@ */ #include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include #endif @@ -228,7 +229,7 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { output_data = 0; - output_ptr = (unsigned long)&_text+0x20001000; + output_ptr = P2SEGADDR((unsigned long)&_text+0x1000); free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 5da88a43d35..50d54c24d76 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o signal.o entry.o traps.o irq.o \ +obj-y := process.o signal.o traps.o irq.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ io.o io_generic.o sh_ksyms.o syscalls.o diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index fb5dac06938..0582e6712b7 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -2,11 +2,12 @@ # Makefile for the Linux/SuperH CPU-specifc backends. # -obj-y += irq/ init.o clock.o - -obj-$(CONFIG_CPU_SH2) += sh2/ -obj-$(CONFIG_CPU_SH3) += sh3/ -obj-$(CONFIG_CPU_SH4) += sh4/ +obj-$(CONFIG_CPU_SH2) = sh2/ +obj-$(CONFIG_CPU_SH2A) = sh2a/ +obj-$(CONFIG_CPU_SH3) = sh3/ +obj-$(CONFIG_CPU_SH4) = sh4/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o + +obj-y += irq/ init.o clock.o diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index bfb90eb0b7a..48121766e8d 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -68,12 +68,14 @@ static void __init cache_init(void) waysize = cpu_data->dcache.sets; +#ifdef CCR_CACHE_ORA /* * If the OC is already in RAM mode, we only have * half of the entries to flush.. */ if (ccr & CCR_CACHE_ORA) waysize >>= 1; +#endif waysize <<= cpu_data->dcache.entry_shift; diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index a33ae3e0a5a..301b505c427 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c @@ -53,7 +53,10 @@ void static inline set_interrupt_registers(int ip) { unsigned long __dummy; - asm volatile("ldc %2, r6_bank\n\t" + asm volatile( +#ifdef CONFIG_CPU_HAS_SR_RB + "ldc %2, r6_bank\n\t" +#endif "stc sr, %0\n\t" "and #0xf0, %0\n\t" "shlr2 %0\n\t" diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index a0089563cbf..f7a2bae1df9 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -62,6 +62,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) } EXPORT_SYMBOL(make_ipr_irq); +/* + * XXX: Move this garbage in to the drivers, and kill off the ridiculous CPU + * subtype checks. + */ static struct ipr_data sys_ipr_map[] = { #ifndef CONFIG_CPU_SUBTYPE_SH7780 { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, @@ -80,6 +84,18 @@ static struct ipr_data sys_ipr_map[] = { { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, #endif +#ifdef SCIF2_ERI_IRQ + { SCIF2_ERI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_RXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_BRI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, + { SCIF2_TXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, +#endif +#ifdef SCIF3_ERI_IRQ + { SCIF3_ERI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_RXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_BRI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, + { SCIF3_TXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, +#endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, diff --git a/arch/sh/kernel/cpu/sh2/Makefile b/arch/sh/kernel/cpu/sh2/Makefile index 389353fba60..f0f059acfcf 100644 --- a/arch/sh/kernel/cpu/sh2/Makefile +++ b/arch/sh/kernel/cpu/sh2/Makefile @@ -2,5 +2,6 @@ # Makefile for the Linux/SuperH SH-2 backends. # -obj-y := probe.o +obj-y := ex.o probe.o entry.o +obj-$(CONFIG_CPU_SUBTYPE_SH7619) += setup-sh7619.o clock-sh7619.o diff --git a/arch/sh/kernel/cpu/sh2/clock-sh7619.c b/arch/sh/kernel/cpu/sh2/clock-sh7619.c new file mode 100644 index 00000000000..d0440b26970 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2/clock-sh7619.c @@ -0,0 +1,81 @@ +/* + * arch/sh/kernel/cpu/sh2/clock-sh7619.c + * + * SH7619 support for the clock framework + * + * Copyright (C) 2006 Yoshinori Sato + * + * Based on clock-sh4.c + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +const static int pll1rate[]={1,2}; +const static int pfc_divisors[]={1,2,0,4}; + +#if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2) +#define PLL2 (4) +#elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6) +#define PLL2 (2) +#else +#error "Illigal Clock Mode!" +#endif + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; +} + +static struct clk_ops sh7619_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7619_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7]; +} + +static struct clk_ops sh7619_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate; +} + +static struct clk_ops sh7619_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7619_clk_ops[] = { + &sh7619_master_clk_ops, + &sh7619_module_clk_ops, + &sh7619_bus_clk_ops, + &sh7619_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7619_clk_ops)) + *ops = sh7619_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh2/probe.c b/arch/sh/kernel/cpu/sh2/probe.c index f17a2a0d588..ba527d9b502 100644 --- a/arch/sh/kernel/cpu/sh2/probe.c +++ b/arch/sh/kernel/cpu/sh2/probe.c @@ -17,17 +17,23 @@ int __init detect_cpu_and_cache_system(void) { - /* - * For now, assume SH7604 .. fix this later. - */ +#if defined(CONFIG_CPU_SUBTYPE_SH7604) cpu_data->type = CPU_SH7604; cpu_data->dcache.ways = 4; - cpu_data->dcache.way_shift = 6; + cpu_data->dcache.way_incr = (1<<10); cpu_data->dcache.sets = 64; cpu_data->dcache.entry_shift = 4; cpu_data->dcache.linesz = L1_CACHE_BYTES; cpu_data->dcache.flags = 0; - +#elif defined(CONFIG_CPU_SUBTYPE_SH7619) + cpu_data->type = CPU_SH7619; + cpu_data->dcache.ways = 4; + cpu_data->dcache.way_incr = (1<<12); + cpu_data->dcache.sets = 256; + cpu_data->dcache.entry_shift = 4; + cpu_data->dcache.linesz = L1_CACHE_BYTES; + cpu_data->dcache.flags = 0; +#endif /* * SH-2 doesn't have separate caches */ diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c new file mode 100644 index 00000000000..82c2d905152 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -0,0 +1,53 @@ +/* + * SH7619 Setup + * + * Copyright (C) 2006 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xf8400000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 88, 89, 91, 90}, + }, { + .mapbase = 0xf8410000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 92, 93, 95, 94}, + }, { + .mapbase = 0xf8420000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 96, 97, 99, 98}, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7619_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7619_devices_setup(void) +{ + return platform_add_devices(sh7619_devices, + ARRAY_SIZE(sh7619_devices)); +} +__initcall(sh7619_devices_setup); diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile new file mode 100644 index 00000000000..350972ae941 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for the Linux/SuperH SH-2A backends. +# + +obj-y := common.o probe.o + +common-y += $(addprefix ../sh2/, ex.o) +common-y += $(addprefix ../sh2/, entry.o) + +obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7206.c b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c new file mode 100644 index 00000000000..a9ad309c6a3 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7206.c @@ -0,0 +1,85 @@ +/* + * arch/sh/kernel/cpu/sh2a/clock-sh7206.c + * + * SH7206 support for the clock framework + * + * Copyright (C) 2006 Yoshinori Sato + * + * Based on clock-sh4.c + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +const static int pll1rate[]={1,2,3,4,6,8}; +const static int pfc_divisors[]={1,2,3,4,6,8,12}; +#define ifc_divisors pfc_divisors + +#if (CONFIG_SH_CLK_MD == 2) +#define PLL2 (4) +#elif (CONFIG_SH_CLK_MD == 6) +#define PLL2 (2) +#elif (CONFIG_SH_CLK_MD == 7) +#define PLL2 (1) +#else +#error "Illigal Clock Mode!" +#endif + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; +} + +static struct clk_ops sh7206_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7206_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 0x0007]; +} + +static struct clk_ops sh7206_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inw(FREQCR) & 0x0007); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7206_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7206_clk_ops[] = { + &sh7206_master_clk_ops, + &sh7206_module_clk_ops, + &sh7206_bus_clk_ops, + &sh7206_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7206_clk_ops)) + *ops = sh7206_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh2a/probe.c b/arch/sh/kernel/cpu/sh2a/probe.c new file mode 100644 index 00000000000..87c6c054208 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/probe.c @@ -0,0 +1,39 @@ +/* + * arch/sh/kernel/cpu/sh2a/probe.c + * + * CPU Subtype Probing for SH-2A. + * + * Copyright (C) 2004, 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include + +int __init detect_cpu_and_cache_system(void) +{ + /* Just SH7206 for now .. */ + cpu_data->type = CPU_SH7206; + + cpu_data->dcache.ways = 4; + cpu_data->dcache.way_incr = (1 << 11); + cpu_data->dcache.sets = 128; + cpu_data->dcache.entry_shift = 4; + cpu_data->dcache.linesz = L1_CACHE_BYTES; + cpu_data->dcache.flags = 0; + + /* + * The icache is the same as the dcache as far as this setup is + * concerned. The only real difference in hardware is that the icache + * lacks the U bit that the dcache has, none of this has any bearing + * on the cache info. + */ + cpu_data->icache = cpu_data->dcache; + + return 0; +} + diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c new file mode 100644 index 00000000000..cdfeef49e62 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -0,0 +1,58 @@ +/* + * SH7206 Setup + * + * Copyright (C) 2006 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xfffe8000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 240, 241, 242, 243}, + }, { + .mapbase = 0xfffe8800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 244, 245, 246, 247}, + }, { + .mapbase = 0xfffe9000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 248, 249, 250, 251}, + }, { + .mapbase = 0xfffe9800, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 252, 253, 254, 255}, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7206_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7206_devices_setup(void) +{ + return platform_add_devices(sh7206_devices, + ARRAY_SIZE(sh7206_devices)); +} +__initcall(sh7206_devices_setup); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 36d86f9ac38..c24f6390007 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -404,6 +404,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", + [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 5213f5bc6ce..764886b4bcf 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -98,7 +98,11 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, */ #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ -#define TRAP16 0xc310 /* Syscall w/no args (NR in R3) */ +#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */ +#else +#define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */ +#endif #define OR_R0_R0 0x200b /* or r0,r0 (insert to avoid hardware bug) */ struct sigframe @@ -350,7 +354,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, } else { /* Generate return code (system call to sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); - err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(TRAP_NOARG, &frame->retcode[1]); err |= __put_user(OR_R0_R0, &frame->retcode[2]); err |= __put_user(OR_R0_R0, &frame->retcode[3]); err |= __put_user(OR_R0_R0, &frame->retcode[4]); @@ -430,7 +434,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, } else { /* Generate return code (system call to rt_sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); - err |= __put_user(TRAP16, &frame->retcode[1]); + err |= __put_user(TRAP_NOARG, &frame->retcode[1]); err |= __put_user(OR_R0_R0, &frame->retcode[2]); err |= __put_user(OR_R0_R0, &frame->retcode[3]); err |= __put_user(OR_R0_R0, &frame->retcode[4]); diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile index 151a6a304ce..bcf244ff6a1 100644 --- a/arch/sh/kernel/timers/Makefile +++ b/arch/sh/kernel/timers/Makefile @@ -5,4 +5,6 @@ obj-y := timer.o obj-$(CONFIG_SH_TMU) += timer-tmu.o +obj-$(CONFIG_SH_MTU2) += timer-mtu2.o +obj-$(CONFIG_SH_CMT) += timer-cmt.o diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c new file mode 100644 index 00000000000..9eab395cd34 --- /dev/null +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -0,0 +1,256 @@ +/* + * arch/sh/kernel/timers/timer-cmt.c - CMT Timer Support + * + * Copyright (C) 2005 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_CPU_SUBTYPE_SH7619) +#define CMT_CMSTR 0xf84a0070 +#define CMT_CMCSR_0 0xf84a0072 +#define CMT_CMCNT_0 0xf84a0074 +#define CMT_CMCOR_0 0xf84a0076 +#define CMT_CMCSR_1 0xf84a0078 +#define CMT_CMCNT_1 0xf84a007a +#define CMT_CMCOR_1 0xf84a007c + +#define STBCR3 0xf80a0000 +#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR3) & ~0x10, STBCR3); } while(0) +#define CMT_CMCSR_INIT 0x0040 +#define CMT_CMCSR_CALIB 0x0000 +#elif defined(CONFIG_CPU_SUBTYPE_SH7206) +#define CMT_CMSTR 0xfffec000 +#define CMT_CMCSR_0 0xfffec002 +#define CMT_CMCNT_0 0xfffec004 +#define CMT_CMCOR_0 0xfffec006 + +#define STBCR4 0xfffe040c +#define cmt_clock_enable() do { ctrl_outb(ctrl_inb(STBCR4) & ~0x04, STBCR4); } while(0) +#define CMT_CMCSR_INIT 0x0040 +#define CMT_CMCSR_CALIB 0x0000 +#else +#error "Unknown CPU SUBTYPE" +#endif + +static DEFINE_SPINLOCK(cmt0_lock); + +static unsigned long cmt_timer_get_offset(void) +{ + int count; + unsigned long flags; + + static unsigned short count_p = 0xffff; /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + spin_lock_irqsave(&cmt0_lock, flags); + /* timer count may underflow right here */ + count = ctrl_inw(CMT_CMCOR_0); + count -= ctrl_inw(CMT_CMCNT_0); + + jiffies_t = jiffies; + + /* + * avoiding timer inconsistencies (they are rare, but they happen)... + * there is one kind of problem that must be avoided here: + * 1. the timer counter underflows + */ + + if (jiffies_t == jiffies_p) { + if (count > count_p) { + /* the nutcase */ + if (ctrl_inw(CMT_CMCSR_0) & 0x80) { /* Check CMF bit */ + count -= LATCH; + } else { + printk("%s (): hardware timer problem?\n", + __FUNCTION__); + } + } + } else + jiffies_p = jiffies_t; + + count_p = count; + spin_unlock_irqrestore(&cmt0_lock, flags); + + count = ((LATCH-1) - count) * TICK_SIZE; + count = (count + LATCH/2) / LATCH; + + return count; +} + +static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long timer_status; + + /* Clear CMF bit */ + timer_status = ctrl_inw(CMT_CMCSR_0); + timer_status &= ~0x80; + ctrl_outw(timer_status, CMT_CMCSR_0); + + /* + * Here we are in the timer irq handler. We just have irqs locally + * disabled but we don't know if the timer_bh is running on the other + * CPU. We need to avoid to SMP race with it. NOTE: we don' t need + * the irq version of write_lock because as just said we have irq + * locally disabled. -arca + */ + write_seqlock(&xtime_lock); + handle_timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction cmt_irq = { + .name = "timer", + .handler = cmt_timer_interrupt, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, +}; + +/* + * Hah! We'll see if this works (switching from usecs to nsecs). + */ +static unsigned long cmt_timer_get_frequency(void) +{ + u32 freq; + struct timespec ts1, ts2; + unsigned long diff_nsec; + unsigned long factor; + + /* Setup the timer: We don't want to generate interrupts, just + * have it count down at its natural rate. + */ + + ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); + ctrl_outw(CMT_CMCSR_CALIB, CMT_CMCSR_0); + ctrl_outw(0xffff, CMT_CMCOR_0); + ctrl_outw(0xffff, CMT_CMCNT_0); + + rtc_sh_get_time(&ts2); + + do { + rtc_sh_get_time(&ts1); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + /* actually start the timer */ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + + do { + rtc_sh_get_time(&ts2); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + freq = 0xffff - ctrl_inw(CMT_CMCNT_0); + if (ts2.tv_nsec < ts1.tv_nsec) { + ts2.tv_nsec += 1000000000; + ts2.tv_sec--; + } + + diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000000 + diff_nsec/2) / diff_nsec; + + if (factor * diff_nsec > 1100000000 || + factor * diff_nsec < 900000000) + panic("weird RTC (diff_nsec %ld)", diff_nsec); + + return freq * factor; +} + +static void cmt_clk_init(struct clk *clk) +{ + u8 divisor = CMT_CMCSR_INIT & 0x3; + ctrl_inw(CMT_CMCSR_0); + ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0); + clk->parent = clk_get("module_clk"); + clk->rate = clk->parent->rate / (8 << (divisor << 1)); +} + +static void cmt_clk_recalc(struct clk *clk) +{ + u8 divisor = ctrl_inw(CMT_CMCSR_0) & 0x3; + clk->rate = clk->parent->rate / (8 << (divisor << 1)); +} + +static struct clk_ops cmt_clk_ops = { + .init = cmt_clk_init, + .recalc = cmt_clk_recalc, +}; + +static struct clk cmt0_clk = { + .name = "cmt0_clk", + .ops = &cmt_clk_ops, +}; + +static int cmt_timer_start(void) +{ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + return 0; +} + +static int cmt_timer_stop(void) +{ + ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); + return 0; +} + +static int cmt_timer_init(void) +{ + unsigned long interval; + + cmt_clock_enable(); + + setup_irq(TIMER_IRQ, &cmt_irq); + + cmt0_clk.parent = clk_get("module_clk"); + + cmt_timer_stop(); + + interval = cmt0_clk.parent->rate / 8 / HZ; + printk(KERN_INFO "Interval = %ld\n", interval); + + ctrl_outw(interval, CMT_CMCOR_0); + + clk_register(&cmt0_clk); + clk_enable(&cmt0_clk); + + cmt_timer_start(); + + return 0; +} + +struct sys_timer_ops cmt_timer_ops = { + .init = cmt_timer_init, + .start = cmt_timer_start, + .stop = cmt_timer_stop, + .get_frequency = cmt_timer_get_frequency, + .get_offset = cmt_timer_get_offset, +}; + +struct sys_timer cmt_timer = { + .name = "cmt", + .ops = &cmt_timer_ops, +}; + diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c new file mode 100644 index 00000000000..73a5ef3c457 --- /dev/null +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -0,0 +1,260 @@ +/* + * arch/sh/kernel/timers/timer-mtu2.c - MTU2 Timer Support + * + * Copyright (C) 2005 Paul Mundt + * + * Based off of arch/sh/kernel/timers/timer-tmu.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * We use channel 1 for our lowly system timer. Channel 2 would be the other + * likely candidate, but we leave it alone as it has higher divisors that + * would be of more use to other more interesting applications. + * + * TODO: Presently we only implement a 16-bit single-channel system timer. + * However, we can implement channel cascade if we go the overflow route and + * get away with using 2 MTU2 channels as a 32-bit timer. + */ + +static DEFINE_SPINLOCK(mtu2_lock); + +#define MTU2_TSTR 0xfffe4280 +#define MTU2_TCR_1 0xfffe4380 +#define MTU2_TMDR_1 0xfffe4381 +#define MTU2_TIOR_1 0xfffe4382 +#define MTU2_TIER_1 0xfffe4384 +#define MTU2_TSR_1 0xfffe4385 +#define MTU2_TCNT_1 0xfffe4386 /* 16-bit counter */ +#define MTU2_TGRA_1 0xfffe438a + +#define STBCR3 0xfffe0408 + +#define MTU2_TSTR_CST1 (1 << 1) /* Counter Start 1 */ + +#define MTU2_TSR_TGFA (1 << 0) /* GRA compare match */ + +#define MTU2_TIER_TGIEA (1 << 0) /* GRA compare match interrupt enable */ + +#define MTU2_TCR_INIT 0x22 + +#define MTU2_TCR_CALIB 0x00 + +static unsigned long mtu2_timer_get_offset(void) +{ + int count; + unsigned long flags; + + static int count_p = 0x7fff; /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + spin_lock_irqsave(&mtu2_lock, flags); + /* timer count may underflow right here */ + count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */ + + jiffies_t = jiffies; + + /* + * avoiding timer inconsistencies (they are rare, but they happen)... + * there is one kind of problem that must be avoided here: + * 1. the timer counter underflows + */ + + if (jiffies_t == jiffies_p) { + if (count > count_p) { + if (ctrl_inb(MTU2_TSR_1) & MTU2_TSR_TGFA) { + count -= LATCH; + } else { + printk("%s (): hardware timer problem?\n", + __FUNCTION__); + } + } + } else + jiffies_p = jiffies_t; + + count_p = count; + spin_unlock_irqrestore(&mtu2_lock, flags); + + count = ((LATCH-1) - count) * TICK_SIZE; + count = (count + LATCH/2) / LATCH; + + return count; +} + +static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +{ + unsigned long timer_status; + + /* Clear TGFA bit */ + timer_status = ctrl_inb(MTU2_TSR_1); + timer_status &= ~MTU2_TSR_TGFA; + ctrl_outb(timer_status, MTU2_TSR_1); + + /* Do timer tick */ + write_seqlock(&xtime_lock); + handle_timer_tick(regs); + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction mtu2_irq = { + .name = "timer", + .handler = mtu2_timer_interrupt, + .flags = SA_INTERRUPT, + .mask = CPU_MASK_NONE, +}; + +/* + * Hah! We'll see if this works (switching from usecs to nsecs). + */ +static unsigned long mtu2_timer_get_frequency(void) +{ + u32 freq; + struct timespec ts1, ts2; + unsigned long diff_nsec; + unsigned long factor; + + /* Setup the timer: We don't want to generate interrupts, just + * have it count down at its natural rate. + */ + + ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR); + ctrl_outb(MTU2_TCR_CALIB, MTU2_TCR_1); + ctrl_outb(ctrl_inb(MTU2_TIER_1) & ~MTU2_TIER_TGIEA, MTU2_TIER_1); + ctrl_outw(0, MTU2_TCNT_1); + + rtc_get_time(&ts2); + + do { + rtc_get_time(&ts1); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + /* actually start the timer */ + ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); + + do { + rtc_get_time(&ts2); + } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); + + freq = ctrl_inw(MTU2_TCNT_0); + if (ts2.tv_nsec < ts1.tv_nsec) { + ts2.tv_nsec += 1000000000; + ts2.tv_sec--; + } + + diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); + + /* this should work well if the RTC has a precision of n Hz, where + * n is an integer. I don't think we have to worry about the other + * cases. */ + factor = (1000000000 + diff_nsec/2) / diff_nsec; + + if (factor * diff_nsec > 1100000000 || + factor * diff_nsec < 900000000) + panic("weird RTC (diff_nsec %ld)", diff_nsec); + + return freq * factor; +} + +static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 }; + +static void mtu2_clk_init(struct clk *clk) +{ + u8 idx = MTU2_TCR_INIT & 0x7; + + clk->rate = clk->parent->rate / divisors[idx]; + /* Start TCNT counting */ + ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR); + +} + +static void mtu2_clk_recalc(struct clk *clk) +{ + u8 idx = ctrl_inb(MTU2_TCR_1) & 0x7; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops mtu2_clk_ops = { + .init = mtu2_clk_init, + .recalc = mtu2_clk_recalc, +}; + +static struct clk mtu2_clk1 = { + .name = "mtu2_clk1", + .ops = &mtu2_clk_ops, +}; + +static int mtu2_timer_start(void) +{ + ctrl_outb(ctrl_inb(MTU2_TSTR) | MTU2_TSTR_CST1, MTU2_TSTR); + return 0; +} + +static int mtu2_timer_stop(void) +{ + ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR); + return 0; +} + +static int mtu2_timer_init(void) +{ + u8 tmp; + unsigned long interval; + + setup_irq(TIMER_IRQ, &mtu2_irq); + + mtu2_clk1.parent = clk_get("module_clk"); + + ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3); + + /* Normal operation */ + ctrl_outb(0, MTU2_TMDR_1); + ctrl_outb(MTU2_TCR_INIT, MTU2_TCR_1); + ctrl_outb(0x01, MTU2_TIOR_1); + + /* Enable underflow interrupt */ + ctrl_outb(ctrl_inb(MTU2_TIER_1) | MTU2_TIER_TGIEA, MTU2_TIER_1); + + interval = CONFIG_SH_PCLK_FREQ / 16 / HZ; + printk(KERN_INFO "Interval = %ld\n", interval); + + ctrl_outw(interval, MTU2_TGRA_1); + ctrl_outw(0, MTU2_TCNT_1); + + clk_register(&mtu2_clk1); + clk_enable(&mtu2_clk1); + + return 0; +} + +struct sys_timer_ops mtu2_timer_ops = { + .init = mtu2_timer_init, + .start = mtu2_timer_start, + .stop = mtu2_timer_stop, + .get_frequency = mtu2_timer_get_frequency, + .get_offset = mtu2_timer_get_offset, +}; + +struct sys_timer mtu2_timer = { + .name = "mtu2", + .ops = &mtu2_timer_ops, +}; diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c index dc1f631053a..a6bcc913d25 100644 --- a/arch/sh/kernel/timers/timer.c +++ b/arch/sh/kernel/timers/timer.c @@ -16,6 +16,12 @@ static struct sys_timer *sys_timers[] __initdata = { #ifdef CONFIG_SH_TMU &tmu_timer, +#endif +#ifdef CONFIG_SH_MTU2 + &mtu2_timer, +#endif +#ifdef CONFIG_SH_CMT + &cmt_timer, #endif NULL, }; diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 9dd606464d2..814a1758697 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -4,8 +4,12 @@ menu "Processor selection" # Processor families # config CPU_SH2 + select SH_WRITETHROUGH if !CPU_SH2A bool - select SH_WRITETHROUGH + +config CPU_SH2A + bool + select CPU_SH2 config CPU_SH3 bool @@ -40,6 +44,16 @@ config CPU_SUBTYPE_SH7604 bool "Support SH7604 processor" select CPU_SH2 +config CPU_SUBTYPE_SH7619 + bool "Support SH7619 processor" + select CPU_SH2 + +comment "SH-2A Processor Support" + +config CPU_SUBTYPE_SH7206 + bool "Support SH7206 processor" + select CPU_SH2A + comment "SH-3 Processor Support" config CPU_SUBTYPE_SH7300 @@ -274,7 +288,6 @@ config SH_DIRECT_MAPPED config SH_WRITETHROUGH bool "Use write-through caching" - default y if CPU_SH2 help Selecting this option will configure the caches in write-through mode, as opposed to the default write-back configuration. diff --git a/arch/sh/mm/cache-sh2.c b/arch/sh/mm/cache-sh2.c index 2689cb24ea2..6614033f6be 100644 --- a/arch/sh/mm/cache-sh2.c +++ b/arch/sh/mm/cache-sh2.c @@ -5,6 +5,7 @@ * * Released under the terms of the GNU GPL v2.0. */ + #include #include @@ -14,37 +15,43 @@ #include #include -/* - * Calculate the OC address and set the way bit on the SH-2. - * - * We must have already jump_to_P2()'ed prior to calling this - * function, since we rely on CCR manipulation to do the - * Right Thing(tm). - */ -unsigned long __get_oc_addr(unsigned long set, unsigned long way) +void __flush_wback_region(void *start, int size) { - unsigned long ccr; - - /* - * On SH-2 the way bit isn't tracked in the address field - * if we're doing address array access .. instead, we need - * to manually switch out the way in the CCR. - */ - ccr = ctrl_inl(CCR); - ccr &= ~0x00c0; - ccr |= way << cpu_data->dcache.way_shift; - - /* - * Despite the number of sets being halved, we end up losing - * the first 2 ways to OCRAM instead of the last 2 (if we're - * 4-way). As a result, forcibly setting the W1 bit handily - * bumps us up 2 ways. - */ - if (ccr & CCR_CACHE_ORA) - ccr |= 1 << (cpu_data->dcache.way_shift + 1); - - ctrl_outl(ccr, CCR); - - return CACHE_OC_ADDRESS_ARRAY | (set << cpu_data->dcache.entry_shift); + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + /* FIXME cache purge */ + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } +} + +void __flush_purge_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } +} + +void __flush_invalidate_region(void *start, int size) +{ + unsigned long v; + unsigned long begin, end; + + begin = (unsigned long)start & ~(L1_CACHE_BYTES-1); + end = ((unsigned long)start + size + L1_CACHE_BYTES-1) + & ~(L1_CACHE_BYTES-1); + for (v = begin; v < end; v+=L1_CACHE_BYTES) { + ctrl_outl((v & 0x1ffffc00), (v & 0x00000ff0) | 0x00000008); + } } diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index ac57638977e..0571755e9a8 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -30,3 +30,5 @@ R7780MP SH_R7780MP TITAN SH_TITAN SHMIN SH_SHMIN 7710VOIPGW SH_7710VOIPGW +7206SE SH_7206_SOLUTION_ENGINE +7619SE SH_7619_SOLUTION_ENGINE -- cgit v1.2.3 From 0983b31849bbe1fe82520947acc1bec97c457d4b Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 5 Nov 2006 15:58:47 +0900 Subject: sh: Wire up division and address error exceptions on SH-2A. SH-2A has special division hardware as opposed to a full-fledged FPU, wire up the exception handlers for this. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/kernel/traps.c | 88 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 53dfa55f315..1edec2709ef 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -33,8 +33,13 @@ #endif #ifdef CONFIG_CPU_SH2 -#define TRAP_RESERVED_INST 4 -#define TRAP_ILLEGAL_SLOT_INST 6 +# define TRAP_RESERVED_INST 4 +# define TRAP_ILLEGAL_SLOT_INST 6 +# define TRAP_ADDRESS_ERROR 9 +# ifdef CONFIG_CPU_SH2A +# define TRAP_DIVZERO_ERROR 17 +# define TRAP_DIVOVF_ERROR 18 +# endif #else #define TRAP_RESERVED_INST 12 #define TRAP_ILLEGAL_SLOT_INST 13 @@ -479,6 +484,14 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) return ret; } +#ifdef CONFIG_CPU_HAS_SR_RB +#define lookup_exception_vector(x) \ + __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x))) +#else +#define lookup_exception_vector(x) \ + __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x))) +#endif + /* * Handle various address error exceptions */ @@ -486,24 +499,37 @@ asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, unsigned long address) { - unsigned long error_code; + unsigned long error_code = 0; mm_segment_t oldfs; u16 instruction; int tmp; - asm volatile("stc r2_bank,%0": "=r" (error_code)); + /* Intentional ifdef */ +#ifdef CONFIG_CPU_HAS_SR_RB + lookup_exception_vector(error_code); +#endif oldfs = get_fs(); if (user_mode(regs)) { local_irq_enable(); current->thread.error_code = error_code; +#ifdef CONFIG_CPU_SH2 + /* + * On the SH-2, we only have a single vector for address + * errors, there's no differentiating between a load error + * and a store error. + */ + current->thread.trap_no = 9; +#else current->thread.trap_no = (writeaccess) ? 8 : 7; +#endif /* bad PC is not something we can fix */ if (regs->pc & 1) goto uspace_segv; +#ifndef CONFIG_CPU_SH2A set_fs(USER_DS); if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. @@ -518,6 +544,7 @@ asmlinkage void do_address_error(struct pt_regs *regs, if (tmp==0) return; /* sorted */ +#endif uspace_segv: printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); @@ -526,6 +553,7 @@ asmlinkage void do_address_error(struct pt_regs *regs, if (regs->pc & 1) die("unaligned program counter", regs, error_code); +#ifndef CONFIG_CPU_SH2A set_fs(KERNEL_DS); if (copy_from_user(&instruction, (u16 *)(regs->pc), 2)) { /* Argh. Fault on the instruction itself. @@ -537,6 +565,10 @@ asmlinkage void do_address_error(struct pt_regs *regs, handle_unaligned_access(instruction, regs); set_fs(oldfs); +#else + printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); + force_sig(SIGSEGV, current); +#endif } } @@ -569,6 +601,29 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ +#ifdef CONFIG_CPU_SH2A +asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs regs) +{ + siginfo_t info; + + current->thread.trap_no = r4; + current->thread.error_code = 0; + + switch (r4) { + case TRAP_DIVZERO_ERROR: + info.si_code = FPE_INTDIV; + break; + case TRAP_DIVOVF_ERROR: + info.si_code = FPE_INTOVF; + break; + } + + force_sig_info(SIGFPE, &info, current); +} +#endif + /* arch/sh/kernel/cpu/sh4/fpu.c */ extern int do_fpu_inst(unsigned short, struct pt_regs *); extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, @@ -582,7 +637,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, struct task_struct *tsk = current; #ifdef CONFIG_SH_FPU_EMU - unsigned short inst; + unsigned short inst = 0; int err; get_user(inst, (unsigned short*)regs.pc); @@ -604,7 +659,8 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, } #endif - asm volatile("stc r2_bank, %0": "=r" (error_code)); + lookup_exception_vector(error_code); + local_irq_enable(); tsk->thread.error_code = error_code; tsk->thread.trap_no = TRAP_RESERVED_INST; @@ -663,7 +719,7 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, unsigned long error_code; struct task_struct *tsk = current; #ifdef CONFIG_SH_FPU_EMU - unsigned short inst; + unsigned short inst = 0; get_user(inst, (unsigned short *)regs.pc + 1); if (!do_fpu_inst(inst, ®s)) { @@ -675,7 +731,8 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, /* not a FPU inst. */ #endif - asm volatile("stc r2_bank, %0": "=r" (error_code)); + lookup_exception_vector(error_code); + local_irq_enable(); tsk->thread.error_code = error_code; tsk->thread.trap_no = TRAP_RESERVED_INST; @@ -689,7 +746,8 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, struct pt_regs regs) { long ex; - asm volatile("stc r2_bank, %0" : "=r" (ex)); + + lookup_exception_vector(ex); die_if_kernel("exception", ®s, ex); } @@ -741,6 +799,10 @@ void *set_exception_table_vec(unsigned int vec, void *handler) return old_handler; } +extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7, + struct pt_regs regs); + void __init trap_init(void) { set_exception_table_vec(TRAP_RESERVED_INST, do_reserved_inst); @@ -759,6 +821,14 @@ void __init trap_init(void) set_exception_table_evt(0x800, do_fpu_state_restore); set_exception_table_evt(0x820, do_fpu_state_restore); #endif + +#ifdef CONFIG_CPU_SH2 + set_exception_table_vec(TRAP_ADDRESS_ERROR, address_error_handler); +#endif +#ifdef CONFIG_CPU_SH2A + set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); + set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error); +#endif /* Setup VBR for boot cpu */ per_cpu_trap_init(); -- cgit v1.2.3 From de39840646a223ae13a346048c280b7c871bf56e Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 5 Nov 2006 16:15:19 +0900 Subject: sh: Exception vector rework and SH-2/SH-2A support. This splits out common bits from the existing exception handler for use between SH-2/SH-2A and SH-3/4, and adds support for the SH-2/2A exceptions. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/entry.S | 325 ++++++++++++++++ arch/sh/kernel/cpu/sh2/ex.S | 46 +++ arch/sh/kernel/cpu/sh3/Makefile | 2 +- arch/sh/kernel/cpu/sh3/entry.S | 526 +++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4/Makefile | 3 +- arch/sh/kernel/entry-common.S | 372 ++++++++++++++++++ arch/sh/kernel/entry.S | 843 ---------------------------------------- arch/sh/kernel/head.S | 12 +- 8 files changed, 1282 insertions(+), 847 deletions(-) create mode 100644 arch/sh/kernel/cpu/sh2/entry.S create mode 100644 arch/sh/kernel/cpu/sh2/ex.S create mode 100644 arch/sh/kernel/cpu/sh3/entry.S create mode 100644 arch/sh/kernel/entry-common.S delete mode 100644 arch/sh/kernel/entry.S (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S new file mode 100644 index 00000000000..298d9191909 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -0,0 +1,325 @@ +/* + * arch/sh/kernel/cpu/sh2/entry.S + * + * The SH-2 exception entry + * + * Copyright (C) 2005,2006 Yoshinori Sato + * Copyright (C) 2005 AXE,Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Offsets to the stack */ +OFF_R0 = 0 /* Return value. New ABI also arg4 */ +OFF_R1 = 4 /* New ABI: arg5 */ +OFF_R2 = 8 /* New ABI: arg6 */ +OFF_R3 = 12 /* New ABI: syscall_nr */ +OFF_R4 = 16 /* New ABI: arg0 */ +OFF_R5 = 20 /* New ABI: arg1 */ +OFF_R6 = 24 /* New ABI: arg2 */ +OFF_R7 = 28 /* New ABI: arg3 */ +OFF_SP = (15*4) +OFF_PC = (16*4) +OFF_SR = (16*4+2*4) +OFF_TRA = (16*4+6*4) + +#include + +ENTRY(exception_handler) + ! already saved r0/r1 + mov.l r2,@-sp + mov.l r3,@-sp + mov r0,r1 + cli + mov.l $cpu_mode,r2 + mov.l @r2,r0 + mov.l @(5*4,r15),r3 ! previous SR + shll2 r3 ! set "S" flag + rotl r0 ! T <- "S" flag + rotl r0 ! "S" flag is LSB + rotcr r3 ! T -> r3:b30 + shlr r3 + shlr r0 + bt/s 1f + mov.l r3,@(5*4,r15) ! copy cpu mode to SR + ! switch to kernel mode + mov #1,r0 + rotr r0 + rotr r0 + mov.l r0,@r2 ! enter kernel mode + mov.l $current_thread_info,r2 + mov.l @r2,r2 + mov #0x20,r0 + shll8 r0 + add r2,r0 + mov r15,r2 ! r2 = user stack top + mov r0,r15 ! switch kernel stack + add #-4,r15 ! dummy + mov.l r1,@-r15 ! TRA + sts.l macl, @-r15 + sts.l mach, @-r15 + stc.l gbr, @-r15 + mov.l @(4*4,r2),r0 + mov.l @(5*4,r2),r1 + mov.l r1,@-r15 ! original SR + sts.l pr,@-r15 + mov.l r0,@-r15 ! original PC + mov r2,r3 + add #(4+2)*4,r3 ! rewind r0 - r3 + exception frame + mov.l r3,@-r15 ! original SP + mov.l r14,@-r15 + mov.l r13,@-r15 + mov.l r12,@-r15 + mov.l r11,@-r15 + mov.l r10,@-r15 + mov.l r9,@-r15 + mov.l r8,@-r15 + mov.l r7,@-r15 + mov.l r6,@-r15 + mov.l r5,@-r15 + mov.l r4,@-r15 + mov r2,r8 ! copy user -> kernel stack + mov.l @r8+,r3 + mov.l r3,@-r15 + mov.l @r8+,r2 + mov.l r2,@-r15 + mov.l @r8+,r1 + mov.l r1,@-r15 + mov.l @r8+,r0 + bra 2f + mov.l r0,@-r15 +1: + ! in kernel exception + mov #(22-4-4-1)*4+4,r0 + mov r15,r2 + sub r0,r15 + mov.l @r2+,r0 ! old R3 + mov.l r0,@-r15 + mov.l @r2+,r0 ! old R2 + mov.l r0,@-r15 + mov.l @r2+,r0 ! old R1 + mov.l r0,@-r15 + mov.l @r2+,r0 ! old R0 + mov.l r0,@-r15 + mov.l @r2+,r3 ! old PC + mov.l @r2+,r0 ! old SR + add #-4,r2 ! exception frame stub (sr) + mov.l r1,@-r2 ! TRA + sts.l macl, @-r2 + sts.l mach, @-r2 + stc.l gbr, @-r2 + mov.l r0,@-r2 ! save old SR + sts.l pr,@-r2 + mov.l r3,@-r2 ! save old PC + mov r2,r0 + add #8*4,r0 + mov.l r0,@-r2 ! save old SP + mov.l r14,@-r2 + mov.l r13,@-r2 + mov.l r12,@-r2 + mov.l r11,@-r2 + mov.l r10,@-r2 + mov.l r9,@-r2 + mov.l r8,@-r2 + mov.l r7,@-r2 + mov.l r6,@-r2 + mov.l r5,@-r2 + mov.l r4,@-r2 + mov.l @(OFF_R0,r15),r0 + mov.l @(OFF_R1,r15),r1 + mov.l @(OFF_R2,r15),r2 + mov.l @(OFF_R3,r15),r3 +2: + mov #OFF_TRA,r8 + add r15,r8 + mov.l @r8,r9 + mov #64,r8 + cmp/hs r8,r9 + bt interrupt_entry ! vec >= 64 is interrupt + mov #32,r8 + cmp/hs r8,r9 + bt trap_entry ! 64 > vec >= 32 is trap + mov.l 4f,r8 + mov r9,r4 + shll2 r9 + add r9,r8 + mov.l @r8,r8 + mov #0,r9 + cmp/eq r9,r8 + bf 3f + mov.l 8f,r8 ! unhandled exception +3: + mov.l 5f,r10 + jmp @r8 + lds r10,pr + +interrupt_entry: + mov r9,r4 + mov.l 6f,r9 + mov.l 7f,r8 + jmp @r8 + lds r9,pr + + .align 2 +4: .long exception_handling_table +5: .long ret_from_exception +6: .long ret_from_irq +7: .long do_IRQ +8: .long do_exception_error + +trap_entry: + add #-0x10,r9 + shll2 r9 ! TRA + mov #OFF_TRA,r8 + add r15,r8 + mov.l r9,@r8 + mov r9,r8 + sti + bra system_call + nop + + .align 2 +1: .long syscall_exit +2: .long break_point_trap_software +3: .long NR_syscalls +4: .long sys_call_table + +#if defined(CONFIG_SH_STANDARD_BIOS) + /* Unwind the stack and jmp to the debug entry */ +debug_kernel_fw: + mov r15,r0 + add #(22-4)*4-4,r0 + ldc.l @r0+,gbr + lds.l @r0+,mach + lds.l @r0+,macl + mov r15,r0 + mov.l @(OFF_SP,r0),r1 + mov #OFF_SR,r2 + mov.l @(r0,r2),r3 + mov.l r3,@-r1 + mov #OFF_SP,r2 + mov.l @(r0,r2),r3 + mov.l r3,@-r1 + mov r15,r0 + add #(22-4)*4-8,r0 + mov.l 1f,r2 + mov.l @r2,r2 + stc sr,r3 + mov.l r2,@r0 + mov.l r3,@r0 + mov.l r1,@(8,r0) + mov.l @r15+, r0 + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r4 + mov.l @r15+, r5 + mov.l @r15+, r6 + mov.l @r15+, r7 + mov.l @r15+, r8 + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + add #8,r15 + lds.l @r15+, pr + rte + mov.l @r15+,r15 + .align 2 +1: .long gdb_vbr_vector +#endif /* CONFIG_SH_STANDARD_BIOS */ + +ENTRY(address_error_handler) + mov r15,r4 ! regs + add #4,r4 + mov #OFF_PC,r0 + mov.l @(r0,r15),r6 ! pc + mov.l 1f,r0 + jmp @r0 + mov #0,r5 ! writeaccess is unknown + .align 2 + +1: .long do_address_error + +restore_all: + cli + mov r15,r0 + mov.l $cpu_mode,r2 + mov #OFF_SR,r3 + mov.l @(r0,r3),r1 + mov.l r1,@r2 + shll2 r1 ! clear MD bit + shlr2 r1 + mov.l @(OFF_SP,r0),r2 + add #-8,r2 + mov.l r2,@(OFF_SP,r0) ! point exception frame top + mov.l r1,@(4,r2) ! set sr + mov #OFF_PC,r3 + mov.l @(r0,r3),r1 + mov.l r1,@r2 ! set pc + add #4*16+4,r0 + lds.l @r0+,pr + add #4,r0 ! skip sr + ldc.l @r0+,gbr + lds.l @r0+,mach + lds.l @r0+,macl + get_current_thread_info r0, r1 + mov.l $current_thread_info,r1 + mov.l r0,@r1 + mov.l @r15+,r0 + mov.l @r15+,r1 + mov.l @r15+,r2 + mov.l @r15+,r3 + mov.l @r15+,r4 + mov.l @r15+,r5 + mov.l @r15+,r6 + mov.l @r15+,r7 + mov.l @r15+,r8 + mov.l @r15+,r9 + mov.l @r15+,r10 + mov.l @r15+,r11 + mov.l @r15+,r12 + mov.l @r15+,r13 + mov.l @r15+,r14 + mov.l @r15,r15 + rte + nop +2: + mov.l 1f,r8 + mov.l 2f,r9 + jmp @r9 + lds r8,pr + + .align 2 +$current_thread_info: + .long __current_thread_info +$cpu_mode: + .long __cpu_mode + +! common exception handler +#include "../../entry-common.S" + + .data +! cpu operation mode +! bit30 = MD (compatible SH3/4) +__cpu_mode: + .long 0x40000000 + + .section .bss +__current_thread_info: + .long 0 + +ENTRY(exception_handling_table) + .space 4*32 diff --git a/arch/sh/kernel/cpu/sh2/ex.S b/arch/sh/kernel/cpu/sh2/ex.S new file mode 100644 index 00000000000..6d285af7846 --- /dev/null +++ b/arch/sh/kernel/cpu/sh2/ex.S @@ -0,0 +1,46 @@ +/* + * arch/sh/kernel/cpu/sh2/ex.S + * + * The SH-2 exception vector table + * + * Copyright (C) 2005 Yoshinori Sato + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#include + +! +! convert Exception Vector to Exception Number +! +exception_entry: +no = 0 + .rept 256 + mov.l r0,@-sp + mov #no,r0 + bra exception_trampoline + and #0xff,r0 +no = no + 1 + .endr +exception_trampoline: + mov.l r1,@-sp + mov.l $exception_handler,r1 + jmp @r1 + + .align 2 +$exception_entry: + .long exception_entry +$exception_handler: + .long exception_handler +! +! Exception Vector Base +! + .align 2 +ENTRY(vbr_base) +vector = 0 + .rept 256 + .long exception_entry + vector * 8 +vector = vector + 1 + .endr diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile index 58d3815695f..83905e4e438 100644 --- a/arch/sh/kernel/cpu/sh3/Makefile +++ b/arch/sh/kernel/cpu/sh3/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux/SuperH SH-3 backends. # -obj-y := ex.o probe.o +obj-y := ex.o probe.o entry.o # CPU subtype setup obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S new file mode 100644 index 00000000000..8bcd63f9f35 --- /dev/null +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -0,0 +1,526 @@ +/* + * arch/sh/kernel/entry.S + * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka + * Copyright (C) 2003 - 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include +#include + +! NOTE: +! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address +! to be jumped is too far, but it causes illegal slot exception. + +/* + * entry.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + * + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. + * + * NOTE: This code uses a convention that instructions in the delay slot + * of a transfer-control instruction are indented by an extra space, thus: + * + * jmp @k0 ! control-transfer instruction + * ldc k1, ssr ! delay slot + * + * Stack layout in 'ret_from_syscall': + * ptrace needs to have all regs on the stack. + * if the order here is changed, it needs to be + * updated in ptrace.c and ptrace.h + * + * r0 + * ... + * r15 = stack pointer + * spc + * pr + * ssr + * gbr + * mach + * macl + * syscall # + * + */ +#if defined(CONFIG_KGDB_NMI) +NMI_VEC = 0x1c0 ! Must catch early for debounce +#endif + +/* Offsets to the stack */ +OFF_R0 = 0 /* Return value. New ABI also arg4 */ +OFF_R1 = 4 /* New ABI: arg5 */ +OFF_R2 = 8 /* New ABI: arg6 */ +OFF_R3 = 12 /* New ABI: syscall_nr */ +OFF_R4 = 16 /* New ABI: arg0 */ +OFF_R5 = 20 /* New ABI: arg1 */ +OFF_R6 = 24 /* New ABI: arg2 */ +OFF_R7 = 28 /* New ABI: arg3 */ +OFF_SP = (15*4) +OFF_PC = (16*4) +OFF_SR = (16*4+8) +OFF_TRA = (16*4+6*4) + + +#define k0 r0 +#define k1 r1 +#define k2 r2 +#define k3 r3 +#define k4 r4 + +#define g_imask r6 /* r6_bank1 */ +#define k_g_imask r6_bank /* r6_bank1 */ +#define current r7 /* r7_bank1 */ + +#include + +/* + * Kernel mode register usage: + * k0 scratch + * k1 scratch + * k2 scratch (Exception code) + * k3 scratch (Return address) + * k4 scratch + * k5 reserved + * k6 Global Interrupt Mask (0--15 << 4) + * k7 CURRENT_THREAD_INFO (pointer to current thread info) + */ + +! +! TLB Miss / Initial Page write exception handling +! _and_ +! TLB hits, but the access violate the protection. +! It can be valid access, such as stack grow and/or C-O-W. +! +! +! Find the pmd/pte entry and loadtlb +! If it's not found, cause address error (SEGV) +! +! Although this could be written in assembly language (and it'd be faster), +! this first version depends *much* on C implementation. +! + +#if defined(CONFIG_MMU) + .align 2 +ENTRY(tlb_miss_load) + bra call_dpf + mov #0, r5 + + .align 2 +ENTRY(tlb_miss_store) + bra call_dpf + mov #1, r5 + + .align 2 +ENTRY(initial_page_write) + bra call_dpf + mov #1, r5 + + .align 2 +ENTRY(tlb_protection_violation_load) + bra call_dpf + mov #0, r5 + + .align 2 +ENTRY(tlb_protection_violation_store) + bra call_dpf + mov #1, r5 + +call_dpf: + mov.l 1f, r0 + mov r5, r8 + mov.l @r0, r6 + mov r6, r9 + mov.l 2f, r0 + sts pr, r10 + jsr @r0 + mov r15, r4 + ! + tst r0, r0 + bf/s 0f + lds r10, pr + rts + nop +0: sti + mov.l 3f, r0 + mov r9, r6 + mov r8, r5 + jmp @r0 + mov r15, r4 + + .align 2 +1: .long MMU_TEA +2: .long __do_page_fault +3: .long do_page_fault + + .align 2 +ENTRY(address_error_load) + bra call_dae + mov #0,r5 ! writeaccess = 0 + + .align 2 +ENTRY(address_error_store) + bra call_dae + mov #1,r5 ! writeaccess = 1 + + .align 2 +call_dae: + mov.l 1f, r0 + mov.l @r0, r6 ! address + mov.l 2f, r0 + jmp @r0 + mov r15, r4 ! regs + + .align 2 +1: .long MMU_TEA +2: .long do_address_error +#endif /* CONFIG_MMU */ + +#if defined(CONFIG_SH_STANDARD_BIOS) + /* Unwind the stack and jmp to the debug entry */ +debug_kernel_fw: + mov.l @r15+, r0 + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r4 + mov.l @r15+, r5 + mov.l @r15+, r6 + mov.l @r15+, r7 + stc sr, r8 + mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F + or r9, r8 + ldc r8, sr ! here, change the register bank + mov.l @r15+, r8 + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + mov.l @r15+, k0 + ldc.l @r15+, spc + lds.l @r15+, pr + mov.l @r15+, k1 + ldc.l @r15+, gbr + lds.l @r15+, mach + lds.l @r15+, macl + mov k0, r15 + ! + mov.l 2f, k0 + mov.l @k0, k0 + jmp @k0 + ldc k1, ssr + .align 2 +1: .long 0x300000f0 +2: .long gdb_vbr_vector +#endif /* CONFIG_SH_STANDARD_BIOS */ + +restore_all: + mov.l @r15+, r0 + mov.l @r15+, r1 + mov.l @r15+, r2 + mov.l @r15+, r3 + mov.l @r15+, r4 + mov.l @r15+, r5 + mov.l @r15+, r6 + mov.l @r15+, r7 + ! + stc sr, r8 + mov.l 7f, r9 + or r9, r8 ! BL =1, RB=1 + ldc r8, sr ! here, change the register bank + ! + mov.l @r15+, r8 + mov.l @r15+, r9 + mov.l @r15+, r10 + mov.l @r15+, r11 + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + mov.l @r15+, k4 ! original stack pointer + ldc.l @r15+, spc + lds.l @r15+, pr + mov.l @r15+, k3 ! original SR + ldc.l @r15+, gbr + lds.l @r15+, mach + lds.l @r15+, macl + add #4, r15 ! Skip syscall number + ! +#ifdef CONFIG_SH_DSP + mov.l @r15+, k0 ! DSP mode marker + mov.l 5f, k1 + cmp/eq k0, k1 ! Do we have a DSP stack frame? + bf skip_restore + + stc sr, k0 ! Enable CPU DSP mode + or k1, k0 ! (within kernel it may be disabled) + ldc k0, sr + mov r2, k0 ! Backup r2 + + ! Restore DSP registers from stack + mov r15, r2 + movs.l @r2+, a1 + movs.l @r2+, a0g + movs.l @r2+, a1g + movs.l @r2+, m0 + movs.l @r2+, m1 + mov r2, r15 + + lds.l @r15+, a0 + lds.l @r15+, x0 + lds.l @r15+, x1 + lds.l @r15+, y0 + lds.l @r15+, y1 + lds.l @r15+, dsr + ldc.l @r15+, rs + ldc.l @r15+, re + ldc.l @r15+, mod + + mov k0, r2 ! Restore r2 +skip_restore: +#endif + ! + ! Calculate new SR value + mov k3, k2 ! original SR value + mov #0xf0, k1 + extu.b k1, k1 + not k1, k1 + and k1, k2 ! Mask orignal SR value + ! + mov k3, k0 ! Calculate IMASK-bits + shlr2 k0 + and #0x3c, k0 + cmp/eq #0x3c, k0 + bt/s 6f + shll2 k0 + mov g_imask, k0 + ! +6: or k0, k2 ! Set the IMASK-bits + ldc k2, ssr + ! +#if defined(CONFIG_KGDB_NMI) + ! Clear in_nmi + mov.l 6f, k0 + mov #0, k1 + mov.b k1, @k0 +#endif + mov.l @r15+, k2 ! restore EXPEVT + mov k4, r15 + rte + nop + + .align 2 +5: .long 0x00001000 ! DSP +7: .long 0x30000000 + +! common exception handler +#include "../../entry.S" + +! Exception Vector Base +! +! Should be aligned page boundary. +! + .balign 4096,0,4096 +ENTRY(vbr_base) + .long 0 +! + .balign 256,0,256 +general_exception: + mov.l 1f, k2 + mov.l 2f, k3 + bra handle_exception + mov.l @k2, k2 + .align 2 +1: .long EXPEVT +2: .long ret_from_exception +! +! + .balign 1024,0,1024 +tlb_miss: + mov.l 1f, k2 + mov.l 4f, k3 + bra handle_exception + mov.l @k2, k2 +! + .balign 512,0,512 +interrupt: + mov.l 2f, k2 + mov.l 3f, k3 +#if defined(CONFIG_KGDB_NMI) + ! Debounce (filter nested NMI) + mov.l @k2, k0 + mov.l 5f, k1 + cmp/eq k1, k0 + bf 0f + mov.l 6f, k1 + tas.b @k1 + bt 0f + rte + nop + .align 2 +5: .long NMI_VEC +6: .long in_nmi +0: +#endif /* defined(CONFIG_KGDB_NMI) */ + bra handle_exception + mov #-1, k2 ! interrupt exception marker + + .align 2 +1: .long EXPEVT +2: .long INTEVT +3: .long ret_from_irq +4: .long ret_from_exception + +! +! + .align 2 +ENTRY(handle_exception) + ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), + ! save all registers onto stack. + ! + stc ssr, k0 ! Is it from kernel space? + shll k0 ! Check MD bit (bit30) by shifting it into... + shll k0 ! ...the T bit + bt/s 1f ! It's a kernel to kernel transition. + mov r15, k0 ! save original stack to k0 + /* User space to kernel */ + mov #(THREAD_SIZE >> 8), k1 + shll8 k1 ! k1 := THREAD_SIZE + add current, k1 + mov k1, r15 ! change to kernel stack + ! +1: mov.l 2f, k1 + ! +#ifdef CONFIG_SH_DSP + mov.l r2, @-r15 ! Save r2, we need another reg + stc sr, k4 + mov.l 1f, r2 + tst r2, k4 ! Check if in DSP mode + mov.l @r15+, r2 ! Restore r2 now + bt/s skip_save + mov #0, k4 ! Set marker for no stack frame + + mov r2, k4 ! Backup r2 (in k4) for later + + ! Save DSP registers on stack + stc.l mod, @-r15 + stc.l re, @-r15 + stc.l rs, @-r15 + sts.l dsr, @-r15 + sts.l y1, @-r15 + sts.l y0, @-r15 + sts.l x1, @-r15 + sts.l x0, @-r15 + sts.l a0, @-r15 + + ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr. + + ! FIXME: Make sure that this is still the case with newer toolchains, + ! as we're not at all interested in supporting ancient toolchains at + ! this point. -- PFM. + + mov r15, r2 + .word 0xf653 ! movs.l a1, @-r2 + .word 0xf6f3 ! movs.l a0g, @-r2 + .word 0xf6d3 ! movs.l a1g, @-r2 + .word 0xf6c3 ! movs.l m0, @-r2 + .word 0xf6e3 ! movs.l m1, @-r2 + mov r2, r15 + + mov k4, r2 ! Restore r2 + mov.l 1f, k4 ! Force DSP stack frame +skip_save: + mov.l k4, @-r15 ! Push DSP mode marker onto stack +#endif + ! Save the user registers on the stack. + mov.l k2, @-r15 ! EXPEVT + + mov #-1, k4 + mov.l k4, @-r15 ! set TRA (default: -1) + ! + sts.l macl, @-r15 + sts.l mach, @-r15 + stc.l gbr, @-r15 + stc.l ssr, @-r15 + sts.l pr, @-r15 + stc.l spc, @-r15 + ! + lds k3, pr ! Set the return address to pr + ! + mov.l k0, @-r15 ! save orignal stack + mov.l r14, @-r15 + mov.l r13, @-r15 + mov.l r12, @-r15 + mov.l r11, @-r15 + mov.l r10, @-r15 + mov.l r9, @-r15 + mov.l r8, @-r15 + ! + stc sr, r8 ! Back to normal register bank, and + or k1, r8 ! Block all interrupts + mov.l 3f, k1 + and k1, r8 ! ... + ldc r8, sr ! ...changed here. + ! + mov.l r7, @-r15 + mov.l r6, @-r15 + mov.l r5, @-r15 + mov.l r4, @-r15 + mov.l r3, @-r15 + mov.l r2, @-r15 + mov.l r1, @-r15 + mov.l r0, @-r15 + + /* + * This gets a bit tricky.. in the INTEVT case we don't want to use + * the VBR offset as a destination in the jump call table, since all + * of the destinations are the same. In this case, (interrupt) sets + * a marker in r2 (now r2_bank since SR.RB changed), which we check + * to determine the exception type. For all other exceptions, we + * forcibly read EXPEVT from memory and fix up the jump address, in + * the interrupt exception case we jump to do_IRQ() and defer the + * INTEVT read until there. As a bonus, we can also clean up the SR.RB + * checks that do_IRQ() was doing.. + */ + stc r2_bank, r8 + cmp/pz r8 + bf interrupt_exception + shlr2 r8 + shlr r8 + mov.l 4f, r9 + add r8, r9 + mov.l @r9, r9 + jmp @r9 + nop + rts + nop + + .align 2 +1: .long 0x00001000 ! DSP=1 +2: .long 0x000080f0 ! FD=1, IMASK=15 +3: .long 0xcfffffff ! RB=0, BL=0 +4: .long exception_handling_table + +interrupt_exception: + mov.l 1f, r9 + jmp @r9 + nop + rts + nop + + .align 2 +1: .long do_IRQ + + .align 2 +ENTRY(exception_none) + rts + nop diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 8dbf3895ece..6e415baf04b 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -2,7 +2,8 @@ # Makefile for the Linux/SuperH SH-4 backends. # -obj-y := ex.o probe.o +obj-y := ex.o probe.o common.o +common-y += $(addprefix ../sh3/, entry.o) obj-$(CONFIG_SH_FPU) += fpu.o obj-$(CONFIG_SH_STORE_QUEUES) += sq.o diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S new file mode 100644 index 00000000000..5bc7fa91d09 --- /dev/null +++ b/arch/sh/kernel/entry-common.S @@ -0,0 +1,372 @@ +/* $Id: entry.S,v 1.37 2004/06/11 13:02:46 doyu Exp $ + * + * linux/arch/sh/entry.S + * + * Copyright (C) 1999, 2000, 2002 Niibe Yutaka + * Copyright (C) 2003 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +! NOTE: +! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address +! to be jumped is too far, but it causes illegal slot exception. + +/* + * entry.S contains the system-call and fault low-level handling routines. + * This also contains the timer-interrupt handler, as well as all interrupts + * and faults that can result in a task-switch. + * + * NOTE: This code handles signal-recognition, which happens every time + * after a timer-interrupt and after each system call. + * + * NOTE: This code uses a convention that instructions in the delay slot + * of a transfer-control instruction are indented by an extra space, thus: + * + * jmp @k0 ! control-transfer instruction + * ldc k1, ssr ! delay slot + * + * Stack layout in 'ret_from_syscall': + * ptrace needs to have all regs on the stack. + * if the order here is changed, it needs to be + * updated in ptrace.c and ptrace.h + * + * r0 + * ... + * r15 = stack pointer + * spc + * pr + * ssr + * gbr + * mach + * macl + * syscall # + * + */ + +#if defined(CONFIG_PREEMPT) +# define preempt_stop() cli +#else +# define preempt_stop() +# define resume_kernel __restore_all +#endif + +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) +! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. +! If both are configured, handle the debug traps (breakpoints) in SW, +! but still allow BIOS traps to FW. + + .align 2 +debug_kernel: +#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) + /* Force BIOS call to FW (debug_trap put TRA in r8) */ + mov r8,r0 + shlr2 r0 + cmp/eq #0x3f,r0 + bt debug_kernel_fw +#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ + +debug_enter: +#if defined(CONFIG_SH_KGDB) + /* Jump to kgdb, pass stacked regs as arg */ +debug_kernel_sw: + mov.l 3f, r0 + jmp @r0 + mov r15, r4 + .align 2 +3: .long kgdb_handle_exception +#endif /* CONFIG_SH_KGDB */ + +#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ + + + .align 2 +debug_trap: +#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + shll r0 + shll r0 ! kernel space? + bt/s debug_kernel +#endif + mov.l @r15, r0 ! Restore R0 value + mov.l 1f, r8 + jmp @r8 + nop + + .align 2 +ENTRY(exception_error) + ! + sti + mov.l 2f, r0 + jmp @r0 + nop + +! + .align 2 +1: .long break_point_trap_software +2: .long do_exception_error + + .align 2 +ret_from_exception: + preempt_stop() +ENTRY(ret_from_irq) + ! + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + shll r0 + shll r0 ! kernel space? + get_current_thread_info r8, r0 + bt resume_kernel ! Yes, it's from kernel, go back soon + +#ifdef CONFIG_PREEMPT + bra resume_userspace + nop +ENTRY(resume_kernel) + mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count + tst r0, r0 + bf noresched +need_resched: + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_NEED_RESCHED, r0 ! need_resched set? + bt noresched + + mov #OFF_SR, r0 + mov.l @(r0,r15), r0 ! get status register + and #0xf0, r0 ! interrupts off (exception path)? + cmp/eq #0xf0, r0 + bt noresched + + mov.l 1f, r0 + mov.l r0, @(TI_PRE_COUNT,r8) + + sti + mov.l 2f, r0 + jsr @r0 + nop + mov #0, r0 + mov.l r0, @(TI_PRE_COUNT,r8) + cli + + bra need_resched + nop +noresched: + bra __restore_all + nop + + .align 2 +1: .long PREEMPT_ACTIVE +2: .long schedule +#endif + +ENTRY(resume_userspace) + ! r8: current_thread_info + cli + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt/s __restore_all + tst #_TIF_NEED_RESCHED, r0 + + .align 2 +work_pending: + ! r0: current_thread_info->flags + ! r8: current_thread_info + ! t: result of "tst #_TIF_NEED_RESCHED, r0" + bf/s work_resched + tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 +work_notifysig: + bt/s __restore_all + mov r15, r4 + mov r12, r5 ! set arg1(save_r0) + mov r0, r6 + mov.l 2f, r1 + mov.l 3f, r0 + jmp @r1 + lds r0, pr +work_resched: +#ifndef CONFIG_PREEMPT + ! gUSA handling + mov.l @(OFF_SP,r15), r0 ! get user space stack pointer + mov r0, r1 + shll r0 + bf/s 1f + shll r0 + bf/s 1f + mov #OFF_PC, r0 + ! SP >= 0xc0000000 : gUSA mark + mov.l @(r0,r15), r2 ! get user space PC (program counter) + mov.l @(OFF_R0,r15), r3 ! end point + cmp/hs r3, r2 ! r2 >= r3? + bt 1f + add r3, r1 ! rewind point #2 + mov.l r1, @(r0,r15) ! reset PC to rewind point #2 + ! +1: +#endif + mov.l 1f, r1 + jsr @r1 ! schedule + nop + cli + ! + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_WORK_MASK, r0 + bt __restore_all + bra work_pending + tst #_TIF_NEED_RESCHED, r0 + + .align 2 +1: .long schedule +2: .long do_notify_resume +3: .long restore_all + + .align 2 +syscall_exit_work: + ! r0: current_thread_info->flags + ! r8: current_thread_info + tst #_TIF_SYSCALL_TRACE, r0 + bt/s work_pending + tst #_TIF_NEED_RESCHED, r0 + sti + ! XXX setup arguments... + mov.l 4f, r0 ! do_syscall_trace + jsr @r0 + nop + bra resume_userspace + nop + + .align 2 +syscall_trace_entry: + ! Yes it is traced. + ! XXX setup arguments... + mov.l 4f, r11 ! Call do_syscall_trace which notifies + jsr @r11 ! superior (will chomp R[0-7]) + nop + ! Reload R0-R4 from kernel stack, where the + ! parent may have modified them using + ! ptrace(POKEUSR). (Note that R0-R2 are + ! used by the system call handler directly + ! from the kernel stack anyway, so don't need + ! to be reloaded here.) This allows the parent + ! to rewrite system calls and args on the fly. + mov.l @(OFF_R4,r15), r4 ! arg0 + mov.l @(OFF_R5,r15), r5 + mov.l @(OFF_R6,r15), r6 + mov.l @(OFF_R7,r15), r7 ! arg3 + mov.l @(OFF_R3,r15), r3 ! syscall_nr + ! Arrange for do_syscall_trace to be called + ! again as the system call returns. + mov.l 2f, r10 ! Number of syscalls + cmp/hs r10, r3 + bf syscall_call + mov #-ENOSYS, r0 + bra syscall_exit + mov.l r0, @(OFF_R0,r15) ! Return value + +__restore_all: + mov.l 1f,r0 + jmp @r0 + nop + + .align 2 +1: .long restore_all + +/* + * Syscall interface: + * + * Syscall #: R3 + * Arguments #0 to #3: R4--R7 + * Arguments #4 to #6: R0, R1, R2 + * TRA: (number of arguments + 0x10) x 4 + * + * This code also handles delegating other traps to the BIOS/gdb stub + * according to: + * + * Trap number + * (TRA>>2) Purpose + * -------- ------- + * 0x0-0xf old syscall ABI + * 0x10-0x1f new syscall ABI + * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. + * + * Note: When we're first called, the TRA value must be shifted + * right 2 bits in order to get the value that was used as the "trapa" + * argument. + */ + + .align 2 + .globl ret_from_fork +ret_from_fork: + mov.l 1f, r8 + jsr @r8 + mov r0, r4 + bra syscall_exit + nop + .align 2 +1: .long schedule_tail + ! +ENTRY(system_call) +#if !defined(CONFIG_CPU_SH2) + mov.l 1f, r9 + mov.l @r9, r8 ! Read from TRA (Trap Address) Register +#endif + ! + ! Is the trap argument >= 0x20? (TRA will be >= 0x80) + mov #0x7f, r9 + cmp/hi r9, r8 + bt/s 0f + mov #OFF_TRA, r9 + add r15, r9 + ! + mov.l r8, @r9 ! set TRA value to tra + sti + ! Call the system call handler through the table. + ! First check for bad syscall number + mov r3, r9 + mov.l 2f, r8 ! Number of syscalls + cmp/hs r8, r9 + get_current_thread_info r8, r10 + bf good_system_call +syscall_badsys: ! Bad syscall number + mov #-ENOSYS, r0 + bra resume_userspace + mov.l r0, @(OFF_R0,r15) ! Return value + ! +0: + bra debug_trap + nop + ! +good_system_call: ! Good syscall number + mov.l @(TI_FLAGS,r8), r8 + mov #_TIF_SYSCALL_TRACE, r10 + tst r10, r8 + bf syscall_trace_entry + ! +syscall_call: + shll2 r9 ! x4 + mov.l 3f, r8 ! Load the address of sys_call_table + add r8, r9 + mov.l @r9, r8 + jsr @r8 ! jump to specific syscall handler + nop + mov.l @(OFF_R0,r15), r12 ! save r0 + mov.l r0, @(OFF_R0,r15) ! save the return value + ! +syscall_exit: + cli + ! + get_current_thread_info r8, r0 + mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags + tst #_TIF_ALLWORK_MASK, r0 + bf syscall_exit_work + bra __restore_all + nop + .align 2 +#if !defined(CONFIG_CPU_SH2) +1: .long TRA +#endif +2: .long NR_syscalls +3: .long sys_call_table +4: .long do_syscall_trace diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S deleted file mode 100644 index 39aaefb2d83..00000000000 --- a/arch/sh/kernel/entry.S +++ /dev/null @@ -1,843 +0,0 @@ -/* - * linux/arch/sh/entry.S - * - * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 - 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include -#include -#include -#include -#include -#include -#include - -! NOTE: -! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address -! to be jumped is too far, but it causes illegal slot exception. - -/* - * entry.S contains the system-call and fault low-level handling routines. - * This also contains the timer-interrupt handler, as well as all interrupts - * and faults that can result in a task-switch. - * - * NOTE: This code handles signal-recognition, which happens every time - * after a timer-interrupt and after each system call. - * - * NOTE: This code uses a convention that instructions in the delay slot - * of a transfer-control instruction are indented by an extra space, thus: - * - * jmp @k0 ! control-transfer instruction - * ldc k1, ssr ! delay slot - * - * Stack layout in 'ret_from_syscall': - * ptrace needs to have all regs on the stack. - * if the order here is changed, it needs to be - * updated in ptrace.c and ptrace.h - * - * r0 - * ... - * r15 = stack pointer - * spc - * pr - * ssr - * gbr - * mach - * macl - * syscall # - * - */ -#if defined(CONFIG_KGDB_NMI) -NMI_VEC = 0x1c0 ! Must catch early for debounce -#endif - -/* Offsets to the stack */ -OFF_R0 = 0 /* Return value. New ABI also arg4 */ -OFF_R1 = 4 /* New ABI: arg5 */ -OFF_R2 = 8 /* New ABI: arg6 */ -OFF_R3 = 12 /* New ABI: syscall_nr */ -OFF_R4 = 16 /* New ABI: arg0 */ -OFF_R5 = 20 /* New ABI: arg1 */ -OFF_R6 = 24 /* New ABI: arg2 */ -OFF_R7 = 28 /* New ABI: arg3 */ -OFF_SP = (15*4) -OFF_PC = (16*4) -OFF_SR = (16*4+8) -OFF_TRA = (16*4+6*4) - - -#define k0 r0 -#define k1 r1 -#define k2 r2 -#define k3 r3 -#define k4 r4 - -#define g_imask r6 /* r6_bank1 */ -#define k_g_imask r6_bank /* r6_bank1 */ -#define current r7 /* r7_bank1 */ - -/* - * Kernel mode register usage: - * k0 scratch - * k1 scratch - * k2 scratch (Exception code) - * k3 scratch (Return address) - * k4 scratch - * k5 reserved - * k6 Global Interrupt Mask (0--15 << 4) - * k7 CURRENT_THREAD_INFO (pointer to current thread info) - */ - -! -! TLB Miss / Initial Page write exception handling -! _and_ -! TLB hits, but the access violate the protection. -! It can be valid access, such as stack grow and/or C-O-W. -! -! -! Find the pmd/pte entry and loadtlb -! If it's not found, cause address error (SEGV) -! -! Although this could be written in assembly language (and it'd be faster), -! this first version depends *much* on C implementation. -! - -#define CLI() \ - stc sr, r0; \ - or #0xf0, r0; \ - ldc r0, sr - -#define STI() \ - mov.l __INV_IMASK, r11; \ - stc sr, r10; \ - and r11, r10; \ - stc k_g_imask, r11; \ - or r11, r10; \ - ldc r10, sr - -#if defined(CONFIG_PREEMPT) -# define preempt_stop() CLI() -#else -# define preempt_stop() -# define resume_kernel restore_all -#endif - -#if defined(CONFIG_MMU) - .align 2 -ENTRY(tlb_miss_load) - bra call_dpf - mov #0, r5 - - .align 2 -ENTRY(tlb_miss_store) - bra call_dpf - mov #1, r5 - - .align 2 -ENTRY(initial_page_write) - bra call_dpf - mov #1, r5 - - .align 2 -ENTRY(tlb_protection_violation_load) - bra call_dpf - mov #0, r5 - - .align 2 -ENTRY(tlb_protection_violation_store) - bra call_dpf - mov #1, r5 - -call_dpf: - mov.l 1f, r0 - mov r5, r8 - mov.l @r0, r6 - mov r6, r9 - mov.l 2f, r0 - sts pr, r10 - jsr @r0 - mov r15, r4 - ! - tst r0, r0 - bf/s 0f - lds r10, pr - rts - nop -0: STI() - mov.l 3f, r0 - mov r9, r6 - mov r8, r5 - jmp @r0 - mov r15, r4 - - .align 2 -1: .long MMU_TEA -2: .long __do_page_fault -3: .long do_page_fault - - .align 2 -ENTRY(address_error_load) - bra call_dae - mov #0,r5 ! writeaccess = 0 - - .align 2 -ENTRY(address_error_store) - bra call_dae - mov #1,r5 ! writeaccess = 1 - - .align 2 -call_dae: - mov.l 1f, r0 - mov.l @r0, r6 ! address - mov.l 2f, r0 - jmp @r0 - mov r15, r4 ! regs - - .align 2 -1: .long MMU_TEA -2: .long do_address_error -#endif /* CONFIG_MMU */ - -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) -! Handle kernel debug if either kgdb (SW) or gdb-stub (FW) is present. -! If both are configured, handle the debug traps (breakpoints) in SW, -! but still allow BIOS traps to FW. - - .align 2 -debug_kernel: -#if defined(CONFIG_SH_STANDARD_BIOS) && defined(CONFIG_SH_KGDB) - /* Force BIOS call to FW (debug_trap put TRA in r8) */ - mov r8,r0 - shlr2 r0 - cmp/eq #0x3f,r0 - bt debug_kernel_fw -#endif /* CONFIG_SH_STANDARD_BIOS && CONFIG_SH_KGDB */ - -debug_enter: -#if defined(CONFIG_SH_KGDB) - /* Jump to kgdb, pass stacked regs as arg */ -debug_kernel_sw: - mov.l 3f, r0 - jmp @r0 - mov r15, r4 - .align 2 -3: .long kgdb_handle_exception -#endif /* CONFIG_SH_KGDB */ - -#if defined(CONFIG_SH_STANDARD_BIOS) - /* Unwind the stack and jmp to the debug entry */ -debug_kernel_fw: - mov.l @r15+, r0 - mov.l @r15+, r1 - mov.l @r15+, r2 - mov.l @r15+, r3 - mov.l @r15+, r4 - mov.l @r15+, r5 - mov.l @r15+, r6 - mov.l @r15+, r7 - stc sr, r8 - mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F - or r9, r8 - ldc r8, sr ! here, change the register bank - mov.l @r15+, r8 - mov.l @r15+, r9 - mov.l @r15+, r10 - mov.l @r15+, r11 - mov.l @r15+, r12 - mov.l @r15+, r13 - mov.l @r15+, r14 - mov.l @r15+, k0 - ldc.l @r15+, spc - lds.l @r15+, pr - mov.l @r15+, k1 - ldc.l @r15+, gbr - lds.l @r15+, mach - lds.l @r15+, macl - mov k0, r15 - ! - mov.l 2f, k0 - mov.l @k0, k0 - jmp @k0 - ldc k1, ssr - .align 2 -1: .long 0x300000f0 -2: .long gdb_vbr_vector -#endif /* CONFIG_SH_STANDARD_BIOS */ - -#endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - - - .align 2 -debug_trap: -#if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - bt/s debug_kernel -#endif - mov.l @r15, r0 ! Restore R0 value - mov.l 1f, r8 - jmp @r8 - nop - - .align 2 -ENTRY(exception_error) - ! - STI() - mov.l 2f, r0 - jmp @r0 - nop - -! - .align 2 -1: .long break_point_trap_software -2: .long do_exception_error - - .align 2 -ret_from_exception: - preempt_stop() -ENTRY(ret_from_irq) - ! - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - shll r0 - shll r0 ! kernel space? - bt/s resume_kernel ! Yes, it's from kernel, go back soon - GET_THREAD_INFO(r8) - -#ifdef CONFIG_PREEMPT - bra resume_userspace - nop -ENTRY(resume_kernel) - mov.l @(TI_PRE_COUNT,r8), r0 ! current_thread_info->preempt_count - tst r0, r0 - bf noresched -need_resched: - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_NEED_RESCHED, r0 ! need_resched set? - bt noresched - - mov #OFF_SR, r0 - mov.l @(r0,r15), r0 ! get status register - and #0xf0, r0 ! interrupts off (exception path)? - cmp/eq #0xf0, r0 - bt noresched - - mov.l 1f, r0 - mov.l r0, @(TI_PRE_COUNT,r8) - - STI() - mov.l 2f, r0 - jsr @r0 - nop - mov #0, r0 - mov.l r0, @(TI_PRE_COUNT,r8) - CLI() - - bra need_resched - nop -noresched: - bra restore_all - nop - - .align 2 -1: .long PREEMPT_ACTIVE -2: .long schedule -#endif - -ENTRY(resume_userspace) - ! r8: current_thread_info - CLI() - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_WORK_MASK, r0 - bt/s restore_all - tst #_TIF_NEED_RESCHED, r0 - - .align 2 -work_pending: - ! r0: current_thread_info->flags - ! r8: current_thread_info - ! t: result of "tst #_TIF_NEED_RESCHED, r0" - bf/s work_resched - tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 -work_notifysig: - bt/s restore_all - mov r15, r4 - mov r12, r5 ! set arg1(save_r0) - mov r0, r6 - mov.l 2f, r1 - mova restore_all, r0 - jmp @r1 - lds r0, pr -work_resched: -#ifndef CONFIG_PREEMPT - ! gUSA handling - mov.l @(OFF_SP,r15), r0 ! get user space stack pointer - mov r0, r1 - shll r0 - bf/s 1f - shll r0 - bf/s 1f - mov #OFF_PC, r0 - ! SP >= 0xc0000000 : gUSA mark - mov.l @(r0,r15), r2 ! get user space PC (program counter) - mov.l @(OFF_R0,r15), r3 ! end point - cmp/hs r3, r2 ! r2 >= r3? - bt 1f - add r3, r1 ! rewind point #2 - mov.l r1, @(r0,r15) ! reset PC to rewind point #2 - ! -1: -#endif - mov.l 1f, r1 - jsr @r1 ! schedule - nop - CLI() - ! - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_WORK_MASK, r0 - bt restore_all - bra work_pending - tst #_TIF_NEED_RESCHED, r0 - - .align 2 -1: .long schedule -2: .long do_notify_resume - - .align 2 -syscall_exit_work: - ! r0: current_thread_info->flags - ! r8: current_thread_info - tst #_TIF_SYSCALL_TRACE, r0 - bt/s work_pending - tst #_TIF_NEED_RESCHED, r0 - STI() - ! XXX setup arguments... - mov.l 4f, r0 ! do_syscall_trace - jsr @r0 - nop - bra resume_userspace - nop - - .align 2 -syscall_trace_entry: - ! Yes it is traced. - ! XXX setup arguments... - mov.l 4f, r11 ! Call do_syscall_trace which notifies - jsr @r11 ! superior (will chomp R[0-7]) - nop - ! Reload R0-R4 from kernel stack, where the - ! parent may have modified them using - ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. - mov.l @(OFF_R4,r15), r4 ! arg0 - mov.l @(OFF_R5,r15), r5 - mov.l @(OFF_R6,r15), r6 - mov.l @(OFF_R7,r15), r7 ! arg3 - mov.l @(OFF_R3,r15), r3 ! syscall_nr - ! Arrange for do_syscall_trace to be called - ! again as the system call returns. - mov.l 2f, r10 ! Number of syscalls - cmp/hs r10, r3 - bf syscall_call - mov #-ENOSYS, r0 - bra syscall_exit - mov.l r0, @(OFF_R0,r15) ! Return value - -/* - * Syscall interface: - * - * Syscall #: R3 - * Arguments #0 to #3: R4--R7 - * Arguments #4 to #6: R0, R1, R2 - * TRA: (number of arguments + 0x10) x 4 - * - * This code also handles delegating other traps to the BIOS/gdb stub - * according to: - * - * Trap number - * (TRA>>2) Purpose - * -------- ------- - * 0x0-0xf old syscall ABI - * 0x10-0x1f new syscall ABI - * 0x20-0xff delegated through debug_trap to BIOS/gdb stub. - * - * Note: When we're first called, the TRA value must be shifted - * right 2 bits in order to get the value that was used as the "trapa" - * argument. - */ - - .align 2 - .globl ret_from_fork -ret_from_fork: - mov.l 1f, r8 - jsr @r8 - mov r0, r4 - bra syscall_exit - nop - .align 2 -1: .long schedule_tail - ! -ENTRY(system_call) - mov.l 1f, r9 - mov.l @r9, r8 ! Read from TRA (Trap Address) Register - ! - ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x7f, r9 - cmp/hi r9, r8 - bt/s 0f - mov #OFF_TRA, r9 - add r15, r9 - ! - mov.l r8, @r9 ! set TRA value to tra - STI() - ! Call the system call handler through the table. - ! First check for bad syscall number - mov r3, r9 - mov.l 2f, r8 ! Number of syscalls - cmp/hs r8, r9 - bf/s good_system_call - GET_THREAD_INFO(r8) -syscall_badsys: ! Bad syscall number - mov #-ENOSYS, r0 - bra resume_userspace - mov.l r0, @(OFF_R0,r15) ! Return value - ! -0: - bra debug_trap - nop - ! -good_system_call: ! Good syscall number - mov.l @(TI_FLAGS,r8), r8 - mov #_TIF_SYSCALL_TRACE, r10 - tst r10, r8 - bf syscall_trace_entry - ! -syscall_call: - shll2 r9 ! x4 - mov.l 3f, r8 ! Load the address of sys_call_table - add r8, r9 - mov.l @r9, r8 - jsr @r8 ! jump to specific syscall handler - nop - mov.l @(OFF_R0,r15), r12 ! save r0 - mov.l r0, @(OFF_R0,r15) ! save the return value - ! -syscall_exit: - CLI() - ! - GET_THREAD_INFO(r8) - mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags - tst #_TIF_ALLWORK_MASK, r0 - bf syscall_exit_work -restore_all: - mov.l @r15+, r0 - mov.l @r15+, r1 - mov.l @r15+, r2 - mov.l @r15+, r3 - mov.l @r15+, r4 - mov.l @r15+, r5 - mov.l @r15+, r6 - mov.l @r15+, r7 - ! - stc sr, r8 - mov.l 7f, r9 - or r9, r8 ! BL =1, RB=1 - ldc r8, sr ! here, change the register bank - ! - mov.l @r15+, r8 - mov.l @r15+, r9 - mov.l @r15+, r10 - mov.l @r15+, r11 - mov.l @r15+, r12 - mov.l @r15+, r13 - mov.l @r15+, r14 - mov.l @r15+, k4 ! original stack pointer - ldc.l @r15+, spc - lds.l @r15+, pr - mov.l @r15+, k3 ! original SR - ldc.l @r15+, gbr - lds.l @r15+, mach - lds.l @r15+, macl - add #4, r15 ! Skip syscall number - ! -#ifdef CONFIG_SH_DSP - mov.l @r15+, k0 ! DSP mode marker - mov.l 5f, k1 - cmp/eq k0, k1 ! Do we have a DSP stack frame? - bf skip_restore - - stc sr, k0 ! Enable CPU DSP mode - or k1, k0 ! (within kernel it may be disabled) - ldc k0, sr - mov r2, k0 ! Backup r2 - - ! Restore DSP registers from stack - mov r15, r2 - movs.l @r2+, a1 - movs.l @r2+, a0g - movs.l @r2+, a1g - movs.l @r2+, m0 - movs.l @r2+, m1 - mov r2, r15 - - lds.l @r15+, a0 - lds.l @r15+, x0 - lds.l @r15+, x1 - lds.l @r15+, y0 - lds.l @r15+, y1 - lds.l @r15+, dsr - ldc.l @r15+, rs - ldc.l @r15+, re - ldc.l @r15+, mod - - mov k0, r2 ! Restore r2 -skip_restore: -#endif - ! - ! Calculate new SR value - mov k3, k2 ! original SR value - mov.l 9f, k1 - and k1, k2 ! Mask orignal SR value - ! - mov k3, k0 ! Calculate IMASK-bits - shlr2 k0 - and #0x3c, k0 - cmp/eq #0x3c, k0 - bt/s 6f - shll2 k0 - mov g_imask, k0 - ! -6: or k0, k2 ! Set the IMASK-bits - ldc k2, ssr - ! -#if defined(CONFIG_KGDB_NMI) - ! Clear in_nmi - mov.l 6f, k0 - mov #0, k1 - mov.b k1, @k0 -#endif - mov.l @r15+, k2 ! restore EXPEVT - mov k4, r15 - rte - nop - - .align 2 -1: .long TRA -2: .long NR_syscalls -3: .long sys_call_table -4: .long do_syscall_trace -5: .long 0x00001000 ! DSP -7: .long 0x30000000 -9: -__INV_IMASK: - .long 0xffffff0f ! ~(IMASK) - -! Exception Vector Base -! -! Should be aligned page boundary. -! - .balign 4096,0,4096 -ENTRY(vbr_base) - .long 0 -! - .balign 256,0,256 -general_exception: - mov.l 1f, k2 - mov.l 2f, k3 - bra handle_exception - mov.l @k2, k2 - .align 2 -1: .long EXPEVT -2: .long ret_from_exception -! -! - .balign 1024,0,1024 -tlb_miss: - mov.l 1f, k2 - mov.l 4f, k3 - bra handle_exception - mov.l @k2, k2 -! - .balign 512,0,512 -interrupt: - mov.l 2f, k2 - mov.l 3f, k3 -#if defined(CONFIG_KGDB_NMI) - ! Debounce (filter nested NMI) - mov.l @k2, k0 - mov.l 5f, k1 - cmp/eq k1, k0 - bf 0f - mov.l 6f, k1 - tas.b @k1 - bt 0f - rte - nop - .align 2 -5: .long NMI_VEC -6: .long in_nmi -0: -#endif /* defined(CONFIG_KGDB_NMI) */ - bra handle_exception - mov #-1, k2 ! interrupt exception marker - - .align 2 -1: .long EXPEVT -2: .long INTEVT -3: .long ret_from_irq -4: .long ret_from_exception - -! -! - .align 2 -ENTRY(handle_exception) - ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), - ! save all registers onto stack. - ! - stc ssr, k0 ! Is it from kernel space? - shll k0 ! Check MD bit (bit30) by shifting it into... - shll k0 ! ...the T bit - bt/s 1f ! It's a kernel to kernel transition. - mov r15, k0 ! save original stack to k0 - /* User space to kernel */ - mov #(THREAD_SIZE >> 8), k1 - shll8 k1 ! k1 := THREAD_SIZE - add current, k1 - mov k1, r15 ! change to kernel stack - ! -1: mov.l 2f, k1 - ! -#ifdef CONFIG_SH_DSP - mov.l r2, @-r15 ! Save r2, we need another reg - stc sr, k4 - mov.l 1f, r2 - tst r2, k4 ! Check if in DSP mode - mov.l @r15+, r2 ! Restore r2 now - bt/s skip_save - mov #0, k4 ! Set marker for no stack frame - - mov r2, k4 ! Backup r2 (in k4) for later - - ! Save DSP registers on stack - stc.l mod, @-r15 - stc.l re, @-r15 - stc.l rs, @-r15 - sts.l dsr, @-r15 - sts.l y1, @-r15 - sts.l y0, @-r15 - sts.l x1, @-r15 - sts.l x0, @-r15 - sts.l a0, @-r15 - - ! GAS is broken, does not generate correct "movs.l Ds,@-As" instr. - - ! FIXME: Make sure that this is still the case with newer toolchains, - ! as we're not at all interested in supporting ancient toolchains at - ! this point. -- PFM. - - mov r15, r2 - .word 0xf653 ! movs.l a1, @-r2 - .word 0xf6f3 ! movs.l a0g, @-r2 - .word 0xf6d3 ! movs.l a1g, @-r2 - .word 0xf6c3 ! movs.l m0, @-r2 - .word 0xf6e3 ! movs.l m1, @-r2 - mov r2, r15 - - mov k4, r2 ! Restore r2 - mov.l 1f, k4 ! Force DSP stack frame -skip_save: - mov.l k4, @-r15 ! Push DSP mode marker onto stack -#endif - ! Save the user registers on the stack. - mov.l k2, @-r15 ! EXPEVT - - mov #-1, k4 - mov.l k4, @-r15 ! set TRA (default: -1) - ! - sts.l macl, @-r15 - sts.l mach, @-r15 - stc.l gbr, @-r15 - stc.l ssr, @-r15 - sts.l pr, @-r15 - stc.l spc, @-r15 - ! - lds k3, pr ! Set the return address to pr - ! - mov.l k0, @-r15 ! save orignal stack - mov.l r14, @-r15 - mov.l r13, @-r15 - mov.l r12, @-r15 - mov.l r11, @-r15 - mov.l r10, @-r15 - mov.l r9, @-r15 - mov.l r8, @-r15 - ! - stc sr, r8 ! Back to normal register bank, and - or k1, r8 ! Block all interrupts - mov.l 3f, k1 - and k1, r8 ! ... - ldc r8, sr ! ...changed here. - ! - mov.l r7, @-r15 - mov.l r6, @-r15 - mov.l r5, @-r15 - mov.l r4, @-r15 - mov.l r3, @-r15 - mov.l r2, @-r15 - mov.l r1, @-r15 - mov.l r0, @-r15 - - /* - * This gets a bit tricky.. in the INTEVT case we don't want to use - * the VBR offset as a destination in the jump call table, since all - * of the destinations are the same. In this case, (interrupt) sets - * a marker in r2 (now r2_bank since SR.RB changed), which we check - * to determine the exception type. For all other exceptions, we - * forcibly read EXPEVT from memory and fix up the jump address, in - * the interrupt exception case we jump to do_IRQ() and defer the - * INTEVT read until there. As a bonus, we can also clean up the SR.RB - * checks that do_IRQ() was doing.. - */ - stc r2_bank, r8 - cmp/pz r8 - bf interrupt_exception - shlr2 r8 - shlr r8 - mov.l 4f, r9 - add r8, r9 - mov.l @r9, r9 - jmp @r9 - nop - rts - nop - - .align 2 -1: .long 0x00001000 ! DSP=1 -2: .long 0x000080f0 ! FD=1, IMASK=15 -3: .long 0xcfffffff ! RB=0, BL=0 -4: .long exception_handling_table - -interrupt_exception: - mov.l 1f, r9 - jmp @r9 - nop - rts - nop - - .align 2 -1: .long do_IRQ - - .align 2 -ENTRY(exception_none) - rts - nop diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index f5f53d14f24..b5ff2326461 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -53,8 +53,10 @@ ENTRY(_stext) ldc r0, sr ! Initialize global interrupt mask mov #0, r0 +#ifdef CONFIG_CPU_HAS_SR_RB ldc r0, r6_bank - +#endif + /* * Prefetch if possible to reduce cache miss penalty. * @@ -71,8 +73,10 @@ ENTRY(_stext) mov #(THREAD_SIZE >> 8), r1 shll8 r1 ! r1 = THREAD_SIZE sub r1, r0 ! +#ifdef CONFIG_CPU_HAS_SR_RB ldc r0, r7_bank ! ... and initial thread_info - +#endif + ! Clear BSS area mov.l 3f, r1 add #4, r1 @@ -95,7 +99,11 @@ ENTRY(_stext) nop .balign 4 +#if defined(CONFIG_CPU_SH2) +1: .long 0x000000F0 ! IMASK=0xF +#else 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF +#endif 2: .long init_thread_union+THREAD_SIZE 3: .long __bss_start 4: .long _end -- cgit v1.2.3 From f36af3fd377081d3ac2ff6b63a60f8db8b3bf531 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Sun, 5 Nov 2006 16:21:09 +0900 Subject: sh: Add support for Solution Engine 7206 and 7619 boards. This adds support for the Solution Engine 7206 and 7619. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/boards/se/7206/Makefile | 7 + arch/sh/boards/se/7206/io.c | 123 ++++++ arch/sh/boards/se/7206/irq.c | 161 ++++++++ arch/sh/boards/se/7206/led.c | 57 +++ arch/sh/boards/se/7206/setup.c | 80 ++++ arch/sh/boards/se/7619/Makefile | 5 + arch/sh/boards/se/7619/io.c | 102 +++++ arch/sh/boards/se/7619/setup.c | 43 ++ arch/sh/configs/se7206_defconfig | 826 +++++++++++++++++++++++++++++++++++++++ 9 files changed, 1404 insertions(+) create mode 100644 arch/sh/boards/se/7206/Makefile create mode 100644 arch/sh/boards/se/7206/io.c create mode 100644 arch/sh/boards/se/7206/irq.c create mode 100644 arch/sh/boards/se/7206/led.c create mode 100644 arch/sh/boards/se/7206/setup.c create mode 100644 arch/sh/boards/se/7619/Makefile create mode 100644 arch/sh/boards/se/7619/io.c create mode 100644 arch/sh/boards/se/7619/setup.c create mode 100644 arch/sh/configs/se7206_defconfig (limited to 'arch') diff --git a/arch/sh/boards/se/7206/Makefile b/arch/sh/boards/se/7206/Makefile new file mode 100644 index 00000000000..63950f4f245 --- /dev/null +++ b/arch/sh/boards/se/7206/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the 7206 SolutionEngine specific parts of the kernel +# + +obj-y := setup.o io.o irq.o +obj-$(CONFIG_HEARTBEAT) += led.o + diff --git a/arch/sh/boards/se/7206/io.c b/arch/sh/boards/se/7206/io.c new file mode 100644 index 00000000000..b557273e0cb --- /dev/null +++ b/arch/sh/boards/se/7206/io.c @@ -0,0 +1,123 @@ +/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ + * + * linux/arch/sh/boards/se/7206/io.c + * + * Copyright (C) 2006 Yoshinori Sato + * + * I/O routine for Hitachi 7206 SolutionEngine. + * + */ + +#include +#include +#include +#include + + +static inline void delay(void) +{ + ctrl_inw(0x20000000); /* P2 ROM Area */ +} + +/* MS7750 requires special versions of in*, out* routines, since + PC-like io ports are located at upper half byte of 16-bit word which + can be accessed only with 16-bit wide. */ + +static inline volatile __u16 * +port2adr(unsigned int port) +{ + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); + else if (port >= 0x300 || port < 0x310) + return (volatile __u16 *) (PA_SMSC + (port - 0x300)); +} + +unsigned char se7206_inb(unsigned long port) +{ + return (*port2adr(port))&0xff; +} + +unsigned char se7206_inb_p(unsigned long port) +{ + unsigned long v; + + v = (*port2adr(port))&0xff; + delay(); + return v; +} + +unsigned short se7206_inw(unsigned long port) +{ + return *port2adr(port);; +} + +unsigned int se7206_inl(unsigned long port) +{ + maybebadio(port); + return 0; +} + +void se7206_outb(unsigned char value, unsigned long port) +{ + *(port2adr(port)) = value; +} + +void se7206_outb_p(unsigned char value, unsigned long port) +{ + *(port2adr(port)) = value; + delay(); +} + +void se7206_outw(unsigned short value, unsigned long port) +{ + *port2adr(port) = value; +} + +void se7206_outl(unsigned int value, unsigned long port) +{ + maybebadio(port); +} + +void se7206_insb(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u8 *ap = addr; + + while (count--) + *ap++ = *p; +} + +void se7206_insw(unsigned long port, void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + __u16 *ap = addr; + while (count--) + *ap++ = *p; +} + +void se7206_insl(unsigned long port, void *addr, unsigned long count) +{ + maybebadio(port); +} + +void se7206_outsb(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u8 *ap = addr; + + while (count--) + *p = *ap++; +} + +void se7206_outsw(unsigned long port, const void *addr, unsigned long count) +{ + volatile __u16 *p = port2adr(port); + const __u16 *ap = addr; + while (count--) + *p = *ap++; +} + +void se7206_outsl(unsigned long port, const void *addr, unsigned long count) +{ + maybebadio(port); +} diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c new file mode 100644 index 00000000000..8d5b278a124 --- /dev/null +++ b/arch/sh/boards/se/7206/irq.c @@ -0,0 +1,161 @@ +/* + * linux/arch/sh/boards/se/7206/irq.c + * + * Copyright (C) 2005,2006 Yoshinori Sato + * + * Hitachi SolutionEngine Support. + * + */ + +#include +#include +#include +#include +#include +#include + +#define INTSTS0 0x31800000 +#define INTSTS1 0x31800002 +#define INTMSK0 0x31800004 +#define INTMSK1 0x31800006 +#define INTSEL 0x31800008 + +/* shutdown is same as "disable" */ +#define shutdown_se7206_irq disable_se7206_irq + +static void disable_se7206_irq(unsigned int irq) +{ + unsigned short val; + unsigned short mask = 0xffff ^ (0x0f << 4 * (3 - (IRQ0_IRQ - irq))); + unsigned short msk0,msk1; + + /* Set the priority in IPR to 0 */ + val = ctrl_inw(INTC_IPR01); + val &= mask; + ctrl_outw(val, INTC_IPR01); + /* FPGA mask set */ + msk0 = ctrl_inw(INTMSK0); + msk1 = ctrl_inw(INTMSK1); + + switch (irq) { + case IRQ0_IRQ: + msk0 |= 0x0010; + break; + case IRQ1_IRQ: + msk0 |= 0x000f; + break; + case IRQ2_IRQ: + msk0 |= 0x0f00; + msk1 |= 0x00ff; + break; + } + ctrl_outw(msk0, INTMSK0); + ctrl_outw(msk1, INTMSK1); +} + +static void enable_se7206_irq(unsigned int irq) +{ + unsigned short val; + unsigned short value = (0x0001 << 4 * (3 - (IRQ0_IRQ - irq))); + unsigned short msk0,msk1; + + /* Set priority in IPR back to original value */ + val = ctrl_inw(INTC_IPR01); + val |= value; + ctrl_outw(val, INTC_IPR01); + + /* FPGA mask reset */ + msk0 = ctrl_inw(INTMSK0); + msk1 = ctrl_inw(INTMSK1); + + switch (irq) { + case IRQ0_IRQ: + msk0 &= ~0x0010; + break; + case IRQ1_IRQ: + msk0 &= ~0x000f; + break; + case IRQ2_IRQ: + msk0 &= ~0x0f00; + msk1 &= ~0x00ff; + break; + } + ctrl_outw(msk0, INTMSK0); + ctrl_outw(msk1, INTMSK1); +} + +static unsigned int startup_se7206_irq(unsigned int irq) +{ + enable_se7206_irq(irq); + return 0; /* never anything pending */ +} + +static void ack_se7206_irq(unsigned int irq) +{ + disable_se7206_irq(irq); +} + +static void end_se7206_irq(unsigned int irq) +{ + unsigned short sts0,sts1; + + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_se7206_irq(irq); + /* FPGA isr clear */ + sts0 = ctrl_inw(INTSTS0); + sts1 = ctrl_inw(INTSTS1); + + switch (irq) { + case IRQ0_IRQ: + sts0 &= ~0x0010; + break; + case IRQ1_IRQ: + sts0 &= ~0x000f; + break; + case IRQ2_IRQ: + sts0 &= ~0x0f00; + sts1 &= ~0x00ff; + break; + } + ctrl_outw(sts0, INTSTS0); + ctrl_outw(sts1, INTSTS1); +} + +static struct hw_interrupt_type se7206_irq_type = { + .typename = "SE7206 FPGA-IRQ", + .startup = startup_se7206_irq, + .shutdown = shutdown_se7206_irq, + .enable = enable_se7206_irq, + .disable = disable_se7206_irq, + .ack = ack_se7206_irq, + .end = end_se7206_irq, +}; + +static void make_se7206_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &se7206_irq_type; + disable_se7206_irq(irq); +} + +/* + * Initialize IRQ setting + */ +void __init init_se7206_IRQ(void) +{ + make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ + make_se7206_irq(IRQ1_IRQ); /* ATA */ + make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ + ctrl_outw(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ + + /* FPGA System register setup*/ + ctrl_outw(0x0000,INTSTS0); /* Clear INTSTS0 */ + ctrl_outw(0x0000,INTSTS1); /* Clear INTSTS1 */ + /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ + ctrl_outw(0x0001,INTSEL); +} + +int se7206_irq_demux(int irq) +{ + return irq; +} diff --git a/arch/sh/boards/se/7206/led.c b/arch/sh/boards/se/7206/led.c new file mode 100644 index 00000000000..ef794601ab8 --- /dev/null +++ b/arch/sh/boards/se/7206/led.c @@ -0,0 +1,57 @@ +/* + * linux/arch/sh/kernel/led_se.c + * + * Copyright (C) 2000 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains Solution Engine specific LED code. + */ + +#include +#include + +#ifdef CONFIG_HEARTBEAT + +#include + +/* Cycle the LED's in the clasic Knightrider/Sun pattern */ +void heartbeat_se(void) +{ + static unsigned int cnt = 0, period = 0; + volatile unsigned short* p = (volatile unsigned short*)PA_LED; + static unsigned bit = 0, up = 1; + + cnt += 1; + if (cnt < period) { + return; + } + + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ( (300< +#include +#include +#include +#include + +static struct resource smc91x_resources[] = { + [0] = { + .start = 0x300, + .end = 0x300 + 0x020 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 64, + .end = 64, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device smc91x_device = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_resources), + .resource = smc91x_resources, +}; + +static int __init se7206_devices_setup(void) +{ + return platform_device_register(&smc91x_device); +} + +__initcall(se7206_devices_setup); + +void heartbeat_se(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_se __initmv = { + .mv_name = "SolutionEngine", + .mv_nr_irqs = 256, + .mv_inb = se7206_inb, + .mv_inw = se7206_inw, + .mv_inl = se7206_inl, + .mv_outb = se7206_outb, + .mv_outw = se7206_outw, + .mv_outl = se7206_outl, + + .mv_inb_p = se7206_inb_p, + .mv_inw_p = se7206_inw, + .mv_inl_p = se7206_inl, + .mv_outb_p = se7206_outb_p, + .mv_outw_p = se7206_outw, + .mv_outl_p = se7206_outl, + + .mv_insb = se7206_insb, + .mv_insw = se7206_insw, + .mv_insl = se7206_insl, + .mv_outsb = se7206_outsb, + .mv_outsw = se7206_outsw, + .mv_outsl = se7206_outsl, + + .mv_init_irq = init_se7206_IRQ, + .mv_irq_demux = se7206_irq_demux, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_se, +#endif +}; +ALIAS_MV(se) diff --git a/arch/sh/boards/se/7619/Makefile b/arch/sh/boards/se/7619/Makefile new file mode 100644 index 00000000000..3666eca8a65 --- /dev/null +++ b/arch/sh/boards/se/7619/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the 7619 SolutionEngine specific parts of the kernel +# + +obj-y := setup.o io.o diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c new file mode 100644 index 00000000000..176f1f39cd9 --- /dev/null +++ b/arch/sh/boards/se/7619/io.c @@ -0,0 +1,102 @@ +/* + * + * linux/arch/sh/boards/se/7619/io.c + * + * Copyright (C) 2006 Yoshinori Sato + * + * I/O routine for Hitachi 7619 SolutionEngine. + * + */ + +#include +#include +#include +#include +#include + +/* FIXME: M3A-ZAB7 Compact Flash Slot support */ + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */ +} + +#define badio(name,port) \ + printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +unsigned char se7619___inb(unsigned long port) +{ + badio(inb, port); + return 0; +} + +unsigned char se7619___inb_p(unsigned long port) +{ + badio(inb_p, port); + delay(); + return 0; +} + +unsigned short se7619___inw(unsigned long port) +{ + badio(inw, port); + return 0; +} + +unsigned int se7619___inl(unsigned long port) +{ + badio(inl, port); + return 0; +} + +void se7619___outb(unsigned char value, unsigned long port) +{ + badio(outb, port); +} + +void se7619___outb_p(unsigned char value, unsigned long port) +{ + badio(outb_p, port); + delay(); +} + +void se7619___outw(unsigned short value, unsigned long port) +{ + badio(outw, port); +} + +void se7619___outl(unsigned int value, unsigned long port) +{ + badio(outl, port); +} + +void se7619___insb(unsigned long port, void *addr, unsigned long count) +{ + badio(inw, port); +} + +void se7619___insw(unsigned long port, void *addr, unsigned long count) +{ + badio(inw, port); +} + +void se7619___insl(unsigned long port, void *addr, unsigned long count) +{ + badio(insl, port); +} + +void se7619___outsb(unsigned long port, const void *addr, unsigned long count) +{ + badio(insl, port); +} + +void se7619___outsw(unsigned long port, const void *addr, unsigned long count) +{ + badio(insl, port); +} + +void se7619___outsl(unsigned long port, const void *addr, unsigned long count) +{ + badio(outsw, port); +} diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c new file mode 100644 index 00000000000..e627b26de0d --- /dev/null +++ b/arch/sh/boards/se/7619/setup.c @@ -0,0 +1,43 @@ +/* + * arch/sh/boards/se/7619/setup.c + * + * Copyright (C) 2006 Yoshinori Sato + * + * Hitachi SH7619 SolutionEngine Support. + */ + +#include +#include +#include +#include +#include + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_se __initmv = { + .mv_name = "SolutionEngine", + .mv_nr_irqs = 108, + .mv_inb = se7619___inb, + .mv_inw = se7619___inw, + .mv_inl = se7619___inl, + .mv_outb = se7619___outb, + .mv_outw = se7619___outw, + .mv_outl = se7619___outl, + + .mv_inb_p = se7619___inb_p, + .mv_inw_p = se7619___inw, + .mv_inl_p = se7619___inl, + .mv_outb_p = se7619___outb_p, + .mv_outw_p = se7619___outw, + .mv_outl_p = se7619___outl, + + .mv_insb = se7619___insb, + .mv_insw = se7619___insw, + .mv_insl = se7619___insl, + .mv_outsb = se7619___outsb, + .mv_outsw = se7619___outsw, + .mv_outsl = se7619___outsl, +}; +ALIAS_MV(se) diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig new file mode 100644 index 00000000000..36cec0b6e7c --- /dev/null +++ b/arch/sh/configs/se7206_defconfig @@ -0,0 +1,826 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19-rc4 +# Sun Nov 5 16:20:10 2006 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +CONFIG_UID16=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_R7780RP is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +CONFIG_SH_7206_SOLUTION_ENGINE=y +# CONFIG_SH_7619_SOLUTION_ENGINE is not set +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH2=y +CONFIG_CPU_SH2A=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +CONFIG_CPU_SUBTYPE_SH7206=y + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set + +# +# Memory management options +# +CONFIG_PAGE_OFFSET=0x00000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x02000000 +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +# CONFIG_SH_FPU is not set +# CONFIG_SH_FPU_EMU is not set +# CONFIG_SH_DSP is not set + +# +# Timer support +# +CONFIG_SH_CMT=y +# CONFIG_SH_MTU2 is not set +CONFIG_SH_PCLK_FREQ=33333333 +CONFIG_SH_CLK_MD=6 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Kernel features +# +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_KEXEC is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +# CONFIG_PACKET is not set +# CONFIG_UNIX is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_DIAG is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x20000000 +CONFIG_MTD_PHYSMAP_LEN=0x1000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_SOLUTIONENGINE is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# +# CONFIG_NETDEVICES is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=4 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y -- cgit v1.2.3 From 710ee0cc45d095f7697821b330a3f8280205c2be Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sun, 5 Nov 2006 16:48:42 +0900 Subject: sh: SE7206 build fixes. A number of API changes happened underneath the 7206 patches, update for everything that broke. Signed-off-by: Paul Mundt --- arch/sh/boards/se/7206/irq.c | 44 +++++++------------------- arch/sh/boards/se/7206/setup.c | 3 +- arch/sh/kernel/sys_sh.c | 2 ++ arch/sh/kernel/timers/timer-cmt.c | 63 +++----------------------------------- arch/sh/kernel/timers/timer-mtu2.c | 62 +++---------------------------------- arch/sh/kernel/traps.c | 12 ++++++-- 6 files changed, 34 insertions(+), 152 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c index 8d5b278a124..3fb0c5f5b23 100644 --- a/arch/sh/boards/se/7206/irq.c +++ b/arch/sh/boards/se/7206/irq.c @@ -6,12 +6,10 @@ * Hitachi SolutionEngine Support. * */ - -#include #include #include -#include -#include +#include +#include #include #define INTSTS0 0x31800000 @@ -20,9 +18,6 @@ #define INTMSK1 0x31800006 #define INTSEL 0x31800008 -/* shutdown is same as "disable" */ -#define shutdown_se7206_irq disable_se7206_irq - static void disable_se7206_irq(unsigned int irq) { unsigned short val; @@ -84,18 +79,7 @@ static void enable_se7206_irq(unsigned int irq) ctrl_outw(msk1, INTMSK1); } -static unsigned int startup_se7206_irq(unsigned int irq) -{ - enable_se7206_irq(irq); - return 0; /* never anything pending */ -} - -static void ack_se7206_irq(unsigned int irq) -{ - disable_se7206_irq(irq); -} - -static void end_se7206_irq(unsigned int irq) +static void eoi_se7206_irq(unsigned int irq) { unsigned short sts0,sts1; @@ -121,20 +105,19 @@ static void end_se7206_irq(unsigned int irq) ctrl_outw(sts1, INTSTS1); } -static struct hw_interrupt_type se7206_irq_type = { - .typename = "SE7206 FPGA-IRQ", - .startup = startup_se7206_irq, - .shutdown = shutdown_se7206_irq, - .enable = enable_se7206_irq, - .disable = disable_se7206_irq, - .ack = ack_se7206_irq, - .end = end_se7206_irq, +static struct irq_chip se7206_irq_chip __read_mostly = { + .name = "SE7206-FPGA-IRQ", + .mask = disable_se7206_irq, + .unmask = enable_se7206_irq, + .mask_ack = disable_se7206_irq, + .eoi = eoi_se7206_irq, }; static void make_se7206_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &se7206_irq_type; + set_irq_chip_and_handler_name(irq, &se7206_irq_chip, + handle_level_irq, "level"); disable_se7206_irq(irq); } @@ -154,8 +137,3 @@ void __init init_se7206_IRQ(void) /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ ctrl_outw(0x0001,INTSEL); } - -int se7206_irq_demux(int irq) -{ - return irq; -} diff --git a/arch/sh/boards/se/7206/setup.c b/arch/sh/boards/se/7206/setup.c index e543e3980c0..0f42e91a323 100644 --- a/arch/sh/boards/se/7206/setup.c +++ b/arch/sh/boards/se/7206/setup.c @@ -10,8 +10,8 @@ #include #include -#include #include +#include #include static struct resource smc91x_resources[] = { @@ -72,7 +72,6 @@ struct sh_machine_vector mv_se __initmv = { .mv_outsl = se7206_outsl, .mv_init_irq = init_se7206_IRQ, - .mv_irq_demux = se7206_irq_demux, #ifdef CONFIG_HEARTBEAT .mv_heartbeat = heartbeat_se, #endif diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 8fde95001c3..07f2b571893 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -50,6 +50,7 @@ unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ EXPORT_SYMBOL(shm_align_mask); +#ifdef CONFIG_MMU /* * To avoid cache aliases, we map the shared page with same color. */ @@ -135,6 +136,7 @@ full_search: addr = COLOUR_ALIGN(addr, pgoff); } } +#endif /* CONFIG_MMU */ static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 9eab395cd34..30687383d4b 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -96,8 +96,7 @@ static unsigned long cmt_timer_get_offset(void) return count; } -static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) { unsigned long timer_status; @@ -114,7 +113,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id, * locally disabled. -arca */ write_seqlock(&xtime_lock); - handle_timer_tick(regs); + handle_timer_tick(); write_sequnlock(&xtime_lock); return IRQ_HANDLED; @@ -123,62 +122,10 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id, static struct irqaction cmt_irq = { .name = "timer", .handler = cmt_timer_interrupt, - .flags = SA_INTERRUPT, + .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, }; -/* - * Hah! We'll see if this works (switching from usecs to nsecs). - */ -static unsigned long cmt_timer_get_frequency(void) -{ - u32 freq; - struct timespec ts1, ts2; - unsigned long diff_nsec; - unsigned long factor; - - /* Setup the timer: We don't want to generate interrupts, just - * have it count down at its natural rate. - */ - - ctrl_outw(ctrl_inw(CMT_CMSTR) & ~0x01, CMT_CMSTR); - ctrl_outw(CMT_CMCSR_CALIB, CMT_CMCSR_0); - ctrl_outw(0xffff, CMT_CMCOR_0); - ctrl_outw(0xffff, CMT_CMCNT_0); - - rtc_sh_get_time(&ts2); - - do { - rtc_sh_get_time(&ts1); - } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); - - /* actually start the timer */ - ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); - - do { - rtc_sh_get_time(&ts2); - } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); - - freq = 0xffff - ctrl_inw(CMT_CMCNT_0); - if (ts2.tv_nsec < ts1.tv_nsec) { - ts2.tv_nsec += 1000000000; - ts2.tv_sec--; - } - - diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); - - /* this should work well if the RTC has a precision of n Hz, where - * n is an integer. I don't think we have to worry about the other - * cases. */ - factor = (1000000000 + diff_nsec/2) / diff_nsec; - - if (factor * diff_nsec > 1100000000 || - factor * diff_nsec < 900000000) - panic("weird RTC (diff_nsec %ld)", diff_nsec); - - return freq * factor; -} - static void cmt_clk_init(struct clk *clk) { u8 divisor = CMT_CMCSR_INIT & 0x3; @@ -245,12 +192,12 @@ struct sys_timer_ops cmt_timer_ops = { .init = cmt_timer_init, .start = cmt_timer_start, .stop = cmt_timer_stop, - .get_frequency = cmt_timer_get_frequency, +#ifndef CONFIG_GENERIC_TIME .get_offset = cmt_timer_get_offset, +#endif }; struct sys_timer cmt_timer = { .name = "cmt", .ops = &cmt_timer_ops, }; - diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 73a5ef3c457..045b2aba13f 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -98,8 +98,7 @@ static unsigned long mtu2_timer_get_offset(void) return count; } -static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) { unsigned long timer_status; @@ -110,7 +109,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id, /* Do timer tick */ write_seqlock(&xtime_lock); - handle_timer_tick(regs); + handle_timer_tick(); write_sequnlock(&xtime_lock); return IRQ_HANDLED; @@ -119,62 +118,10 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id, static struct irqaction mtu2_irq = { .name = "timer", .handler = mtu2_timer_interrupt, - .flags = SA_INTERRUPT, + .flags = IRQF_DISABLED, .mask = CPU_MASK_NONE, }; -/* - * Hah! We'll see if this works (switching from usecs to nsecs). - */ -static unsigned long mtu2_timer_get_frequency(void) -{ - u32 freq; - struct timespec ts1, ts2; - unsigned long diff_nsec; - unsigned long factor; - - /* Setup the timer: We don't want to generate interrupts, just - * have it count down at its natural rate. - */ - - ctrl_outb(ctrl_inb(MTU2_TSTR) & ~MTU2_TSTR_CST1, MTU2_TSTR); - ctrl_outb(MTU2_TCR_CALIB, MTU2_TCR_1); - ctrl_outb(ctrl_inb(MTU2_TIER_1) & ~MTU2_TIER_TGIEA, MTU2_TIER_1); - ctrl_outw(0, MTU2_TCNT_1); - - rtc_get_time(&ts2); - - do { - rtc_get_time(&ts1); - } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); - - /* actually start the timer */ - ctrl_outw(ctrl_inw(CMT_CMSTR) | 0x01, CMT_CMSTR); - - do { - rtc_get_time(&ts2); - } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); - - freq = ctrl_inw(MTU2_TCNT_0); - if (ts2.tv_nsec < ts1.tv_nsec) { - ts2.tv_nsec += 1000000000; - ts2.tv_sec--; - } - - diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); - - /* this should work well if the RTC has a precision of n Hz, where - * n is an integer. I don't think we have to worry about the other - * cases. */ - factor = (1000000000 + diff_nsec/2) / diff_nsec; - - if (factor * diff_nsec > 1100000000 || - factor * diff_nsec < 900000000) - panic("weird RTC (diff_nsec %ld)", diff_nsec); - - return freq * factor; -} - static unsigned int divisors[] = { 1, 4, 16, 64, 1, 1, 256 }; static void mtu2_clk_init(struct clk *clk) @@ -250,8 +197,9 @@ struct sys_timer_ops mtu2_timer_ops = { .init = mtu2_timer_init, .start = mtu2_timer_start, .stop = mtu2_timer_stop, - .get_frequency = mtu2_timer_get_frequency, +#ifndef CONFIG_GENERIC_TIME .get_offset = mtu2_timer_get_offset, +#endif }; struct sys_timer mtu2_timer = { diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 1edec2709ef..f558748d754 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -107,8 +107,6 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs, die(str, regs, err); } -static int handle_unaligned_notify_count = 10; - /* * try and fix up kernelspace address errors * - userspace errors just cause EFAULT to be returned, resulting in SEGV @@ -347,6 +345,13 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs) #define SH_PC_8BIT_OFFSET(instr) ((((signed char)(instr))*2) + 4) #define SH_PC_12BIT_OFFSET(instr) ((((signed short)(instr<<4))>>3) + 4) +/* + * XXX: SH-2A needs this too, but it needs an overhaul thanks to mixed 32-bit + * opcodes.. + */ +#ifndef CONFIG_CPU_SH2A +static int handle_unaligned_notify_count = 10; + static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) { u_int rm; @@ -483,6 +488,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) regs->pc += 2; return ret; } +#endif /* CONFIG_CPU_SH2A */ #ifdef CONFIG_CPU_HAS_SR_RB #define lookup_exception_vector(x) \ @@ -501,8 +507,10 @@ asmlinkage void do_address_error(struct pt_regs *regs, { unsigned long error_code = 0; mm_segment_t oldfs; +#ifndef CONFIG_CPU_SH2A u16 instruction; int tmp; +#endif /* Intentional ifdef */ #ifdef CONFIG_CPU_HAS_SR_RB -- cgit v1.2.3 From 716067f28931d46b9f460acbeae1478a337e58ec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 7 Nov 2006 10:29:23 +0000 Subject: sh: Fixup entry-common path breakage for SH-3. The nommu patches broke the path for the common bits, get it building for the SH-3/4 case again. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 8bcd63f9f35..869d56fb7d6 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -323,7 +323,7 @@ skip_restore: 7: .long 0x30000000 ! common exception handler -#include "../../entry.S" +#include "../../entry-common.S" ! Exception Vector Base ! -- cgit v1.2.3 From 417528a2e35f46bc42721de5c4efd33a0eba019d Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Nov 2006 11:18:30 +0900 Subject: sh: Configurable timer IRQ. All of the various CPU subtypes currently hardcode TIMER_IRQ, switch this to a config option in the few places we need this. This allows further removal of hardcoded IRQ headers.. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 7 +++++++ arch/sh/kernel/cpu/sh4/setup-sh7780.c | 2 +- arch/sh/kernel/timers/timer-cmt.c | 2 +- arch/sh/kernel/timers/timer-mtu2.c | 2 +- arch/sh/kernel/timers/timer-tmu.c | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index ba7a1501630..b95dbb8db66 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -405,6 +405,13 @@ source "arch/sh/boards/renesas/rts7751r2d/Kconfig" source "arch/sh/boards/renesas/r7780rp/Kconfig" +config SH_TIMER_IRQ + int + default "28" if CPU_SUBTYPE_SH7780 + default "86" if CPU_SUBTYPE_SH7619 + default "140" if CPU_SUBTYPE_SH7206 + default "16" + config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c index 814ddb22653..4a2b9e01b91 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -79,7 +79,7 @@ static int __init sh7780_devices_setup(void) __initcall(sh7780_devices_setup); static struct intc2_data intc2_irq_table[] = { - { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2 }, + { 28, 0, 24, 0, INTC_TMU0_MSK, 2 }, { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 30687383d4b..24b03996da5 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -169,7 +169,7 @@ static int cmt_timer_init(void) cmt_clock_enable(); - setup_irq(TIMER_IRQ, &cmt_irq); + setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq); cmt0_clk.parent = clk_get("module_clk"); diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 045b2aba13f..92c98b5b11e 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -167,7 +167,7 @@ static int mtu2_timer_init(void) u8 tmp; unsigned long interval; - setup_irq(TIMER_IRQ, &mtu2_irq); + setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq); mtu2_clk1.parent = clk_get("module_clk"); diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 24927015dc3..06a70db7386 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -149,7 +149,7 @@ static int tmu_timer_init(void) { unsigned long interval; - setup_irq(TIMER_IRQ, &tmu_irq); + setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); tmu0_clk.parent = clk_get("module_clk"); -- cgit v1.2.3 From 9a7ef6d59f9d4780ff5bc9c4d05266b52dcb9211 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Nov 2006 13:55:34 +0900 Subject: sh: Drop CPU subtype IRQ headers. This drops the various IRQ headers that were floating around and primarily providing hardcoded IRQ definitions for the various CPU subtypes. This quickly got to be an unmaintainable mess, made even more evident by the subtle breakage introduced by the SH-2 and SH-2A changes. Now that subtypes are able to register IRQ maps directly, just rip all of the headers out. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/irq.c | 1 + arch/sh/drivers/pci/pci-sh7780.c | 14 ++++++++++++++ arch/sh/kernel/cpu/irq/intc2.c | 25 ++++++++++++++---------- arch/sh/kernel/cpu/irq/ipr.c | 6 ++---- arch/sh/kernel/cpu/sh4/setup-sh7780.c | 36 ++++++++++++++++++----------------- 5 files changed, 51 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/renesas/r7780rp/irq.c b/arch/sh/boards/renesas/r7780rp/irq.c index aa15ec5bc69..cc381e19778 100644 --- a/arch/sh/boards/renesas/r7780rp/irq.c +++ b/arch/sh/boards/renesas/r7780rp/irq.c @@ -10,6 +10,7 @@ */ #include #include +#include #include #include diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index d6e63529653..602b644c35a 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -22,6 +22,20 @@ #include #include "pci-sh4.h" +#define INTC_BASE 0xffd00000 +#define INTC_ICR0 (INTC_BASE+0x0) +#define INTC_ICR1 (INTC_BASE+0x1c) +#define INTC_INTPRI (INTC_BASE+0x10) +#define INTC_INTREQ (INTC_BASE+0x24) +#define INTC_INTMSK0 (INTC_BASE+0x44) +#define INTC_INTMSK1 (INTC_BASE+0x48) +#define INTC_INTMSK2 (INTC_BASE+0x40080) +#define INTC_INTMSKCLR0 (INTC_BASE+0x64) +#define INTC_INTMSKCLR1 (INTC_BASE+0x68) +#define INTC_INTMSKCLR2 (INTC_BASE+0x40084) +#define INTC_INT2MSKR (INTC_BASE+0x40038) +#define INTC_INT2MSKCR (INTC_BASE+0x4003c) + /* * Initialization. Try all known PCI access methods. Note that we support * using both PCI BIOS and direct access: in such cases, we use I/O ports diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 74ca576a7ce..74defe76a05 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -11,22 +11,29 @@ * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. */ #include -#include +#include #include -#include + +#if defined(CONFIG_CPU_SUBTYPE_SH7760) +#define INTC2_BASE 0xfe080000 +#define INTC2_INTMSK (INTC2_BASE + 0x40) +#define INTC2_INTMSKCLR (INTC2_BASE + 0x60) +#elif defined(CONFIG_CPU_SUBTYPE_SH7780) +#define INTC2_BASE 0xffd40000 +#define INTC2_INTMSK (INTC2_BASE + 0x38) +#define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) +#endif static void disable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, - INTC2_BASE + INTC2_INTMSK_OFFSET + p->msk_offset); + ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); } static void enable_intc2_irq(unsigned int irq) { struct intc2_data *p = get_irq_chip_data(irq); - ctrl_outl(1 << p->msk_shift, - INTC2_BASE + INTC2_INTMSKCLR_OFFSET + p->msk_offset); + ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); } static struct irq_chip intc2_irq_chip = { @@ -61,12 +68,10 @@ void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) /* Set the priority level */ local_irq_save(flags); - ipr = ctrl_inl(INTC2_BASE + INTC2_INTPRI_OFFSET + - p->ipr_offset); + ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); ipr &= ~(0xf << p->ipr_shift); ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, INTC2_BASE + INTC2_INTPRI_OFFSET + - p->ipr_offset); + ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); local_irq_restore(flags); diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index f7a2bae1df9..a181ccdf290 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -19,10 +19,8 @@ #include #include #include -#include -#include -#include - +#include +#include static void disable_ipr_irq(unsigned int irq) { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c index 4a2b9e01b91..9aeaa2ddaa2 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -79,25 +79,27 @@ static int __init sh7780_devices_setup(void) __initcall(sh7780_devices_setup); static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, INTC_TMU0_MSK, 2 }, - { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, - { SCIF0_TXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, + { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - { SCIF1_ERI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_RXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_BRI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, - { SCIF1_TXI_IRQ, 8, 16, 0, INTC_SCIF1_MSK, SCIF1_PRIORITY }, + { 21, 1, 0, 0, 2, 2 }, + { 22, 1, 1, 0, 2, 2 }, + { 23, 1, 2, 0, 2, 2 }, - { PCIC0_IRQ, 0x10, 8, 0, INTC_PCIC0_MSK, PCIC0_PRIORITY }, - { PCIC1_IRQ, 0x10, 0, 0, INTC_PCIC1_MSK, PCIC1_PRIORITY }, - { PCIC2_IRQ, 0x14, 24, 0, INTC_PCIC2_MSK, PCIC2_PRIORITY }, - { PCIC3_IRQ, 0x14, 16, 0, INTC_PCIC3_MSK, PCIC3_PRIORITY }, - { PCIC4_IRQ, 0x14, 8, 0, INTC_PCIC4_MSK, PCIC4_PRIORITY }, + { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ + { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ + { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ + { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ + + { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ + { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ + { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ + { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ + + { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ + { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ + { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ + { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ + { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ }; void __init init_IRQ_intc2(void) -- cgit v1.2.3 From b552c7e8bceae8a04ae79ecee6fa369c1ba4f8e4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Nov 2006 14:14:29 +0900 Subject: sh: Hook SH7785 in to the build system. Simple 7785 placeholders to start hooking up other bits of code. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 3 ++- arch/sh/mm/Kconfig | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index c24f6390007..696ca75752d 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -392,6 +392,7 @@ static int __init topology_init(void) subsys_initcall(topology_init); static const char *cpu_name[] = { + [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300", [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", @@ -404,7 +405,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", - [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619", + [CPU_SH7785] = "SH7785", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 814a1758697..27463e26a7b 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -171,6 +171,11 @@ config CPU_SUBTYPE_SH7780 select CPU_SH4A select CPU_HAS_INTC2_IRQ +config CPU_SUBTYPE_SH7785 + bool "Support SH7785 processor" + select CPU_SH4A + select CPU_HAS_INTC2_IRQ + comment "SH4AL-DSP Processor Support" config CPU_SUBTYPE_SH73180 -- cgit v1.2.3 From 21440cf04a64cd1b1209c12a6e1a3afba2a28709 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Nov 2006 14:30:26 +0900 Subject: sh: Preliminary support for SH-X2 MMU. This adds some preliminary support for the SH-X2 MMU, used by newer SH-4A parts (particularly SH7785). This MMU implements a 'compat' mode with SH-X MMUs and an 'extended' mode for SH-X2 extended features. Extended features include additional page sizes (8kB, 4MB, 64MB), as well as the addition of page execute permissions. The extended mode attributes are placed in a second data array, which requires us to switch to 64-bit PTEs when in X2 mode. With the addition of the exec perms, we also overhaul the mmap prots somewhat, now that it's possible to handle them more intelligently. Signed-off-by: Paul Mundt --- arch/sh/mm/Kconfig | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- arch/sh/mm/init.c | 4 ++-- arch/sh/mm/ioremap.c | 4 +--- arch/sh/mm/pg-sh4.c | 12 ++---------- 4 files changed, 52 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 27463e26a7b..88e9663fc9f 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -235,13 +235,22 @@ config MEMORY_SIZE config 32BIT bool "Support 32-bit physical addressing through PMB" - depends on CPU_SH4A && MMU + depends on CPU_SH4A && MMU && (!X2TLB || BROKEN) default y help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy 29-bit physical addressing will be used. +config X2TLB + bool "Enable extended TLB mode" + depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL + help + Selecting this option will enable the extended mode of the SH-X2 + TLB. For legacy SH-X behaviour and interoperability, say N. For + all of the fun new features and a willingless to submit bug reports, + say Y. + config VSYSCALL bool "Support vsyscall page" depends on MMU @@ -255,17 +264,53 @@ config VSYSCALL For systems with an MMU that can afford to give up a page, (the default value) say Y. +choice + prompt "Kernel page size" + default PAGE_SIZE_4KB + +config PAGE_SIZE_4KB + bool "4kB" + help + This is the default page size used by all SuperH CPUs. + +config PAGE_SIZE_8KB + bool "8kB" + depends on EXPERIMENTAL && X2TLB + help + This enables 8kB pages as supported by SH-X2 and later MMUs. + +config PAGE_SIZE_64KB + bool "64kB" + depends on EXPERIMENTAL && CPU_SH4 + help + This enables support for 64kB pages, possible on all SH-4 + CPUs and later. Highly experimental, not recommended. + +endchoice + choice prompt "HugeTLB page size" depends on HUGETLB_PAGE && CPU_SH4 && MMU default HUGETLB_PAGE_SIZE_64K config HUGETLB_PAGE_SIZE_64K - bool "64K" + bool "64kB" + +config HUGETLB_PAGE_SIZE_256K + bool "256kB" + depends on X2TLB config HUGETLB_PAGE_SIZE_1MB bool "1MB" +config HUGETLB_PAGE_SIZE_4MB + bool "4MB" + depends on X2TLB + +config HUGETLB_PAGE_SIZE_64MB + bool "64MB" + depends on X2TLB + endchoice source "mm/Kconfig" diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 7154d1ce978..8b275166f40 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -93,7 +93,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pud = pud_offset(pgd, addr); if (pud_none(*pud)) { pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); + set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE)); if (pmd != pmd_offset(pud, 0)) { pud_ERROR(*pud); return; @@ -103,7 +103,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pmd = pmd_offset(pud, addr); if (pmd_none(*pmd)) { pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); - set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); + set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); if (pte != pte_offset_kernel(pmd, 0)) { pmd_ERROR(*pmd); return; diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index a9fe80cfc23..11d54c14982 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -28,9 +28,7 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, { unsigned long end; unsigned long pfn; - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | - _PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | flags); + pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); address &= ~PMD_MASK; end = address + size; diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index 07371ed7a31..e973ac3b13b 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -37,10 +37,6 @@ void clear_user_page(void *to, unsigned long address, struct page *page) if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) clear_page(to); else { - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | - _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *pgd = pgd_offset_k(p3_addr); @@ -50,7 +46,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page) pte_t entry; unsigned long flags; - entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot); + entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); down(&p3map_sem[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); @@ -77,10 +73,6 @@ void copy_user_page(void *to, void *from, unsigned long address, if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) copy_page(to, from); else { - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | - _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | - _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); pgd_t *pgd = pgd_offset_k(p3_addr); @@ -90,7 +82,7 @@ void copy_user_page(void *to, void *from, unsigned long address, pte_t entry; unsigned long flags; - entry = pfn_pte(phys_addr >> PAGE_SHIFT, pgprot); + entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); down(&p3map_sem[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); -- cgit v1.2.3 From 52e27782e1c4afa1feca0fdf194d279595e0431c Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 21 Nov 2006 11:09:41 +0900 Subject: sh: p3map_sem sem2mutex conversion. Simple sem2mutex conversion for the p3map semaphores. Signed-off-by: Paul Mundt --- arch/sh/mm/cache-sh4.c | 14 +++++--------- arch/sh/mm/pg-sh4.c | 23 ++++++----------------- 2 files changed, 11 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index e48cc22724d..7e62ba071d6 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -11,12 +11,8 @@ */ #include #include -#include -#include -#include -#include -#include -#include +#include +#include #include #include @@ -83,9 +79,9 @@ static void __init emit_cache_params(void) */ /* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */ -#define MAX_P3_SEMAPHORES 16 +#define MAX_P3_MUTEXES 16 -struct semaphore p3map_sem[MAX_P3_SEMAPHORES]; +struct mutex p3map_mutex[MAX_P3_MUTEXES]; void __init p3_cache_init(void) { @@ -115,7 +111,7 @@ void __init p3_cache_init(void) panic("%s failed.", __FUNCTION__); for (i = 0; i < cpu_data->dcache.n_aliases; i++) - sema_init(&p3map_sem[i], 1); + mutex_init(&p3map_mutex[i]); } /* diff --git a/arch/sh/mm/pg-sh4.c b/arch/sh/mm/pg-sh4.c index e973ac3b13b..3f98d2a4f93 100644 --- a/arch/sh/mm/pg-sh4.c +++ b/arch/sh/mm/pg-sh4.c @@ -6,22 +6,12 @@ * * Released under the terms of the GNU GPL v2.0. */ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -extern struct semaphore p3map_sem[]; +extern struct mutex p3map_mutex[]; #define CACHE_ALIAS (cpu_data->dcache.alias_mask) @@ -47,7 +37,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page) unsigned long flags; entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); - down(&p3map_sem[(address & CACHE_ALIAS)>>12]); + mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); __flush_tlb_page(get_asid(), p3_addr); @@ -55,7 +45,7 @@ void clear_user_page(void *to, unsigned long address, struct page *page) update_mmu_cache(NULL, p3_addr, entry); __clear_user_page((void *)p3_addr, to); pte_clear(&init_mm, p3_addr, pte); - up(&p3map_sem[(address & CACHE_ALIAS)>>12]); + mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); } } @@ -83,7 +73,7 @@ void copy_user_page(void *to, void *from, unsigned long address, unsigned long flags; entry = pfn_pte(phys_addr >> PAGE_SHIFT, PAGE_KERNEL); - down(&p3map_sem[(address & CACHE_ALIAS)>>12]); + mutex_lock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); set_pte(pte, entry); local_irq_save(flags); __flush_tlb_page(get_asid(), p3_addr); @@ -91,7 +81,7 @@ void copy_user_page(void *to, void *from, unsigned long address, update_mmu_cache(NULL, p3_addr, entry); __copy_user_page((void *)p3_addr, from, to); pte_clear(&init_mm, p3_addr, pte); - up(&p3map_sem[(address & CACHE_ALIAS)>>12]); + mutex_unlock(&p3map_mutex[(address & CACHE_ALIAS)>>12]); } } @@ -114,4 +104,3 @@ inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t } return pte; } - -- cgit v1.2.3 From 53644087a607040a56d883df612b588814a56f11 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 21 Nov 2006 11:12:19 +0900 Subject: sh: Explicit endian selection support. Previously big endian was simply assumed if little endian was not set, which led to some cflags ordering issues. There's not much point to not having a big endian option, so shove one in a choice and wire it up in the Makefile. This lets us clean up some of the cflags ordering while we're at it. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 16 ++++++++++++---- arch/sh/Makefile | 19 +++++++++---------- 2 files changed, 21 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b95dbb8db66..d62183f355a 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -294,12 +294,20 @@ config CF_BASE_ADDR menu "Processor features" -config CPU_LITTLE_ENDIAN - bool "Little Endian" +choice + prompt "Endianess selection" + default CPU_LITTLE_ENDIAN help Some SuperH machines can be configured for either little or big - endian byte order. These modes require different kernels. Say Y if - your machine is little endian, N if it's a big endian machine. + endian byte order. These modes require different kernels. + +config CPU_LITTLE_ENDIAN + bool "Little Endian" + +config CPU_BIG_ENDIAN + bool "Big Endian" + +endchoice config SH_FPU bool "FPU support" diff --git a/arch/sh/Makefile b/arch/sh/Makefile index dc43984bd4b..6b3af5ce66a 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -13,10 +13,6 @@ # for "archclean" and "archdep" for cleaning up and making dependencies for # this architecture # - -cflags-y := -mb -cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml - isa-y := any isa-$(CONFIG_SH_DSP) := sh isa-$(CONFIG_CPU_SH2) := sh2 @@ -38,13 +34,16 @@ isa-y := $(isa-y)-nofpu endif endif -cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) - -cflags-$(CONFIG_CPU_SH2) += -m2 -cflags-$(CONFIG_CPU_SH3) += -m3 -cflags-$(CONFIG_CPU_SH4) += -m4 \ +cflags-$(CONFIG_CPU_SH2) := -m2 +cflags-$(CONFIG_CPU_SH3) := -m3 +cflags-$(CONFIG_CPU_SH4) := -m4 \ $(call cc-option,-mno-implicit-fp,-m4-nofpu) -cflags-$(CONFIG_CPU_SH4A) += $(call cc-option,-m4a-nofpu,) +cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,) + +cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb +cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml + +cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) cflags-$(CONFIG_SH_DSP) += -Wa,-dsp cflags-$(CONFIG_SH_KGDB) += -g -- cgit v1.2.3 From f0bc814cfbc212683c882e58b3d1afec6b3e3aa3 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Tue, 21 Nov 2006 11:16:57 +0900 Subject: sh: gcc4 support. This fixes up the kernel for gcc4. The existing exception handlers needed some wrapping for pt_regs access, acessing the registers via a RELOC_HIDE() pointer. The strcpy() issues popped up here too, so add -ffreestanding and kill off the symbol export. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/Makefile | 2 +- arch/sh/kernel/cpu/sh4/fpu.c | 18 ++++++++------- arch/sh/kernel/irq.c | 5 +++-- arch/sh/kernel/process.c | 32 +++++++++++++++------------ arch/sh/kernel/sh_ksyms.c | 2 -- arch/sh/kernel/signal.c | 26 ++++++++++++---------- arch/sh/kernel/sys_sh.c | 5 +++-- arch/sh/kernel/traps.c | 52 ++++++++++++++++++++++++-------------------- 8 files changed, 78 insertions(+), 64 deletions(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 6b3af5ce66a..7f4516c3f83 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -43,7 +43,7 @@ cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,) cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml -cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) +cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) -ffreestanding cflags-$(CONFIG_SH_DSP) += -Wa,-dsp cflags-$(CONFIG_SH_KGDB) += -g diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index f486c07e10e..378b488237c 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c @@ -296,16 +296,17 @@ ieee_fpe_handler (struct pt_regs *regs) } asmlinkage void -do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) +do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, + unsigned long r7, struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct task_struct *tsk = current; - if (ieee_fpe_handler (®s)) + if (ieee_fpe_handler(regs)) return; - regs.pc += 2; - save_fpu(tsk, ®s); + regs->pc += 2; + save_fpu(tsk, regs); tsk->thread.trap_no = 11; tsk->thread.error_code = 0; force_sig(SIGFPE, tsk); @@ -313,12 +314,13 @@ do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6, - unsigned long r7, struct pt_regs regs) + unsigned long r7, struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct task_struct *tsk = current; - grab_fpu(®s); - if (!user_mode(®s)) { + grab_fpu(regs); + if (!user_mode(regs)) { printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); return; } diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 944128ce970..edf4d2d2133 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -84,9 +84,10 @@ static union irq_ctx *softirq_ctx[NR_CPUS]; asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - struct pt_regs *old_regs = set_irq_regs(®s); + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *old_regs = set_irq_regs(regs); int irq; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index a52b13ac6b7..f3e2631be14 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -385,10 +385,11 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne asmlinkage int sys_fork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); #ifdef CONFIG_MMU - return do_fork(SIGCHLD, regs.regs[15], ®s, 0, NULL, NULL); + return do_fork(SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); #else /* fork almost works, enough to trick you into looking elsewhere :-( */ return -EINVAL; @@ -398,11 +399,12 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5, asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, unsigned long parent_tidptr, unsigned long child_tidptr, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); if (!newsp) - newsp = regs.regs[15]; - return do_fork(clone_flags, newsp, ®s, 0, + newsp = regs->regs[15]; + return do_fork(clone_flags, newsp, regs, 0, (int __user *)parent_tidptr, (int __user *)child_tidptr); } @@ -418,9 +420,10 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, */ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], ®s, + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->regs[15], regs, 0, NULL, NULL); } @@ -429,8 +432,9 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5, */ asmlinkage int sys_execve(char *ufilename, char **uargv, char **uenvp, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int error; char *filename; @@ -442,7 +446,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv, error = do_execve(filename, (char __user * __user *)uargv, (char __user * __user *)uenvp, - ®s); + regs); if (error == 0) { task_lock(current); current->ptrace &= ~PT_DTRACE; @@ -472,9 +476,7 @@ unsigned long get_wchan(struct task_struct *p) return pc; } -asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs regs) +asmlinkage void break_point_trap(void) { /* Clear tracing. */ #if defined(CONFIG_CPU_SH4A) @@ -492,8 +494,10 @@ asmlinkage void break_point_trap(unsigned long r4, unsigned long r5, asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - regs.pc -= 2; + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + + regs->pc -= 2; force_sig(SIGTRAP, current); } diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index 8a2fd19dc9e..c706f3bfd89 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -73,8 +73,6 @@ DECLARE_EXPORT(__lshrdi3); DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movstrSI16); -EXPORT_SYMBOL(strcpy); - #ifdef CONFIG_CPU_SH4 DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 764886b4bcf..50d7c4993be 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -37,7 +37,7 @@ asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); @@ -52,7 +52,7 @@ sys_sigsuspend(old_sigset_t mask, return -ERESTARTNOHAND; } -asmlinkage int +asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act, struct old_sigaction __user *oact) { @@ -87,9 +87,11 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - return do_sigaltstack(uss, uoss, regs.regs[15]); + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + + return do_sigaltstack(uss, uoss, regs->regs[15]); } @@ -198,9 +200,10 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - struct sigframe __user *frame = (struct sigframe __user *)regs.regs[15]; + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15]; sigset_t set; int r0; @@ -220,7 +223,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->sc, &r0)) + if (restore_sigcontext(regs, &frame->sc, &r0)) goto badframe; return r0; @@ -231,9 +234,10 @@ badframe: asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { - struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs.regs[15]; + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15]; sigset_t set; stack_t st; int r0; @@ -250,14 +254,14 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &r0)) + if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) goto badframe; if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) goto badframe; /* It is more difficult to avoid calling this function than to call it and ignore errors. */ - do_sigaltstack(&st, NULL, regs.regs[15]); + do_sigaltstack(&st, NULL, regs->regs[15]); return r0; diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 07f2b571893..5083b6ed4b3 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -33,14 +33,15 @@ */ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int fd[2]; int error; error = do_pipe(fd); if (!error) { - regs.regs[1] = fd[1]; + regs->regs[1] = fd[1]; return fd[0]; } return error; diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index f558748d754..b52037bc125 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -23,8 +23,8 @@ #ifdef CONFIG_SH_KGDB #include -#define CHK_REMOTE_DEBUG(regs) \ -{ \ +#define CHK_REMOTE_DEBUG(regs) \ +{ \ if (kgdb_debug_hook && !user_mode(regs))\ (*kgdb_debug_hook)(regs); \ } @@ -501,7 +501,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) /* * Handle various address error exceptions */ -asmlinkage void do_address_error(struct pt_regs *regs, +asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, unsigned long address) { @@ -588,7 +588,7 @@ int is_dsp_inst(struct pt_regs *regs) { unsigned short inst; - /* + /* * Safe guard if DSP mode is already enabled or we're lacking * the DSP altogether. */ @@ -612,8 +612,9 @@ int is_dsp_inst(struct pt_regs *regs) #ifdef CONFIG_CPU_SH2A asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); siginfo_t info; current->thread.trap_no = r4; @@ -635,12 +636,13 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, /* arch/sh/kernel/cpu/sh4/fpu.c */ extern int do_fpu_inst(unsigned short, struct pt_regs *); extern asmlinkage void do_fpu_state_restore(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, struct pt_regs regs); + unsigned long r6, unsigned long r7, struct pt_regs __regs); asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); unsigned long error_code; struct task_struct *tsk = current; @@ -648,11 +650,11 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, unsigned short inst = 0; int err; - get_user(inst, (unsigned short*)regs.pc); + get_user(inst, (unsigned short*)regs->pc); - err = do_fpu_inst(inst, ®s); + err = do_fpu_inst(inst, regs); if (!err) { - regs.pc += 2; + regs->pc += 2; return; } /* not a FPU inst. */ @@ -660,9 +662,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, #ifdef CONFIG_SH_DSP /* Check if it's a DSP instruction */ - if (is_dsp_inst(®s)) { + if (is_dsp_inst(regs)) { /* Enable DSP mode, and restart instruction. */ - regs.sr |= SR_DSP; + regs->sr |= SR_DSP; return; } #endif @@ -672,9 +674,9 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, local_irq_enable(); tsk->thread.error_code = error_code; tsk->thread.trap_no = TRAP_RESERVED_INST; - CHK_REMOTE_DEBUG(®s); + CHK_REMOTE_DEBUG(regs); force_sig(SIGILL, tsk); - die_if_no_fixup("reserved instruction", ®s, error_code); + die_if_no_fixup("reserved instruction", regs, error_code); } #ifdef CONFIG_SH_FPU_EMU @@ -722,17 +724,18 @@ static int emulate_branch(unsigned short inst, struct pt_regs* regs) asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); unsigned long error_code; struct task_struct *tsk = current; #ifdef CONFIG_SH_FPU_EMU unsigned short inst = 0; - get_user(inst, (unsigned short *)regs.pc + 1); - if (!do_fpu_inst(inst, ®s)) { - get_user(inst, (unsigned short *)regs.pc); - if (!emulate_branch(inst, ®s)) + get_user(inst, (unsigned short *)regs->pc + 1); + if (!do_fpu_inst(inst, regs)) { + get_user(inst, (unsigned short *)regs->pc); + if (!emulate_branch(inst, regs)) return; /* fault in branch.*/ } @@ -744,19 +747,20 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, local_irq_enable(); tsk->thread.error_code = error_code; tsk->thread.trap_no = TRAP_RESERVED_INST; - CHK_REMOTE_DEBUG(®s); + CHK_REMOTE_DEBUG(regs); force_sig(SIGILL, tsk); - die_if_no_fixup("illegal slot instruction", ®s, error_code); + die_if_no_fixup("illegal slot instruction", regs, error_code); } asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs) + struct pt_regs __regs) { + struct pt_regs *regs = RELOC_HIDE(&__regs, 0); long ex; lookup_exception_vector(ex); - die_if_kernel("exception", ®s, ex); + die_if_kernel("exception", regs, ex); } #if defined(CONFIG_SH_STANDARD_BIOS) @@ -809,7 +813,7 @@ void *set_exception_table_vec(unsigned int vec, void *handler) extern asmlinkage void address_error_handler(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, - struct pt_regs regs); + struct pt_regs __regs); void __init trap_init(void) { -- cgit v1.2.3 From b5a1bcbee434b843c8850a968d9a6c7541f1be9d Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Tue, 21 Nov 2006 13:34:04 +0900 Subject: sh: Set up correct siginfo structures for page faults. Remove the previous saving of fault codes into the thread_struct as they are never used, and appeared to be inherited from x86. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/fpu.c | 7 +---- arch/sh/kernel/traps.c | 74 ++++++++++++++++++++++++-------------------- arch/sh/mm/fault.c | 26 ++++++++++------ 3 files changed, 58 insertions(+), 49 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index 378b488237c..7624677f662 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c @@ -282,11 +282,8 @@ ieee_fpe_handler (struct pt_regs *regs) grab_fpu(regs); restore_fpu(tsk); set_tsk_thread_flag(tsk, TIF_USEDFPU); - } else { - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; + } else force_sig(SIGFPE, tsk); - } regs->pc = nextpc; return 1; @@ -307,8 +304,6 @@ do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, regs->pc += 2; save_fpu(tsk, regs); - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; force_sig(SIGFPE, tsk); } diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index b52037bc125..0ee298079d8 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -93,7 +93,7 @@ void die(const char * str, struct pt_regs * regs, long err) if (!user_mode(regs) || in_interrupt()) dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + - (unsigned long)task_stack_page(current)); + (unsigned long)task_stack_page(current)); bust_spinlocks(0); spin_unlock_irq(&die_lock); @@ -201,7 +201,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) if (copy_to_user(dst,src,4)) goto fetch_fault; ret = 0; - break; + break; case 2: /* mov.[bwl] to memory, possibly with pre-decrement */ if (instruction & 4) @@ -225,7 +225,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) if (copy_from_user(dst,src,4)) goto fetch_fault; ret = 0; - break; + break; case 6: /* mov.[bwl] from memory, possibly with post-increment */ src = (unsigned char*) *rm; @@ -233,7 +233,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) *rm += count; dst = (unsigned char*) rn; *(unsigned long*)dst = 0; - + #ifdef __LITTLE_ENDIAN__ if (copy_from_user(dst, src, count)) goto fetch_fault; @@ -244,7 +244,7 @@ static int handle_unaligned_ins(u16 instruction, struct pt_regs *regs) } #else dst += 4-count; - + if (copy_from_user(dst, src, count)) goto fetch_fault; @@ -323,7 +323,8 @@ static inline int handle_unaligned_delayslot(struct pt_regs *regs) return -EFAULT; /* kernel */ - die("delay-slot-insn faulting in handle_unaligned_delayslot", regs, 0); + die("delay-slot-insn faulting in handle_unaligned_delayslot", + regs, 0); } return handle_unaligned_ins(instruction,regs); @@ -364,7 +365,8 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) if (user_mode(regs) && handle_unaligned_notify_count>0) { handle_unaligned_notify_count--; - printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", + printk(KERN_NOTICE "Fixing up unaligned userspace access " + "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", current->comm,current->pid,(u16*)regs->pc,instruction); } @@ -499,7 +501,15 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) #endif /* - * Handle various address error exceptions + * Handle various address error exceptions: + * - instruction address error: + * misaligned PC + * PC >= 0x80000000 in user mode + * - data address error (read and write) + * misaligned data access + * access to >= 0x80000000 is user mode + * Unfortuntaly we can't distinguish between instruction address error + * and data address errors caused by read acceses. */ asmlinkage void do_address_error(struct pt_regs *regs, unsigned long writeaccess, @@ -507,6 +517,7 @@ asmlinkage void do_address_error(struct pt_regs *regs, { unsigned long error_code = 0; mm_segment_t oldfs; + siginfo_t info; #ifndef CONFIG_CPU_SH2A u16 instruction; int tmp; @@ -520,22 +531,15 @@ asmlinkage void do_address_error(struct pt_regs *regs, oldfs = get_fs(); if (user_mode(regs)) { + int si_code = BUS_ADRERR; + local_irq_enable(); - current->thread.error_code = error_code; -#ifdef CONFIG_CPU_SH2 - /* - * On the SH-2, we only have a single vector for address - * errors, there's no differentiating between a load error - * and a store error. - */ - current->thread.trap_no = 9; -#else - current->thread.trap_no = (writeaccess) ? 8 : 7; -#endif /* bad PC is not something we can fix */ - if (regs->pc & 1) + if (regs->pc & 1) { + si_code = BUS_ADRALN; goto uspace_segv; + } #ifndef CONFIG_CPU_SH2A set_fs(USER_DS); @@ -554,9 +558,16 @@ asmlinkage void do_address_error(struct pt_regs *regs, return; /* sorted */ #endif - uspace_segv: - printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); - force_sig(SIGSEGV, current); +uspace_segv: + printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned " + "access (PC %lx PR %lx)\n", current->comm, regs->pc, + regs->pr); + + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = si_code; + info.si_addr = (void *) address; + force_sig_info(SIGBUS, &info, current); } else { if (regs->pc & 1) die("unaligned program counter", regs, error_code); @@ -574,7 +585,9 @@ asmlinkage void do_address_error(struct pt_regs *regs, handle_unaligned_access(instruction, regs); set_fs(oldfs); #else - printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n", current->comm); + printk(KERN_NOTICE "Killing process \"%s\" due to unaligned " + "access\n", current->comm); + force_sig(SIGSEGV, current); #endif } @@ -617,9 +630,6 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, struct pt_regs *regs = RELOC_HIDE(&__regs, 0); siginfo_t info; - current->thread.trap_no = r4; - current->thread.error_code = 0; - switch (r4) { case TRAP_DIVZERO_ERROR: info.si_code = FPE_INTDIV; @@ -662,7 +672,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, #ifdef CONFIG_SH_DSP /* Check if it's a DSP instruction */ - if (is_dsp_inst(regs)) { + if (is_dsp_inst(regs)) { /* Enable DSP mode, and restart instruction. */ regs->sr |= SR_DSP; return; @@ -672,8 +682,6 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, lookup_exception_vector(error_code); local_irq_enable(); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = TRAP_RESERVED_INST; CHK_REMOTE_DEBUG(regs); force_sig(SIGILL, tsk); die_if_no_fixup("reserved instruction", regs, error_code); @@ -745,8 +753,6 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, lookup_exception_vector(error_code); local_irq_enable(); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = TRAP_RESERVED_INST; CHK_REMOTE_DEBUG(regs); force_sig(SIGILL, tsk); die_if_no_fixup("illegal slot instruction", regs, error_code); @@ -805,7 +811,7 @@ void *set_exception_table_vec(unsigned int vec, void *handler) { extern void *exception_handling_table[]; void *old_handler; - + old_handler = exception_handling_table[vec]; exception_handling_table[vec] = handler; return old_handler; @@ -841,7 +847,7 @@ void __init trap_init(void) set_exception_table_vec(TRAP_DIVZERO_ERROR, do_divide_error); set_exception_table_vec(TRAP_DIVOVF_ERROR, do_divide_error); #endif - + /* Setup VBR for boot cpu */ per_cpu_trap_init(); } diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 68663b8f99a..43bed2cb00e 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -26,13 +26,16 @@ extern void die(const char *,struct pt_regs *,long); * and the problem, and then passes it off to one of the appropriate * routines. */ -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, - unsigned long address) +asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, + unsigned long writeaccess, + unsigned long address) { struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; unsigned long page; + int si_code; + siginfo_t info; #ifdef CONFIG_SH_KGDB if (kgdb_nofault && kgdb_bus_err_hook) @@ -41,6 +44,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, tsk = current; mm = tsk->mm; + si_code = SEGV_MAPERR; /* * If we're in an interrupt or have no user @@ -65,6 +69,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * we can handle it.. */ good_area: + si_code = SEGV_ACCERR; if (writeaccess) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -105,9 +110,11 @@ bad_area: up_read(&mm->mmap_sem); if (user_mode(regs)) { - tsk->thread.address = address; - tsk->thread.error_code = writeaccess; - force_sig(SIGSEGV, tsk); + info.si_signo = SIGSEGV; + info.si_errno = 0; + info.si_code = si_code; + info.si_addr = (void *) address; + force_sig_info(SIGSEGV, &info, tsk); return; } @@ -166,10 +173,11 @@ do_sigbus: * Send a sigbus, regardless of whether we were in kernel * or user mode. */ - tsk->thread.address = address; - tsk->thread.error_code = writeaccess; - tsk->thread.trap_no = 14; - force_sig(SIGBUS, tsk); + info.si_signo = SIGBUS; + info.si_errno = 0; + info.si_code = BUS_ADRERR; + info.si_addr = (void *)address; + force_sig_info(SIGBUS, &info, tsk); /* Kernel mode? Handle exceptions or die */ if (!user_mode(regs)) -- cgit v1.2.3 From 6e4662ff49c6b94e16a47bfddb920576963b5a20 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Tue, 21 Nov 2006 13:53:44 +0900 Subject: sh: Use MMU.TTB register as pointer to current pgd. Add TTB accessor functions and give it a sensible default value. We will use this later for optimizing the fault path. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/mm/init.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 8b275166f40..8c8d3911838 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -155,9 +155,6 @@ extern char __init_begin, __init_end; /* * paging_init() sets up the page tables - * - * This routines also unmaps the page at virtual kernel address 0, so - * that we can trap those pesky NULL-reference errors in the kernel. */ void __init paging_init(void) { @@ -180,14 +177,11 @@ void __init paging_init(void) */ { unsigned long max_dma, low, start_pfn; - pgd_t *pg_dir; - int i; - - /* We don't need kernel mapping as hardware support that. */ - pg_dir = swapper_pg_dir; - for (i = 0; i < PTRS_PER_PGD; i++) - pgd_val(pg_dir[i]) = 0; + /* We don't need to map the kernel through the TLB, as + * it is permanatly mapped using P1. So clear the + * entire pgd. */ + memset(swapper_pg_dir, 0, sizeof(swapper_pg_dir)); /* Turn on the MMU */ enable_mmu(); @@ -206,6 +200,10 @@ void __init paging_init(void) } } + /* Set an initial value for the MMU.TTB so we don't have to + * check for a null value. */ + set_TTB(swapper_pg_dir); + #elif defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4) /* * If we don't have CONFIG_MMU set and the processor in question -- cgit v1.2.3 From 99a596f93be10001c50894bcab69e458a49a3b8c Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Tue, 21 Nov 2006 15:38:05 +0900 Subject: sh: pmd rework. Remove extra bits from the pmd structure and store a kernel logical address rather than a physical address. This allows it to be directly dereferenced. Another piece of wierdness inherited from x86. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/mm/fault.c | 40 ++++++++++++++++++++++++++++++++++++++++ arch/sh/mm/init.c | 26 +++++++++----------------- 2 files changed, 49 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 43bed2cb00e..128907ef7fc 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -46,6 +46,45 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, mm = tsk->mm; si_code = SEGV_MAPERR; + if (unlikely(address >= TASK_SIZE)) { + /* + * Synchronize this task's top level page-table + * with the 'reference' page table. + * + * Do _not_ use "tsk" here. We might be inside + * an interrupt in the middle of a task switch.. + */ + int offset = pgd_index(address); + pgd_t *pgd, *pgd_k; + pud_t *pud, *pud_k; + pmd_t *pmd, *pmd_k; + + pgd = get_TTB() + offset; + pgd_k = swapper_pg_dir + offset; + + /* This will never happen with the folded page table. */ + if (!pgd_present(*pgd)) { + if (!pgd_present(*pgd_k)) + goto bad_area_nosemaphore; + set_pgd(pgd, *pgd_k); + return; + } + + pud = pud_offset(pgd, address); + pud_k = pud_offset(pgd_k, address); + if (pud_present(*pud) || !pud_present(*pud_k)) + goto bad_area_nosemaphore; + set_pud(pud, *pud_k); + + pmd = pmd_offset(pud, address); + pmd_k = pmd_offset(pud_k, address); + if (pmd_present(*pmd) || !pmd_present(*pmd_k)) + goto bad_area_nosemaphore; + set_pmd(pmd, *pmd_k); + + return; + } + /* * If we're in an interrupt or have no user * context, we must not take the fault.. @@ -109,6 +148,7 @@ survive: bad_area: up_read(&mm->mmap_sem); +bad_area_nosemaphore: if (user_mode(regs)) { info.si_signo = SIGSEGV; info.si_errno = 0; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 8c8d3911838..462bfeac6d9 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -84,30 +84,22 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) pmd_t *pmd; pte_t *pte; - pgd = swapper_pg_dir + pgd_index(addr); + pgd = pgd_offset_k(addr); if (pgd_none(*pgd)) { pgd_ERROR(*pgd); return; } - pud = pud_offset(pgd, addr); - if (pud_none(*pud)) { - pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); - set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE)); - if (pmd != pmd_offset(pud, 0)) { - pud_ERROR(*pud); - return; - } + pud = pud_alloc(NULL, pgd, addr); + if (unlikely(!pud)) { + pud_ERROR(*pud); + return; } - pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) { - pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); - set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE)); - if (pte != pte_offset_kernel(pmd, 0)) { - pmd_ERROR(*pmd); - return; - } + pmd = pmd_alloc(NULL, pud, addr); + if (unlikely(!pmd)) { + pmd_ERROR(*pmd); + return; } pte = pte_offset_kernel(pmd, addr); -- cgit v1.2.3 From 9f5e8eee5cfe1328660c71812d87c2a67bda389f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 11:22:57 +0900 Subject: sh: generic push-switch framework. This adds support for a generic push switch framework. Adaptable for various switches, including GPIO switches and the push switches commonly found on Renesas debug boards. This allows switch states to be trivially reported through sysfs. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 + arch/sh/drivers/Kconfig | 9 +++ arch/sh/drivers/Makefile | 2 +- arch/sh/drivers/push-switch.c | 138 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/sh/drivers/Kconfig create mode 100644 arch/sh/drivers/push-switch.c (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d62183f355a..a03f155571c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -473,6 +473,8 @@ config HEARTBEAT behavior is platform-dependent, but normally the flash frequency is a hyperbolic function of the 5-minute load average. +source "arch/sh/drivers/Kconfig" + endmenu config ISA_DMA_API diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig new file mode 100644 index 00000000000..c54c758e624 --- /dev/null +++ b/arch/sh/drivers/Kconfig @@ -0,0 +1,9 @@ +menu "Additional SuperH Device Drivers" + +config PUSH_SWITCH + tristate "Push switch support" + help + This enables support for the push switch framework, a simple + framework that allows for sysfs driven switch status reporting. + +endmenu diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile index 338c3729d27..bf18dbfb678 100644 --- a/arch/sh/drivers/Makefile +++ b/arch/sh/drivers/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_SH_DMA) += dma/ obj-$(CONFIG_SUPERHYWAY) += superhyway/ - +obj-$(CONFIG_PUSH_SWITCH) += push-switch.o diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c new file mode 100644 index 00000000000..f2b9157c314 --- /dev/null +++ b/arch/sh/drivers/push-switch.c @@ -0,0 +1,138 @@ +/* + * Generic push-switch framework + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +#define DRV_NAME "push-switch" +#define DRV_VERSION "0.1.0" + +static ssize_t switch_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct push_switch_platform_info *psw_info = dev->platform_data; + return sprintf(buf, "%s\n", psw_info->name); +} +static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL); + +static void switch_timer(unsigned long data) +{ + struct push_switch *psw = (struct push_switch *)data; + + schedule_work(&psw->work); +} + +static void switch_work_handler(void *data) +{ + struct platform_device *pdev = data; + struct push_switch *psw = platform_get_drvdata(pdev); + + psw->state = 0; + + kobject_uevent(&pdev->dev.kobj, KOBJ_CHANGE); +} + +static int switch_drv_probe(struct platform_device *pdev) +{ + struct push_switch_platform_info *psw_info; + struct push_switch *psw; + int ret, irq; + + psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL); + if (unlikely(!psw)) + return -ENOMEM; + + irq = platform_get_irq(pdev, 0); + if (unlikely(irq < 0)) { + ret = -ENODEV; + goto err; + } + + psw_info = pdev->dev.platform_data; + BUG_ON(!psw_info); + + ret = request_irq(irq, psw_info->irq_handler, + IRQF_DISABLED | psw_info->irq_flags, + psw_info->name ? psw_info->name : DRV_NAME, pdev); + if (unlikely(ret < 0)) + goto err; + + if (psw_info->name) { + ret = device_create_file(&pdev->dev, &dev_attr_switch); + if (unlikely(ret)) { + dev_err(&pdev->dev, "Failed creating device attrs\n"); + ret = -EINVAL; + goto err_irq; + } + } + + INIT_WORK(&psw->work, switch_work_handler, pdev); + init_timer(&psw->debounce); + + psw->debounce.function = switch_timer; + psw->debounce.data = (unsigned long)psw; + + platform_set_drvdata(pdev, psw); + + return 0; + +err_irq: + free_irq(irq, pdev); +err: + kfree(psw); + return ret; +} + +static int switch_drv_remove(struct platform_device *pdev) +{ + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + int irq = platform_get_irq(pdev, 0); + + if (psw_info->name) + device_remove_file(&pdev->dev, &dev_attr_switch); + + platform_set_drvdata(pdev, NULL); + flush_scheduled_work(); + del_timer_sync(&psw->debounce); + free_irq(irq, pdev); + + kfree(psw); + + return 0; +} + +static struct platform_driver switch_driver = { + .probe = switch_drv_probe, + .remove = switch_drv_remove, + .driver = { + .name = DRV_NAME, + }, +}; + +static int __init switch_init(void) +{ + printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION); + return platform_driver_register(&switch_driver); +} + +static void __exit switch_exit(void) +{ + platform_driver_unregister(&switch_driver); +} +module_init(switch_init); +module_exit(switch_exit); + +MODULE_VERSION(DRV_VERSION); +MODULE_AUTHOR("Paul Mundt"); +MODULE_LICENSE("GPLv2"); -- cgit v1.2.3 From 9daa0c257d6c200b58092e0bfc32b77c4618a8af Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 11:24:39 +0900 Subject: sh: R7780RP push-switch support. This adds simple push-switch support for the RDBRP-1/RDBREVRP-1 debug boards found on the R7780RP-1. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/Makefile | 4 +- arch/sh/boards/renesas/r7780rp/psw.c | 122 ++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 arch/sh/boards/renesas/r7780rp/psw.c (limited to 'arch') diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile index f1776d02797..574b0316ed5 100644 --- a/arch/sh/boards/renesas/r7780rp/Makefile +++ b/arch/sh/boards/renesas/r7780rp/Makefile @@ -3,4 +3,6 @@ # obj-y := setup.o io.o irq.o -obj-$(CONFIG_HEARTBEAT) += led.o + +obj-$(CONFIG_HEARTBEAT) += led.o +obj-$(CONFIG_PUSH_SWITCH) += psw.o diff --git a/arch/sh/boards/renesas/r7780rp/psw.c b/arch/sh/boards/renesas/r7780rp/psw.c new file mode 100644 index 00000000000..c844dfa5d58 --- /dev/null +++ b/arch/sh/boards/renesas/r7780rp/psw.c @@ -0,0 +1,122 @@ +/* + * arch/sh/boards/renesas/r7780rp/psw.c + * + * push switch support for RDBRP-1/RDBREVRP-1 debug boards. + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include +#include + +static irqreturn_t psw_irq_handler(int irq, void *arg) +{ + struct platform_device *pdev = arg; + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + unsigned int l, mask; + int ret = 0; + + l = ctrl_inw(PA_DBSW); + + /* Nothing to do if there's no state change */ + if (psw->state) { + ret = 1; + goto out; + } + + mask = l & 0x70; + /* Figure out who raised it */ + if (mask & (1 << psw_info->bit)) { + psw->state = !!(mask & (1 << psw_info->bit)); + if (psw->state) /* debounce */ + mod_timer(&psw->debounce, jiffies + 50); + + ret = 1; + } + +out: + /* Clear the switch IRQs */ + l |= (0x7 << 12); + ctrl_outw(l, PA_DBSW); + + return IRQ_RETVAL(ret); +} + +static struct resource psw_resources[] = { + [0] = { + .start = IRQ_PSW, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct push_switch_platform_info s2_platform_data = { + .name = "s2", + .bit = 6, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s2_switch_device = { + .name = "push-switch", + .id = 0, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s2_platform_data, + }, +}; + +static struct push_switch_platform_info s3_platform_data = { + .name = "s3", + .bit = 5, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s3_switch_device = { + .name = "push-switch", + .id = 1, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s3_platform_data, + }, +}; + +static struct push_switch_platform_info s4_platform_data = { + .name = "s4", + .bit = 4, + .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device s4_switch_device = { + .name = "push-switch", + .id = 2, + .num_resources = ARRAY_SIZE(psw_resources), + .resource = psw_resources, + .dev = { + .platform_data = &s4_platform_data, + }, +}; + +static struct platform_device *psw_devices[] = { + &s2_switch_device, &s3_switch_device, &s4_switch_device, +}; + +static int __init psw_init(void) +{ + return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); +} +module_init(psw_init); -- cgit v1.2.3 From 9b3a53ab76771e3669e50086c131e1574fe25847 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Fri, 24 Nov 2006 11:42:24 +0900 Subject: sh: TLB miss fast-path optimizations. Handle simple TLB miss faults which can be resolved completely from the page table in assembler. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 + arch/sh/kernel/cpu/sh3/entry.S | 206 +++++++++++++++++++++++++++++++++++++---- arch/sh/kernel/cpu/sh4/probe.c | 19 ++-- arch/sh/mm/Kconfig | 1 + arch/sh/mm/fault.c | 86 ----------------- 5 files changed, 201 insertions(+), 114 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index a03f155571c..48308dc86e3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -379,6 +379,9 @@ config CPU_HAS_SR_RB See for further information on SR.RB and register banking in the kernel in general. +config CPU_HAS_PTEA + bool + endmenu menu "Timer support" diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 869d56fb7d6..5de99b49873 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -13,8 +13,10 @@ #include #include #include -#include #include +#include +#include +#include ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address @@ -136,29 +138,14 @@ ENTRY(tlb_protection_violation_store) call_dpf: mov.l 1f, r0 - mov r5, r8 - mov.l @r0, r6 - mov r6, r9 - mov.l 2f, r0 - sts pr, r10 - jsr @r0 - mov r15, r4 - ! - tst r0, r0 - bf/s 0f - lds r10, pr - rts - nop -0: sti + mov.l @r0, r6 ! address mov.l 3f, r0 - mov r9, r6 - mov r8, r5 + sti jmp @r0 - mov r15, r4 + mov r15, r4 ! regs .align 2 1: .long MMU_TEA -2: .long __do_page_fault 3: .long do_page_fault .align 2 @@ -344,9 +331,176 @@ general_exception: 2: .long ret_from_exception ! ! + +/* This code makes some assumptions to improve performance. + * Make sure they are stil true. */ +#if PTRS_PER_PGD != PTRS_PER_PTE +#error PDG and PTE sizes don't match +#endif + +/* gas doesn't flag impossible values for mov #immediate as an error */ +#if (_PAGE_PRESENT >> 2) > 0x7f +#error cannot load PAGE_PRESENT as an immediate +#endif +#if _PAGE_DIRTY > 0x7f +#error cannot load PAGE_DIRTY as an immediate +#endif +#if (_PAGE_PRESENT << 2) != _PAGE_ACCESSED +#error cannot derive PAGE_ACCESSED from PAGE_PRESENT +#endif + +#if defined(CONFIG_CPU_SH4) +#define ldmmupteh(r) mov.l 8f, r +#else +#define ldmmupteh(r) mov #MMU_PTEH, r +#endif + .balign 1024,0,1024 tlb_miss: - mov.l 1f, k2 +#ifdef COUNT_EXCEPTIONS + ! Increment the counts + mov.l 9f, k1 + mov.l @k1, k2 + add #1, k2 + mov.l k2, @k1 +#endif + + ! k0 scratch + ! k1 pgd and pte pointers + ! k2 faulting address + ! k3 pgd and pte index masks + ! k4 shift + + ! Load up the pgd entry (k1) + + ldmmupteh(k0) ! 9 LS (latency=2) MMU_PTEH + + mov.w 4f, k3 ! 8 LS (latency=2) (PTRS_PER_PGD-1) << 2 + mov #-(PGDIR_SHIFT-2), k4 ! 6 EX + + mov.l @(MMU_TEA-MMU_PTEH,k0), k2 ! 18 LS (latency=2) + + mov.l @(MMU_TTB-MMU_PTEH,k0), k1 ! 18 LS (latency=2) + + mov k2, k0 ! 5 MT (latency=0) + shld k4, k0 ! 99 EX + + and k3, k0 ! 78 EX + + mov.l @(k0, k1), k1 ! 21 LS (latency=2) + mov #-(PAGE_SHIFT-2), k4 ! 6 EX + + ! Load up the pte entry (k2) + + mov k2, k0 ! 5 MT (latency=0) + shld k4, k0 ! 99 EX + + tst k1, k1 ! 86 MT + + bt 20f ! 110 BR + + and k3, k0 ! 78 EX + mov.w 5f, k4 ! 8 LS (latency=2) _PAGE_PRESENT + + mov.l @(k0, k1), k2 ! 21 LS (latency=2) + add k0, k1 ! 49 EX + +#ifdef CONFIG_CPU_HAS_PTEA + ! Test the entry for present and _PAGE_ACCESSED + + mov #-28, k3 ! 6 EX + mov k2, k0 ! 5 MT (latency=0) + + tst k4, k2 ! 68 MT + shld k3, k0 ! 99 EX + + bt 20f ! 110 BR + + ! Set PTEA register + ! MMU_PTEA = ((pteval >> 28) & 0xe) | (pteval & 0x1) + ! + ! k0=pte>>28, k1=pte*, k2=pte, k3=, k4=_PAGE_PRESENT + + and #0xe, k0 ! 79 EX + + mov k0, k3 ! 5 MT (latency=0) + mov k2, k0 ! 5 MT (latency=0) + + and #1, k0 ! 79 EX + + or k0, k3 ! 82 EX + + ldmmupteh(k0) ! 9 LS (latency=2) + shll2 k4 ! 101 EX _PAGE_ACCESSED + + tst k4, k2 ! 68 MT + + mov.l k3, @(MMU_PTEA-MMU_PTEH,k0) ! 27 LS + + mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK + + ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED +#else + + ! Test the entry for present and _PAGE_ACCESSED + + mov.l 7f, k3 ! 9 LS (latency=2) _PAGE_FLAGS_HARDWARE_MASK + tst k4, k2 ! 68 MT + + shll2 k4 ! 101 EX _PAGE_ACCESSED + ldmmupteh(k0) ! 9 LS (latency=2) + + bt 20f ! 110 BR + tst k4, k2 ! 68 MT + + ! k0=MMU_PTEH, k1=pte*, k2=pte, k3=_PAGE_FLAGS_HARDWARE, k4=_PAGE_ACCESSED + +#endif + + ! Set up the entry + + and k2, k3 ! 78 EX + bt/s 10f ! 108 BR + + mov.l k3, @(MMU_PTEL-MMU_PTEH,k0) ! 27 LS + + ldtlb ! 128 CO + + ! At least one instruction between ldtlb and rte + nop ! 119 NOP + + rte ! 126 CO + + nop ! 119 NOP + + +10: or k4, k2 ! 82 EX + + ldtlb ! 128 CO + + ! At least one instruction between ldtlb and rte + mov.l k2, @k1 ! 27 LS + + rte ! 126 CO + + ! Note we cannot execute mov here, because it is executed after + ! restoring SSR, so would be executed in user space. + nop ! 119 NOP + + + .align 5 + ! Once cache line if possible... +1: .long swapper_pg_dir +4: .short (PTRS_PER_PGD-1) << 2 +5: .short _PAGE_PRESENT +7: .long _PAGE_FLAGS_HARDWARE_MASK +8: .long MMU_PTEH +#ifdef COUNT_EXCEPTIONS +9: .long exception_count_miss +#endif + + ! Either pgd or pte not present +20: mov.l 1f, k2 mov.l 4f, k3 bra handle_exception mov.l @k2, k2 @@ -496,6 +650,15 @@ skip_save: bf interrupt_exception shlr2 r8 shlr r8 + +#ifdef COUNT_EXCEPTIONS + mov.l 5f, r9 + add r8, r9 + mov.l @r9, r10 + add #1, r10 + mov.l r10, @r9 +#endif + mov.l 4f, r9 add r8, r9 mov.l @r9, r9 @@ -509,6 +672,9 @@ skip_save: 2: .long 0x000080f0 ! FD=1, IMASK=15 3: .long 0xcfffffff ! RB=0, BL=0 4: .long exception_handling_table +#ifdef COUNT_EXCEPTIONS +5: .long exception_count_table +#endif interrupt_exception: mov.l 1f, r9 diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index c294de1e14a..afe0f1b1c03 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -79,16 +79,16 @@ int __init detect_cpu_and_cache_system(void) case 0x205: cpu_data->type = CPU_SH7750; cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; + CPU_HAS_PERF_COUNTER; break; case 0x206: cpu_data->type = CPU_SH7750S; cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; + CPU_HAS_PERF_COUNTER; break; case 0x1100: cpu_data->type = CPU_SH7751; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_FPU; break; case 0x2000: cpu_data->type = CPU_SH73180; @@ -126,23 +126,22 @@ int __init detect_cpu_and_cache_system(void) break; case 0x8000: cpu_data->type = CPU_ST40RA; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_FPU; break; case 0x8100: cpu_data->type = CPU_ST40GX1; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_FPU; break; case 0x700: cpu_data->type = CPU_SH4_501; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_PTEA; break; case 0x600: cpu_data->type = CPU_SH4_202; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_FPU; break; case 0x500 ... 0x501: switch (prr) { @@ -160,7 +159,7 @@ int __init detect_cpu_and_cache_system(void) cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_FPU; break; default: @@ -173,6 +172,10 @@ int __init detect_cpu_and_cache_system(void) cpu_data->dcache.ways = 1; #endif +#ifdef CONFIG_CPU_HAS_PTEA + cpu_data->flags |= CPU_HAS_PTEA; +#endif + /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 88e9663fc9f..6cd6d0045d1 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -20,6 +20,7 @@ config CPU_SH4 bool select CPU_HAS_INTEVT select CPU_HAS_SR_RB + select CPU_HAS_PTEA if !CPU_SUBTYPE_ST40 config CPU_SH4A bool diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 128907ef7fc..123fb80c859 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -223,89 +223,3 @@ do_sigbus: if (!user_mode(regs)) goto no_context; } - -#ifdef CONFIG_SH_STORE_QUEUES -/* - * This is a special case for the SH-4 store queues, as pages for this - * space still need to be faulted in before it's possible to flush the - * store queue cache for writeout to the remapped region. - */ -#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000) -#else -#define P3_ADDR_MAX P4SEG -#endif - -/* - * Called with interrupts disabled. - */ -asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, - unsigned long writeaccess, - unsigned long address) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *pte; - pte_t entry; - struct mm_struct *mm = current->mm; - spinlock_t *ptl; - int ret = 1; - -#ifdef CONFIG_SH_KGDB - if (kgdb_nofault && kgdb_bus_err_hook) - kgdb_bus_err_hook(); -#endif - - /* - * We don't take page faults for P1, P2, and parts of P4, these - * are always mapped, whether it be due to legacy behaviour in - * 29-bit mode, or due to PMB configuration in 32-bit mode. - */ - if (address >= P3SEG && address < P3_ADDR_MAX) { - pgd = pgd_offset_k(address); - mm = NULL; - } else { - if (unlikely(address >= TASK_SIZE || !mm)) - return 1; - - pgd = pgd_offset(mm, address); - } - - pud = pud_offset(pgd, address); - if (pud_none_or_clear_bad(pud)) - return 1; - pmd = pmd_offset(pud, address); - if (pmd_none_or_clear_bad(pmd)) - return 1; - - if (mm) - pte = pte_offset_map_lock(mm, pmd, address, &ptl); - else - pte = pte_offset_kernel(pmd, address); - - entry = *pte; - if (unlikely(pte_none(entry) || pte_not_present(entry))) - goto unlock; - if (unlikely(writeaccess && !pte_write(entry))) - goto unlock; - - if (writeaccess) - entry = pte_mkdirty(entry); - entry = pte_mkyoung(entry); - -#ifdef CONFIG_CPU_SH4 - /* - * ITLB is not affected by "ldtlb" instruction. - * So, we need to flush the entry by ourselves. - */ - __flush_tlb_page(get_asid(), address & PAGE_MASK); -#endif - - set_pte(pte, entry); - update_mmu_cache(NULL, address, entry); - ret = 0; -unlock: - if (mm) - pte_unmap_unlock(pte, ptl); - return ret; -} -- cgit v1.2.3 From e0969e0c9b609fdfe217e34f3e046179ffe88eb6 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Fri, 24 Nov 2006 13:01:36 +0900 Subject: sh: Fix syscall tracing ordering. The implementation of system call tracing in the kernel has a couple of ordering problems: - the validity of the system call number is checked before calling out to system call tracing code, and should be done after - the system call number used when tracing is the one the system call was invoked with, while the system call tracing code can legitimatly change the call number (for example strace permutes fork into clone) This patch fixes both of these problems, and also reoders the code slightly to make the direct path through the code the common case. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/kernel/entry-common.S | 45 +++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 5bc7fa91d09..8f96d21fcb1 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -256,8 +256,7 @@ syscall_trace_entry: mov.l @(OFF_R6,r15), r6 mov.l @(OFF_R7,r15), r7 ! arg3 mov.l @(OFF_R3,r15), r3 ! syscall_nr - ! Arrange for do_syscall_trace to be called - ! again as the system call returns. + ! mov.l 2f, r10 ! Number of syscalls cmp/hs r10, r3 bf syscall_call @@ -273,6 +272,18 @@ __restore_all: .align 2 1: .long restore_all + .align 2 +not_syscall_tra: + bra debug_trap + nop + + .align 2 +syscall_badsys: ! Bad syscall number + mov #-ENOSYS, r0 + bra resume_userspace + mov.l r0, @(OFF_R0,r15) ! Return value + + /* * Syscall interface: * @@ -316,39 +327,27 @@ ENTRY(system_call) ! Is the trap argument >= 0x20? (TRA will be >= 0x80) mov #0x7f, r9 cmp/hi r9, r8 - bt/s 0f + bt/s not_syscall_tra mov #OFF_TRA, r9 add r15, r9 - ! mov.l r8, @r9 ! set TRA value to tra sti - ! Call the system call handler through the table. - ! First check for bad syscall number - mov r3, r9 - mov.l 2f, r8 ! Number of syscalls - cmp/hs r8, r9 - get_current_thread_info r8, r10 - bf good_system_call -syscall_badsys: ! Bad syscall number - mov #-ENOSYS, r0 - bra resume_userspace - mov.l r0, @(OFF_R0,r15) ! Return value ! -0: - bra debug_trap - nop - ! -good_system_call: ! Good syscall number + get_current_thread_info r8, r10 mov.l @(TI_FLAGS,r8), r8 mov #_TIF_SYSCALL_TRACE, r10 tst r10, r8 bf syscall_trace_entry ! + mov.l 2f, r8 ! Number of syscalls + cmp/hs r8, r3 + bt syscall_badsys + ! syscall_call: - shll2 r9 ! x4 + shll2 r3 ! x4 mov.l 3f, r8 ! Load the address of sys_call_table - add r8, r9 - mov.l @r9, r8 + add r8, r3 + mov.l @r3, r8 jsr @r8 ! jump to specific syscall handler nop mov.l @(OFF_R0,r15), r12 ! save r0 -- cgit v1.2.3 From 4dfc119f1c0723c54a20ff5ca4ea460ce7a4edb5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 14:43:09 +0900 Subject: sh: dma-sysfs fixes. Handle the case where no registered DMACs exist somewhat more gracefully. While we're at it, check for sysdev_create_file() failing. Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-sysfs.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c index 29b8ef9873d..eebcd4768bb 100644 --- a/arch/sh/drivers/dma/dma-sysfs.c +++ b/arch/sh/drivers/dma/dma-sysfs.c @@ -3,7 +3,7 @@ * * sysfs interface for SH DMA API * - * Copyright (C) 2004, 2005 Paul Mundt + * Copyright (C) 2004 - 2006 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -21,7 +21,6 @@ static struct sysdev_class dma_sysclass = { set_kset_name("dma"), }; - EXPORT_SYMBOL(dma_sysclass); static ssize_t dma_show_devices(struct sys_device *dev, char *buf) @@ -31,7 +30,10 @@ static ssize_t dma_show_devices(struct sys_device *dev, char *buf) for (i = 0; i < MAX_DMA_CHANNELS; i++) { struct dma_info *info = get_dma_info(i); - struct dma_channel *channel = &info->channels[i]; + struct dma_channel *channel = get_dma_channel(i); + + if (unlikely(!info) || !channel) + continue; len += sprintf(buf + len, "%2d: %14s %s\n", channel->chan, info->name, @@ -125,11 +127,16 @@ int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info) if (ret) return ret; - sysdev_create_file(dev, &attr_dev_id); - sysdev_create_file(dev, &attr_count); - sysdev_create_file(dev, &attr_mode); - sysdev_create_file(dev, &attr_flags); - sysdev_create_file(dev, &attr_config); + ret |= sysdev_create_file(dev, &attr_dev_id); + ret |= sysdev_create_file(dev, &attr_count); + ret |= sysdev_create_file(dev, &attr_mode); + ret |= sysdev_create_file(dev, &attr_flags); + ret |= sysdev_create_file(dev, &attr_config); + + if (unlikely(ret)) { + dev_err(&info->pdev->dev, "Failed creating attrs\n"); + return ret; + } snprintf(name, sizeof(name), "dma%d", chan->chan); return sysfs_create_link(&info->pdev->dev.kobj, &dev->kobj, name); -- cgit v1.2.3 From 49f860bb5db877a2c75642e7e19af40e3010afec Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 14:48:14 +0900 Subject: sh: Make dma-isa depend on ISA_DMA_API. Previously we linked in the ISA DMA wrapper unconditionally. As there are very few users of this, it's better to make it conditional. Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile index 065d4c90970..db1295d3226 100644 --- a/arch/sh/drivers/dma/Makefile +++ b/arch/sh/drivers/dma/Makefile @@ -2,8 +2,8 @@ # Makefile for the SuperH DMA specific kernel interface routines under Linux. # -obj-y += dma-api.o dma-isa.o +obj-y += dma-api.o +obj-$(CONFIG_ISA_DMA_API) += dma-isa.o obj-$(CONFIG_SYSFS) += dma-sysfs.o obj-$(CONFIG_SH_DMA) += dma-sh.o obj-$(CONFIG_SH_DREAMCAST) += dma-pvr2.o dma-g2.o - -- cgit v1.2.3 From e803aaf63a18b26668fbfbfd41c65527bcc10532 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 14:50:05 +0900 Subject: sh: Drop name overload in dma-sh. Pass along the dev_id from request_dma() all the way down, rather than inserting an artificial name relating to the TEI line that we were doing before. This makes the line a bit less obvious, but dev_id is the proper behaviour for this regardless. Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-sh.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 66078601335..f63721ed86c 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -94,20 +94,13 @@ static int sh_dmac_request_dma(struct dma_channel *chan) if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) return 0; - chan->name = kzalloc(32, GFP_KERNEL); - if (unlikely(chan->name == NULL)) - return -ENOMEM; - snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)", - chan->chan); - return request_irq(get_dmte_irq(chan->chan), dma_tei, - IRQF_DISABLED, chan->name, chan); + IRQF_DISABLED, chan->dev_id, chan); } static void sh_dmac_free_dma(struct dma_channel *chan) { free_irq(get_dmte_irq(chan->chan), chan); - kfree(chan->name); } static void -- cgit v1.2.3 From db9b99d461ddbbaa43c1e3581b1677b82c960948 Mon Sep 17 00:00:00 2001 From: Mark Glaisher Date: Fri, 24 Nov 2006 15:13:52 +0900 Subject: sh: dma-api channel capability extensions. This extends the SH DMA API for allowing handling of DMA channels based off of their respective capabilities. A couple of functions are added to the existing API, the core bits are register_chan_caps() for registering channel capabilities, and request_dma_bycap() for fetching a channel dynamically based off of a capability set. Signed-off-by: Mark Glaisher Signed-off-by: Paul Mundt --- arch/sh/drivers/dma/dma-api.c | 274 +++++++++++++++++++++++++++++------------- 1 file changed, 189 insertions(+), 85 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index 47c3e837599..e062067edd2 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -11,61 +11,27 @@ */ #include #include -#include #include #include #include #include +#include #include DEFINE_SPINLOCK(dma_spin_lock); static LIST_HEAD(registered_dmac_list); -/* - * A brief note about the reasons for this API as it stands. - * - * For starters, the old ISA DMA API didn't work for us for a number of - * reasons, for one, the vast majority of channels on the SH DMAC are - * dual-address mode only, and both the new and the old DMA APIs are after the - * concept of managing a DMA buffer, which doesn't overly fit this model very - * well. In addition to which, the new API is largely geared at IOMMUs and - * GARTs, and doesn't even support the channel notion very well. - * - * The other thing that's a marginal issue, is the sheer number of random DMA - * engines that are present (ie, in boards like the Dreamcast), some of which - * cascade off of the SH DMAC, and others do not. As such, there was a real - * need for a scalable subsystem that could deal with both single and - * dual-address mode usage, in addition to interoperating with cascaded DMACs. - * - * There really isn't any reason why this needs to be SH specific, though I'm - * not aware of too many other processors (with the exception of some MIPS) - * that have the same concept of a dual address mode, or any real desire to - * actually make use of the DMAC even if such a subsystem were exposed - * elsewhere. - * - * The idea for this was derived from the ARM port, which acted as an excellent - * reference when trying to address these issues. - * - * It should also be noted that the decision to add Yet Another DMA API(tm) to - * the kernel wasn't made easily, and was only decided upon after conferring - * with jejb with regards to the state of the old and new APIs as they applied - * to these circumstances. Philip Blundell was also a great help in figuring - * out some single-address mode DMA semantics that were otherwise rather - * confusing. - */ - struct dma_info *get_dma_info(unsigned int chan) { struct dma_info *info; - unsigned int total = 0; /* * Look for each DMAC's range to determine who the owner of * the channel is. */ list_for_each_entry(info, ®istered_dmac_list, list) { - total += info->nr_channels; - if (chan > total) + if ((chan < info->first_channel_nr) || + (chan >= info->first_channel_nr + info->nr_channels)) continue; return info; @@ -73,6 +39,22 @@ struct dma_info *get_dma_info(unsigned int chan) return NULL; } +EXPORT_SYMBOL(get_dma_info); + +struct dma_info *get_dma_info_by_name(const char *dmac_name) +{ + struct dma_info *info; + + list_for_each_entry(info, ®istered_dmac_list, list) { + if (dmac_name && (strcmp(dmac_name, info->name) != 0)) + continue; + else + return info; + } + + return NULL; +} +EXPORT_SYMBOL(get_dma_info_by_name); static unsigned int get_nr_channels(void) { @@ -91,63 +73,161 @@ static unsigned int get_nr_channels(void) struct dma_channel *get_dma_channel(unsigned int chan) { struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel; + int i; - if (!info) + if (unlikely(!info)) return ERR_PTR(-EINVAL); - return info->channels + chan; + for (i = 0; i < info->nr_channels; i++) { + channel = &info->channels[i]; + if (channel->chan == chan) + return channel; + } + + return NULL; } +EXPORT_SYMBOL(get_dma_channel); int get_dma_residue(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + struct dma_channel *channel = get_dma_channel(chan); if (info->ops->get_residue) return info->ops->get_residue(channel); return 0; } +EXPORT_SYMBOL(get_dma_residue); -int request_dma(unsigned int chan, const char *dev_id) +static int search_cap(const char **haystack, const char *needle) { - struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + const char **p; + + for (p = haystack; *p; p++) + if (strcmp(*p, needle) == 0) + return 1; + + return 0; +} + +/** + * request_dma_bycap - Allocate a DMA channel based on its capabilities + * @dmac: List of DMA controllers to search + * @caps: List of capabilites + * + * Search all channels of all DMA controllers to find a channel which + * matches the requested capabilities. The result is the channel + * number if a match is found, or %-ENODEV if no match is found. + * + * Note that not all DMA controllers export capabilities, in which + * case they can never be allocated using this API, and so + * request_dma() must be used specifying the channel number. + */ +int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id) +{ + unsigned int found = 0; + struct dma_info *info; + const char **p; + int i; + + BUG_ON(!dmac || !caps); + + list_for_each_entry(info, ®istered_dmac_list, list) + if (strcmp(*dmac, info->name) == 0) { + found = 1; + break; + } + + if (!found) + return -ENODEV; + + for (i = 0; i < info->nr_channels; i++) { + struct dma_channel *channel = &info->channels[i]; + + if (unlikely(!channel->caps)) + continue; + + for (p = caps; *p; p++) { + if (!search_cap(channel->caps, *p)) + break; + if (request_dma(channel->chan, dev_id) == 0) + return channel->chan; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL(request_dma_bycap); + +int dmac_search_free_channel(const char *dev_id) +{ + struct dma_channel *channel = { 0 }; + struct dma_info *info = get_dma_info(0); + int i; + + for (i = 0; i < info->nr_channels; i++) { + channel = &info->channels[i]; + if (unlikely(!channel)) + return -ENODEV; + + if (atomic_read(&channel->busy) == 0) + break; + } - down(&channel->sem); + if (info->ops->request) { + int result = info->ops->request(channel); + if (result) + return result; - if (!info->ops || chan >= MAX_DMA_CHANNELS) { - up(&channel->sem); - return -EINVAL; + atomic_set(&channel->busy, 1); + return channel->chan; } - atomic_set(&channel->busy, 1); + return -ENOSYS; +} + +int request_dma(unsigned int chan, const char *dev_id) +{ + struct dma_channel *channel = { 0 }; + struct dma_info *info = get_dma_info(chan); + int result; + + channel = get_dma_channel(chan); + if (atomic_xchg(&channel->busy, 1)) + return -EBUSY; strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id)); - up(&channel->sem); + if (info->ops->request) { + result = info->ops->request(channel); + if (result) + atomic_set(&channel->busy, 0); - if (info->ops->request) - return info->ops->request(channel); + return result; + } return 0; } +EXPORT_SYMBOL(request_dma); void free_dma(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + struct dma_channel *channel = get_dma_channel(chan); if (info->ops->free) info->ops->free(channel); atomic_set(&channel->busy, 0); } +EXPORT_SYMBOL(free_dma); void dma_wait_for_completion(unsigned int chan) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + struct dma_channel *channel = get_dma_channel(chan); if (channel->flags & DMA_TEI_CAPABLE) { wait_event(channel->wait_queue, @@ -158,21 +238,52 @@ void dma_wait_for_completion(unsigned int chan) while (info->ops->get_residue(channel)) cpu_relax(); } +EXPORT_SYMBOL(dma_wait_for_completion); + +int register_chan_caps(const char *dmac, struct dma_chan_caps *caps) +{ + struct dma_info *info; + unsigned int found = 0; + int i; + + list_for_each_entry(info, ®istered_dmac_list, list) + if (strcmp(dmac, info->name) == 0) { + found = 1; + break; + } + + if (unlikely(!found)) + return -ENODEV; + + for (i = 0; i < info->nr_channels; i++, caps++) { + struct dma_channel *channel; + + if ((info->first_channel_nr + i) != caps->ch_num) + return -EINVAL; + + channel = &info->channels[i]; + channel->caps = caps->caplist; + } + + return 0; +} +EXPORT_SYMBOL(register_chan_caps); void dma_configure_channel(unsigned int chan, unsigned long flags) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + struct dma_channel *channel = get_dma_channel(chan); if (info->ops->configure) info->ops->configure(channel, flags); } +EXPORT_SYMBOL(dma_configure_channel); int dma_xfer(unsigned int chan, unsigned long from, unsigned long to, size_t size, unsigned int mode) { struct dma_info *info = get_dma_info(chan); - struct dma_channel *channel = &info->channels[chan]; + struct dma_channel *channel = get_dma_channel(chan); channel->sar = from; channel->dar = to; @@ -181,8 +292,20 @@ int dma_xfer(unsigned int chan, unsigned long from, return info->ops->xfer(channel); } +EXPORT_SYMBOL(dma_xfer); + +int dma_extend(unsigned int chan, unsigned long op, void *param) +{ + struct dma_info *info = get_dma_info(chan); + struct dma_channel *channel = get_dma_channel(chan); + + if (info->ops->extend) + return info->ops->extend(channel, op, param); + + return -ENOSYS; +} +EXPORT_SYMBOL(dma_extend); -#ifdef CONFIG_PROC_FS static int dma_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data) { @@ -214,8 +337,6 @@ static int dma_read_proc(char *buf, char **start, off_t off, return p - buf; } -#endif - int register_dmac(struct dma_info *info) { @@ -224,8 +345,7 @@ int register_dmac(struct dma_info *info) INIT_LIST_HEAD(&info->list); printk(KERN_INFO "DMA: Registering %s handler (%d channel%s).\n", - info->name, info->nr_channels, - info->nr_channels > 1 ? "s" : ""); + info->name, info->nr_channels, info->nr_channels > 1 ? "s" : ""); BUG_ON((info->flags & DMAC_CHANNELS_CONFIGURED) && !info->channels); @@ -242,28 +362,26 @@ int register_dmac(struct dma_info *info) size = sizeof(struct dma_channel) * info->nr_channels; - info->channels = kmalloc(size, GFP_KERNEL); + info->channels = kzalloc(size, GFP_KERNEL); if (!info->channels) return -ENOMEM; - - memset(info->channels, 0, size); } total_channels = get_nr_channels(); for (i = 0; i < info->nr_channels; i++) { - struct dma_channel *chan = info->channels + i; + struct dma_channel *chan = &info->channels[i]; + + atomic_set(&chan->busy, 0); - chan->chan = i; - chan->vchan = i + total_channels; + chan->chan = info->first_channel_nr + i; + chan->vchan = info->first_channel_nr + i + total_channels; memcpy(chan->dev_id, "Unused", 7); if (info->flags & DMAC_CHANNELS_TEI_CAPABLE) chan->flags |= DMA_TEI_CAPABLE; - init_MUTEX(&chan->sem); init_waitqueue_head(&chan->wait_queue); - dma_create_sysfs_files(chan, info); } @@ -271,6 +389,7 @@ int register_dmac(struct dma_info *info) return 0; } +EXPORT_SYMBOL(register_dmac); void unregister_dmac(struct dma_info *info) { @@ -285,31 +404,16 @@ void unregister_dmac(struct dma_info *info) list_del(&info->list); platform_device_unregister(info->pdev); } +EXPORT_SYMBOL(unregister_dmac); static int __init dma_api_init(void) { - printk("DMA: Registering DMA API.\n"); - -#ifdef CONFIG_PROC_FS + printk(KERN_NOTICE "DMA: Registering DMA API.\n"); create_proc_read_entry("dma", 0, 0, dma_read_proc, 0); -#endif - return 0; } - subsys_initcall(dma_api_init); MODULE_AUTHOR("Paul Mundt "); MODULE_DESCRIPTION("DMA API for SuperH"); MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(request_dma); -EXPORT_SYMBOL(free_dma); -EXPORT_SYMBOL(register_dmac); -EXPORT_SYMBOL(get_dma_residue); -EXPORT_SYMBOL(get_dma_info); -EXPORT_SYMBOL(get_dma_channel); -EXPORT_SYMBOL(dma_xfer); -EXPORT_SYMBOL(dma_wait_for_completion); -EXPORT_SYMBOL(dma_configure_channel); - -- cgit v1.2.3 From 1dc41e58a553e612e3d0349bb60eef08f9462bde Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 24 Nov 2006 19:46:18 +0900 Subject: sh: Fixup 4K irq stacks. There was a clobber issue with the register we were saving the stack in, so we switch to a register that we handle in the clobber list properly already. This also follows the x86 changes for allowing the softirq checks from hardirq context. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index edf4d2d2133..46a19e07abd 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -78,8 +78,8 @@ union irq_ctx { u32 stack[THREAD_SIZE/sizeof(u32)]; }; -static union irq_ctx *hardirq_ctx[NR_CPUS]; -static union irq_ctx *softirq_ctx[NR_CPUS]; +static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; +static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; #endif asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, @@ -136,17 +136,24 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, irqctx->tinfo.task = curctx->tinfo.task; irqctx->tinfo.previous_sp = current_stack_pointer; + /* + * Copy the softirq bits in preempt_count so that the + * softirq checks work in the hardirq context. + */ + irqctx->tinfo.preempt_count = + (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | + (curctx->tinfo.preempt_count & SOFTIRQ_MASK); + __asm__ __volatile__ ( "mov %0, r4 \n" - "mov r15, r9 \n" + "mov r15, r8 \n" "jsr @%1 \n" /* swith to the irq stack */ " mov %2, r15 \n" /* restore the stack (ring zero) */ - "mov r9, r15 \n" + "mov r8, r15 \n" : /* no outputs */ : "r" (irq), "r" (generic_handle_irq), "r" (isp) - /* XXX: A somewhat excessive clobber list? -PFM */ : "memory", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "t", "pr" ); @@ -194,7 +201,7 @@ void irq_ctx_init(int cpu) irqctx->tinfo.task = NULL; irqctx->tinfo.exec_domain = NULL; irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET; + irqctx->tinfo.preempt_count = 0; irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); softirq_ctx[cpu] = irqctx; @@ -240,10 +247,14 @@ asmlinkage void do_softirq(void) "mov r9, r15 \n" : /* no outputs */ : "r" (__do_softirq), "r" (isp) - /* XXX: A somewhat excessive clobber list? -PFM */ : "memory", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" ); + + /* + * Shouldnt happen, we returned above if in_interrupt(): + */ + WARN_ON_ONCE(softirq_count()); } local_irq_restore(flags); -- cgit v1.2.3 From 510c72ad2dd4e05e6908755f51ac89482c6eb987 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Nov 2006 12:06:26 +0900 Subject: sh: Fixup various PAGE_SIZE == 4096 assumptions. There were a number of places that made evil PAGE_SIZE == 4k assumptions that ended up breaking when trying to play with 8k and 64k page sizes, this fixes those up. The most significant change is the way we load THREAD_SIZE, previously this was done via: mov #(THREAD_SIZE >> 8), reg shll8 reg to avoid a memory access and allow the immediate load. With a 64k PAGE_SIZE, we're out of range for the immediate load size without resorting to special instructions available in later ISAs (movi20s and so on). The "workaround" for this is to bump up the shift to 10 and insert a shll2, which gives a bit more flexibility while still being much cheaper than a memory access. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh3/entry.S | 5 +++-- arch/sh/kernel/head.S | 5 +++-- arch/sh/kernel/relocate_kernel.S | 14 ++++++-------- arch/sh/mm/cache-sh4.c | 4 ++-- arch/sh/mm/clear_page.S | 18 +++++++++--------- arch/sh/mm/copy_page.S | 16 ++++++++-------- arch/sh/mm/init.c | 1 - arch/sh/mm/pg-dma.c | 2 -- 8 files changed, 31 insertions(+), 34 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 5de99b49873..7ba3dcbe750 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -335,7 +335,7 @@ general_exception: /* This code makes some assumptions to improve performance. * Make sure they are stil true. */ #if PTRS_PER_PGD != PTRS_PER_PTE -#error PDG and PTE sizes don't match +#error PGD and PTE sizes don't match #endif /* gas doesn't flag impossible values for mov #immediate as an error */ @@ -547,8 +547,9 @@ ENTRY(handle_exception) bt/s 1f ! It's a kernel to kernel transition. mov r15, k0 ! save original stack to k0 /* User space to kernel */ - mov #(THREAD_SIZE >> 8), k1 + mov #(THREAD_SIZE >> 10), k1 shll8 k1 ! k1 := THREAD_SIZE + shll2 k1 add current, k1 mov k1, r15 ! change to kernel stack ! diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index b5ff2326461..6aca4bc6ec5 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -33,7 +33,7 @@ ENTRY(empty_zero_page) .long 0x00360000 /* INITRD_START */ .long 0x000a0000 /* INITRD_SIZE */ .long 0 - .balign 4096,0,4096 + .balign PAGE_SIZE,0,PAGE_SIZE .text /* @@ -70,8 +70,9 @@ ENTRY(_stext) ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #(THREAD_SIZE >> 8), r1 + mov #(THREAD_SIZE >> 10), r1 shll8 r1 ! r1 = THREAD_SIZE + shll2 r1 sub r1, r0 ! #ifdef CONFIG_CPU_HAS_SR_RB ldc r0, r7_bank ! ... and initial thread_info diff --git a/arch/sh/kernel/relocate_kernel.S b/arch/sh/kernel/relocate_kernel.S index 8221b37c977..c66cb3209db 100644 --- a/arch/sh/kernel/relocate_kernel.S +++ b/arch/sh/kernel/relocate_kernel.S @@ -7,11 +7,9 @@ * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ - #include - -#define PAGE_SIZE 4096 /* must be same value as in */ - +#include +#include .globl relocate_new_kernel relocate_new_kernel: @@ -20,8 +18,8 @@ relocate_new_kernel: /* r6 = start_address */ /* r7 = vbr_reg */ - mov.l 10f,r8 /* 4096 */ - mov.l 11f,r9 /* 0xa0000000 */ + mov.l 10f,r8 /* PAGE_SIZE */ + mov.l 11f,r9 /* P2SEG */ /* stack setting */ add r8,r5 @@ -32,7 +30,7 @@ relocate_new_kernel: 0: mov.l @r4+,r0 /* cmd = *ind++ */ -1: /* addr = (cmd | 0xa0000000) & 0xfffffff0 */ +1: /* addr = (cmd | P2SEG) & 0xfffffff0 */ mov r0,r2 or r9,r2 mov #-16,r1 @@ -92,7 +90,7 @@ relocate_new_kernel: 10: .long PAGE_SIZE 11: - .long 0xa0000000 + .long P2SEG relocate_new_kernel_end: diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index 7e62ba071d6..ae531affccb 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -225,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start, */ if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || (start < CACHE_OC_ADDRESS_ARRAY)) - exec_offset = 0x20000000; + exec_offset = 0x20000000; local_irq_save(flags); __flush_cache_4096(start | SH_CACHE_ASSOC, @@ -246,7 +246,7 @@ void flush_dcache_page(struct page *page) /* Loop all the D-cache */ n = cpu_data->dcache.n_aliases; - for (i = 0; i < n; i++, addr += PAGE_SIZE) + for (i = 0; i < n; i++, addr += 4096) flush_cache_4096(addr, phys); } diff --git a/arch/sh/mm/clear_page.S b/arch/sh/mm/clear_page.S index 7b96425ae27..8a706131e52 100644 --- a/arch/sh/mm/clear_page.S +++ b/arch/sh/mm/clear_page.S @@ -1,12 +1,12 @@ -/* $Id: clear_page.S,v 1.13 2003/08/25 17:03:10 lethal Exp $ - * +/* * __clear_user_page, __clear_user, clear_page implementation of SuperH * * Copyright (C) 2001 Kaz Kojima * Copyright (C) 2001, 2002 Niibe Yutaka - * + * Copyright (C) 2006 Paul Mundt */ #include +#include /* * clear_page_slow @@ -18,11 +18,11 @@ /* * r0 --- scratch * r4 --- to - * r5 --- to + 4096 + * r5 --- to + PAGE_SIZE */ ENTRY(clear_page_slow) mov r4,r5 - mov.w .Llimit,r0 + mov.l .Llimit,r0 add r0,r5 mov #0,r0 ! @@ -50,7 +50,7 @@ ENTRY(clear_page_slow) ! rts nop -.Llimit: .word (4096-28) +.Llimit: .long (PAGE_SIZE-28) ENTRY(__clear_user) ! @@ -164,10 +164,10 @@ ENTRY(__clear_user) * r0 --- scratch * r4 --- to * r5 --- orig_to - * r6 --- to + 4096 + * r6 --- to + PAGE_SIZE */ ENTRY(__clear_user_page) - mov.w .L4096,r0 + mov.l .Lpsz,r0 mov r4,r6 add r0,r6 mov #0,r0 @@ -191,7 +191,7 @@ ENTRY(__clear_user_page) ! rts nop -.L4096: .word 4096 +.Lpsz: .long PAGE_SIZE #endif diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S index 1addffe117c..397c94c9731 100644 --- a/arch/sh/mm/copy_page.S +++ b/arch/sh/mm/copy_page.S @@ -1,12 +1,12 @@ -/* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $ - * +/* * copy_page, __copy_user_page, __copy_user implementation of SuperH * * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima * Copyright (C) 2002 Toshinobu Sugioka - * + * Copyright (C) 2006 Paul Mundt */ #include +#include /* * copy_page_slow @@ -18,7 +18,7 @@ /* * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch - * r8 --- from + 4096 + * r8 --- from + PAGE_SIZE * r9 --- not used * r10 --- to * r11 --- from @@ -30,7 +30,7 @@ ENTRY(copy_page_slow) mov r4,r10 mov r5,r11 mov r5,r8 - mov.w .L4096,r0 + mov.l .Lpsz,r0 add r0,r8 ! 1: mov.l @r11+,r0 @@ -80,7 +80,7 @@ ENTRY(copy_page_slow) /* * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch - * r8 --- from + 4096 + * r8 --- from + PAGE_SIZE * r9 --- orig_to * r10 --- to * r11 --- from @@ -94,7 +94,7 @@ ENTRY(__copy_user_page) mov r5,r11 mov r6,r9 mov r5,r8 - mov.w .L4096,r0 + mov.l .Lpsz,r0 add r0,r8 ! 1: ocbi @r9 @@ -129,7 +129,7 @@ ENTRY(__copy_user_page) rts nop #endif -.L4096: .word 4096 +.Lpsz: .long PAGE_SIZE /* * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); * Return the number of bytes NOT copied diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 462bfeac6d9..59f4cc18235 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -217,7 +217,6 @@ static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) { - extern unsigned long empty_zero_page[1024]; int codesize, reservedpages, datasize, initsize; int tmp; extern unsigned long memory_start; diff --git a/arch/sh/mm/pg-dma.c b/arch/sh/mm/pg-dma.c index 1406d2e348c..bb23679369d 100644 --- a/arch/sh/mm/pg-dma.c +++ b/arch/sh/mm/pg-dma.c @@ -39,8 +39,6 @@ static void copy_page_dma(void *to, void *from) static void clear_page_dma(void *to) { - extern unsigned long empty_zero_page[1024]; - /* * We get invoked quite early on, if the DMAC hasn't been initialized * yet, fall back on the slow manual implementation. -- cgit v1.2.3 From 6fc21b82ef74911887ced1aff8d37ce079bb8b36 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 27 Nov 2006 12:10:23 +0900 Subject: sh: More flexible + SH7780 earlyprintk SCIF support. This makes the early printk support somewhat more flexible, moving the port definition to a config option, and making the port initialization configurable for sh-ipl+g users. At the same time, this allows us to trivially wire up the SH7780 SCIF0, so that's thrown in too more or less for free. Signed-off-by: Paul Mundt --- arch/sh/Kconfig.debug | 18 +++++++++++++++++- arch/sh/kernel/early_printk.c | 44 +++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 48479e014da..dcceec95a2d 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -17,7 +17,18 @@ config SH_STANDARD_BIOS config EARLY_SCIF_CONSOLE bool "Use early SCIF console" - depends on CPU_SH4 || CPU_SH2A && !SH_STANDARD_BIOS + help + This enables an early console using a fixed SCIF port. This can + be used by platforms that are either not running the SH + standard BIOS, or do not wish to use the BIOS callbacks for the + serial I/O. + +config EARLY_SCIF_CONSOLE_PORT + hex "SCIF port for early console" + depends on EARLY_SCIF_CONSOLE + default "0xffe00000" if CPU_SUBTYPE_SH7780 + default "0xfffe9800" if CPU_SUBTYPE_SH72060 + default "0xffe80000" if CPU_SH4 config EARLY_PRINTK bool "Early printk support" @@ -30,6 +41,11 @@ config EARLY_PRINTK when the kernel may crash or hang before the serial console is initialised. If unsure, say N. + On devices that are running SH-IPL and want to keep the port + initialization consistent while not using the BIOS callbacks, + select both the EARLY_SCIF_CONSOLE and SH_STANDARD_BIOS, using + the kernel command line option to toggle back and forth. + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index a00022722e9..60340823798 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include @@ -62,17 +62,9 @@ static struct console bios_console = { #include #include "../../../drivers/serial/sh-sci.h" -#ifdef CONFIG_CPU_SH4 -#define SCIF_REG 0xffe80000 -#elif defined(CONFIG_CPU_SUBTYPE_SH72060) -#define SCIF_REG 0xfffe9800 -#else -#error "Undefined SCIF for this subtype" -#endif - static struct uart_port scif_port = { - .mapbase = SCIF_REG, - .membase = (char __iomem *)SCIF_REG, + .mapbase = CONFIG_EARLY_SCIF_CONSOLE_PORT, + .membase = (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, }; static void scif_sercon_putc(int c) @@ -113,23 +105,29 @@ static struct console scif_console = { .index = -1, }; +#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +/* + * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 + * devices that aren't using sh-ipl+g. + */ static void scif_sercon_init(int baud) { - ctrl_outw(0, SCIF_REG + 8); - ctrl_outw(0, SCIF_REG); + ctrl_outw(0, scif_port.mapbase + 8); + ctrl_outw(0, scif_port.mapbase); /* Set baud rate */ ctrl_outb((CONFIG_SH_PCLK_FREQ + 16 * baud) / - (32 * baud) - 1, SCIF_REG + 4); - - ctrl_outw(12, SCIF_REG + 24); - ctrl_outw(8, SCIF_REG + 24); - ctrl_outw(0, SCIF_REG + 32); - ctrl_outw(0x60, SCIF_REG + 16); - ctrl_outw(0, SCIF_REG + 36); - ctrl_outw(0x30, SCIF_REG + 8); + (32 * baud) - 1, scif_port.mapbase + 4); + + ctrl_outw(12, scif_port.mapbase + 24); + ctrl_outw(8, scif_port.mapbase + 24); + ctrl_outw(0, scif_port.mapbase + 32); + ctrl_outw(0x60, scif_port.mapbase + 16); + ctrl_outw(0, scif_port.mapbase + 36); + ctrl_outw(0x30, scif_port.mapbase + 8); } -#endif +#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ +#endif /* CONFIG_EARLY_SCIF_CONSOLE */ /* * Setup a default console, if more than one is compiled in, rely on the @@ -168,7 +166,7 @@ int __init setup_early_printk(char *opt) if (!strncmp(buf, "serial", 6)) { early_console = &scif_console; -#ifdef CONFIG_CPU_SH4 +#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) scif_sercon_init(115200); #endif } -- cgit v1.2.3 From 9f650cf2b811cfb605f10483eeb1dc86f43cdbcb Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 12:01:43 +0900 Subject: sh: Fix store queue bitmap end. The end of the store queue bitmap is miscalculated when searching for a free range in sq_remap(), missing the PAGE_SHIFT shift that's done in sq_api_init(). This runs in to workloads where we can scan beyond the end of the bitmap. Spotted by Paul Jackson: http://marc.theaimsgroup.com/?l=linux-kernel&m=116493191224097&w Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/sq.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 7bcc73f9b8d..55f43506995 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,6 +67,7 @@ void sq_flush_range(unsigned long start, unsigned int len) /* Wait for completion */ store_queue_barrier(); } +EXPORT_SYMBOL(sq_flush_range); static inline void sq_mapping_list_add(struct sq_mapping *map) { @@ -166,7 +167,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, map->size = size; map->name = name; - page = bitmap_find_free_region(sq_bitmap, 0x04000000, + page = bitmap_find_free_region(sq_bitmap, 0x04000000 >> PAGE_SHIFT, get_order(map->size)); if (unlikely(page < 0)) { ret = -ENOSPC; @@ -193,6 +194,7 @@ out: kmem_cache_free(sq_cache, map); return ret; } +EXPORT_SYMBOL(sq_remap); /** * sq_unmap - Unmap a Store Queue allocation @@ -234,6 +236,7 @@ void sq_unmap(unsigned long vaddr) kmem_cache_free(sq_cache, map); } +EXPORT_SYMBOL(sq_unmap); /* * Needlessly complex sysfs interface. Unfortunately it doesn't seem like @@ -402,7 +405,3 @@ module_exit(sq_api_exit); MODULE_AUTHOR("Paul Mundt , M. R. Brown "); MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(sq_remap); -EXPORT_SYMBOL(sq_unmap); -EXPORT_SYMBOL(sq_flush_range); -- cgit v1.2.3 From bca7c20764c83a44c7b8b0831089922d56a3a9a2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 12:14:11 +0900 Subject: sh: Get the PGD right in oops case with 64-bit PTEs. Previously this was using a static pgd shift in the reporting code, simply flip this to PGDIR_SHIFT which does the right thing depending on varying PTE magnitudes on the SH-X2 MMU. While we're at it, and since it's been recently added, use get_TTB() for fetching the TTB, rather than the open coded instructions. Signed-off-by: Paul Mundt --- arch/sh/mm/fault.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 123fb80c859..cfeefc10e25 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -174,11 +174,9 @@ no_context: printk(KERN_ALERT "Unable to handle kernel paging request"); printk(" at virtual address %08lx\n", address); printk(KERN_ALERT "pc = %08lx\n", regs->pc); - asm volatile("mov.l %1, %0" - : "=r" (page) - : "m" (__m(MMU_TTB))); + page = (unsigned long)get_TTB(); if (page) { - page = ((unsigned long *) page)[address >> 22]; + page = ((unsigned long *) page)[address >> PGDIR_SHIFT]; printk(KERN_ALERT "*pde = %08lx\n", page); if (page & _PAGE_PRESENT) { page &= PAGE_MASK; -- cgit v1.2.3 From e74b56800e78a10bc09b56a87831876a1d9d09ae Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 13:12:05 +0900 Subject: sh: Turn off IRQs around get_timer_offset() calls. Since all of the sys_timer sources currently do this on their own within the ->get_offset() path, it's more sensible to just have the caller take care of it when grabbing xtime_lock. Incidentally, this is more in line with what others (ie, ARM) are doing already. Signed-off-by: Paul Mundt --- arch/sh/kernel/time.c | 13 +++++++++---- arch/sh/kernel/timers/timer-cmt.c | 9 +-------- arch/sh/kernel/timers/timer-mtu2.c | 10 +--------- arch/sh/kernel/timers/timer-tmu.c | 9 +-------- 4 files changed, 12 insertions(+), 29 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 57e708d7b52..c55d6f217a4 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -50,15 +50,20 @@ unsigned long long __attribute__ ((weak)) sched_clock(void) #ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { + unsigned long flags; unsigned long seq; unsigned long usec, sec; do { - seq = read_seqbegin(&xtime_lock); + /* + * Turn off IRQs when grabbing xtime_lock, so that + * the sys_timer get_offset code doesn't have to handle it. + */ + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = get_timer_offset(); sec = xtime.tv_sec; - usec += xtime.tv_nsec / 1000; - } while (read_seqretry(&xtime_lock, seq)); + usec += xtime.tv_nsec / NSEC_PER_USEC; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); while (usec >= 1000000) { usec -= 1000000; @@ -85,7 +90,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * get_timer_offset(); + nsec -= get_timer_offset() * NSEC_PER_USEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 24b03996da5..95581dccbbf 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -46,13 +45,9 @@ #error "Unknown CPU SUBTYPE" #endif -static DEFINE_SPINLOCK(cmt0_lock); - static unsigned long cmt_timer_get_offset(void) { int count; - unsigned long flags; - static unsigned short count_p = 0xffff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -61,7 +56,6 @@ static unsigned long cmt_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&cmt0_lock, flags); /* timer count may underflow right here */ count = ctrl_inw(CMT_CMCOR_0); count -= ctrl_inw(CMT_CMCNT_0); @@ -88,7 +82,6 @@ static unsigned long cmt_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&cmt0_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -122,7 +115,7 @@ static irqreturn_t cmt_timer_interrupt(int irq, void *dev_id) static struct irqaction cmt_irq = { .name = "timer", .handler = cmt_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 92c98b5b11e..201f0a62132 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -28,9 +27,6 @@ * However, we can implement channel cascade if we go the overflow route and * get away with using 2 MTU2 channels as a 32-bit timer. */ - -static DEFINE_SPINLOCK(mtu2_lock); - #define MTU2_TSTR 0xfffe4280 #define MTU2_TCR_1 0xfffe4380 #define MTU2_TMDR_1 0xfffe4381 @@ -55,8 +51,6 @@ static DEFINE_SPINLOCK(mtu2_lock); static unsigned long mtu2_timer_get_offset(void) { int count; - unsigned long flags; - static int count_p = 0x7fff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -65,7 +59,6 @@ static unsigned long mtu2_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&mtu2_lock, flags); /* timer count may underflow right here */ count = ctrl_inw(MTU2_TCNT_1); /* read the latched count */ @@ -90,7 +83,6 @@ static unsigned long mtu2_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&mtu2_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -118,7 +110,7 @@ static irqreturn_t mtu2_timer_interrupt(int irq, void *dev_id) static struct irqaction mtu2_irq = { .name = "timer", .handler = mtu2_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 06a70db7386..b9ed8a38755 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -31,13 +30,9 @@ #define TMU0_TCR_CALIB 0x0000 -static DEFINE_SPINLOCK(tmu0_lock); - static unsigned long tmu_timer_get_offset(void) { int count; - unsigned long flags; - static int count_p = 0x7fffffff; /* for the first call after boot */ static unsigned long jiffies_p = 0; @@ -46,7 +41,6 @@ static unsigned long tmu_timer_get_offset(void) */ unsigned long jiffies_t; - spin_lock_irqsave(&tmu0_lock, flags); /* timer count may underflow right here */ count = ctrl_inl(TMU0_TCNT); /* read the latched count */ @@ -72,7 +66,6 @@ static unsigned long tmu_timer_get_offset(void) jiffies_p = jiffies_t; count_p = count; - spin_unlock_irqrestore(&tmu0_lock, flags); count = ((LATCH-1) - count) * TICK_SIZE; count = (count + LATCH/2) / LATCH; @@ -106,7 +99,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) static struct irqaction tmu_irq = { .name = "timer", .handler = tmu_timer_interrupt, - .flags = IRQF_DISABLED, + .flags = IRQF_DISABLED | IRQF_TIMER, .mask = CPU_MASK_NONE, }; -- cgit v1.2.3 From 1d118562c2067a42d0e8f70671a4ce27d7c6ffee Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 13:15:14 +0900 Subject: sh: Clock framework tidying. This syncs up the SH clock framework with the linux/clk.h API, for which there were only some minor changes required, namely the clk_get() dev_id and subsequent callsites. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/clock.c | 27 +++++++++++++++++++++++++-- arch/sh/kernel/cpu/sh3/clock-sh7709.c | 2 +- arch/sh/kernel/cpu/sh4/clock-sh4-202.c | 4 ++-- arch/sh/kernel/cpu/sh4/clock-sh7780.c | 2 +- arch/sh/kernel/timers/timer-cmt.c | 4 ++-- arch/sh/kernel/timers/timer-mtu2.c | 2 +- arch/sh/kernel/timers/timer-tmu.c | 2 +- 7 files changed, 33 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 51ec64cdf34..abb586b1256 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -5,9 +5,11 @@ * * This clock framework is derived from the OMAP version by: * - * Copyright (C) 2004 Nokia Corporation + * Copyright (C) 2004 - 2005 Nokia Corporation * Written by Tuukka Tikkanen * + * Modified for omap shared clock framework by Tony Lindgren + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -20,6 +22,7 @@ #include #include #include +#include #include #include @@ -195,17 +198,37 @@ void clk_recalc_rate(struct clk *clk) propagate_rate(clk); } -struct clk *clk_get(const char *id) +/* + * Returns a clock. Note that we first try to use device id on the bus + * and clock name. If this fails, we try to use clock name only. + */ +struct clk *clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); + int idno; + + if (dev == NULL || dev->bus != &platform_bus_type) + idno = -1; + else + idno = to_platform_device(dev)->id; mutex_lock(&clock_list_sem); + list_for_each_entry(p, &clock_list, node) { + if (p->id == idno && + strcmp(id, p->name) == 0 && try_module_get(p->owner)) { + clk = p; + goto found; + } + } + list_for_each_entry(p, &clock_list, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } + +found: mutex_unlock(&clock_list_sem); return clk; diff --git a/arch/sh/kernel/cpu/sh3/clock-sh7709.c b/arch/sh/kernel/cpu/sh3/clock-sh7709.c index 10461a745e5..b791a29fdb6 100644 --- a/arch/sh/kernel/cpu/sh3/clock-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/clock-sh7709.c @@ -24,7 +24,7 @@ static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; static void set_bus_parent(struct clk *clk) { - struct clk *bus_clk = clk_get("bus_clk"); + struct clk *bus_clk = clk_get(NULL, "bus_clk"); clk->parent = bus_clk; clk_put(bus_clk); } diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index bfdf5fe8d94..fa2019aabd7 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c @@ -97,7 +97,7 @@ static void shoc_clk_recalc(struct clk *clk) static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) { - struct clk *bclk = clk_get("bus_clk"); + struct clk *bclk = clk_get(NULL, "bus_clk"); unsigned long bclk_rate = clk_get_rate(bclk); clk_put(bclk); @@ -151,7 +151,7 @@ static struct clk *sh4202_onchip_clocks[] = { static int __init sh4202_clk_init(void) { - struct clk *clk = clk_get("master_clk"); + struct clk *clk = clk_get(NULL, "master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c index 93ad367342c..9e6a216750c 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh7780.c @@ -98,7 +98,7 @@ static struct clk *sh7780_onchip_clocks[] = { static int __init sh7780_clk_init(void) { - struct clk *clk = clk_get("master_clk"); + struct clk *clk = clk_get(NULL, "master_clk"); int i; for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c index 95581dccbbf..a574b93a4e7 100644 --- a/arch/sh/kernel/timers/timer-cmt.c +++ b/arch/sh/kernel/timers/timer-cmt.c @@ -124,7 +124,7 @@ static void cmt_clk_init(struct clk *clk) u8 divisor = CMT_CMCSR_INIT & 0x3; ctrl_inw(CMT_CMCSR_0); ctrl_outw(CMT_CMCSR_INIT, CMT_CMCSR_0); - clk->parent = clk_get("module_clk"); + clk->parent = clk_get(NULL, "module_clk"); clk->rate = clk->parent->rate / (8 << (divisor << 1)); } @@ -164,7 +164,7 @@ static int cmt_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &cmt_irq); - cmt0_clk.parent = clk_get("module_clk"); + cmt0_clk.parent = clk_get(NULL, "module_clk"); cmt_timer_stop(); diff --git a/arch/sh/kernel/timers/timer-mtu2.c b/arch/sh/kernel/timers/timer-mtu2.c index 201f0a62132..fffcd1c0987 100644 --- a/arch/sh/kernel/timers/timer-mtu2.c +++ b/arch/sh/kernel/timers/timer-mtu2.c @@ -161,7 +161,7 @@ static int mtu2_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &mtu2_irq); - mtu2_clk1.parent = clk_get("module_clk"); + mtu2_clk1.parent = clk_get(NULL, "module_clk"); ctrl_outb(ctrl_inb(STBCR3) & (~0x20), STBCR3); diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index b9ed8a38755..e060e71d078 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c @@ -144,7 +144,7 @@ static int tmu_timer_init(void) setup_irq(CONFIG_SH_TIMER_IRQ, &tmu_irq); - tmu0_clk.parent = clk_get("module_clk"); + tmu0_clk.parent = clk_get(NULL, "module_clk"); /* Start TMU0 */ tmu_timer_stop(); -- cgit v1.2.3 From bd156147eb63ae525e0ac67868e41a808f03c532 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 1 Dec 2006 13:23:47 +0900 Subject: sh: dyntick infrastructure. This adds basic NO_IDLE_HZ support to the SH timer API so timers are able to wire it up. Taken from the ARM version, as it fit in to our API with very few changes needed. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 18 ++++++++ arch/sh/kernel/time.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 48308dc86e3..aa1ebc561b8 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -423,6 +423,24 @@ config SH_TIMER_IRQ default "140" if CPU_SUBTYPE_SH7206 default "16" +config NO_IDLE_HZ + bool "Dynamic tick timer" + help + Select this option if you want to disable continuous timer ticks + and have them programmed to occur as required. This option saves + power as the system can remain in idle state for longer. + + By default dynamic tick is disabled during the boot, and can be + manually enabled with: + + echo 1 > /sys/devices/system/timer/timer0/dyn_tick + + Alternatively, if you want dynamic tick automatically enabled + during boot, pass "dyntick=enable" via the kernel command string. + + Please note that dynamic tick may affect the accuracy of + timekeeping on some platforms depending on the implementation. + config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index c55d6f217a4..1b91c721497 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -174,6 +174,108 @@ static struct sysdev_class timer_sysclass = { .resume = timer_resume, }; +#ifdef CONFIG_NO_IDLE_HZ +static int timer_dyn_tick_enable(void) +{ + struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; + unsigned long flags; + int ret = -ENODEV; + + if (dyn_tick) { + spin_lock_irqsave(&dyn_tick->lock, flags); + ret = 0; + if (!(dyn_tick->state & DYN_TICK_ENABLED)) { + ret = dyn_tick->enable(); + + if (ret == 0) + dyn_tick->state |= DYN_TICK_ENABLED; + } + spin_unlock_irqrestore(&dyn_tick->lock, flags); + } + + return ret; +} + +static int timer_dyn_tick_disable(void) +{ + struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; + unsigned long flags; + int ret = -ENODEV; + + if (dyn_tick) { + spin_lock_irqsave(&dyn_tick->lock, flags); + ret = 0; + if (dyn_tick->state & DYN_TICK_ENABLED) { + ret = dyn_tick->disable(); + + if (ret == 0) + dyn_tick->state &= ~DYN_TICK_ENABLED; + } + spin_unlock_irqrestore(&dyn_tick->lock, flags); + } + + return ret; +} + +/* + * Reprogram the system timer for at least the calculated time interval. + * This function should be called from the idle thread with IRQs disabled, + * immediately before sleeping. + */ +void timer_dyn_reprogram(void) +{ + struct dyn_tick_timer *dyn_tick = sys_timer->dyn_tick; + unsigned long next, seq, flags; + + if (!dyn_tick) + return; + + spin_lock_irqsave(&dyn_tick->lock, flags); + if (dyn_tick->state & DYN_TICK_ENABLED) { + next = next_timer_interrupt(); + do { + seq = read_seqbegin(&xtime_lock); + dyn_tick->reprogram(next - jiffies); + } while (read_seqretry(&xtime_lock, seq)); + } + spin_unlock_irqrestore(&dyn_tick->lock, flags); +} + +static ssize_t timer_show_dyn_tick(struct sys_device *dev, char *buf) +{ + return sprintf(buf, "%i\n", + (sys_timer->dyn_tick->state & DYN_TICK_ENABLED) >> 1); +} + +static ssize_t timer_set_dyn_tick(struct sys_device *dev, const char *buf, + size_t count) +{ + unsigned int enable = simple_strtoul(buf, NULL, 2); + + if (enable) + timer_dyn_tick_enable(); + else + timer_dyn_tick_disable(); + + return count; +} +static SYSDEV_ATTR(dyn_tick, 0644, timer_show_dyn_tick, timer_set_dyn_tick); + +/* + * dyntick=enable|disable + */ +static char dyntick_str[4] __initdata = ""; + +static int __init dyntick_setup(char *str) +{ + if (str) + strlcpy(dyntick_str, str, sizeof(dyntick_str)); + return 1; +} + +__setup("dyntick=", dyntick_setup); +#endif + static int __init timer_init_sysfs(void) { int ret = sysdev_class_register(&timer_sysclass); @@ -181,7 +283,22 @@ static int __init timer_init_sysfs(void) return ret; sys_timer->dev.cls = &timer_sysclass; - return sysdev_register(&sys_timer->dev); + ret = sysdev_register(&sys_timer->dev); + +#ifdef CONFIG_NO_IDLE_HZ + if (ret == 0 && sys_timer->dyn_tick) { + ret = sysdev_create_file(&sys_timer->dev, &attr_dyn_tick); + + /* + * Turn on dynamic tick after calibrate delay + * for correct bogomips + */ + if (ret == 0 && dyntick_str[0] == 'e') + ret = timer_dyn_tick_enable(); + } +#endif + + return ret; } device_initcall(timer_init_sysfs); @@ -205,6 +322,11 @@ void __init time_init(void) sys_timer = get_sys_timer(); printk(KERN_INFO "Using %s for system timer\n", sys_timer->name); +#ifdef CONFIG_NO_IDLE_HZ + if (sys_timer->dyn_tick) + spin_lock_init(&sys_timer->dyn_tick->lock); +#endif + #if defined(CONFIG_SH_KGDB) /* * Set up kgdb as requested. We do it here because the serial -- cgit v1.2.3 From afbfb52e47273a440df33274452c603e8c332de2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 4 Dec 2006 18:17:28 +0900 Subject: sh: stacktrace/lockdep/irqflags tracing support. Wire up all of the essentials for lockdep.. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 8 ++++++ arch/sh/Kconfig.debug | 4 +++ arch/sh/kernel/Makefile | 1 + arch/sh/kernel/cpu/sh2/entry.S | 16 +++++++++++ arch/sh/kernel/cpu/sh3/entry.S | 2 +- arch/sh/kernel/entry-common.S | 64 +++++++++++++++++++++++++++++++++++++++++- arch/sh/kernel/stacktrace.c | 43 ++++++++++++++++++++++++++++ arch/sh/mm/fault.c | 3 ++ 8 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 arch/sh/kernel/stacktrace.c (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index aa1ebc561b8..013732074d3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -51,6 +51,14 @@ config GENERIC_TIME config ARCH_MAY_HAVE_PC_FDC bool +config STACKTRACE_SUPPORT + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + source "init/Kconfig" menu "System type" diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index dcceec95a2d..66a25ef4ef1 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -1,5 +1,9 @@ menu "Kernel hacking" +config TRACE_IRQFLAGS_SUPPORT + bool + default y + source "lib/Kconfig.debug" config SH_STANDARD_BIOS diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index 50d54c24d76..99c7e5249f7 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_APM) += apm.o obj-$(CONFIG_PM) += pm.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index 298d9191909..34d51b3745e 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -184,6 +184,11 @@ trap_entry: add r15,r8 mov.l r9,@r8 mov r9,r8 +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r9 + jsr @r9 + nop +#endif sti bra system_call nop @@ -193,6 +198,9 @@ trap_entry: 2: .long break_point_trap_software 3: .long NR_syscalls 4: .long sys_call_table +#ifdef CONFIG_TRACE_IRQFLAGS +5: .long trace_hardirqs_on +#endif #if defined(CONFIG_SH_STANDARD_BIOS) /* Unwind the stack and jmp to the debug entry */ @@ -255,6 +263,11 @@ ENTRY(address_error_handler) restore_all: cli +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 3f, r0 + jsr @r0 + nop +#endif mov r15,r0 mov.l $cpu_mode,r2 mov #OFF_SR,r3 @@ -307,6 +320,9 @@ $current_thread_info: .long __current_thread_info $cpu_mode: .long __cpu_mode +#ifdef CONFIG_TRACE_IRQFLAGS +3: .long trace_hardirqs_off +#endif ! common exception handler #include "../../entry-common.S" diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 7ba3dcbe750..8c0dc2700c6 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -140,7 +140,7 @@ call_dpf: mov.l 1f, r0 mov.l @r0, r6 ! address mov.l 3f, r0 - sti + jmp @r0 mov r15, r4 ! regs diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 8f96d21fcb1..29136a35d7c 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -100,6 +100,11 @@ debug_trap: .align 2 ENTRY(exception_error) ! +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 3f, r0 + jsr @r0 + nop +#endif sti mov.l 2f, r0 jmp @r0 @@ -109,10 +114,18 @@ ENTRY(exception_error) .align 2 1: .long break_point_trap_software 2: .long do_exception_error +#ifdef CONFIG_TRACE_IRQFLAGS +3: .long trace_hardirqs_on +#endif .align 2 ret_from_exception: preempt_stop() +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 4f, r0 + jsr @r0 + nop +#endif ENTRY(ret_from_irq) ! mov #OFF_SR, r0 @@ -143,6 +156,11 @@ need_resched: mov.l 1f, r0 mov.l r0, @(TI_PRE_COUNT,r8) +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 3f, r0 + jsr @r0 + nop +#endif sti mov.l 2f, r0 jsr @r0 @@ -150,9 +168,15 @@ need_resched: mov #0, r0 mov.l r0, @(TI_PRE_COUNT,r8) cli +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 4f, r0 + jsr @r0 + nop +#endif bra need_resched nop + noresched: bra __restore_all nop @@ -160,11 +184,20 @@ noresched: .align 2 1: .long PREEMPT_ACTIVE 2: .long schedule +#ifdef CONFIG_TRACE_IRQFLAGS +3: .long trace_hardirqs_on +4: .long trace_hardirqs_off +#endif #endif ENTRY(resume_userspace) ! r8: current_thread_info cli +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r0 + jsr @r0 + nop +#endif mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags tst #_TIF_WORK_MASK, r0 bt/s __restore_all @@ -210,6 +243,11 @@ work_resched: jsr @r1 ! schedule nop cli +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r0 + jsr @r0 + nop +#endif ! mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags tst #_TIF_WORK_MASK, r0 @@ -221,6 +259,10 @@ work_resched: 1: .long schedule 2: .long do_notify_resume 3: .long restore_all +#ifdef CONFIG_TRACE_IRQFLAGS +4: .long trace_hardirqs_on +5: .long trace_hardirqs_off +#endif .align 2 syscall_exit_work: @@ -229,6 +271,11 @@ syscall_exit_work: tst #_TIF_SYSCALL_TRACE, r0 bt/s work_pending tst #_TIF_NEED_RESCHED, r0 +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r0 + jsr @r0 + nop +#endif sti ! XXX setup arguments... mov.l 4f, r0 ! do_syscall_trace @@ -265,7 +312,7 @@ syscall_trace_entry: mov.l r0, @(OFF_R0,r15) ! Return value __restore_all: - mov.l 1f,r0 + mov.l 1f, r0 jmp @r0 nop @@ -331,7 +378,13 @@ ENTRY(system_call) mov #OFF_TRA, r9 add r15, r9 mov.l r8, @r9 ! set TRA value to tra +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 5f, r10 + jsr @r10 + nop +#endif sti + ! get_current_thread_info r8, r10 mov.l @(TI_FLAGS,r8), r8 @@ -355,6 +408,11 @@ syscall_call: ! syscall_exit: cli +#ifdef CONFIG_TRACE_IRQFLAGS + mov.l 6f, r0 + jsr @r0 + nop +#endif ! get_current_thread_info r8, r0 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags @@ -369,3 +427,7 @@ syscall_exit: 2: .long NR_syscalls 3: .long sys_call_table 4: .long do_syscall_trace +#ifdef CONFIG_TRACE_IRQFLAGS +5: .long trace_hardirqs_on +6: .long trace_hardirqs_off +#endif diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c new file mode 100644 index 00000000000..0d5268afe80 --- /dev/null +++ b/arch/sh/kernel/stacktrace.c @@ -0,0 +1,43 @@ +/* + * arch/sh/kernel/stacktrace.c + * + * Stack trace management functions + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + */ +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + unsigned long *sp; + + if (!task) + task = current; + if (task == current) + sp = (unsigned long *)current_stack_pointer; + else + sp = (unsigned long *)task->thread.sp; + + while (!kstack_end(sp)) { + unsigned long addr = *sp++; + + if (__kernel_text_address(addr)) { + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = addr; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +} diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index cfeefc10e25..716ebf568af 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -37,6 +37,9 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, int si_code; siginfo_t info; + trace_hardirqs_on(); + local_irq_enable(); + #ifdef CONFIG_SH_KGDB if (kgdb_nofault && kgdb_bus_err_hook) kgdb_bus_err_hook(); -- cgit v1.2.3 From 0c020e3dfb9429a3b31669a5ac2b86dd675c1ad2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 10:43:44 +0900 Subject: sh: platform_pata support for R7780RP This adds a platform device for the directly connected CF interface on R7780RP boards, for use with the pata_platform libata driver. Signed-off-by: Paul Mundt --- arch/sh/boards/renesas/r7780rp/setup.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/sh/boards/renesas/r7780rp/setup.c b/arch/sh/boards/renesas/r7780rp/setup.c index c331caeb694..9f89c8de9db 100644 --- a/arch/sh/boards/renesas/r7780rp/setup.c +++ b/arch/sh/boards/renesas/r7780rp/setup.c @@ -44,8 +44,37 @@ static struct platform_device m66596_usb_host_device = { .resource = m66596_usb_host_resources, }; +static struct resource cf_ide_resources[] = { + [0] = { + .start = 0x1f0, + .end = 0x1f0 + 8, + .flags = IORESOURCE_IO, + }, + [1] = { + .start = 0x1f0 + 0x206, + .end = 0x1f0 + 8 + 0x206 + 8, + .flags = IORESOURCE_IO, + }, + [2] = { +#ifdef CONFIG_SH_R7780MP + .start = 1, +#else + .start = 4, +#endif + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, +}; + static struct platform_device *r7780rp_devices[] __initdata = { &m66596_usb_host_device, + &cf_ide_device, }; static int __init r7780rp_devices_setup(void) -- cgit v1.2.3 From 9b8c90eb0d916f6802f8bbac79f61aca6ac533e8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 11:07:51 +0900 Subject: sh: show held locks in stack trace with lockdep. Follows the same change as other architectures.. Signed-off-by: Paul Mundt --- arch/sh/kernel/traps.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 0ee298079d8..3762d9dc204 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -872,6 +873,11 @@ void show_trace(struct task_struct *tsk, unsigned long *sp, } printk("\n"); + + if (!tsk) + tsk = current; + + debug_show_held_locks(tsk); } void show_stack(struct task_struct *tsk, unsigned long *sp) -- cgit v1.2.3 From f36af73304555849985b1fb5c0821c1bfab3a5a0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 11:08:49 +0900 Subject: sh: set KBUILD_IMAGE to something sensible. This was missing for sh too, wire it up.. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 7f4516c3f83..d10bba5e107 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -58,7 +58,9 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -R .stab -R .stabstr -S # never be used by anyone. Use a board-specific defconfig that has a # reasonable chance of being current instead. # -KBUILD_DEFCONFIG := rts7751r2d_defconfig +KBUILD_DEFCONFIG := r7780rp_defconfig + +KBUILD_IMAGE := arch/sh/boot/zImage # # Choosing incompatible machines durings configuration will result in -- cgit v1.2.3 From 65e5d90de6dba9975332dac4f849b81f663e16fa Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 11:24:48 +0900 Subject: sh: compile fixes for header cleanup. Since some header inclusion paths were cleaned up, compilation broke. Add in the headers we need directly to build again. Signed-off-by: Paul Mundt --- arch/sh/kernel/time.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 1b91c721497..c206c9504c4 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include -- cgit v1.2.3 From fe9687dec0400c6de7187ab5efa91facd958ca84 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 12:02:01 +0900 Subject: sh: update r7780rp defconfig. Signed-off-by: Paul Mundt --- arch/sh/configs/r7780rp_defconfig | 69 +++++++++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/sh/configs/r7780rp_defconfig b/arch/sh/configs/r7780rp_defconfig index 34e2046c321..2b75b4896ba 100644 --- a/arch/sh/configs/r7780rp_defconfig +++ b/arch/sh/configs/r7780rp_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc3 -# Tue Oct 31 12:32:06 2006 +# Linux kernel version: 2.6.19 +# Wed Dec 6 11:59:38 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,6 +11,8 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -37,6 +39,7 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_SYSFS_DEPRECATED is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -118,6 +121,8 @@ CONFIG_SH_R7780RP=y # CONFIG_SH_LANDISK is not set # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set # CONFIG_SH_UNKNOWN is not set # @@ -130,6 +135,12 @@ CONFIG_CPU_SH4A=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -165,6 +176,7 @@ CONFIG_CPU_SH4A=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set CONFIG_CPU_SUBTYPE_SH7780=y +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -181,8 +193,14 @@ CONFIG_MEMORY_START=0x08000000 CONFIG_MEMORY_SIZE=0x08000000 # CONFIG_32BIT is not set CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_HUGETLB_PAGE_SIZE_64K=y +# CONFIG_HUGETLB_PAGE_SIZE_256K is not set # CONFIG_HUGETLB_PAGE_SIZE_1MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set +# CONFIG_HUGETLB_PAGE_SIZE_64MB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -204,12 +222,14 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set CONFIG_SH_STORE_QUEUES=y CONFIG_CPU_HAS_INTEVT=y CONFIG_CPU_HAS_INTC2_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y # # Timer support @@ -220,6 +240,8 @@ CONFIG_SH_TMU=y # R7780RP options # CONFIG_SH_R7780MP=y +CONFIG_SH_TIMER_IRQ=28 +CONFIG_NO_IDLE_HZ=y CONFIG_SH_PCLK_FREQ=32000000 # @@ -237,6 +259,11 @@ CONFIG_SH_PCLK_FREQ=32000000 # # CONFIG_HD6446X_SERIES is not set +# +# Additional SuperH Device Drivers +# +CONFIG_PUSH_SWITCH=y + # # Kernel features # @@ -244,7 +271,7 @@ CONFIG_SH_PCLK_FREQ=32000000 CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set CONFIG_HZ=250 -# CONFIG_KEXEC is not set +CONFIG_KEXEC=y # CONFIG_SMP is not set # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set @@ -278,10 +305,7 @@ CONFIG_PCI_AUTO_UPDATE_RESOURCES=y # # PCI Hotplug Support # -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_FAKE is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set +# CONFIG_HOTPLUG_PCI is not set # # Executable file formats @@ -341,6 +365,7 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set @@ -556,6 +581,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -572,6 +598,7 @@ CONFIG_SATA_SIL=y # CONFIG_PATA_SIS is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set +CONFIG_PATA_PLATFORM=y # # Multi-device support (RAID and LVM) @@ -688,6 +715,7 @@ CONFIG_R8169=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -830,10 +858,6 @@ CONFIG_HW_RANDOM=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -1020,7 +1044,7 @@ CONFIG_INOTIFY_USER=y CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set +CONFIG_FUSE_FS=m # # CD-ROM/DVD Filesystems @@ -1052,7 +1076,7 @@ CONFIG_TMPFS=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set +CONFIG_CONFIGFS_FS=m # # Miscellaneous filesystems @@ -1153,28 +1177,33 @@ CONFIG_NLS_ISO8859_1=y # # Profiling support # -# CONFIG_PROFILING is not set +CONFIG_PROFILING=y +CONFIG_OPROFILE=m # # Kernel hacking # -# CONFIG_PRINTK_TIME is not set +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_PRINTK_TIME=y CONFIG_ENABLE_MUST_CHECK=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_SPINLOCK=y +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set @@ -1184,7 +1213,7 @@ CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_SH_STANDARD_BIOS is not set # CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_DEBUG_STACKOVERFLOW is not set +CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_4KSTACKS is not set # CONFIG_KGDB is not set -- cgit v1.2.3 From ea0f8feaa041f3ccec3d6b8ee51325b177daef06 Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Wed, 6 Dec 2006 12:05:02 +0900 Subject: sh: sh775x/titan fixes for irq header changes. The following moves the creation of IPR interupts into setup-7750.c and updates a few other things to make it all work after the "Drop CPU subtype IRQ headers" commit. It boots and runs fine on my titan board. - adds an ipr_idx to the ipr_data and uses a function in the subtype code to calculate the address of the IPR registers - adds a function to enable individual interrupt mode for externals in the subtype code and calls that from the titan board code instead of doing it directly. - I changed the shift in the ipr_data to be the actual # of bits to shift, instead of the numnber / 4 - made it easier to match with the manual. Signed-off-by: Jamie Lenehan Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 3 + arch/sh/boards/titan/setup.c | 27 +++++---- arch/sh/drivers/pci/ops-titan.c | 24 ++++---- arch/sh/kernel/cpu/irq/Makefile | 3 +- arch/sh/kernel/cpu/irq/ipr.c | 103 ++-------------------------------- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 70 +++++++++++++++++++++++ arch/sh/kernel/irq.c | 25 ++++++++- arch/sh/mm/Kconfig | 5 ++ 8 files changed, 134 insertions(+), 126 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 013732074d3..d83d64af31f 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -375,6 +375,9 @@ config CPU_HAS_MASKREG_IRQ config CPU_HAS_INTC2_IRQ bool +config CPU_HAS_IPR_IRQ + bool + config CPU_HAS_SR_RB bool "CPU has SR.RB" depends on CPU_SH3 || CPU_SH4 diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index a6046d93758..6bcd939bfae 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c @@ -1,26 +1,30 @@ /* - * Setup for Titan + * arch/sh/boards/titan/setup.c - Setup for Titan + * + * Copyright (C) 2006 Jamie Lenehan + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ - #include -#include +#include #include #include -extern void __init pcibios_init_platform(void); - static struct ipr_data titan_ipr_map[] = { - { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, - { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, - { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, - { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, + /* IRQ, IPR idx, shift, prio */ + { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ + { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ + { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */ + { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ }; static void __init init_titan_irq(void) { /* enable individual interrupt mode for externals */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - + ipr_irq_enable_irlm(); + /* register ipr irqs */ make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); } @@ -47,6 +51,5 @@ struct sh_machine_vector mv_titan __initmv = { .mv_ioport_map = titan_ioport_map, .mv_init_irq = init_titan_irq, - .mv_init_pci = pcibios_init_platform, }; ALIAS_MV(titan) diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c index cd56d53375e..ac8ee2312cd 100644 --- a/arch/sh/drivers/pci/ops-titan.c +++ b/arch/sh/drivers/pci/ops-titan.c @@ -15,25 +15,21 @@ #include #include #include -#include +#include #include #include "pci-sh4.h" +static char titan_irq_tab[] __initdata = { + TITAN_IRQ_WAN, + TITAN_IRQ_LAN, + TITAN_IRQ_MPCIA, + TITAN_IRQ_MPCIB, + TITAN_IRQ_USB, +}; + int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { - int irq = -1; - - switch (slot) { - case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */ - case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */ - case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */ - case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */ - case 4: irq = TITAN_IRQ_USB; break; /* USB */ - default: - printk(KERN_INFO "PCI: Bad IRQ mapping " - "request for slot %d\n", slot); - return -1; - } + int irq = titan_irq_tab[slot]; printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", slot, pin - 1 + 'A', irq); diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 1c034c283f5..0049d217561 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile @@ -1,8 +1,9 @@ # # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. # -obj-y += ipr.o imask.o +obj-y += imask.o +obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index a181ccdf290..35eb5751a3a 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -25,17 +25,15 @@ static void disable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); - int shift = p->shift*4; /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr); + ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); } static void enable_ipr_irq(unsigned int irq) { struct ipr_data *p = get_irq_chip_data(irq); - int shift = p->shift*4; /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr); + ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); } static struct irq_chip ipr_irq_chip = { @@ -51,6 +49,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) for (i = 0; i < nr_irqs; i++) { unsigned int irq = table[i].irq; + table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); + /* could the IPR index be mapped, if not we ignore this */ + if (table[i].addr == 0) + continue; disable_irq_nosync(irq); set_irq_chip_and_handler_name(irq, &ipr_irq_chip, handle_level_irq, "level"); @@ -60,99 +62,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) } EXPORT_SYMBOL(make_ipr_irq); -/* - * XXX: Move this garbage in to the drivers, and kill off the ridiculous CPU - * subtype checks. - */ -static struct ipr_data sys_ipr_map[] = { -#ifndef CONFIG_CPU_SUBTYPE_SH7780 - { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, - { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY }, -#ifdef RTC_IRQ - { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY }, -#endif -#ifdef SCI_ERI_IRQ - { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, - { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, - { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, -#endif -#ifdef SCIF1_ERI_IRQ - { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, - { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, -#endif -#ifdef SCIF2_ERI_IRQ - { SCIF2_ERI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, - { SCIF2_RXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, - { SCIF2_BRI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, - { SCIF2_TXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, -#endif -#ifdef SCIF3_ERI_IRQ - { SCIF3_ERI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, - { SCIF3_RXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, - { SCIF3_BRI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, - { SCIF3_TXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7300) - { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, - { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, - { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, -#endif -#ifdef SCIF_ERI_IRQ - { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, - { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, -#endif -#ifdef IRDA_ERI_IRQ - { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, - { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) - /* - * Initialize the Interrupt Controller (INTC) - * registers to their power on values - */ - - /* - * Enable external irq (INTC IRQ mode). - * You should set corresponding bits of PFC to "00" - * to enable these interrupts. - */ - { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY }, - { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, - { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, - { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY }, - { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY }, - { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY }, -#endif -#endif -}; - -void __init init_IRQ(void) -{ - make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map)); - -#ifdef CONFIG_CPU_HAS_PINT_IRQ - init_IRQ_pint(); -#endif - -#ifdef CONFIG_CPU_HAS_INTC2_IRQ - init_IRQ_intc2(); -#endif - /* Perform the machine specific initialisation */ - if (sh_mv.mv_init_irq != NULL) - sh_mv.mv_init_irq(); - - irq_ctx_init(smp_processor_id()); -} - #if !defined(CONFIG_CPU_HAS_PINT_IRQ) int ipr_irq_demux(int irq) { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 50812d57c1c..bbcb06f18b0 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -2,6 +2,7 @@ * SH7750/SH7751 Setup * * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2006 Jamie Lenehan * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -10,6 +11,7 @@ #include #include #include +#include #include static struct plat_sci_port sci_platform_data[] = { @@ -46,3 +48,71 @@ static int __init sh7750_devices_setup(void) ARRAY_SIZE(sh7750_devices)); } __initcall(sh7750_devices_setup); + +static struct ipr_data sh7750_ipr_map[] = { + /* IRQ, IPR-idx, shift, priority */ + { 16, 0, 12, 2 }, /* TMU0 TUNI*/ + { 17, 0, 12, 2 }, /* TMU1 TUNI */ + { 18, 0, 4, 2 }, /* TMU2 TUNI */ + { 19, 0, 4, 2 }, /* TMU2 TIPCI */ + { 27, 1, 12, 2 }, /* WDT ITI */ + { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ + { 21, 0, 0, 2 }, /* RTC PRI (period) */ + { 22, 0, 0, 2 }, /* RTC CUI (carry) */ + { 23, 1, 4, 3 }, /* SCI ERI */ + { 24, 1, 4, 3 }, /* SCI RXI */ + { 25, 1, 4, 3 }, /* SCI TXI */ + { 40, 2, 4, 3 }, /* SCIF ERI */ + { 41, 2, 4, 3 }, /* SCIF RXI */ + { 42, 2, 4, 3 }, /* SCIF BRI */ + { 43, 2, 4, 3 }, /* SCIF TXI */ + { 34, 2, 8, 7 }, /* DMAC DMTE0 */ + { 35, 2, 8, 7 }, /* DMAC DMTE1 */ + { 36, 2, 8, 7 }, /* DMAC DMTE2 */ + { 37, 2, 8, 7 }, /* DMAC DMTE3 */ + { 28, 2, 8, 7 }, /* DMAC DMAE */ +}; + +static struct ipr_data sh7751_ipr_map[] = { + { 44, 2, 8, 7 }, /* DMAC DMTE4 */ + { 45, 2, 8, 7 }, /* DMAC DMTE5 */ + { 46, 2, 8, 7 }, /* DMAC DMTE6 */ + { 47, 2, 8, 7 }, /* DMAC DMTE7 */ + /* The following use INTC_INPRI00 for masking, which is a 32-bit + register, not a 16-bit register like the IPRx registers, so it + would need special support */ + /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ + /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ +}; + +static unsigned long ipr_offsets[] = { + 0xffd00004UL, /* 0: IPRA */ + 0xffd00008UL, /* 1: IPRB */ + 0xffd0000cUL, /* 2: IPRC */ + 0xffd00010UL, /* 3: IPRD */ +}; + +/* given the IPR index return the address of the IPR register */ +unsigned int map_ipridx_to_addr(int idx) +{ + if (idx >= ARRAY_SIZE(ipr_offsets)) + return 0; + return ipr_offsets[idx]; +} + +#define INTC_ICR 0xffd00000UL +#define INTC_ICR_IRLM (1<<7) + +/* enable individual interrupt mode for external interupts */ +void ipr_irq_enable_irlm(void) +{ + ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); +} + +void __init init_IRQ_ipr() +{ + make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map)); +#ifdef CONFIG_CPU_SUBTYPE_SH7751 + make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map)); +#endif +} diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 46a19e07abd..67be2b6e8cd 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -112,7 +112,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif #ifdef CONFIG_CPU_HAS_INTEVT - irq = (ctrl_inl(INTEVT) >> 5) - 16; + irq = evt2irq(ctrl_inl(INTEVT)); #else irq = r4; #endif @@ -261,3 +261,24 @@ asmlinkage void do_softirq(void) } EXPORT_SYMBOL(do_softirq); #endif + +void __init init_IRQ(void) +{ +#ifdef CONFIG_CPU_HAS_PINT_IRQ + init_IRQ_pint(); +#endif + +#ifdef CONFIG_CPU_HAS_INTC2_IRQ + init_IRQ_intc2(); +#endif + +#ifdef CONFIG_CPU_HAS_IPR_IRQ + init_IRQ_ipr(); +#endif + + /* Perform the machine specific initialisation */ + if (sh_mv.mv_init_irq) + sh_mv.mv_init_irq(); + + irq_ctx_init(smp_processor_id()); +} diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 6cd6d0045d1..4e0362f5038 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -104,6 +104,7 @@ comment "SH-4 Processor Support" config CPU_SUBTYPE_SH7750 bool "Support SH7750 processor" select CPU_SH4 + select CPU_HAS_IPR_IRQ help Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. @@ -119,15 +120,18 @@ config CPU_SUBTYPE_SH7750R bool "Support SH7750R processor" select CPU_SH4 select CPU_SUBTYPE_SH7750 + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7750S bool "Support SH7750S processor" select CPU_SH4 select CPU_SUBTYPE_SH7750 + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7751 bool "Support SH7751 processor" select CPU_SH4 + select CPU_HAS_IPR_IRQ help Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, or if you have a HD6417751R CPU. @@ -136,6 +140,7 @@ config CPU_SUBTYPE_SH7751R bool "Support SH7751R processor" select CPU_SH4 select CPU_SUBTYPE_SH7751 + select CPU_HAS_IPR_IRQ config CPU_SUBTYPE_SH7760 bool "Support SH7760 processor" -- cgit v1.2.3 From deb77c8501f47ab228bf7cc7fd649e50603ed2cd Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 6 Dec 2006 11:36:59 +1000 Subject: [PATCH] m68knommu: fix timer register access on 523x ColdFire platforms The 523x timer TRR register is a full 32bits, the older register (on other ColdFire parts) was only 16 bits. Use the right type of __raw_read when accessing it. Problem found by Yaroslav Vinogradov Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/platform/5307/timers.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c index 24781f00933..e5668af1978 100644 --- a/arch/m68knommu/platform/5307/timers.c +++ b/arch/m68knommu/platform/5307/timers.c @@ -3,7 +3,7 @@ /* * timers.c -- generic ColdFire hardware timer support. * - * Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com) + * Copyright (C) 1999-2006, Greg Ungerer (gerg@snapgear.com) */ /***************************************************************************/ @@ -44,6 +44,14 @@ unsigned int mcf_timerlevel = 5; extern void mcf_settimericr(int timer, int level); extern int mcf_timerirqpending(int timer); +#if defined(CONFIG_M532x) +#define __raw_readtrr __raw_readl +#define __raw_writetrr __raw_writel +#else +#define __raw_readtrr __raw_readw +#define __raw_writetrr __raw_writew +#endif + /***************************************************************************/ void coldfire_tick(void) @@ -57,7 +65,7 @@ void coldfire_tick(void) void coldfire_timer_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)) { __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); - __raw_writew(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); + __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); @@ -76,7 +84,7 @@ unsigned long coldfire_timer_offset(void) unsigned long trr, tcn, offset; tcn = __raw_readw(TA(MCFTIMER_TCN)); - trr = __raw_readw(TA(MCFTIMER_TRR)); + trr = __raw_readtrr(TA(MCFTIMER_TRR)); offset = (tcn * (1000000 / HZ)) / trr; /* Check if we just wrapped the counters and maybe missed a tick */ @@ -120,7 +128,7 @@ void coldfire_profile_init(void) /* Set up TIMER 2 as high speed profile clock */ __raw_writew(MCFTIMER_TMR_DISABLE, PA(MCFTIMER_TMR)); - __raw_writew(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); + __raw_writetrr(((MCF_CLK / 16) / PROFILEHZ), PA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, PA(MCFTIMER_TMR)); -- cgit v1.2.3 From dcb14775493170ea60fb8b657b411cdc9532b7ee Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 6 Dec 2006 11:43:14 +1000 Subject: [PATCH] m68knommu: switch 68360 to using rtc_time Adds support for RTCs (through genrtc) for M68KNOMMU. Board-specific code will have to link the appropriate RTC driver to the mach_hwclk callback, at minimum. This patch switches the 68360 code over to using rtc_time. Signed-off-by: Gavin Lambert Signed-off-by: Greg Ungerer Signed-off-by: Linus Torvalds --- arch/m68knommu/platform/68360/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68knommu/platform/68360/config.c b/arch/m68knommu/platform/68360/config.c index c5482e3622e..1b36f626176 100644 --- a/arch/m68knommu/platform/68360/config.c +++ b/arch/m68knommu/platform/68360/config.c @@ -114,7 +114,7 @@ void BSP_gettod (int *yearp, int *monp, int *dayp, { } -int BSP_hwclk(int op, struct hwclk_time *t) +int BSP_hwclk(int op, struct rtc_time *t) { if (!op) { /* read */ -- cgit v1.2.3 From 25ba2f506c69bd54a7342210422176baf10018c5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sat, 2 Dec 2006 00:08:03 +0900 Subject: [MIPS] Do not use handle_level_irq for ioasic_dma_irq_type. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/dec/ioasic-irq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index 269b22b3431..e21476d955c 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -106,8 +106,7 @@ void __init init_ioasic_irqs(int base) set_irq_chip_and_handler(i, &ioasic_irq_type, handle_level_irq); for (; i < base + IO_IRQ_LINES; i++) - set_irq_chip_and_handler(i, &ioasic_dma_irq_type, - handle_level_irq); + set_irq_chip(i, &ioasic_dma_irq_type); ioasic_irq_base = base; } -- cgit v1.2.3 From 1ccd1c1c35a6cb21da32479931d4fa6d47320095 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 6 Dec 2006 01:20:57 +0900 Subject: [MIPS] genirq: use name instead of typename The "typename" field was obsoleted by the "name" field. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index b339798b317..2fe4c868a80 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c @@ -117,7 +117,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].chip->name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) -- cgit v1.2.3 From e77c232cfc6e1250b2916a7c69225d6634d05a49 Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Fri, 1 Dec 2006 18:22:27 +0100 Subject: [MIPS] Compile __do_IRQ() when really needed __do_IRQ() is needed only by irq handlers that can't use default handlers defined in kernel/irq/chip.c. For others platforms there's no need to compile this function since it won't be used. For those platforms this patch defines GENERIC_HARDIRQS_NO__DO_IRQ symbol which is used exactly for this purpose. Futhermore for platforms which do not use __do_IRQ(), end() method which is part of the 'irq_chip' structure is not used. This patch simply removes this method in this case. Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 9 +++++++ arch/mips/dec/ioasic-irq.c | 1 - arch/mips/dec/kn02-irq.c | 7 ------ arch/mips/emma2rh/common/irq_emma2rh.c | 7 ------ arch/mips/emma2rh/markeins/irq_markeins.c | 7 ------ arch/mips/jazz/irq.c | 7 ------ arch/mips/kernel/irq-mv6434x.c | 10 -------- arch/mips/kernel/irq-rm7000.c | 7 ------ arch/mips/kernel/irq-rm9000.c | 8 ------- arch/mips/kernel/irq_cpu.c | 10 -------- arch/mips/lasat/interrupt.c | 7 ------ arch/mips/momentum/ocelot_c/cpci-irq.c | 10 -------- arch/mips/momentum/ocelot_c/uart-irq.c | 10 -------- arch/mips/philips/pnx8550/common/int.c | 8 ------- arch/mips/sgi-ip22/ip22-int.c | 28 ---------------------- arch/mips/sgi-ip27/ip27-irq.c | 8 ------- arch/mips/sgi-ip27/ip27-timer.c | 5 ---- arch/mips/tx4927/common/tx4927_irq.c | 26 -------------------- .../tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 21 ---------------- arch/mips/tx4938/common/irq.c | 20 ---------------- arch/mips/tx4938/toshiba_rbtx4938/irq.c | 10 -------- arch/mips/vr41xx/Kconfig | 5 ++++ arch/mips/vr41xx/common/icu.c | 14 ----------- 23 files changed, 14 insertions(+), 231 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 4d64960be03..d8af858fe3f 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -242,6 +242,7 @@ config LASAT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config MIPS_ATLAS bool "MIPS Atlas board" @@ -265,6 +266,7 @@ config MIPS_ATLAS select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_MULTITHREADING if EXPERIMENTAL + select GENERIC_HARDIRQS_NO__DO_IRQ help This enables support for the MIPS Technologies Atlas evaluation board. @@ -419,6 +421,7 @@ config MOMENCO_OCELOT_C select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer . @@ -569,6 +572,7 @@ config SGI_IP27 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_NUMA select SYS_SUPPORTS_SMP + select GENERIC_HARDIRQS_NO__DO_IRQ help This are the SGI Origin 200, Origin 2000 and Onyx 2 Graphics workstations. To compile a Linux kernel that runs on these, say Y @@ -835,6 +839,10 @@ config SCHED_NO_NO_OMIT_FRAME_POINTER bool default y +config GENERIC_HARDIRQS_NO__DO_IRQ + bool + default n + # # Select some configuration options automatically based on user selections. # @@ -996,6 +1004,7 @@ config SOC_PNX8550 select HW_HAS_PCI select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL + select GENERIC_HARDIRQS_NO__DO_IRQ config SWAP_IO_SPACE bool diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c index e21476d955c..4c7cb4048d3 100644 --- a/arch/mips/dec/ioasic-irq.c +++ b/arch/mips/dec/ioasic-irq.c @@ -67,7 +67,6 @@ static struct irq_chip ioasic_irq_type = { .mask = mask_ioasic_irq, .mask_ack = ack_ioasic_irq, .unmask = unmask_ioasic_irq, - .end = end_ioasic_irq, }; diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c index 5a9be4c9358..916e46b8ccd 100644 --- a/arch/mips/dec/kn02-irq.c +++ b/arch/mips/dec/kn02-irq.c @@ -57,19 +57,12 @@ static void ack_kn02_irq(unsigned int irq) iob(); } -static void end_kn02_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_kn02_irq(irq); -} - static struct irq_chip kn02_irq_type = { .typename = "KN02-CSR", .ack = ack_kn02_irq, .mask = mask_kn02_irq, .mask_ack = ack_kn02_irq, .unmask = unmask_kn02_irq, - .end = end_kn02_irq, }; diff --git a/arch/mips/emma2rh/common/irq_emma2rh.c b/arch/mips/emma2rh/common/irq_emma2rh.c index 59b98299c89..8d880f0b06e 100644 --- a/arch/mips/emma2rh/common/irq_emma2rh.c +++ b/arch/mips/emma2rh/common/irq_emma2rh.c @@ -56,19 +56,12 @@ static void emma2rh_irq_disable(unsigned int irq) ll_emma2rh_irq_disable(irq - emma2rh_irq_base); } -static void emma2rh_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - ll_emma2rh_irq_enable(irq - emma2rh_irq_base); -} - struct irq_chip emma2rh_irq_controller = { .typename = "emma2rh_irq", .ack = emma2rh_irq_disable, .mask = emma2rh_irq_disable, .mask_ack = emma2rh_irq_disable, .unmask = emma2rh_irq_enable, - .end = emma2rh_irq_end, }; void emma2rh_irq_init(u32 irq_base) diff --git a/arch/mips/emma2rh/markeins/irq_markeins.c b/arch/mips/emma2rh/markeins/irq_markeins.c index 3ac4e405ecd..2116d9be5fa 100644 --- a/arch/mips/emma2rh/markeins/irq_markeins.c +++ b/arch/mips/emma2rh/markeins/irq_markeins.c @@ -48,19 +48,12 @@ static void emma2rh_sw_irq_disable(unsigned int irq) ll_emma2rh_sw_irq_disable(irq - emma2rh_sw_irq_base); } -static void emma2rh_sw_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - ll_emma2rh_sw_irq_enable(irq - emma2rh_sw_irq_base); -} - struct irq_chip emma2rh_sw_irq_controller = { .typename = "emma2rh_sw_irq", .ack = emma2rh_sw_irq_disable, .mask = emma2rh_sw_irq_disable, .mask_ack = emma2rh_sw_irq_disable, .unmask = emma2rh_sw_irq_enable, - .end = emma2rh_sw_irq_end, }; void emma2rh_sw_irq_init(u32 irq_base) diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index 5c4f50cdf15..f8d417b5c2b 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c @@ -39,19 +39,12 @@ void disable_r4030_irq(unsigned int irq) spin_unlock_irqrestore(&r4030_lock, flags); } -static void end_r4030_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_r4030_irq(irq); -} - static struct irq_chip r4030_irq_type = { .typename = "R4030", .ack = disable_r4030_irq, .mask = disable_r4030_irq, .mask_ack = disable_r4030_irq, .unmask = enable_r4030_irq, - .end = end_r4030_irq, }; void __init init_r4030_ints(void) diff --git a/arch/mips/kernel/irq-mv6434x.c b/arch/mips/kernel/irq-mv6434x.c index 6cfb31cafde..efbd219845b 100644 --- a/arch/mips/kernel/irq-mv6434x.c +++ b/arch/mips/kernel/irq-mv6434x.c @@ -66,15 +66,6 @@ static inline void unmask_mv64340_irq(unsigned int irq) } } -/* - * End IRQ processing - */ -static void end_mv64340_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_mv64340_irq(irq); -} - /* * Interrupt handler for interrupts coming from the Marvell chip. * It could be built in ethernet ports etc... @@ -106,7 +97,6 @@ struct irq_chip mv64340_irq_type = { .mask = mask_mv64340_irq, .mask_ack = mask_mv64340_irq, .unmask = unmask_mv64340_irq, - .end = end_mv64340_irq, }; void __init mv64340_irq_init(unsigned int base) diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c index ddcc2a5f8a0..123324ba8c1 100644 --- a/arch/mips/kernel/irq-rm7000.c +++ b/arch/mips/kernel/irq-rm7000.c @@ -29,19 +29,12 @@ static inline void mask_rm7k_irq(unsigned int irq) clear_c0_intcontrol(0x100 << (irq - irq_base)); } -static void rm7k_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_rm7k_irq(irq); -} - static struct irq_chip rm7k_irq_controller = { .typename = "RM7000", .ack = mask_rm7k_irq, .mask = mask_rm7k_irq, .mask_ack = mask_rm7k_irq, .unmask = unmask_rm7k_irq, - .end = rm7k_cpu_irq_end, }; void __init rm7k_cpu_irq_init(int base) diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c index ba6440c88ab..0e6f4c5349d 100644 --- a/arch/mips/kernel/irq-rm9000.c +++ b/arch/mips/kernel/irq-rm9000.c @@ -80,19 +80,12 @@ static void rm9k_perfcounter_irq_shutdown(unsigned int irq) on_each_cpu(local_rm9k_perfcounter_irq_shutdown, (void *) irq, 0, 1); } -static void rm9k_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_rm9k_irq(irq); -} - static struct irq_chip rm9k_irq_controller = { .typename = "RM9000", .ack = mask_rm9k_irq, .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, - .end = rm9k_cpu_irq_end, }; static struct irq_chip rm9k_perfcounter_irq = { @@ -103,7 +96,6 @@ static struct irq_chip rm9k_perfcounter_irq = { .mask = mask_rm9k_irq, .mask_ack = mask_rm9k_irq, .unmask = unmask_rm9k_irq, - .end = rm9k_cpu_irq_end, }; unsigned int rm9000_perfcount_irq; diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index be5ac23d381..fcc86b96ccf 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c @@ -50,12 +50,6 @@ static inline void mask_mips_irq(unsigned int irq) irq_disable_hazard(); } -static void mips_cpu_irq_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - unmask_mips_irq(irq); -} - static struct irq_chip mips_cpu_irq_controller = { .typename = "MIPS", .ack = mask_mips_irq, @@ -63,7 +57,6 @@ static struct irq_chip mips_cpu_irq_controller = { .mask_ack = mask_mips_irq, .unmask = unmask_mips_irq, .eoi = unmask_mips_irq, - .end = mips_cpu_irq_end, }; /* @@ -96,8 +89,6 @@ static void mips_mt_cpu_irq_ack(unsigned int irq) mask_mips_mt_irq(irq); } -#define mips_mt_cpu_irq_end mips_cpu_irq_end - static struct irq_chip mips_mt_cpu_irq_controller = { .typename = "MIPS", .startup = mips_mt_cpu_irq_startup, @@ -106,7 +97,6 @@ static struct irq_chip mips_mt_cpu_irq_controller = { .mask_ack = mips_mt_cpu_irq_ack, .unmask = unmask_mips_mt_irq, .eoi = unmask_mips_mt_irq, - .end = mips_mt_cpu_irq_end, }; void __init mips_cpu_irq_init(int irq_base) diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 4a84a7beac5..2affa5ff171 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c @@ -44,19 +44,12 @@ void enable_lasat_irq(unsigned int irq_nr) *lasat_int_mask |= (1 << irq_nr) << lasat_int_mask_shift; } -static void end_lasat_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_lasat_irq(irq); -} - static struct irq_chip lasat_irq_type = { .typename = "Lasat", .ack = disable_lasat_irq, .mask = disable_lasat_irq, .mask_ack = disable_lasat_irq, .unmask = enable_lasat_irq, - .end = end_lasat_irq, }; static inline int ls1bit32(unsigned int x) diff --git a/arch/mips/momentum/ocelot_c/cpci-irq.c b/arch/mips/momentum/ocelot_c/cpci-irq.c index e5a4a0a8a7f..bb11fef0847 100644 --- a/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -65,15 +65,6 @@ static inline void unmask_cpci_irq(unsigned int irq) value = OCELOT_FPGA_READ(INTMASK); } -/* - * End IRQ processing - */ -static void end_cpci_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_cpci_irq(irq); -} - /* * Interrupt handler for interrupts coming from the FPGA chip. * It could be built in ethernet ports etc... @@ -98,7 +89,6 @@ struct irq_chip cpci_irq_type = { .mask = mask_cpci_irq, .mask_ack = mask_cpci_irq, .unmask = unmask_cpci_irq, - .end = end_cpci_irq, }; void cpci_irq_init(void) diff --git a/arch/mips/momentum/ocelot_c/uart-irq.c b/arch/mips/momentum/ocelot_c/uart-irq.c index 0029f0008de..a7a80c0da56 100644 --- a/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/arch/mips/momentum/ocelot_c/uart-irq.c @@ -59,15 +59,6 @@ static inline void unmask_uart_irq(unsigned int irq) value = OCELOT_FPGA_READ(UART_INTMASK); } -/* - * End IRQ processing - */ -static void end_uart_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - unmask_uart_irq(irq); -} - /* * Interrupt handler for interrupts coming from the FPGA chip. */ @@ -91,7 +82,6 @@ struct irq_chip uart_irq_type = { .mask = mask_uart_irq, .mask_ack = mask_uart_irq, .unmask = unmask_uart_irq, - .end = end_uart_irq, }; void uart_irq_init(void) diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index 0dc23930edb..2c36c108c4d 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c @@ -158,20 +158,12 @@ int pnx8550_set_gic_priority(int irq, int priority) return prev_priority; } -static void end_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { - unmask_irq(irq); - } -} - static struct irq_chip level_irq_type = { .typename = "PNX Level IRQ", .ack = mask_irq, .mask = mask_irq, .mask_ack = mask_irq, .unmask = unmask_irq, - .end = end_irq, }; static struct irqaction gic_action = { diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index c7b13805315..c44f8be0644 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c @@ -51,19 +51,12 @@ static void disable_local0_irq(unsigned int irq) sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0)); } -static void end_local0_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local0_irq(irq); -} - static struct irq_chip ip22_local0_irq_type = { .typename = "IP22 local 0", .ack = disable_local0_irq, .mask = disable_local0_irq, .mask_ack = disable_local0_irq, .unmask = enable_local0_irq, - .end = end_local0_irq, }; static void enable_local1_irq(unsigned int irq) @@ -79,19 +72,12 @@ void disable_local1_irq(unsigned int irq) sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1)); } -static void end_local1_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local1_irq(irq); -} - static struct irq_chip ip22_local1_irq_type = { .typename = "IP22 local 1", .ack = disable_local1_irq, .mask = disable_local1_irq, .mask_ack = disable_local1_irq, .unmask = enable_local1_irq, - .end = end_local1_irq, }; static void enable_local2_irq(unsigned int irq) @@ -107,19 +93,12 @@ void disable_local2_irq(unsigned int irq) sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0)); } -static void end_local2_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local2_irq(irq); -} - static struct irq_chip ip22_local2_irq_type = { .typename = "IP22 local 2", .ack = disable_local2_irq, .mask = disable_local2_irq, .mask_ack = disable_local2_irq, .unmask = enable_local2_irq, - .end = end_local2_irq, }; static void enable_local3_irq(unsigned int irq) @@ -135,19 +114,12 @@ void disable_local3_irq(unsigned int irq) sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1)); } -static void end_local3_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_local3_irq(irq); -} - static struct irq_chip ip22_local3_irq_type = { .typename = "IP22 local 3", .ack = disable_local3_irq, .mask = disable_local3_irq, .mask_ack = disable_local3_irq, .unmask = enable_local3_irq, - .end = end_local3_irq, }; static void indy_local0_irqdispatch(void) diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 5f8835b4e84..319f8803ef6 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -332,13 +332,6 @@ static inline void disable_bridge_irq(unsigned int irq) intr_disconnect_level(cpu, swlevel); } -static void end_bridge_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && - irq_desc[irq].action) - enable_bridge_irq(irq); -} - static struct irq_chip bridge_irq_type = { .typename = "bridge", .startup = startup_bridge_irq, @@ -347,7 +340,6 @@ static struct irq_chip bridge_irq_type = { .mask = disable_bridge_irq, .mask_ack = disable_bridge_irq, .unmask = enable_bridge_irq, - .end = end_bridge_irq, }; void __devinit register_bridge_irq(unsigned int irq) diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 7d361726bbf..c20e9899b34 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c @@ -180,10 +180,6 @@ static void disable_rt_irq(unsigned int irq) { } -static void end_rt_irq(unsigned int irq) -{ -} - static struct irq_chip rt_irq_type = { .typename = "SN HUB RT timer", .ack = disable_rt_irq, @@ -191,7 +187,6 @@ static struct irq_chip rt_irq_type = { .mask_ack = disable_rt_irq, .unmask = enable_rt_irq, .eoi = enable_rt_irq, - .end = end_rt_irq, }; static struct irqaction rt_irqaction = { diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 21873de49aa..ed4a19adf36 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c @@ -66,12 +66,10 @@ #define TX4927_IRQ_CP0_INIT ( 1 << 10 ) #define TX4927_IRQ_CP0_ENABLE ( 1 << 13 ) #define TX4927_IRQ_CP0_DISABLE ( 1 << 14 ) -#define TX4927_IRQ_CP0_ENDIRQ ( 1 << 16 ) #define TX4927_IRQ_PIC_INIT ( 1 << 20 ) #define TX4927_IRQ_PIC_ENABLE ( 1 << 23 ) #define TX4927_IRQ_PIC_DISABLE ( 1 << 24 ) -#define TX4927_IRQ_PIC_ENDIRQ ( 1 << 26 ) #define TX4927_IRQ_ALL 0xffffffff #endif @@ -82,12 +80,10 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE | TX4927_IRQ_WARN | TX4927_IRQ_EROR // | TX4927_IRQ_CP0_INIT // | TX4927_IRQ_CP0_ENABLE -// | TX4927_IRQ_CP0_DISABLE // | TX4927_IRQ_CP0_ENDIRQ // | TX4927_IRQ_PIC_INIT // | TX4927_IRQ_PIC_ENABLE // | TX4927_IRQ_PIC_DISABLE -// | TX4927_IRQ_PIC_ENDIRQ // | TX4927_IRQ_INIT // | TX4927_IRQ_NEST1 // | TX4927_IRQ_NEST2 @@ -114,11 +110,9 @@ static const u32 tx4927_irq_debug_flag = (TX4927_IRQ_NONE static void tx4927_irq_cp0_enable(unsigned int irq); static void tx4927_irq_cp0_disable(unsigned int irq); -static void tx4927_irq_cp0_end(unsigned int irq); static void tx4927_irq_pic_enable(unsigned int irq); static void tx4927_irq_pic_disable(unsigned int irq); -static void tx4927_irq_pic_end(unsigned int irq); /* * Kernel structs for all pic's @@ -131,7 +125,6 @@ static struct irq_chip tx4927_irq_cp0_type = { .mask = tx4927_irq_cp0_disable, .mask_ack = tx4927_irq_cp0_disable, .unmask = tx4927_irq_cp0_enable, - .end = tx4927_irq_cp0_end, }; #define TX4927_PIC_NAME "TX4927-PIC" @@ -141,7 +134,6 @@ static struct irq_chip tx4927_irq_pic_type = { .mask = tx4927_irq_pic_disable, .mask_ack = tx4927_irq_pic_disable, .unmask = tx4927_irq_pic_enable, - .end = tx4927_irq_pic_end, }; #define TX4927_PIC_ACTION(s) { no_action, 0, CPU_MASK_NONE, s, NULL, NULL } @@ -214,15 +206,6 @@ static void tx4927_irq_cp0_disable(unsigned int irq) tx4927_irq_cp0_modify(CCP0_STATUS, tx4927_irq_cp0_mask(irq), 0); } -static void tx4927_irq_cp0_end(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_CP0_ENDIRQ, "irq=%d \n", irq); - - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - tx4927_irq_cp0_enable(irq); - } -} - /* * Functions for pic */ @@ -376,15 +359,6 @@ static void tx4927_irq_pic_disable(unsigned int irq) tx4927_irq_pic_mask(irq), 0); } -static void tx4927_irq_pic_end(unsigned int irq) -{ - TX4927_IRQ_DPRINTK(TX4927_IRQ_PIC_ENDIRQ, "irq=%d\n", irq); - - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - tx4927_irq_pic_enable(irq); - } -} - /* * Main init functions */ diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 34cdb2a240e..5a5ea6c0b9f 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -153,7 +153,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_IOC_INIT ( 1 << 10 ) #define TOSHIBA_RBTX4927_IRQ_IOC_ENABLE ( 1 << 13 ) #define TOSHIBA_RBTX4927_IRQ_IOC_DISABLE ( 1 << 14 ) -#define TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ ( 1 << 16 ) #define TOSHIBA_RBTX4927_IRQ_ISA_INIT ( 1 << 20 ) #define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) @@ -172,7 +171,6 @@ static const u32 toshiba_rbtx4927_irq_debug_flag = // | TOSHIBA_RBTX4927_IRQ_IOC_INIT // | TOSHIBA_RBTX4927_IRQ_IOC_ENABLE // | TOSHIBA_RBTX4927_IRQ_IOC_DISABLE -// | TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ // | TOSHIBA_RBTX4927_IRQ_ISA_INIT // | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE // | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE @@ -223,7 +221,6 @@ extern void mask_and_ack_8259A(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); -static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq); #ifdef CONFIG_TOSHIBA_FPCIB0 static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); @@ -239,7 +236,6 @@ static struct irq_chip toshiba_rbtx4927_irq_ioc_type = { .mask = toshiba_rbtx4927_irq_ioc_disable, .mask_ack = toshiba_rbtx4927_irq_ioc_disable, .unmask = toshiba_rbtx4927_irq_ioc_enable, - .end = toshiba_rbtx4927_irq_ioc_end, }; #define TOSHIBA_RBTX4927_IOC_INTR_ENAB 0xbc002000 #define TOSHIBA_RBTX4927_IOC_INTR_STAT 0xbc002006 @@ -388,23 +384,6 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq) TOSHIBA_RBTX4927_WR08(TOSHIBA_RBTX4927_IOC_INTR_ENAB, v); } -static void toshiba_rbtx4927_irq_ioc_end(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_IOC_ENDIRQ, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_IOC_BEG - || irq > TOSHIBA_RBTX4927_IRQ_IOC_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - toshiba_rbtx4927_irq_ioc_enable(irq); - } -} - /**********************************************************************************/ /* Functions for isa */ diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 42e127683ae..a347b424d91 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c @@ -39,11 +39,9 @@ static void tx4938_irq_cp0_enable(unsigned int irq); static void tx4938_irq_cp0_disable(unsigned int irq); -static void tx4938_irq_cp0_end(unsigned int irq); static void tx4938_irq_pic_enable(unsigned int irq); static void tx4938_irq_pic_disable(unsigned int irq); -static void tx4938_irq_pic_end(unsigned int irq); /**********************************************************************************/ /* Kernel structs for all pic's */ @@ -56,7 +54,6 @@ static struct irq_chip tx4938_irq_cp0_type = { .mask = tx4938_irq_cp0_disable, .mask_ack = tx4938_irq_cp0_disable, .unmask = tx4938_irq_cp0_enable, - .end = tx4938_irq_cp0_end, }; #define TX4938_PIC_NAME "TX4938-PIC" @@ -66,7 +63,6 @@ static struct irq_chip tx4938_irq_pic_type = { .mask = tx4938_irq_pic_disable, .mask_ack = tx4938_irq_pic_disable, .unmask = tx4938_irq_pic_enable, - .end = tx4938_irq_pic_end, }; static struct irqaction tx4938_irq_pic_action = { @@ -104,14 +100,6 @@ tx4938_irq_cp0_disable(unsigned int irq) clear_c0_status(tx4938_irq_cp0_mask(irq)); } -static void -tx4938_irq_cp0_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - tx4938_irq_cp0_enable(irq); - } -} - /**********************************************************************************/ /* Functions for pic */ /**********************************************************************************/ @@ -269,14 +257,6 @@ tx4938_irq_pic_disable(unsigned int irq) tx4938_irq_pic_mask(irq), 0); } -static void -tx4938_irq_pic_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - tx4938_irq_pic_enable(irq); - } -} - /**********************************************************************************/ /* Main init functions */ /**********************************************************************************/ diff --git a/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 8c87a35f306..b6f363d0801 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -89,7 +89,6 @@ IRQ Device static void toshiba_rbtx4938_irq_ioc_enable(unsigned int irq); static void toshiba_rbtx4938_irq_ioc_disable(unsigned int irq); -static void toshiba_rbtx4938_irq_ioc_end(unsigned int irq); #define TOSHIBA_RBTX4938_IOC_NAME "RBTX4938-IOC" static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { @@ -98,7 +97,6 @@ static struct irq_chip toshiba_rbtx4938_irq_ioc_type = { .mask = toshiba_rbtx4938_irq_ioc_disable, .mask_ack = toshiba_rbtx4938_irq_ioc_disable, .unmask = toshiba_rbtx4938_irq_ioc_enable, - .end = toshiba_rbtx4938_irq_ioc_end, }; #define TOSHIBA_RBTX4938_IOC_INTR_ENAB 0xb7f02000 @@ -167,14 +165,6 @@ toshiba_rbtx4938_irq_ioc_disable(unsigned int irq) TX4938_RD08(TOSHIBA_RBTX4938_IOC_INTR_ENAB); } -static void -toshiba_rbtx4938_irq_ioc_end(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - toshiba_rbtx4938_irq_ioc_enable(irq); - } -} - extern void __init txx9_spi_irqinit(int irc_irq); void __init arch_init_irq(void) diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index 92f41f6f934..c8dfd8092ca 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -6,6 +6,7 @@ config CASIO_E55 select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config IBM_WORKPAD bool "Support for IBM WorkPad z50" @@ -15,6 +16,7 @@ config IBM_WORKPAD select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config NEC_CMBVR4133 bool "Support for NEC CMB-VR4133" @@ -39,6 +41,7 @@ config TANBAC_TB022X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ help The TANBAC VR4131 multichip module(TB0225) and the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms @@ -71,6 +74,7 @@ config VICTOR_MPC30X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config ZAO_CAPCELLA bool "Support for ZAO Networks Capcella" @@ -80,6 +84,7 @@ config ZAO_CAPCELLA select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config PCI_VR41XX bool "Add PCI control unit support of NEC VR4100 series" diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c index 54b92a74c7a..c075261976c 100644 --- a/arch/mips/vr41xx/common/icu.c +++ b/arch/mips/vr41xx/common/icu.c @@ -427,19 +427,12 @@ static void enable_sysint1_irq(unsigned int irq) icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); } -static void end_sysint1_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - icu1_set(MSYSINT1REG, 1 << SYSINT1_IRQ_TO_PIN(irq)); -} - static struct irq_chip sysint1_irq_type = { .typename = "SYSINT1", .ack = disable_sysint1_irq, .mask = disable_sysint1_irq, .mask_ack = disable_sysint1_irq, .unmask = enable_sysint1_irq, - .end = end_sysint1_irq, }; static void disable_sysint2_irq(unsigned int irq) @@ -452,19 +445,12 @@ static void enable_sysint2_irq(unsigned int irq) icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); } -static void end_sysint2_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - icu2_set(MSYSINT2REG, 1 << SYSINT2_IRQ_TO_PIN(irq)); -} - static struct irq_chip sysint2_irq_type = { .typename = "SYSINT2", .ack = disable_sysint2_irq, .mask = disable_sysint2_irq, .mask_ack = disable_sysint2_irq, .unmask = enable_sysint2_irq, - .end = end_sysint2_irq, }; static inline int set_sysint1_assign(unsigned int irq, unsigned char assign) -- cgit v1.2.3 From 49afb1f67b42c4240fef9d2d8b76c317c56a189d Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Wed, 6 Dec 2006 11:50:23 +0000 Subject: [MIPS] *-berr: Header inclusions for DEC bus error handlers A fixup to add missing header inclusions for bus error handlers for DECstation system after the recent switch to get_irq_regs(). Signed-off-by: Maciej W. Rozycki Signed-off-by: Ralf Baechle --- arch/mips/dec/ecc-berr.c | 1 + arch/mips/dec/kn01-berr.c | 2 ++ 2 files changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c index c8430c07355..6d55e8aab66 100644 --- a/arch/mips/dec/ecc-berr.c +++ b/arch/mips/dec/ecc-berr.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c index f19b4617a0a..d3b8002bf1e 100644 --- a/arch/mips/dec/kn01-berr.c +++ b/arch/mips/dec/kn01-berr.c @@ -20,8 +20,10 @@ #include #include +#include #include #include +#include #include #include #include -- cgit v1.2.3 From 2cafe978462bc4016392aa330bf501a674679a86 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 7 Dec 2006 02:04:17 +0900 Subject: [MIPS] Import updates from i386's i8259.c Import many updates from i386's i8259.c, especially genirq transitions. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/i8259.c | 162 +++++++++++++++++++++++++---------------------- 1 file changed, 86 insertions(+), 76 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 2526c0ca4d8..b59a676c6d0 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c @@ -19,9 +19,6 @@ #include #include -void enable_8259A_irq(unsigned int irq); -void disable_8259A_irq(unsigned int irq); - /* * This is the 'legacy' 8259A Programmable Interrupt Controller, * present in the majority of PC/AT boxes. @@ -31,23 +28,16 @@ void disable_8259A_irq(unsigned int irq); * moves to arch independent land */ +static int i8259A_auto_eoi; DEFINE_SPINLOCK(i8259A_lock); - -static void end_8259A_irq (unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && - irq_desc[irq].action) - enable_8259A_irq(irq); -} - +/* some platforms call this... */ void mask_and_ack_8259A(unsigned int); -static struct irq_chip i8259A_irq_type = { - .typename = "XT-PIC", - .enable = enable_8259A_irq, - .disable = disable_8259A_irq, - .ack = mask_and_ack_8259A, - .end = end_8259A_irq, +static struct irq_chip i8259A_chip = { + .name = "XT-PIC", + .mask = disable_8259A_irq, + .unmask = enable_8259A_irq, + .mask_ack = mask_and_ack_8259A, }; /* @@ -59,8 +49,8 @@ static struct irq_chip i8259A_irq_type = { */ static unsigned int cached_irq_mask = 0xffff; -#define cached_21 (cached_irq_mask) -#define cached_A1 (cached_irq_mask >> 8) +#define cached_master_mask (cached_irq_mask) +#define cached_slave_mask (cached_irq_mask >> 8) void disable_8259A_irq(unsigned int irq) { @@ -70,9 +60,9 @@ void disable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask |= mask; if (irq & 8) - outb(cached_A1,0xA1); + outb(cached_slave_mask, PIC_SLAVE_IMR); else - outb(cached_21,0x21); + outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -84,9 +74,9 @@ void enable_8259A_irq(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask &= mask; if (irq & 8) - outb(cached_A1,0xA1); + outb(cached_slave_mask, PIC_SLAVE_IMR); else - outb(cached_21,0x21); + outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -98,9 +88,9 @@ int i8259A_irq_pending(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); if (irq < 8) - ret = inb(0x20) & mask; + ret = inb(PIC_MASTER_CMD) & mask; else - ret = inb(0xA0) & (mask >> 8); + ret = inb(PIC_SLAVE_CMD) & (mask >> 8); spin_unlock_irqrestore(&i8259A_lock, flags); return ret; @@ -109,7 +99,7 @@ int i8259A_irq_pending(unsigned int irq) void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); - set_irq_chip(irq, &i8259A_irq_type); + set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); enable_irq(irq); } @@ -125,14 +115,14 @@ static inline int i8259A_irq_real(unsigned int irq) int irqmask = 1 << irq; if (irq < 8) { - outb(0x0B,0x20); /* ISR register */ - value = inb(0x20) & irqmask; - outb(0x0A,0x20); /* back to the IRR register */ + outb(0x0B,PIC_MASTER_CMD); /* ISR register */ + value = inb(PIC_MASTER_CMD) & irqmask; + outb(0x0A,PIC_MASTER_CMD); /* back to the IRR register */ return value; } - outb(0x0B,0xA0); /* ISR register */ - value = inb(0xA0) & (irqmask >> 8); - outb(0x0A,0xA0); /* back to the IRR register */ + outb(0x0B,PIC_SLAVE_CMD); /* ISR register */ + value = inb(PIC_SLAVE_CMD) & (irqmask >> 8); + outb(0x0A,PIC_SLAVE_CMD); /* back to the IRR register */ return value; } @@ -149,17 +139,19 @@ void mask_and_ack_8259A(unsigned int irq) spin_lock_irqsave(&i8259A_lock, flags); /* - * Lightweight spurious IRQ detection. We do not want to overdo - * spurious IRQ handling - it's usually a sign of hardware problems, so - * we only do the checks we can do without slowing down good hardware - * nnecesserily. + * Lightweight spurious IRQ detection. We do not want + * to overdo spurious IRQ handling - it's usually a sign + * of hardware problems, so we only do the checks we can + * do without slowing down good hardware unnecessarily. * - * Note that IRQ7 and IRQ15 (the two spurious IRQs usually resulting - * rom the 8259A-1|2 PICs) occur even if the IRQ is masked in the 8259A. - * Thus we can check spurious 8259A IRQs without doing the quite slow - * i8259A_irq_real() call for every IRQ. This does not cover 100% of - * spurious interrupts, but should be enough to warn the user that - * there is something bad going on ... + * Note that IRQ7 and IRQ15 (the two spurious IRQs + * usually resulting from the 8259A-1|2 PICs) occur + * even if the IRQ is masked in the 8259A. Thus we + * can check spurious 8259A IRQs without doing the + * quite slow i8259A_irq_real() call for every IRQ. + * This does not cover 100% of spurious interrupts, + * but should be enough to warn the user that there + * is something bad going on ... */ if (cached_irq_mask & irqmask) goto spurious_8259A_irq; @@ -167,14 +159,14 @@ void mask_and_ack_8259A(unsigned int irq) handle_real_irq: if (irq & 8) { - inb(0xA1); /* DUMMY - (do we need this?) */ - outb(cached_A1,0xA1); - outb(0x60+(irq&7),0xA0);/* 'Specific EOI' to slave */ - outb(0x62,0x20); /* 'Specific EOI' to master-IRQ2 */ + inb(PIC_SLAVE_IMR); /* DUMMY - (do we need this?) */ + outb(cached_slave_mask, PIC_SLAVE_IMR); + outb(0x60+(irq&7),PIC_SLAVE_CMD);/* 'Specific EOI' to slave */ + outb(0x60+PIC_CASCADE_IR,PIC_MASTER_CMD); /* 'Specific EOI' to master-IRQ2 */ } else { - inb(0x21); /* DUMMY - (do we need this?) */ - outb(cached_21,0x21); - outb(0x60+irq,0x20); /* 'Specific EOI' to master */ + inb(PIC_MASTER_IMR); /* DUMMY - (do we need this?) */ + outb(cached_master_mask, PIC_MASTER_IMR); + outb(0x60+irq,PIC_MASTER_CMD); /* 'Specific EOI to master */ } #ifdef CONFIG_MIPS_MT_SMTC if (irq_hwmask[irq] & ST0_IM) @@ -195,7 +187,7 @@ spurious_8259A_irq: goto handle_real_irq; { - static int spurious_irq_mask = 0; + static int spurious_irq_mask; /* * At this point we can be sure the IRQ is spurious, * lets ACK and report it. [once per IRQ] @@ -216,13 +208,25 @@ spurious_8259A_irq: static int i8259A_resume(struct sys_device *dev) { - init_8259A(0); + init_8259A(i8259A_auto_eoi); + return 0; +} + +static int i8259A_shutdown(struct sys_device *dev) +{ + /* Put the i8259A into a quiescent state that + * the kernel initialization code can get it + * out of. + */ + outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ return 0; } static struct sysdev_class i8259_sysdev_class = { set_kset_name("i8259"), .resume = i8259A_resume, + .shutdown = i8259A_shutdown, }; static struct sys_device device_i8259A = { @@ -244,41 +248,41 @@ void __init init_8259A(int auto_eoi) { unsigned long flags; + i8259A_auto_eoi = auto_eoi; + spin_lock_irqsave(&i8259A_lock, flags); - outb(0xff, 0x21); /* mask all of 8259A-1 */ - outb(0xff, 0xA1); /* mask all of 8259A-2 */ + outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ + outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ /* * outb_p - this has to work on a wide range of PC hardware. */ - outb_p(0x11, 0x20); /* ICW1: select 8259A-1 init */ - outb_p(0x00, 0x21); /* ICW2: 8259A-1 IR0-7 mapped to 0x00-0x07 */ - outb_p(0x04, 0x21); /* 8259A-1 (the master) has a slave on IR2 */ - if (auto_eoi) - outb_p(0x03, 0x21); /* master does Auto EOI */ - else - outb_p(0x01, 0x21); /* master expects normal EOI */ - - outb_p(0x11, 0xA0); /* ICW1: select 8259A-2 init */ - outb_p(0x08, 0xA1); /* ICW2: 8259A-2 IR0-7 mapped to 0x08-0x0f */ - outb_p(0x02, 0xA1); /* 8259A-2 is a slave on master's IR2 */ - outb_p(0x01, 0xA1); /* (slave's support for AEOI in flat mode - is to be investigated) */ - + outb_p(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ + outb_p(I8259A_IRQ_BASE + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0 mapped to I8259A_IRQ_BASE + 0x00 */ + outb_p(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ + if (auto_eoi) /* master does Auto EOI */ + outb_p(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); + else /* master expects normal EOI */ + outb_p(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); + + outb_p(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ + outb_p(I8259A_IRQ_BASE + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0 mapped to I8259A_IRQ_BASE + 0x08 */ + outb_p(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master's IR2 */ + outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ if (auto_eoi) /* - * in AEOI mode we just have to mask the interrupt + * In AEOI mode we just have to mask the interrupt * when acking. */ - i8259A_irq_type.ack = disable_8259A_irq; + i8259A_chip.mask_ack = disable_8259A_irq; else - i8259A_irq_type.ack = mask_and_ack_8259A; + i8259A_chip.mask_ack = mask_and_ack_8259A; udelay(100); /* wait for 8259A to initialize */ - outb(cached_21, 0x21); /* restore master IRQ mask */ - outb(cached_A1, 0xA1); /* restore slave IRQ mask */ + outb(cached_master_mask, PIC_MASTER_IMR); /* restore master IRQ mask */ + outb(cached_slave_mask, PIC_SLAVE_IMR); /* restore slave IRQ mask */ spin_unlock_irqrestore(&i8259A_lock, flags); } @@ -291,11 +295,17 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY + .name = "pic1", + .start = PIC_MASTER_CMD, + .end = PIC_MASTER_IMR, + .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY + .name = "pic2", + .start = PIC_SLAVE_CMD, + .end = PIC_SLAVE_IMR, + .flags = IORESOURCE_BUSY }; /* @@ -313,7 +323,7 @@ void __init init_i8259_irqs (void) init_8259A(0); for (i = 0; i < 16; i++) - set_irq_chip(i, &i8259A_irq_type); + set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); - setup_irq(2, &irq2); + setup_irq(PIC_CASCADE_IR, &irq2); } -- cgit v1.2.3 From c7f570a5eca59575572ee231390df727df207bda Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Tue, 5 Dec 2006 12:25:31 +1100 Subject: [IA64] Fix pci.c kernel compilation breakage. The recent change to convert the is_enabled flag in the PCI device to an atomic count broke the IA64 compilation. As pcibios_disable_device is only ever called if the reference count is zero, convert the if to a BUG_ON. Signed-off-by: Peter Chubb Signed-off-by: Tony Luck --- arch/ia64/pci/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index f4edfbf2713..eb92cef9cd0 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -564,8 +564,8 @@ pcibios_enable_device (struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - if (dev->is_enabled) - acpi_pci_irq_disable(dev); + BUG_ON(atomic_read(&dev->enable_cnt)); + acpi_pci_irq_disable(dev); } void -- cgit v1.2.3 From 8f820e976057261e249367514e9920cf20048c76 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] x86-64: Update defconfig Signed-off-by: Andi Kleen --- arch/x86_64/defconfig | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 0f5d44e86be..96f226cfb33 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2-git4 -# Sat Oct 21 03:38:52 2006 +# Linux kernel version: 2.6.19-git7 +# Wed Dec 6 23:50:47 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -47,13 +47,14 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -87,9 +88,7 @@ CONFIG_STOP_MACHINE=y # Block layer # CONFIG_BLOCK=y -CONFIG_LBD=y # CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set # # IO Schedulers @@ -111,10 +110,11 @@ CONFIG_X86_PC=y # CONFIG_X86_VSMP is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set -CONFIG_GENERIC_CPU=y -CONFIG_X86_L1_CACHE_BYTES=128 -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_INTERNODE_CACHE_BYTES=128 +CONFIG_MCORE2=y +# CONFIG_GENERIC_CPU is not set +CONFIG_X86_L1_CACHE_BYTES=64 +CONFIG_X86_L1_CACHE_SHIFT=6 +CONFIG_X86_INTERNODE_CACHE_BYTES=64 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set @@ -322,6 +322,7 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -624,6 +625,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -795,6 +797,7 @@ CONFIG_BNX2=y CONFIG_S2IO=m # CONFIG_S2IO_NAPI is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -927,10 +930,6 @@ CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# CONFIG_AGP=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y @@ -1135,6 +1134,7 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1212,6 +1212,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y -- cgit v1.2.3 From dc3d1742543fffc79dc4d680ab64d2059e97d809 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] i386: Update defconfig Signed-off-by: Andi Kleen --- arch/i386/defconfig | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 97aacd6bd7d..65891f11ace 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2-git4 -# Sat Oct 21 03:38:56 2006 +# Linux kernel version: 2.6.19-git7 +# Wed Dec 6 23:50:49 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -40,13 +40,14 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -110,6 +111,7 @@ CONFIG_SMP=y # CONFIG_X86_VISWS is not set CONFIG_X86_GENERICARCH=y # CONFIG_X86_ES7000 is not set +# CONFIG_PARAVIRT is not set CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M386 is not set # CONFIG_M486 is not set @@ -120,6 +122,7 @@ CONFIG_X86_CYCLONE_TIMER=y # CONFIG_MPENTIUMII is not set CONFIG_MPENTIUMIII=y # CONFIG_MPENTIUMM is not set +# CONFIG_MCORE2 is not set # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set # CONFIG_MK7 is not set @@ -197,7 +200,6 @@ CONFIG_RESOURCES_64BIT=y CONFIG_MTRR=y # CONFIG_EFI is not set # CONFIG_IRQBALANCE is not set -CONFIG_REGPARM=y CONFIG_SECCOMP=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y @@ -205,7 +207,8 @@ CONFIG_HZ_250=y CONFIG_HZ=250 # CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -CONFIG_PHYSICAL_START=0x100000 +# CONFIG_RELOCATABLE is not set +CONFIG_PHYSICAL_ALIGN=0x100000 # CONFIG_HOTPLUG_CPU is not set CONFIG_COMPAT_VDSO=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y @@ -367,6 +370,7 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set @@ -677,6 +681,7 @@ CONFIG_SATA_INTEL_COMBINED=y # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_NETCELL is not set @@ -850,6 +855,7 @@ CONFIG_BNX2=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -984,10 +990,6 @@ CONFIG_RTC=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# CONFIG_AGP=y # CONFIG_AGP_ALI is not set # CONFIG_AGP_ATI is not set @@ -1108,6 +1110,7 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1185,6 +1188,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y -- cgit v1.2.3 From 9b483417527f2e47985856867c5716df013227c7 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] i386: fix buggy MTRR address checks Fix checks that failed to realize that values are 4-kB-unit-sized (note the format strings in this same diff context which *do* realize the unit size, via appended "000"!). Also fix an incorrect below-1MB area check (as gathered from Jan Beulich's unapplied patch at http://www.ussg.iu.edu/hypermail/linux/kernel/0411.1/1378.html ) Update mtrr_add_page() docu to make 4-kB-sized calculation more obvious. Given several further items mentioned in Jan's patch mail, all in all MTRR code seems surprisingly buggy, for a surprisingly long period of time (many years). Further work/investigation would be useful. TBD Note that my patch is pretty much UNTESTED, since I can only verify that it TBD successfully boots my machine, but I cannot test against actual buggy TBD hardware which would require these (formerly broken) checks. Long -mm TBD simmering would make sense, especially since these now-working checks might TBD turn out to have adverse effects on unaffected hardware. Signed-off-by: Andreas Mohr Signed-off-by: Andi Kleen Acked-by: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/mtrr/generic.c | 4 ++-- arch/i386/kernel/cpu/mtrr/main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index 0b61eed8bbd..ee8dc675395 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -366,7 +366,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i printk(KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base); return -EINVAL; } - if (!(base + size < 0x70000000 || base > 0x7003FFFF) && + if (!(base + size < 0x70000 || base > 0x7003F) && (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK)) { printk(KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n"); @@ -374,7 +374,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i } } - if (base + size < 0x100) { + if (base < 0x100) { printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n", base, size); return -EINVAL; diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index fff90bda473..2b8b0b361cc 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -263,8 +263,8 @@ static void set_mtrr(unsigned int reg, unsigned long base, /** * mtrr_add_page - Add a memory type region - * @base: Physical base address of region in pages (4 KB) - * @size: Physical size of region in pages (4 KB) + * @base: Physical base address of region in pages (in units of 4 kB!) + * @size: Physical size of region in pages (4 kB) * @type: Type of MTRR desired * @increment: If this is true do usage counting on the region * -- cgit v1.2.3 From b615ebdac97c648a2ae7d23c5a0bbb3972adf928 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] x86: shorten lines in unwinder to be <= 80 characters Andrew complained about > 80 character lines in the new unwinder. Fix that. Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 16 ++++++++++------ arch/x86_64/kernel/traps.c | 21 +++++++++++++-------- 2 files changed, 23 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index fe9c5e8e7e6..fe81d89c50d 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -173,6 +173,8 @@ dump_trace_unwind(struct unwind_frame_info *info, void *data) return n; } +#define MSG(msg) ops->warning(data, msg) + void dump_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack, struct stacktrace_ops *ops, void *data) @@ -191,29 +193,31 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (unwind_init_frame_info(&info, task, regs) == 0) unw_ret = dump_trace_unwind(&info, &oad); } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, dump_trace_unwind, + &oad); else { if (unwind_init_blocked(&info, task) == 0) unw_ret = dump_trace_unwind(&info, &oad); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + ops->warning_symbol(data, + "DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if (UNW_SP(&info) >= PAGE_OFFSET) { - ops->warning(data, "Leftover inexact backtrace:\n"); + MSG("Leftover inexact backtrace:\n"); stack = (void *)UNW_SP(&info); if (!stack) return; ebp = UNW_FP(&info); } else - ops->warning(data, "Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); + MSG("Inexact backtrace:\n"); } if (!stack) { unsigned long dummy; diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 0d65b22f229..d3f43c958ca 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -235,6 +235,8 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) return n; } +#define MSG(txt) ops->warning(data, txt) + /* * x86-64 can have upto three kernel stacks: * process stack @@ -248,11 +250,12 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) return p > t && p < t + THREAD_SIZE - 3; } -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, +void dump_trace(struct task_struct *tsk, struct pt_regs *regs, + unsigned long *stack, struct stacktrace_ops *ops, void *data) { const unsigned cpu = smp_processor_id(); - unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; + unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; unsigned used = 0; struct thread_info *tinfo; @@ -268,28 +271,30 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s if (unwind_init_frame_info(&info, tsk, regs) == 0) unw_ret = dump_trace_unwind(&info, &oad); } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, dump_trace_unwind, + &oad); else { if (unwind_init_blocked(&info, tsk) == 0) unw_ret = dump_trace_unwind(&info, &oad); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + ops->warning_symbol(data, + "DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if ((long)UNW_SP(&info) < 0) { - ops->warning(data, "Leftover inexact backtrace:\n"); + MSG("Leftover inexact backtrace:"); stack = (unsigned long *)UNW_SP(&info); if (!stack) return; } else - ops->warning(data, "Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); + MSG("Inexact backtrace:\n"); } if (!stack) { unsigned long dummy; -- cgit v1.2.3 From dd315df1767cf56bd4fb8d730fdff4a3d7e15d84 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] x86: Compress stack unwinder output The unwinder has some extra newlines, which eat up loads of screen space when it spews. (See https://bugzilla.redhat.com/bugzilla/attachment.cgi?id=137900 for a nasty example). warning_symbol-> and warning-> already printk a newline, so don't add one in the strings passed to them. [AK: redone for new code] Signed-off-by: Dave Jones Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 10 +++++----- arch/x86_64/kernel/traps.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index fe81d89c50d..396041a46e3 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -202,22 +202,22 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s\n", + "DWARF2 unwinder stuck at %s", UNW_PC(&info)); if (UNW_SP(&info) >= PAGE_OFFSET) { - MSG("Leftover inexact backtrace:\n"); + MSG("Leftover inexact backtrace:"); stack = (void *)UNW_SP(&info); if (!stack) return; ebp = UNW_FP(&info); } else - MSG("Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:"); } else if (call_trace >= 1) return; else - MSG("Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:"); } else - MSG("Inexact backtrace:\n"); + MSG("Inexact backtrace:"); } if (!stack) { unsigned long dummy; diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index d3f43c958ca..eedd4e759c3 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -280,7 +280,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { ops->warning_symbol(data, - "DWARF2 unwinder stuck at %s\n", + "DWARF2 unwinder stuck at %s", UNW_PC(&info)); if ((long)UNW_SP(&info) < 0) { MSG("Leftover inexact backtrace:"); @@ -288,13 +288,13 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (!stack) return; } else - MSG("Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:"); } else if (call_trace >= 1) return; else - MSG("Full inexact backtrace again:\n"); + MSG("Full inexact backtrace again:"); } else - MSG("Inexact backtrace:\n"); + MSG("Inexact backtrace:"); } if (!stack) { unsigned long dummy; -- cgit v1.2.3 From d606f88fa5e529e9dc72be97e79db1e36a6261cb Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] i386: fix must_checks Fix __must_check warnings in i386/math-emu. Signed-off-by: Randy Dunlap Signed-off-by: Andi Kleen --- arch/i386/math-emu/fpu_emu.h | 1 + arch/i386/math-emu/fpu_entry.c | 3 ++- arch/i386/math-emu/fpu_system.h | 1 + arch/i386/math-emu/load_store.c | 2 ++ arch/i386/math-emu/reg_ld_str.c | 15 ++++++++++----- 5 files changed, 16 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/math-emu/fpu_emu.h b/arch/i386/math-emu/fpu_emu.h index d62b20a3e66..65120f52385 100644 --- a/arch/i386/math-emu/fpu_emu.h +++ b/arch/i386/math-emu/fpu_emu.h @@ -57,6 +57,7 @@ #define TAG_Special Const(2) /* De-normal, + or - infinity, or Not a Number */ #define TAG_Empty Const(3) /* empty */ +#define TAG_Error Const(0x80) /* probably need to abort */ #define LOADED_DATA Const(10101) /* Special st() number to identify loaded data (not on stack). */ diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c index d93f16ef828..ddf8fa3bbd0 100644 --- a/arch/i386/math-emu/fpu_entry.c +++ b/arch/i386/math-emu/fpu_entry.c @@ -742,7 +742,8 @@ int save_i387_soft(void *s387, struct _fpstate __user * buf) S387->fcs &= ~0xf8000000; S387->fos |= 0xffff0000; #endif /* PECULIAR_486 */ - __copy_to_user(d, &S387->cwd, 7*4); + if (__copy_to_user(d, &S387->cwd, 7*4)) + return -1; RE_ENTRANT_CHECK_ON; d += 7*4; diff --git a/arch/i386/math-emu/fpu_system.h b/arch/i386/math-emu/fpu_system.h index bf26341c8bd..a3ae28c49dd 100644 --- a/arch/i386/math-emu/fpu_system.h +++ b/arch/i386/math-emu/fpu_system.h @@ -68,6 +68,7 @@ #define FPU_access_ok(x,y,z) if ( !access_ok(x,y,z) ) \ math_abort(FPU_info,SIGSEGV) +#define FPU_abort math_abort(FPU_info, SIGSEGV) #undef FPU_IGNORE_CODE_SEGV #ifdef FPU_IGNORE_CODE_SEGV diff --git a/arch/i386/math-emu/load_store.c b/arch/i386/math-emu/load_store.c index 85314be2fef..eebd6fb1c8a 100644 --- a/arch/i386/math-emu/load_store.c +++ b/arch/i386/math-emu/load_store.c @@ -227,6 +227,8 @@ int FPU_load_store(u_char type, fpu_addr_modes addr_modes, case 027: /* fild m64int */ clear_C1(); loaded_tag = FPU_load_int64((long long __user *)data_address); + if (loaded_tag == TAG_Error) + return 0; FPU_settag0(loaded_tag); break; case 030: /* fstenv m14/28byte */ diff --git a/arch/i386/math-emu/reg_ld_str.c b/arch/i386/math-emu/reg_ld_str.c index f06ed41d191..e976caef649 100644 --- a/arch/i386/math-emu/reg_ld_str.c +++ b/arch/i386/math-emu/reg_ld_str.c @@ -244,7 +244,8 @@ int FPU_load_int64(long long __user *_s) RE_ENTRANT_CHECK_OFF; FPU_access_ok(VERIFY_READ, _s, 8); - copy_from_user(&s,_s,8); + if (copy_from_user(&s,_s,8)) + FPU_abort; RE_ENTRANT_CHECK_ON; if (s == 0) @@ -907,7 +908,8 @@ int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d) RE_ENTRANT_CHECK_OFF; FPU_access_ok(VERIFY_WRITE,d,8); - copy_to_user(d, &tll, 8); + if (copy_to_user(d, &tll, 8)) + FPU_abort; RE_ENTRANT_CHECK_ON; return 1; @@ -1336,7 +1338,8 @@ u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d) I387.soft.fcs &= ~0xf8000000; I387.soft.fos |= 0xffff0000; #endif /* PECULIAR_486 */ - __copy_to_user(d, &control_word, 7*4); + if (__copy_to_user(d, &control_word, 7*4)) + FPU_abort; RE_ENTRANT_CHECK_ON; d += 0x1c; } @@ -1359,9 +1362,11 @@ void fsave(fpu_addr_modes addr_modes, u_char __user *data_address) FPU_access_ok(VERIFY_WRITE,d,80); /* Copy all registers in stack order. */ - __copy_to_user(d, register_base+offset, other); + if (__copy_to_user(d, register_base+offset, other)) + FPU_abort; if ( offset ) - __copy_to_user(d+other, register_base, offset); + if (__copy_to_user(d+other, register_base, offset)) + FPU_abort; RE_ENTRANT_CHECK_ON; finit(); -- cgit v1.2.3 From a63954b5cad5765e52870bb649992bf636f32a6b Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] i386: remove pointless printk from i386 oops output This just got removed on x86-64, do the same on 32bit. It always annoyed me when this ate a line of oops output pushing interesting stuff off the screen. Signed-off-by: Dave Jones Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 396041a46e3..48ebfab661b 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -777,7 +777,6 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg) printk(" on CPU%d, eip %08lx, registers:\n", smp_processor_id(), regs->eip); show_registers(regs); - printk(KERN_EMERG "console shuts up ...\n"); console_silent(); spin_unlock(&nmi_print_lock); bust_spinlocks(0); -- cgit v1.2.3 From 36b2a8d5aff4cb3ee83d5e40447a8f073bcfe2fb Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86-64: add X86_FEATURE_PEBS and detection Here is a patch (used by perfmon2) to detect the presence of the Precise Event Based Sampling (PEBS) feature for Intel 64-bit processors. The patch also adds the cpu_has_pebs macro. changelog: - adds X86_FEATURE_PEBS - adds cpu_has_pebs to test for X86_FEATURE_PEBS Signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index fc944b5e8f4..619af2e2fa2 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -835,6 +835,13 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); } + if (cpu_has_ds) { + unsigned int l1, l2; + rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<12))) + set_bit(X86_FEATURE_PEBS, c->x86_capability); + } + n = c->extended_cpuid_level; if (n >= 0x80000008) { unsigned eax = cpuid_eax(0x80000008); -- cgit v1.2.3 From 42ed458aa51337357d7632c64aed4528f923e829 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] i386: i386 add X86_FEATURE_PEBS and detection Here is a patch (used by perfmon2) to detect the presence of the Precise Event Based Sampling (PEBS) feature for i386. The patch also adds the cpu_has_pebs macro. - adds X86_FEATURE_PEBS - adds cpu_has_pebs to test for X86_FEATURE_PEBS Signed-off-by: stephane eranian Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/intel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 94a95aa5227..798c2f617e8 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -195,8 +195,14 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability); -} + if (cpu_has_ds) { + unsigned int l1; + rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<12))) + set_bit(X86_FEATURE_PEBS, c->x86_capability); + } +} static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) { -- cgit v1.2.3 From e2764a1e306c986053a52b33748c33463cf888de Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86-64: use BUILD_BUG_ON in FPU code Signed-off-by: Alexey Dobriyan Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/x86_64/kernel/i387.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/i387.c b/arch/x86_64/kernel/i387.c index 3aa1e9bb781..1d58c13bc6b 100644 --- a/arch/x86_64/kernel/i387.c +++ b/arch/x86_64/kernel/i387.c @@ -82,11 +82,8 @@ int save_i387(struct _fpstate __user *buf) struct task_struct *tsk = current; int err = 0; - { - extern void bad_user_i387_struct(void); - if (sizeof(struct user_i387_struct) != sizeof(tsk->thread.i387.fxsave)) - bad_user_i387_struct(); - } + BUILD_BUG_ON(sizeof(struct user_i387_struct) != + sizeof(tsk->thread.i387.fxsave)); if ((unsigned long)buf % 16) printk("save_i387: bad fpstate %p\n",buf); -- cgit v1.2.3 From e5e3a0428968dcc1f9318ce1c941a918e99f8b84 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] i386: remove default_ldt, and simplify ldt-setting. This patch removes the default_ldt[] array, as it has been unused since iBCS stopped being supported. This means it is now possible to actually set an empty LDT segment. In order to deal with this, the set_ldt_desc/load_LDT pair has been replaced with a single set_ldt() operation which is responsible for both setting up the LDT descriptor in the GDT, and reloading the LDT register. If there are no LDT entries, the LDT register is loaded with a NULL descriptor. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Andi Kleen Acked-by: Zachary Amsden Signed-off-by: Andrew Morton --- arch/i386/kernel/ldt.c | 4 +--- arch/i386/kernel/traps.c | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/ldt.c b/arch/i386/kernel/ldt.c index 445211eb2d5..b410e5fb034 100644 --- a/arch/i386/kernel/ldt.c +++ b/arch/i386/kernel/ldt.c @@ -160,16 +160,14 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount) { int err; unsigned long size; - void *address; err = 0; - address = &default_ldt[0]; size = 5*sizeof(struct desc_struct); if (size > bytecount) size = bytecount; err = size; - if (copy_to_user(ptr, address, size)) + if (clear_user(ptr, size)) err = -EFAULT; return err; diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 48ebfab661b..56655ea8d98 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -61,9 +61,6 @@ int panic_on_unrecovered_nmi; asmlinkage int system_call(void); -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 } }; - /* Do we ignore FPU interrupts ? */ char ignore_fpu_irq = 0; -- cgit v1.2.3 From bb81a09e55eaf7e5f798468ab971469b6f66a259 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86: all cpu backtrace When a spinlock lockup occurs, arrange for the NMI code to emit an all-cpu backtrace, so we get to see which CPU is holding the lock, and where. Cc: Andi Kleen Cc: Ingo Molnar Cc: Badari Pulavarty Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 26 ++++++++++++++++++++++++++ arch/x86_64/kernel/nmi.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index eaafe233a5d..171194ccb7b 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,8 @@ int nmi_watchdog_enabled; static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); +static cpumask_t backtrace_mask = CPU_MASK_NONE; + /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -907,6 +910,16 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } + if (cpu_isset(cpu, backtrace_mask)) { + static DEFINE_SPINLOCK(lock); /* Serialise the printks */ + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); + dump_stack(); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } + sum = per_cpu(irq_stat, cpu).apic_timer_irqs; /* if the apic timer isn't firing, this cpu isn't doing much */ @@ -1033,6 +1046,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +void __trigger_all_cpu_backtrace(void) +{ + int i; + + backtrace_mask = cpu_online_map; + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpus_empty(backtrace_mask)) + break; + mdelay(1); + } +} + EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 7af9cb3e2d9..27e95e7922c 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -12,14 +12,15 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ +#include #include #include #include #include #include -#include #include #include +#include #include #include @@ -41,6 +42,8 @@ int panic_on_unrecovered_nmi; static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); +static cpumask_t backtrace_mask = CPU_MASK_NONE; + /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -782,6 +785,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; + int cpu = smp_processor_id(); struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); u64 dummy; int rc=0; @@ -799,6 +803,16 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } + if (cpu_isset(cpu, backtrace_mask)) { + static DEFINE_SPINLOCK(lock); /* Serialise the printks */ + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); + dump_stack(); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } + #ifdef CONFIG_X86_MCE /* Could check oops_in_progress here too, but it's safer not too */ @@ -931,6 +945,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +void __trigger_all_cpu_backtrace(void) +{ + int i; + + backtrace_mask = cpu_online_map; + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpus_empty(backtrace_mask)) + break; + mdelay(1); + } +} + EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -- cgit v1.2.3 From be44d2aabce2d62f72d5751d1871b6212bf7a1c7 Mon Sep 17 00:00:00 2001 From: Stas Sergeev Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] i386: espfix cleanup Clean up the espfix code: - Introduced PER_CPU() macro to be used from asm - Introduced GET_DESC_BASE() macro to be used from asm - Rewrote the fixup code in asm, as calling a C code with the altered %ss appeared to be unsafe - No longer altering the stack from a .fixup section - 16bit per-cpu stack is no longer used, instead the stack segment base is patched the way so that the high word of the kernel and user %esp are the same. - Added the limit-patching for the espfix segment. (Chuck Ebbert) [jeremy@goop.org: use the x86 scaling addressing mode rather than shifting] Signed-off-by: Stas Sergeev Signed-off-by: Andi Kleen Acked-by: Zachary Amsden Acked-by: Chuck Ebbert <76306.1226@compuserve.com> Acked-by: Jan Beulich Cc: Andi Kleen Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 5 +++ arch/i386/kernel/cpu/common.c | 11 ------- arch/i386/kernel/entry.S | 73 +++++++++++++++++++----------------------- arch/i386/kernel/head.S | 2 +- arch/i386/kernel/traps.c | 57 +++++++++------------------------ 5 files changed, 55 insertions(+), 93 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index c80271f8f08..e94d910a28b 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -58,6 +58,11 @@ void foo(void) OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); + OFFSET(GDS_size, Xgt_desc_struct, size); + OFFSET(GDS_address, Xgt_desc_struct, address); + OFFSET(GDS_pad, Xgt_desc_struct, pad); + BLANK(); + OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext); BLANK(); diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index d9f3e3c31f0..5532fc4e1bf 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -24,9 +24,6 @@ DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); -DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); -EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); - static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; static int disable_x86_serial_nr __cpuinitdata = 1; @@ -603,7 +600,6 @@ void __cpuinit cpu_init(void) struct tss_struct * t = &per_cpu(init_tss, cpu); struct thread_struct *thread = ¤t->thread; struct desc_struct *gdt; - __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu); struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); if (cpu_test_and_set(cpu, cpu_initialized)) { @@ -651,13 +647,6 @@ old_gdt: * and set up the GDT descriptor: */ memcpy(gdt, cpu_gdt_table, GDT_SIZE); - - /* Set up GDT entry for 16bit stack */ - *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |= - ((((__u64)stk16_off) << 16) & 0x000000ffffff0000ULL) | - ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) | - (CPU_16BIT_STACK_SIZE - 1); - cpu_gdt_descr->size = GDT_SIZE - 1; cpu_gdt_descr->address = (unsigned long)gdt; diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 5a63d6fdb70..c38d801ba0b 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "irq_vectors.h" @@ -418,23 +419,18 @@ ldt_ss: * This is an "official" bug of all the x86-compatible * CPUs, which we can try to work around to make * dosemu and wine happy. */ - subl $8, %esp # reserve space for switch16 pointer - CFI_ADJUST_CFA_OFFSET 8 + movl OLDESP(%esp), %eax + movl %esp, %edx + call patch_espfix_desc + pushl $__ESPFIX_SS + CFI_ADJUST_CFA_OFFSET 4 + pushl %eax + CFI_ADJUST_CFA_OFFSET 4 DISABLE_INTERRUPTS TRACE_IRQS_OFF - movl %esp, %eax - /* Set up the 16bit stack frame with switch32 pointer on top, - * and a switch16 pointer on top of the current frame. */ - call setup_x86_bogus_stack - CFI_ADJUST_CFA_OFFSET -8 # frame has moved - TRACE_IRQS_IRET - RESTORE_REGS - lss 20+4(%esp), %esp # switch to 16bit stack -1: INTERRUPT_RETURN -.section __ex_table,"a" - .align 4 - .long 1b,iret_exc -.previous + lss (%esp), %esp + CFI_ADJUST_CFA_OFFSET -8 + jmp restore_nocheck CFI_ENDPROC # perform work that needs to be done immediately before resumption @@ -524,30 +520,30 @@ syscall_badsys: CFI_ENDPROC #define FIXUP_ESPFIX_STACK \ - movl %esp, %eax; \ - /* switch to 32bit stack using the pointer on top of 16bit stack */ \ - lss %ss:CPU_16BIT_STACK_SIZE-8, %esp; \ - /* copy data from 16bit stack to 32bit stack */ \ - call fixup_x86_bogus_stack; \ - /* put ESP to the proper location */ \ - movl %eax, %esp; -#define UNWIND_ESPFIX_STACK \ + /* since we are on a wrong stack, we cant make it a C code :( */ \ + GET_THREAD_INFO(%ebp); \ + movl TI_cpu(%ebp), %ebx; \ + PER_CPU(cpu_gdt_descr, %ebx); \ + movl GDS_address(%ebx), %ebx; \ + GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ + addl %esp, %eax; \ + pushl $__KERNEL_DS; \ + CFI_ADJUST_CFA_OFFSET 4; \ pushl %eax; \ CFI_ADJUST_CFA_OFFSET 4; \ + lss (%esp), %esp; \ + CFI_ADJUST_CFA_OFFSET -8; +#define UNWIND_ESPFIX_STACK \ movl %ss, %eax; \ - /* see if on 16bit stack */ \ + /* see if on espfix stack */ \ cmpw $__ESPFIX_SS, %ax; \ - je 28f; \ -27: popl %eax; \ - CFI_ADJUST_CFA_OFFSET -4; \ -.section .fixup,"ax"; \ -28: movl $__KERNEL_DS, %eax; \ + jne 27f; \ + movl $__KERNEL_DS, %eax; \ movl %eax, %ds; \ movl %eax, %es; \ - /* switch to 32bit stack */ \ + /* switch to normal stack */ \ FIXUP_ESPFIX_STACK; \ - jmp 27b; \ -.previous +27:; /* * Build the entry stubs and pointer table with @@ -614,7 +610,6 @@ error_code: pushl %eax CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eax, 0 - xorl %eax, %eax pushl %ebp CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ebp, 0 @@ -627,7 +622,6 @@ error_code: pushl %edx CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET edx, 0 - decl %eax # eax = -1 pushl %ecx CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ecx, 0 @@ -644,7 +638,7 @@ error_code: /*CFI_REGISTER es, ecx*/ movl ES(%esp), %edi # get the function address movl ORIG_EAX(%esp), %edx # get the error code - movl %eax, ORIG_EAX(%esp) + movl $-1, ORIG_EAX(%esp) movl %ecx, ES(%esp) /*CFI_REL_OFFSET es, ES*/ movl $(__USER_DS), %ecx @@ -754,7 +748,7 @@ KPROBE_ENTRY(nmi) cmpw $__ESPFIX_SS, %ax popl %eax CFI_ADJUST_CFA_OFFSET -4 - je nmi_16bit_stack + je nmi_espfix_stack cmpl $sysenter_entry,(%esp) je nmi_stack_fixup pushl %eax @@ -797,7 +791,7 @@ nmi_debug_stack_check: FIX_STACK(24,nmi_stack_correct, 1) jmp nmi_stack_correct -nmi_16bit_stack: +nmi_espfix_stack: /* We have a RING0_INT_FRAME here. * * create the pointer to lss back @@ -806,7 +800,6 @@ nmi_16bit_stack: CFI_ADJUST_CFA_OFFSET 4 pushl %esp CFI_ADJUST_CFA_OFFSET 4 - movzwl %sp, %esp addw $4, (%esp) /* copy the iret frame of 12 bytes */ .rept 3 @@ -817,11 +810,11 @@ nmi_16bit_stack: CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL FIXUP_ESPFIX_STACK # %eax == %esp - CFI_ADJUST_CFA_OFFSET -20 # the frame has now moved xorl %edx,%edx # zero error code call do_nmi RESTORE_REGS - lss 12+4(%esp), %esp # back to 16bit stack + lss 12+4(%esp), %esp # back to espfix stack + CFI_ADJUST_CFA_OFFSET -24 1: INTERRUPT_RETURN CFI_ENDPROC .section __ex_table,"a" diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index ca31f18d277..b1f1df11fcc 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -584,7 +584,7 @@ ENTRY(cpu_gdt_table) .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */ .quad 0x004092000000ffff /* 0xc8 APM DS data */ - .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */ + .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ .quad 0x0000000000000000 /* 0xd8 - unused */ .quad 0x0000000000000000 /* 0xe0 - unused */ .quad 0x0000000000000000 /* 0xe8 - unused */ diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 56655ea8d98..f9bb1f89d68 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -1088,49 +1088,24 @@ fastcall void do_spurious_interrupt_bug(struct pt_regs * regs, #endif } -fastcall void setup_x86_bogus_stack(unsigned char * stk) +fastcall unsigned long patch_espfix_desc(unsigned long uesp, + unsigned long kesp) { - unsigned long *switch16_ptr, *switch32_ptr; - struct pt_regs *regs; - unsigned long stack_top, stack_bot; - unsigned short iret_frame16_off; int cpu = smp_processor_id(); - /* reserve the space on 32bit stack for the magic switch16 pointer */ - memmove(stk, stk + 8, sizeof(struct pt_regs)); - switch16_ptr = (unsigned long *)(stk + sizeof(struct pt_regs)); - regs = (struct pt_regs *)stk; - /* now the switch32 on 16bit stack */ - stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); - stack_top = stack_bot + CPU_16BIT_STACK_SIZE; - switch32_ptr = (unsigned long *)(stack_top - 8); - iret_frame16_off = CPU_16BIT_STACK_SIZE - 8 - 20; - /* copy iret frame on 16bit stack */ - memcpy((void *)(stack_bot + iret_frame16_off), ®s->eip, 20); - /* fill in the switch pointers */ - switch16_ptr[0] = (regs->esp & 0xffff0000) | iret_frame16_off; - switch16_ptr[1] = __ESPFIX_SS; - switch32_ptr[0] = (unsigned long)stk + sizeof(struct pt_regs) + - 8 - CPU_16BIT_STACK_SIZE; - switch32_ptr[1] = __KERNEL_DS; -} - -fastcall unsigned char * fixup_x86_bogus_stack(unsigned short sp) -{ - unsigned long *switch32_ptr; - unsigned char *stack16, *stack32; - unsigned long stack_top, stack_bot; - int len; - int cpu = smp_processor_id(); - stack_bot = (unsigned long)&per_cpu(cpu_16bit_stack, cpu); - stack_top = stack_bot + CPU_16BIT_STACK_SIZE; - switch32_ptr = (unsigned long *)(stack_top - 8); - /* copy the data from 16bit stack to 32bit stack */ - len = CPU_16BIT_STACK_SIZE - 8 - sp; - stack16 = (unsigned char *)(stack_bot + sp); - stack32 = (unsigned char *) - (switch32_ptr[0] + CPU_16BIT_STACK_SIZE - 8 - len); - memcpy(stack32, stack16, len); - return stack32; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address; + unsigned long base = (kesp - uesp) & -THREAD_SIZE; + unsigned long new_kesp = kesp - base; + unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT; + __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS]; + /* Set up base for espfix segment */ + desc &= 0x00f0ff0000000000ULL; + desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) | + ((((__u64)base) << 32) & 0xff00000000000000ULL) | + ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) | + (lim_pages & 0xffff); + *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc; + return new_kesp; } /* -- cgit v1.2.3 From acc207616a91a413a50fdd8847a747c4a7324167 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] i386: add sleazy FPU optimization i386 port of the sLeAZY-fpu feature. Chuck reports that this gives him a +/- 0.4% improvement on his simple benchmark x86_64 description follows: Right now the kernel on x86-64 has a 100% lazy fpu behavior: after *every* context switch a trap is taken for the first FPU use to restore the FPU context lazily. This is of course great for applications that have very sporadic or no FPU use (since then you avoid doing the expensive save/restore all the time). However for very frequent FPU users... you take an extra trap every context switch. The patch below adds a simple heuristic to this code: After 5 consecutive context switches of FPU use, the lazy behavior is disabled and the context gets restored every context switch. If the app indeed uses the FPU, the trap is avoided. (the chance of the 6th time slice using FPU after the previous 5 having done so are quite high obviously). After 256 switches, this is reset and lazy behavior is returned (until there are 5 consecutive ones again). The reason for this is to give apps that do longer bursts of FPU use still the lazy behavior back after some time. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/process.c | 12 ++++++++++++ arch/i386/kernel/traps.c | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index dd53c58f64f..ae924c416b6 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -648,6 +648,11 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas __unlazy_fpu(prev_p); + + /* we're going to use this soon, after a few expensive things */ + if (next_p->fpu_counter > 5) + prefetch(&next->i387.fxsave); + /* * Reload esp0. */ @@ -697,6 +702,13 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas disable_tsc(prev_p, next_p); + /* If the task has used fpu the last 5 timeslices, just do a full + * restore of the math state immediately to avoid the trap; the + * chances of needing FPU soon are obviously high now + */ + if (next_p->fpu_counter > 5) + math_state_restore(); + return prev_p; } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index f9bb1f89d68..4a6fa2837df 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -1118,7 +1118,7 @@ fastcall unsigned long patch_espfix_desc(unsigned long uesp, * Must be called with kernel preemption disabled (in this case, * local interrupts are disabled at the call-site in entry.S). */ -asmlinkage void math_state_restore(struct pt_regs regs) +asmlinkage void math_state_restore(void) { struct thread_info *thread = current_thread_info(); struct task_struct *tsk = thread->task; @@ -1128,6 +1128,7 @@ asmlinkage void math_state_restore(struct pt_regs regs) init_fpu(tsk); restore_fpu(tsk); thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */ + tsk->fpu_counter++; } #ifndef CONFIG_MATH_EMULATION -- cgit v1.2.3 From 399287229c775a8962a852a761d65dc9475dec7c Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86-64: Insert Local and IO APIC(s) into resource map Insert the Local APIC and IO APIC(s) into the resource tree. It allows the APIC resources to be visible within /proc/iomem. The patch also takes into account IO APIC(s) mapped in the PCI space by deferring the insertion until after PCI has allocated its necessary resources. Signed-off-by: Aaron Durbin Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/apic.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 4d9d5ed942b..5c468971e64 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,12 @@ int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; +static struct resource *ioapic_resources; +static struct resource lapic_resource = { + .name = "Local APIC", + .flags = IORESOURCE_MEM | IORESOURCE_BUSY, +}; + /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -585,6 +592,64 @@ static int __init detect_init_APIC (void) return 0; } +#ifdef CONFIG_X86_IO_APIC +static struct resource * __init ioapic_setup_resources(void) +{ +#define IOAPIC_RESOURCE_NAME_SIZE 11 + unsigned long n; + struct resource *res; + char *mem; + int i; + + if (nr_ioapics <= 0) + return NULL; + + n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); + n *= nr_ioapics; + + mem = alloc_bootmem(n); + res = (void *)mem; + + if (mem != NULL) { + memset(mem, 0, n); + mem += sizeof(struct resource) * nr_ioapics; + + for (i = 0; i < nr_ioapics; i++) { + res[i].name = mem; + res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; + sprintf(mem, "IOAPIC %u", i); + mem += IOAPIC_RESOURCE_NAME_SIZE; + } + } + + ioapic_resources = res; + + return res; +} + +static int __init ioapic_insert_resources(void) +{ + int i; + struct resource *r = ioapic_resources; + + if (!r) { + printk("IO APIC resources could be not be allocated.\n"); + return -1; + } + + for (i = 0; i < nr_ioapics; i++) { + insert_resource(&iomem_resource, r); + r++; + } + + return 0; +} + +/* Insert the IO APIC resources after PCI initialization has occured to handle + * IO APICS that are mapped in on a BAR in PCI space. */ +late_initcall(ioapic_insert_resources); +#endif + void __init init_apic_mappings(void) { unsigned long apic_phys; @@ -604,6 +669,11 @@ void __init init_apic_mappings(void) apic_mapped = 1; apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); + /* Put local APIC into the resource map. */ + lapic_resource.start = apic_phys; + lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; + insert_resource(&iomem_resource, &lapic_resource); + /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). @@ -613,7 +683,9 @@ void __init init_apic_mappings(void) { unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; int i; + struct resource *ioapic_res; + ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; @@ -625,6 +697,12 @@ void __init init_apic_mappings(void) apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", __fix_to_virt(idx), ioapic_phys); idx++; + + if (ioapic_res != NULL) { + ioapic_res->start = ioapic_phys; + ioapic_res->end = ioapic_phys + (4 * 1024) - 1; + ioapic_res++; + } } } } -- cgit v1.2.3 From c0e84b9901c0924e2503c0aab3772a4469ba4aef Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Add iounmap in error paths in hpet code Signed-off-by: Amol Lad Signed-off-by: Andi Kleen --- arch/i386/kernel/time_hpet.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/time_hpet.c b/arch/i386/kernel/time_hpet.c index 1a2a979cf6a..1e4702dfcd0 100644 --- a/arch/i386/kernel/time_hpet.c +++ b/arch/i386/kernel/time_hpet.c @@ -132,14 +132,20 @@ int __init hpet_enable(void) * the single HPET timer for system time. */ #ifdef CONFIG_HPET_EMULATE_RTC - if (!(id & HPET_ID_NUMBER)) + if (!(id & HPET_ID_NUMBER)) { + iounmap(hpet_virt_address); + hpet_virt_address = NULL; return -1; + } #endif hpet_period = hpet_readl(HPET_PERIOD); - if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) + if ((hpet_period < HPET_MIN_PERIOD) || (hpet_period > HPET_MAX_PERIOD)) { + iounmap(hpet_virt_address); + hpet_virt_address = NULL; return -1; + } /* * 64 bit math @@ -156,8 +162,11 @@ int __init hpet_enable(void) hpet_use_timer = id & HPET_ID_LEGSUP; - if (hpet_timer_stop_set_go(hpet_tick)) + if (hpet_timer_stop_set_go(hpet_tick)) { + iounmap(hpet_virt_address); + hpet_virt_address = NULL; return -1; + } use_hpet = 1; -- cgit v1.2.3 From fa5cecd111d235819a1d807d43216ae459a0dd6f Mon Sep 17 00:00:00 2001 From: Amol Lad Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: add missing iounmap in i386 hpet clocksource code ioremap must be balanced by an iounmap and failing to do so can result in a memory leak. Tested (compilation only): - using allmodconfig - making sure the files are compiling without any warning/error due to new changes Signed-off-by: Amol Lad Signed-off-by: Andi Kleen --- arch/i386/kernel/hpet.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c index 17647a530b2..45a8685bb60 100644 --- a/arch/i386/kernel/hpet.c +++ b/arch/i386/kernel/hpet.c @@ -34,6 +34,7 @@ static int __init init_hpet_clocksource(void) unsigned long hpet_period; void __iomem* hpet_base; u64 tmp; + int err; if (!is_hpet_enabled()) return -ENODEV; @@ -61,7 +62,11 @@ static int __init init_hpet_clocksource(void) do_div(tmp, FSEC_PER_NSEC); clocksource_hpet.mult = (u32)tmp; - return clocksource_register(&clocksource_hpet); + err = clocksource_register(&clocksource_hpet); + if (err) + iounmap(hpet_base); + + return err; } module_init(init_hpet_clocksource); -- cgit v1.2.3 From da68933e0a999fb13636653c710cca701b457ad2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] x86-64: dump_trace() atomicity fix Fix BUG: using smp_processor_id() in preemptible [00000001] code: in backtracer on preemptible debug kernels. Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index eedd4e759c3..e37b4d77d5a 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -254,7 +254,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack, struct stacktrace_ops *ops, void *data) { - const unsigned cpu = smp_processor_id(); + const unsigned cpu = get_cpu(); unsigned long *irqstack_end = (unsigned long*)cpu_pda(cpu)->irqstackptr; unsigned used = 0; struct thread_info *tinfo; @@ -286,11 +286,11 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, MSG("Leftover inexact backtrace:"); stack = (unsigned long *)UNW_SP(&info); if (!stack) - return; + goto out; } else MSG("Full inexact backtrace again:"); } else if (call_trace >= 1) - return; + goto out; else MSG("Full inexact backtrace again:"); } else @@ -385,6 +385,8 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, tinfo = current_thread_info(); HANDLE_STACK (valid_stack_ptr(tinfo, stack)); #undef HANDLE_STACK +out: + put_cpu(); } EXPORT_SYMBOL(dump_trace); -- cgit v1.2.3 From bcddc0155f351ab3f06c6ede6d91fd399ef9e18f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] x86-64: miscellaneous entry.S adjustments This patch: - makes ret_from_sys_call no longer global (all external users were previously switched to use int_ret_from_sys_call) - adjusts placement of a CFI_{REMEMBER,RESTORE}_STATE pair to better fit logic flow - eliminates an unnecessary pair of CFI_{REMEMBER,RESTORE}_STATE - glues together function- and unwinder-wise the previously separate system_call and int_ret_from_sys_call function fragments Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/x86_64/kernel/entry.S | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 7d401b00d82..601d332c4b7 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -230,7 +230,6 @@ ENTRY(system_call) CFI_REL_OFFSET rip,RIP-ARGOFFSET GET_THREAD_INFO(%rcx) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),threadinfo_flags(%rcx) - CFI_REMEMBER_STATE jnz tracesys cmpq $__NR_syscall_max,%rax ja badsys @@ -241,7 +240,6 @@ ENTRY(system_call) * Syscall return path ending with SYSRET (fast path) * Has incomplete stack frame and undefined top of stack. */ - .globl ret_from_sys_call ret_from_sys_call: movl $_TIF_ALLWORK_MASK,%edi /* edi: flagmask */ @@ -251,8 +249,8 @@ sysret_check: TRACE_IRQS_OFF movl threadinfo_flags(%rcx),%edx andl %edi,%edx - CFI_REMEMBER_STATE jnz sysret_careful + CFI_REMEMBER_STATE /* * sysretq will re-enable interrupts: */ @@ -265,10 +263,10 @@ sysret_check: swapgs sysretq + CFI_RESTORE_STATE /* Handle reschedules */ /* edx: work, edi: workmask */ sysret_careful: - CFI_RESTORE_STATE bt $TIF_NEED_RESCHED,%edx jnc sysret_signal TRACE_IRQS_ON @@ -306,7 +304,6 @@ badsys: /* Do syscall tracing */ tracesys: - CFI_RESTORE_STATE SAVE_REST movq $-ENOSYS,RAX(%rsp) FIXUP_TOP_OF_STACK %rdi @@ -322,32 +319,13 @@ tracesys: call *sys_call_table(,%rax,8) 1: movq %rax,RAX-ARGOFFSET(%rsp) /* Use IRET because user could have changed frame */ - jmp int_ret_from_sys_call - CFI_ENDPROC -END(system_call) /* * Syscall return path ending with IRET. * Has correct top of stack, but partial stack frame. - */ -ENTRY(int_ret_from_sys_call) - CFI_STARTPROC simple - CFI_SIGNAL_FRAME - CFI_DEF_CFA rsp,SS+8-ARGOFFSET - /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ - CFI_REL_OFFSET rsp,RSP-ARGOFFSET - /*CFI_REL_OFFSET rflags,EFLAGS-ARGOFFSET*/ - /*CFI_REL_OFFSET cs,CS-ARGOFFSET*/ - CFI_REL_OFFSET rip,RIP-ARGOFFSET - CFI_REL_OFFSET rdx,RDX-ARGOFFSET - CFI_REL_OFFSET rcx,RCX-ARGOFFSET - CFI_REL_OFFSET rax,RAX-ARGOFFSET - CFI_REL_OFFSET rdi,RDI-ARGOFFSET - CFI_REL_OFFSET rsi,RSI-ARGOFFSET - CFI_REL_OFFSET r8,R8-ARGOFFSET - CFI_REL_OFFSET r9,R9-ARGOFFSET - CFI_REL_OFFSET r10,R10-ARGOFFSET - CFI_REL_OFFSET r11,R11-ARGOFFSET + */ + .globl int_ret_from_sys_call +int_ret_from_sys_call: cli TRACE_IRQS_OFF testl $3,CS-ARGOFFSET(%rsp) @@ -394,8 +372,6 @@ int_very_careful: popq %rdi CFI_ADJUST_CFA_OFFSET -8 andl $~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP),%edi - cli - TRACE_IRQS_OFF jmp int_restore_rest int_signal: @@ -411,7 +387,7 @@ int_restore_rest: TRACE_IRQS_OFF jmp int_with_check CFI_ENDPROC -END(int_ret_from_sys_call) +END(system_call) /* * Certain special system calls that need to save a complete full stack frame. -- cgit v1.2.3 From eb5b7b9d86f46b45ba1f986302fdf7df84fb8297 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Use asm-offsets for the offsets of registers into the pt_regs struct Use asm-offsets for the offsets of registers into the pt_regs struct, rather than having hard-coded constants I left the constants in the comments of entry.S because they're useful for reference; the code in entry.S is very dependent on the layout of pt_regs, even when using asm-offsets. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Keith Owens Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 17 ++++++ arch/i386/kernel/entry.S | 120 ++++++++++++++++++----------------------- 2 files changed, 69 insertions(+), 68 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index e94d910a28b..70b19807acf 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -63,6 +63,23 @@ void foo(void) OFFSET(GDS_pad, Xgt_desc_struct, pad); BLANK(); + OFFSET(PT_EBX, pt_regs, ebx); + OFFSET(PT_ECX, pt_regs, ecx); + OFFSET(PT_EDX, pt_regs, edx); + OFFSET(PT_ESI, pt_regs, esi); + OFFSET(PT_EDI, pt_regs, edi); + OFFSET(PT_EBP, pt_regs, ebp); + OFFSET(PT_EAX, pt_regs, eax); + OFFSET(PT_DS, pt_regs, xds); + OFFSET(PT_ES, pt_regs, xes); + OFFSET(PT_ORIG_EAX, pt_regs, orig_eax); + OFFSET(PT_EIP, pt_regs, eip); + OFFSET(PT_CS, pt_regs, xcs); + OFFSET(PT_EFLAGS, pt_regs, eflags); + OFFSET(PT_OLDESP, pt_regs, esp); + OFFSET(PT_OLDSS, pt_regs, xss); + BLANK(); + OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext); BLANK(); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index c38d801ba0b..0069bf01603 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -54,22 +54,6 @@ #define nr_syscalls ((syscall_table_size)/4) -EBX = 0x00 -ECX = 0x04 -EDX = 0x08 -ESI = 0x0C -EDI = 0x10 -EBP = 0x14 -EAX = 0x18 -DS = 0x1C -ES = 0x20 -ORIG_EAX = 0x24 -EIP = 0x28 -CS = 0x2C -EFLAGS = 0x30 -OLDESP = 0x34 -OLDSS = 0x38 - CF_MASK = 0x00000001 TF_MASK = 0x00000100 IF_MASK = 0x00000200 @@ -93,7 +77,7 @@ VM_MASK = 0x00020000 .macro TRACE_IRQS_IRET #ifdef CONFIG_TRACE_IRQFLAGS - testl $IF_MASK,EFLAGS(%esp) # interrupts off? + testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off? jz 1f TRACE_IRQS_ON 1: @@ -199,18 +183,18 @@ VM_MASK = 0x00020000 #define RING0_PTREGS_FRAME \ CFI_STARTPROC simple;\ CFI_SIGNAL_FRAME;\ - CFI_DEF_CFA esp, OLDESP-EBX;\ - /*CFI_OFFSET cs, CS-OLDESP;*/\ - CFI_OFFSET eip, EIP-OLDESP;\ - /*CFI_OFFSET es, ES-OLDESP;*/\ - /*CFI_OFFSET ds, DS-OLDESP;*/\ - CFI_OFFSET eax, EAX-OLDESP;\ - CFI_OFFSET ebp, EBP-OLDESP;\ - CFI_OFFSET edi, EDI-OLDESP;\ - CFI_OFFSET esi, ESI-OLDESP;\ - CFI_OFFSET edx, EDX-OLDESP;\ - CFI_OFFSET ecx, ECX-OLDESP;\ - CFI_OFFSET ebx, EBX-OLDESP + CFI_DEF_CFA esp, PT_OLDESP-PT_EBX;\ + /*CFI_OFFSET cs, PT_CS-PT_OLDESP;*/\ + CFI_OFFSET eip, PT_EIP-PT_OLDESP;\ + /*CFI_OFFSET es, PT_ES-PT_OLDESP;*/\ + /*CFI_OFFSET ds, PT_DS-PT_OLDESP;*/\ + CFI_OFFSET eax, PT_EAX-PT_OLDESP;\ + CFI_OFFSET ebp, PT_EBP-PT_OLDESP;\ + CFI_OFFSET edi, PT_EDI-PT_OLDESP;\ + CFI_OFFSET esi, PT_ESI-PT_OLDESP;\ + CFI_OFFSET edx, PT_EDX-PT_OLDESP;\ + CFI_OFFSET ecx, PT_ECX-PT_OLDESP;\ + CFI_OFFSET ebx, PT_EBX-PT_OLDESP ENTRY(ret_from_fork) CFI_STARTPROC @@ -242,8 +226,8 @@ ret_from_exception: ret_from_intr: GET_THREAD_INFO(%ebp) check_userspace: - movl EFLAGS(%esp), %eax # mix EFLAGS and CS - movb CS(%esp), %al + movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS + movb PT_CS(%esp), %al andl $(VM_MASK | SEGMENT_RPL_MASK), %eax cmpl $USER_RPL, %eax jb resume_kernel # not returning to v8086 or userspace @@ -266,7 +250,7 @@ need_resched: movl TI_flags(%ebp), %ecx # need_resched set ? testb $_TIF_NEED_RESCHED, %cl jz restore_all - testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? + testl $IF_MASK,PT_EFLAGS(%esp) # interrupts off (exception path) ? jz restore_all call preempt_schedule_irq jmp need_resched @@ -332,15 +316,15 @@ sysenter_past_esp: cmpl $(nr_syscalls), %eax jae syscall_badsys call *sys_call_table(,%eax,4) - movl %eax,EAX(%esp) + movl %eax,PT_EAX(%esp) DISABLE_INTERRUPTS TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx jne syscall_exit_work /* if something modifies registers it must also disable sysexit */ - movl EIP(%esp), %edx - movl OLDESP(%esp), %ecx + movl PT_EIP(%esp), %edx + movl PT_OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON ENABLE_INTERRUPTS_SYSEXIT @@ -354,7 +338,7 @@ ENTRY(system_call) CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) - testl $TF_MASK,EFLAGS(%esp) + testl $TF_MASK,PT_EFLAGS(%esp) jz no_singlestep orl $_TIF_SINGLESTEP,TI_flags(%ebp) no_singlestep: @@ -366,7 +350,7 @@ no_singlestep: jae syscall_badsys syscall_call: call *sys_call_table(,%eax,4) - movl %eax,EAX(%esp) # store the return value + movl %eax,PT_EAX(%esp) # store the return value syscall_exit: DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending @@ -377,12 +361,12 @@ syscall_exit: jne syscall_exit_work restore_all: - movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS - # Warning: OLDSS(%esp) contains the wrong/random values if we + movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS + # Warning: PT_OLDSS(%esp) contains the wrong/random values if we # are returning to the kernel. # See comments in process.c:copy_thread() for details. - movb OLDSS(%esp), %ah - movb CS(%esp), %al + movb PT_OLDSS(%esp), %ah + movb PT_CS(%esp), %al andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax CFI_REMEMBER_STATE @@ -409,7 +393,7 @@ iret_exc: CFI_RESTORE_STATE ldt_ss: - larl OLDSS(%esp), %eax + larl PT_OLDSS(%esp), %eax jnz restore_nocheck testl $0x00400000, %eax # returning to 32bit stack? jnz restore_nocheck # allright, normal return @@ -419,7 +403,7 @@ ldt_ss: * This is an "official" bug of all the x86-compatible * CPUs, which we can try to work around to make * dosemu and wine happy. */ - movl OLDESP(%esp), %eax + movl PT_OLDESP(%esp), %eax movl %esp, %edx call patch_espfix_desc pushl $__ESPFIX_SS @@ -454,7 +438,7 @@ work_resched: work_notifysig: # deal with pending signals and # notify-resume requests - testl $VM_MASK, EFLAGS(%esp) + testl $VM_MASK, PT_EFLAGS(%esp) movl %esp, %eax jne work_notifysig_v86 # returning to kernel-space or # vm86-space @@ -479,14 +463,14 @@ work_notifysig_v86: # perform syscall exit tracing ALIGN syscall_trace_entry: - movl $-ENOSYS,EAX(%esp) + movl $-ENOSYS,PT_EAX(%esp) movl %esp, %eax xorl %edx,%edx call do_syscall_trace cmpl $0, %eax jne resume_userspace # ret != 0 -> running under PTRACE_SYSEMU, # so must skip actual syscall - movl ORIG_EAX(%esp), %eax + movl PT_ORIG_EAX(%esp), %eax cmpl $(nr_syscalls), %eax jnae syscall_call jmp syscall_exit @@ -511,11 +495,11 @@ syscall_fault: CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL GET_THREAD_INFO(%ebp) - movl $-EFAULT,EAX(%esp) + movl $-EFAULT,PT_EAX(%esp) jmp resume_userspace syscall_badsys: - movl $-ENOSYS,EAX(%esp) + movl $-ENOSYS,PT_EAX(%esp) jmp resume_userspace CFI_ENDPROC @@ -636,10 +620,10 @@ error_code: popl %ecx CFI_ADJUST_CFA_OFFSET -4 /*CFI_REGISTER es, ecx*/ - movl ES(%esp), %edi # get the function address - movl ORIG_EAX(%esp), %edx # get the error code - movl $-1, ORIG_EAX(%esp) - movl %ecx, ES(%esp) + movl PT_ES(%esp), %edi # get the function address + movl PT_ORIG_EAX(%esp), %edx # get the error code + movl $-1, PT_ORIG_EAX(%esp) + movl %ecx, PT_ES(%esp) /*CFI_REL_OFFSET es, ES*/ movl $(__USER_DS), %ecx movl %ecx, %ds @@ -942,26 +926,26 @@ ENTRY(arch_unwind_init_running) movl 4(%esp), %edx movl (%esp), %ecx leal 4(%esp), %eax - movl %ebx, EBX(%edx) + movl %ebx, PT_EBX(%edx) xorl %ebx, %ebx - movl %ebx, ECX(%edx) - movl %ebx, EDX(%edx) - movl %esi, ESI(%edx) - movl %edi, EDI(%edx) - movl %ebp, EBP(%edx) - movl %ebx, EAX(%edx) - movl $__USER_DS, DS(%edx) - movl $__USER_DS, ES(%edx) - movl %ebx, ORIG_EAX(%edx) - movl %ecx, EIP(%edx) + movl %ebx, PT_ECX(%edx) + movl %ebx, PT_EDX(%edx) + movl %esi, PT_ESI(%edx) + movl %edi, PT_EDI(%edx) + movl %ebp, PT_EBP(%edx) + movl %ebx, PT_EAX(%edx) + movl $__USER_DS, PT_DS(%edx) + movl $__USER_DS, PT_ES(%edx) + movl %ebx, PT_ORIG_EAX(%edx) + movl %ecx, PT_EIP(%edx) movl 12(%esp), %ecx - movl $__KERNEL_CS, CS(%edx) - movl %ebx, EFLAGS(%edx) - movl %eax, OLDESP(%edx) + movl $__KERNEL_CS, PT_CS(%edx) + movl %ebx, PT_EFLAGS(%edx) + movl %eax, PT_OLDESP(%edx) movl 8(%esp), %eax movl %ecx, 8(%esp) - movl EBX(%edx), %ebx - movl $__KERNEL_DS, OLDSS(%edx) + movl PT_EBX(%edx), %ebx + movl $__KERNEL_DS, PT_OLDSS(%edx) jmpl *%eax CFI_ENDPROC ENDPROC(arch_unwind_init_running) -- cgit v1.2.3 From 9ca36101a8d74704d78f10910f89d62de96f9dc8 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Basic definitions for i386-pda This patch has the basic definitions of struct i386_pda, and the segment selector in the GDT. asm-i386/pda.h is more or less a direct copy of asm-x86_64/pda.h. The most interesting difference is the use of _proxy_pda, which is used to give gcc a model for the actual memory operations on the real pda structure. No actual reference is ever made to _proxy_pda, so it is never defined. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index b1f1df11fcc..4a83384c5a6 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -585,7 +585,7 @@ ENTRY(cpu_gdt_table) .quad 0x004092000000ffff /* 0xc8 APM DS data */ .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ - .quad 0x0000000000000000 /* 0xd8 - unused */ + .quad 0x0000000000000000 /* 0xd8 - PDA */ .quad 0x0000000000000000 /* 0xe0 - unused */ .quad 0x0000000000000000 /* 0xe8 - unused */ .quad 0x0000000000000000 /* 0xf0 - unused */ -- cgit v1.2.3 From 62111195800d80c66cdc69063ea3145878c99fbf Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Initialize the per-CPU data area When a CPU is brought up, a PDA and GDT are allocated for it. The GDT's __KERNEL_PDA entry is pointed to the allocated PDA memory, so that all references using this segment descriptor will refer to the PDA. This patch rearranges CPU initialization a bit, so that the GDT/PDA are set up as early as possible in cpu_init(). Also for secondary CPUs, GDT+PDA are preallocated and initialized so all the secondary CPU needs to do is set up the ldt and load %gs. This will be important once smp_processor_id() and current use the PDA. In all cases, the PDA is set up in head.S, before a CPU starts running C code, so the PDA is always available. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Cc: James Bottomley Cc: Matt Tolentino Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 177 ++++++++++++++++++++++++++--------- arch/i386/kernel/smpboot.c | 28 ++++-- arch/i386/mach-voyager/voyager_smp.c | 14 ++- 3 files changed, 169 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 5532fc4e1bf..2534e25ed74 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -18,12 +18,16 @@ #include #include #endif +#include #include "cpu.h" DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr); +struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly; +EXPORT_SYMBOL(_cpu_pda); + static int cachesize_override __cpuinitdata = -1; static int disable_x86_fxsr __cpuinitdata; static int disable_x86_serial_nr __cpuinitdata = 1; @@ -588,41 +592,16 @@ void __init early_cpu_init(void) disable_pse = 1; #endif } -/* - * cpu_init() initializes state that is per-CPU. Some data is already - * initialized (naturally) in the bootstrap process, such as the GDT - * and IDT. We reload them nevertheless, this function acts as a - * 'CPU state barrier', nothing should get across. - */ -void __cpuinit cpu_init(void) + +__cpuinit int alloc_gdt(int cpu) { - int cpu = smp_processor_id(); - struct tss_struct * t = &per_cpu(init_tss, cpu); - struct thread_struct *thread = ¤t->thread; - struct desc_struct *gdt; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt; + struct i386_pda *pda; - if (cpu_test_and_set(cpu, cpu_initialized)) { - printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); - for (;;) local_irq_enable(); - } - printk(KERN_INFO "Initializing CPU#%d\n", cpu); + gdt = (struct desc_struct *)cpu_gdt_descr->address; + pda = cpu_pda(cpu); - if (cpu_has_vme || cpu_has_tsc || cpu_has_de) - clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); - if (tsc_disable && cpu_has_tsc) { - printk(KERN_NOTICE "Disabling TSC...\n"); - /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ - clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); - set_in_cr4(X86_CR4_TSD); - } - - /* The CPU hotplug case */ - if (cpu_gdt_descr->address) { - gdt = (struct desc_struct *)cpu_gdt_descr->address; - memset(gdt, 0, PAGE_SIZE); - goto old_gdt; - } /* * This is a horrible hack to allocate the GDT. The problem * is that cpu_init() is called really early for the boot CPU @@ -630,36 +609,117 @@ void __cpuinit cpu_init(void) * CPUs, when bootmem will have gone away */ if (NODE_DATA(0)->bdata->node_bootmem_map) { - gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE); - /* alloc_bootmem_pages panics on failure, so no check */ + BUG_ON(gdt != NULL || pda != NULL); + + gdt = alloc_bootmem_pages(PAGE_SIZE); + pda = alloc_bootmem(sizeof(*pda)); + /* alloc_bootmem(_pages) panics on failure, so no check */ + memset(gdt, 0, PAGE_SIZE); + memset(pda, 0, sizeof(*pda)); } else { - gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); - if (unlikely(!gdt)) { - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); - for (;;) - local_irq_enable(); + /* GDT and PDA might already have been allocated if + this is a CPU hotplug re-insertion. */ + if (gdt == NULL) + gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL); + + if (pda == NULL) + pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu)); + + if (unlikely(!gdt || !pda)) { + free_pages((unsigned long)gdt, 0); + kfree(pda); + return 0; } } -old_gdt: + + cpu_gdt_descr->address = (unsigned long)gdt; + cpu_pda(cpu) = pda; + + return 1; +} + +/* Initial PDA used by boot CPU */ +struct i386_pda boot_pda = { + ._pda = &boot_pda, +}; + +/* Initialize the CPU's GDT and PDA. The boot CPU does this for + itself, but secondaries find this done for them. */ +__cpuinit int init_gdt(int cpu, struct task_struct *idle) +{ + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + struct desc_struct *gdt; + struct i386_pda *pda; + + /* For non-boot CPUs, the GDT and PDA should already have been + allocated. */ + if (!alloc_gdt(cpu)) { + printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu); + return 0; + } + + gdt = (struct desc_struct *)cpu_gdt_descr->address; + pda = cpu_pda(cpu); + + BUG_ON(gdt == NULL || pda == NULL); + /* * Initialize the per-CPU GDT with the boot GDT, * and set up the GDT descriptor: */ memcpy(gdt, cpu_gdt_table, GDT_SIZE); cpu_gdt_descr->size = GDT_SIZE - 1; - cpu_gdt_descr->address = (unsigned long)gdt; + pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a, + (u32 *)&gdt[GDT_ENTRY_PDA].b, + (unsigned long)pda, sizeof(*pda) - 1, + 0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */ + + memset(pda, 0, sizeof(*pda)); + pda->_pda = pda; + + return 1; +} + +/* Common CPU init for both boot and secondary CPUs */ +static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) +{ + struct tss_struct * t = &per_cpu(init_tss, cpu); + struct thread_struct *thread = &curr->thread; + struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); + + /* Reinit these anyway, even if they've already been done (on + the boot CPU, this will transition from the boot gdt+pda to + the real ones). */ load_gdt(cpu_gdt_descr); + + if (cpu_test_and_set(cpu, cpu_initialized)) { + printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); + for (;;) local_irq_enable(); + } + + printk(KERN_INFO "Initializing CPU#%d\n", cpu); + + if (cpu_has_vme || cpu_has_tsc || cpu_has_de) + clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE); + if (tsc_disable && cpu_has_tsc) { + printk(KERN_NOTICE "Disabling TSC...\n"); + /**** FIX-HPA: DOES THIS REALLY BELONG HERE? ****/ + clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability); + set_in_cr4(X86_CR4_TSD); + } + load_idt(&idt_descr); /* * Set up and load the per-CPU TSS and LDT */ atomic_inc(&init_mm.mm_count); - current->active_mm = &init_mm; - BUG_ON(current->mm); - enter_lazy_tlb(&init_mm, current); + curr->active_mm = &init_mm; + if (curr->mm) + BUG(); + enter_lazy_tlb(&init_mm, curr); load_esp0(t, thread); set_tss_desc(cpu,t); @@ -690,6 +750,37 @@ old_gdt: mxcsr_feature_mask_init(); } +/* Entrypoint to initialize secondary CPU */ +void __cpuinit secondary_cpu_init(void) +{ + int cpu = smp_processor_id(); + struct task_struct *curr = current; + + _cpu_init(cpu, curr); +} + +/* + * cpu_init() initializes state that is per-CPU. Some data is already + * initialized (naturally) in the bootstrap process, such as the GDT + * and IDT. We reload them nevertheless, this function acts as a + * 'CPU state barrier', nothing should get across. + */ +void __cpuinit cpu_init(void) +{ + int cpu = smp_processor_id(); + struct task_struct *curr = current; + + /* Set up the real GDT and PDA, so we can transition from the + boot versions. */ + if (!init_gdt(cpu, curr)) { + /* failed to allocate something; not much we can do... */ + for (;;) + local_irq_enable(); + } + + _cpu_init(cpu, curr); +} + #ifdef CONFIG_HOTPLUG_CPU void __cpuinit cpu_uninit(void) { diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 4bb8b77cd65..095636620fa 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -536,11 +537,11 @@ set_cpu_sibling_map(int cpu) static void __devinit start_secondary(void *unused) { /* - * Dont put anything before smp_callin(), SMP + * Don't put *anything* before secondary_cpu_init(), SMP * booting is too fragile that we want to limit the * things done here to the most necessary things. */ - cpu_init(); + secondary_cpu_init(); preempt_disable(); smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) @@ -599,13 +600,16 @@ void __devinit initialize_secondary(void) "movl %0,%%esp\n\t" "jmp *%1" : - :"r" (current->thread.esp),"r" (current->thread.eip)); + :"m" (current->thread.esp),"m" (current->thread.eip)); } +/* Static state in head.S used to set up a CPU */ extern struct { void * esp; unsigned short ss; } stack_start; +extern struct i386_pda *start_pda; +extern struct Xgt_desc_struct cpu_gdt_descr; #ifdef CONFIG_NUMA @@ -936,9 +940,6 @@ static int __devinit do_boot_cpu(int apicid, int cpu) unsigned long start_eip; unsigned short nmi_high = 0, nmi_low = 0; - ++cpucount; - alternatives_smp_switch(1); - /* * We can't use kernel_thread since we must avoid to * reschedule the child. @@ -946,15 +947,30 @@ static int __devinit do_boot_cpu(int apicid, int cpu) idle = alloc_idle_task(cpu); if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); + + /* Pre-allocate and initialize the CPU's GDT and PDA so it + doesn't have to do any memory allocation during the + delicate CPU-bringup phase. */ + if (!init_gdt(cpu, idle)) { + printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); + return -1; /* ? */ + } + idle->thread.eip = (unsigned long) start_secondary; /* start_eip had better be page-aligned! */ start_eip = setup_trampoline(); + ++cpucount; + alternatives_smp_switch(1); + /* So we see what's up */ printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); /* Stack for startup_32 can be just as for start_secondary onwards */ stack_start.esp = (void *) idle->thread.esp; + start_pda = cpu_pda(cpu); + cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu); + irq_ctx_init(cpu); x86_cpu_to_apicid[cpu] = apicid; diff --git a/arch/i386/mach-voyager/voyager_smp.c b/arch/i386/mach-voyager/voyager_smp.c index f3fea2ad50f..55428e656a3 100644 --- a/arch/i386/mach-voyager/voyager_smp.c +++ b/arch/i386/mach-voyager/voyager_smp.c @@ -28,6 +28,7 @@ #include #include #include +#include /* TLB state -- visible externally, indexed physically */ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; @@ -422,6 +423,7 @@ find_smp_config(void) VOYAGER_SUS_IN_CONTROL_PORT); current_thread_info()->cpu = boot_cpu_id; + write_pda(cpu_number, boot_cpu_id); } /* @@ -458,7 +460,7 @@ start_secondary(void *unused) /* external functions not defined in the headers */ extern void calibrate_delay(void); - cpu_init(); + secondary_cpu_init(); /* OK, we're in the routine */ ack_CPI(VIC_CPU_BOOT_CPI); @@ -578,6 +580,15 @@ do_boot_cpu(__u8 cpu) /* init_tasks (in sched.c) is indexed logically */ stack_start.esp = (void *) idle->thread.esp; + /* Pre-allocate and initialize the CPU's GDT and PDA so it + doesn't have to do any memory allocation during the + delicate CPU-bringup phase. */ + if (!init_gdt(cpu, idle)) { + printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu); + cpucount--; + return; + } + irq_ctx_init(cpu); /* Note: Don't modify initial ss override */ @@ -1963,4 +1974,5 @@ void __init smp_setup_processor_id(void) { current_thread_info()->cpu = hard_smp_processor_id(); + write_pda(cpu_number, hard_smp_processor_id()); } -- cgit v1.2.3 From f95d47caae5302a63d92be9a0292abc90e2a14e1 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Use %gs as the PDA base-segment in the kernel This patch is the meat of the PDA change. This patch makes several related changes: 1: Most significantly, %gs is now used in the kernel. This means that on entry, the old value of %gs is saved away, and it is reloaded with __KERNEL_PDA. 2: entry.S constructs the stack in the shape of struct pt_regs, and this is passed around the kernel so that the process's saved register state can be accessed. Unfortunately struct pt_regs doesn't currently have space for %gs (or %fs). This patch extends pt_regs to add space for gs (no space is allocated for %fs, since it won't be used, and it would just complicate the code in entry.S to work around the space). 3: Because %gs is now saved on the stack like %ds, %es and the integer registers, there are a number of places where it no longer needs to be handled specially; namely context switch, and saving/restoring the register state in a signal context. 4: And since kernel threads run in kernel space and call normal kernel code, they need to be created with their %gs == __KERNEL_PDA. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 1 + arch/i386/kernel/cpu/common.c | 21 +++++++++++-- arch/i386/kernel/entry.S | 70 +++++++++++++++++++++++++++++------------- arch/i386/kernel/head.S | 31 ++++++++++++++++--- arch/i386/kernel/process.c | 26 ++++++++-------- arch/i386/kernel/signal.c | 6 ++-- 6 files changed, 109 insertions(+), 46 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 70b19807acf..9620872d353 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -72,6 +72,7 @@ void foo(void) OFFSET(PT_EAX, pt_regs, eax); OFFSET(PT_DS, pt_regs, xds); OFFSET(PT_ES, pt_regs, xes); + OFFSET(PT_GS, pt_regs, xgs); OFFSET(PT_ORIG_EAX, pt_regs, orig_eax); OFFSET(PT_EIP, pt_regs, eip); OFFSET(PT_CS, pt_regs, xcs); diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 2534e25ed74..4e63d8ce602 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -593,6 +593,14 @@ void __init early_cpu_init(void) #endif } +/* Make sure %gs is initialized properly in idle threads */ +struct pt_regs * __devinit idle_regs(struct pt_regs *regs) +{ + memset(regs, 0, sizeof(struct pt_regs)); + regs->xgs = __KERNEL_PDA; + return regs; +} + __cpuinit int alloc_gdt(int cpu) { struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); @@ -644,6 +652,14 @@ struct i386_pda boot_pda = { ._pda = &boot_pda, }; +static inline void set_kernel_gs(void) +{ + /* Set %gs for this CPU's PDA. Memory clobber is to create a + barrier with respect to any PDA operations, so the compiler + doesn't move any before here. */ + asm volatile ("mov %0, %%gs" : : "r" (__KERNEL_PDA) : "memory"); +} + /* Initialize the CPU's GDT and PDA. The boot CPU does this for itself, but secondaries find this done for them. */ __cpuinit int init_gdt(int cpu, struct task_struct *idle) @@ -693,6 +709,7 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) the boot CPU, this will transition from the boot gdt+pda to the real ones). */ load_gdt(cpu_gdt_descr); + set_kernel_gs(); if (cpu_test_and_set(cpu, cpu_initialized)) { printk(KERN_WARNING "CPU#%d already initialized!\n", cpu); @@ -731,8 +748,8 @@ static void __cpuinit _cpu_init(int cpu, struct task_struct *curr) __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); #endif - /* Clear %fs and %gs. */ - asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0)); + /* Clear %fs. */ + asm volatile ("mov %0, %%fs" : : "r" (0)); /* Clear all 6 debug registers: */ set_debugreg(0, 0); diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 0069bf01603..b99d4a16007 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -30,12 +30,13 @@ * 18(%esp) - %eax * 1C(%esp) - %ds * 20(%esp) - %es - * 24(%esp) - orig_eax - * 28(%esp) - %eip - * 2C(%esp) - %cs - * 30(%esp) - %eflags - * 34(%esp) - %oldesp - * 38(%esp) - %oldss + * 24(%esp) - %gs + * 28(%esp) - orig_eax + * 2C(%esp) - %eip + * 30(%esp) - %cs + * 34(%esp) - %eflags + * 38(%esp) - %oldesp + * 3C(%esp) - %oldss * * "current" is in register %ebx during any slow entries. */ @@ -92,6 +93,9 @@ VM_MASK = 0x00020000 #define SAVE_ALL \ cld; \ + pushl %gs; \ + CFI_ADJUST_CFA_OFFSET 4;\ + /*CFI_REL_OFFSET gs, 0;*/\ pushl %es; \ CFI_ADJUST_CFA_OFFSET 4;\ /*CFI_REL_OFFSET es, 0;*/\ @@ -121,7 +125,9 @@ VM_MASK = 0x00020000 CFI_REL_OFFSET ebx, 0;\ movl $(__USER_DS), %edx; \ movl %edx, %ds; \ - movl %edx, %es; + movl %edx, %es; \ + movl $(__KERNEL_PDA), %edx; \ + movl %edx, %gs #define RESTORE_INT_REGS \ popl %ebx; \ @@ -154,17 +160,22 @@ VM_MASK = 0x00020000 2: popl %es; \ CFI_ADJUST_CFA_OFFSET -4;\ /*CFI_RESTORE es;*/\ -.section .fixup,"ax"; \ -3: movl $0,(%esp); \ - jmp 1b; \ +3: popl %gs; \ + CFI_ADJUST_CFA_OFFSET -4;\ + /*CFI_RESTORE gs;*/\ +.pushsection .fixup,"ax"; \ 4: movl $0,(%esp); \ + jmp 1b; \ +5: movl $0,(%esp); \ jmp 2b; \ -.previous; \ +6: movl $0,(%esp); \ + jmp 3b; \ .section __ex_table,"a";\ .align 4; \ - .long 1b,3b; \ - .long 2b,4b; \ -.previous + .long 1b,4b; \ + .long 2b,5b; \ + .long 3b,6b; \ +.popsection #define RING0_INT_FRAME \ CFI_STARTPROC simple;\ @@ -231,6 +242,7 @@ check_userspace: andl $(VM_MASK | SEGMENT_RPL_MASK), %eax cmpl $USER_RPL, %eax jb resume_kernel # not returning to v8086 or userspace + ENTRY(resume_userspace) DISABLE_INTERRUPTS # make sure we don't miss an interrupt # setting need_resched or sigpending @@ -327,9 +339,16 @@ sysenter_past_esp: movl PT_OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON +1: mov PT_GS(%esp), %gs ENABLE_INTERRUPTS_SYSEXIT CFI_ENDPROC - +.pushsection .fixup,"ax" +2: movl $0,PT_GS(%esp) + jmp 1b +.section __ex_table,"a" + .align 4 + .long 1b,2b +.popsection # system call handler stub ENTRY(system_call) @@ -375,7 +394,7 @@ restore_nocheck: TRACE_IRQS_IRET restore_nocheck_notrace: RESTORE_REGS - addl $4, %esp + addl $4, %esp # skip orig_eax/error_code CFI_ADJUST_CFA_OFFSET -4 1: INTERRUPT_RETURN .section .fixup,"ax" @@ -588,6 +607,10 @@ KPROBE_ENTRY(page_fault) CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: + /* the function address is in %gs's slot on the stack */ + pushl %es + CFI_ADJUST_CFA_OFFSET 4 + /*CFI_REL_OFFSET es, 0*/ pushl %ds CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ds, 0*/ @@ -613,18 +636,20 @@ error_code: CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET ebx, 0 cld - pushl %es + pushl %gs CFI_ADJUST_CFA_OFFSET 4 - /*CFI_REL_OFFSET es, 0*/ + /*CFI_REL_OFFSET gs, 0*/ + movl $(__KERNEL_PDA), %ecx + movl %ecx, %gs UNWIND_ESPFIX_STACK popl %ecx CFI_ADJUST_CFA_OFFSET -4 /*CFI_REGISTER es, ecx*/ - movl PT_ES(%esp), %edi # get the function address + movl PT_GS(%esp), %edi # get the function address movl PT_ORIG_EAX(%esp), %edx # get the error code - movl $-1, PT_ORIG_EAX(%esp) - movl %ecx, PT_ES(%esp) - /*CFI_REL_OFFSET es, ES*/ + movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart + mov %ecx, PT_GS(%esp) + /*CFI_REL_OFFSET gs, ES*/ movl $(__USER_DS), %ecx movl %ecx, %ds movl %ecx, %es @@ -936,6 +961,7 @@ ENTRY(arch_unwind_init_running) movl %ebx, PT_EAX(%edx) movl $__USER_DS, PT_DS(%edx) movl $__USER_DS, PT_ES(%edx) + movl $0, PT_GS(%edx) movl %ebx, PT_ORIG_EAX(%edx) movl %ecx, PT_EIP(%edx) movl 12(%esp), %ecx diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 4a83384c5a6..5b14e95ac8b 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -302,6 +302,7 @@ is386: movl $2,%ecx # set MP movl %eax,%cr0 call check_x87 + call setup_pda lgdt cpu_gdt_descr lidt idt_descr ljmp $(__KERNEL_CS),$1f @@ -312,10 +313,13 @@ is386: movl $2,%ecx # set MP movl %eax,%ds movl %eax,%es - xorl %eax,%eax # Clear FS/GS and LDT + xorl %eax,%eax # Clear FS and LDT movl %eax,%fs - movl %eax,%gs lldt %ax + + movl $(__KERNEL_PDA),%eax + mov %eax,%gs + cld # gcc2 wants the direction flag cleared at all times pushl $0 # fake return address for unwinder #ifdef CONFIG_SMP @@ -345,6 +349,23 @@ check_x87: .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ ret +/* + * Point the GDT at this CPU's PDA. On boot this will be + * cpu_gdt_table and boot_pda; for secondary CPUs, these will be + * that CPU's GDT and PDA. + */ +setup_pda: + /* get the PDA pointer */ + movl start_pda, %eax + + /* slot the PDA address into the GDT */ + mov cpu_gdt_descr+2, %ecx + mov %ax, (__KERNEL_PDA+0+2)(%ecx) /* base & 0x0000ffff */ + shr $16, %eax + mov %al, (__KERNEL_PDA+4+0)(%ecx) /* base & 0x00ff0000 */ + mov %ah, (__KERNEL_PDA+4+3)(%ecx) /* base & 0xff000000 */ + ret + /* * setup_idt * @@ -484,6 +505,8 @@ ENTRY(empty_zero_page) * This starts the data section. */ .data +ENTRY(start_pda) + .long boot_pda ENTRY(stack_start) .long init_thread_union+THREAD_SIZE @@ -525,7 +548,7 @@ idt_descr: # boot GDT descriptor (later on used by CPU#0): .word 0 # 32 bit align gdt_desc.address -cpu_gdt_descr: +ENTRY(cpu_gdt_descr) .word GDT_ENTRIES*8-1 .long cpu_gdt_table @@ -585,7 +608,7 @@ ENTRY(cpu_gdt_table) .quad 0x004092000000ffff /* 0xc8 APM DS data */ .quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */ - .quad 0x0000000000000000 /* 0xd8 - PDA */ + .quad 0x00cf92000000ffff /* 0xd8 - PDA */ .quad 0x0000000000000000 /* 0xe0 - unused */ .quad 0x0000000000000000 /* 0xe8 - unused */ .quad 0x0000000000000000 /* 0xf0 - unused */ diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index ae924c416b6..905364d4284 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -56,6 +56,7 @@ #include #include +#include asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); @@ -346,6 +347,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xds = __USER_DS; regs.xes = __USER_DS; + regs.xgs = __KERNEL_PDA; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; regs.xcs = __KERNEL_CS | get_kernel_rpl(); @@ -431,7 +433,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, p->thread.eip = (unsigned long) ret_from_fork; savesegment(fs,p->thread.fs); - savesegment(gs,p->thread.gs); tsk = current; if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { @@ -659,16 +660,16 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas load_esp0(tss, next); /* - * Save away %fs and %gs. No need to save %es and %ds, as - * those are always kernel segments while inside the kernel. - * Doing this before setting the new TLS descriptors avoids - * the situation where we temporarily have non-reloadable - * segments in %fs and %gs. This could be an issue if the - * NMI handler ever used %fs or %gs (it does not today), or - * if the kernel is running inside of a hypervisor layer. + * Save away %fs. No need to save %gs, as it was saved on the + * stack on entry. No need to save %es and %ds, as those are + * always kernel segments while inside the kernel. Doing this + * before setting the new TLS descriptors avoids the situation + * where we temporarily have non-reloadable segments in %fs + * and %gs. This could be an issue if the NMI handler ever + * used %fs or %gs (it does not today), or if the kernel is + * running inside of a hypervisor layer. */ savesegment(fs, prev->fs); - savesegment(gs, prev->gs); /* * Load the per-thread Thread-Local Storage descriptor. @@ -676,16 +677,13 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas load_TLS(next, cpu); /* - * Restore %fs and %gs if needed. + * Restore %fs if needed. * - * Glibc normally makes %fs be zero, and %gs is one of - * the TLS segments. + * Glibc normally makes %fs be zero. */ if (unlikely(prev->fs | next->fs)) loadsegment(fs, next->fs); - if (prev->gs | next->gs) - loadsegment(gs, next->gs); /* * Restore IOPL if needed. diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 43002cfb40c..65d7620eaa0 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -128,7 +128,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax X86_EFLAGS_TF | X86_EFLAGS_SF | X86_EFLAGS_ZF | \ X86_EFLAGS_AF | X86_EFLAGS_PF | X86_EFLAGS_CF) - GET_SEG(gs); + COPY_SEG(gs); GET_SEG(fs); COPY_SEG(es); COPY_SEG(ds); @@ -244,9 +244,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate, { int tmp, err = 0; - tmp = 0; - savesegment(gs, tmp); - err |= __put_user(tmp, (unsigned int __user *)&sc->gs); + err |= __put_user(regs->xgs, (unsigned int __user *)&sc->gs); savesegment(fs, tmp); err |= __put_user(tmp, (unsigned int __user *)&sc->fs); -- cgit v1.2.3 From 66e10a44d724f1464b5e8b5a3eae1e2cbbc2cca6 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] i386: Fix places where using %gs changes the usermode ABI There are a few places where the change in struct pt_regs and the use of %gs affect the userspace ABI. These are primarily debugging interfaces where thread state can be inspected or extracted. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/process.c | 6 +++--- arch/i386/kernel/ptrace.c | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 905364d4284..dc427254517 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -315,8 +315,8 @@ void show_regs(struct pt_regs * regs) regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", regs->esi, regs->edi, regs->ebp); - printk(" DS: %04x ES: %04x\n", - 0xffff & regs->xds,0xffff & regs->xes); + printk(" DS: %04x ES: %04x GS: %04x\n", + 0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xgs); cr0 = read_cr0(); cr2 = read_cr2(); @@ -509,7 +509,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump) dump->regs.ds = regs->xds; dump->regs.es = regs->xes; savesegment(fs,dump->regs.fs); - savesegment(gs,dump->regs.gs); + dump->regs.gs = regs->xgs; dump->regs.orig_eax = regs->orig_eax; dump->regs.eip = regs->eip; dump->regs.cs = regs->xcs; diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 775f50e9395..f3f94ac5736 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -94,13 +94,9 @@ static int putreg(struct task_struct *child, return -EIO; child->thread.fs = value; return 0; - case GS: - if (value && (value & 3) != 3) - return -EIO; - child->thread.gs = value; - return 0; case DS: case ES: + case GS: if (value && (value & 3) != 3) return -EIO; value &= 0xffff; @@ -116,8 +112,8 @@ static int putreg(struct task_struct *child, value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; break; } - if (regno > GS*4) - regno -= 2*4; + if (regno > ES*4) + regno -= 1*4; put_stack_long(child, regno - sizeof(struct pt_regs), value); return 0; } @@ -131,18 +127,16 @@ static unsigned long getreg(struct task_struct *child, case FS: retval = child->thread.fs; break; - case GS: - retval = child->thread.gs; - break; case DS: case ES: + case GS: case SS: case CS: retval = 0xffff; /* fall through */ default: - if (regno > GS*4) - regno -= 2*4; + if (regno > ES*4) + regno -= 1*4; regno = regno - sizeof(struct pt_regs); retval &= get_stack_long(child, regno); } -- cgit v1.2.3 From 49d26b6eaa8e970c8cf6e299e6ccba2474191bf5 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Update sys_vm86 to cope with changed pt_regs and %gs usage sys_vm86 uses a struct kernel_vm86_regs, which is identical to pt_regs, but adds an extra space for all the segment registers. Previously this structure was completely independent, so changes in pt_regs had to be reflected in kernel_vm86_regs. This changes just embeds pt_regs in kernel_vm86_regs, and makes the appropriate changes to vm86.c to deal with the new naming. Also, since %gs is dealt with differently in the kernel, this change adjusts vm86.c to reflect this. While making these changes, I also cleaned up some frankly bizarre code which was added when auditing was added to sys_vm86. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Cc: Al Viro Cc: Jason Baron Cc: Chris Wright Signed-off-by: Andrew Morton --- arch/i386/kernel/vm86.c | 121 +++++++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 47 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index cbcd61d6120..be2f96e67f7 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -72,10 +73,10 @@ /* * 8- and 16-bit register defines.. */ -#define AL(regs) (((unsigned char *)&((regs)->eax))[0]) -#define AH(regs) (((unsigned char *)&((regs)->eax))[1]) -#define IP(regs) (*(unsigned short *)&((regs)->eip)) -#define SP(regs) (*(unsigned short *)&((regs)->esp)) +#define AL(regs) (((unsigned char *)&((regs)->pt.eax))[0]) +#define AH(regs) (((unsigned char *)&((regs)->pt.eax))[1]) +#define IP(regs) (*(unsigned short *)&((regs)->pt.eip)) +#define SP(regs) (*(unsigned short *)&((regs)->pt.esp)) /* * virtual flags (16 and 32-bit versions) @@ -89,10 +90,37 @@ #define SAFE_MASK (0xDD5) #define RETURN_MASK (0xDFF) -#define VM86_REGS_PART2 orig_eax -#define VM86_REGS_SIZE1 \ - ( (unsigned)( & (((struct kernel_vm86_regs *)0)->VM86_REGS_PART2) ) ) -#define VM86_REGS_SIZE2 (sizeof(struct kernel_vm86_regs) - VM86_REGS_SIZE1) +/* convert kernel_vm86_regs to vm86_regs */ +static int copy_vm86_regs_to_user(struct vm86_regs __user *user, + const struct kernel_vm86_regs *regs) +{ + int ret = 0; + + /* kernel_vm86_regs is missing xfs, so copy everything up to + (but not including) xgs, and then rest after xgs. */ + ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.xgs)); + ret += copy_to_user(&user->__null_gs, ®s->pt.xgs, + sizeof(struct kernel_vm86_regs) - + offsetof(struct kernel_vm86_regs, pt.xgs)); + + return ret; +} + +/* convert vm86_regs to kernel_vm86_regs */ +static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs, + const struct vm86_regs __user *user, + unsigned extra) +{ + int ret = 0; + + ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.xgs)); + ret += copy_from_user(®s->pt.xgs, &user->__null_gs, + sizeof(struct kernel_vm86_regs) - + offsetof(struct kernel_vm86_regs, pt.xgs) + + extra); + + return ret; +} struct pt_regs * FASTCALL(save_v86_state(struct kernel_vm86_regs * regs)); struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) @@ -112,10 +140,8 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) printk("no vm86_info: BAD\n"); do_exit(SIGSEGV); } - set_flags(regs->eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); - tmp = copy_to_user(¤t->thread.vm86_info->regs,regs, VM86_REGS_SIZE1); - tmp += copy_to_user(¤t->thread.vm86_info->regs.VM86_REGS_PART2, - ®s->VM86_REGS_PART2, VM86_REGS_SIZE2); + set_flags(regs->pt.eflags, VEFLAGS, VIF_MASK | current->thread.v86mask); + tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs,regs); tmp += put_user(current->thread.screen_bitmap,¤t->thread.vm86_info->screen_bitmap); if (tmp) { printk("vm86: could not access userspace vm86_info\n"); @@ -129,9 +155,11 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs) current->thread.saved_esp0 = 0; put_cpu(); - loadsegment(fs, current->thread.saved_fs); - loadsegment(gs, current->thread.saved_gs); ret = KVM86->regs32; + + loadsegment(fs, current->thread.saved_fs); + ret->xgs = current->thread.saved_gs; + return ret; } @@ -183,9 +211,9 @@ asmlinkage int sys_vm86old(struct pt_regs regs) tsk = current; if (tsk->thread.saved_esp0) goto out; - tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); - tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, - (long)&info.vm86plus - (long)&info.regs.VM86_REGS_PART2); + tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, + offsetof(struct kernel_vm86_struct, vm86plus) - + sizeof(info.regs)); ret = -EFAULT; if (tmp) goto out; @@ -233,9 +261,9 @@ asmlinkage int sys_vm86(struct pt_regs regs) if (tsk->thread.saved_esp0) goto out; v86 = (struct vm86plus_struct __user *)regs.ecx; - tmp = copy_from_user(&info, v86, VM86_REGS_SIZE1); - tmp += copy_from_user(&info.regs.VM86_REGS_PART2, &v86->regs.VM86_REGS_PART2, - (long)&info.regs32 - (long)&info.regs.VM86_REGS_PART2); + tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, + offsetof(struct kernel_vm86_struct, regs32) - + sizeof(info.regs)); ret = -EFAULT; if (tmp) goto out; @@ -252,15 +280,15 @@ out: static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { struct tss_struct *tss; - long eax; /* * make sure the vm86() system call doesn't try to do anything silly */ - info->regs.__null_ds = 0; - info->regs.__null_es = 0; + info->regs.pt.xds = 0; + info->regs.pt.xes = 0; + info->regs.pt.xgs = 0; -/* we are clearing fs,gs later just before "jmp resume_userspace", - * because starting with Linux 2.1.x they aren't no longer saved/restored +/* we are clearing fs later just before "jmp resume_userspace", + * because it is not saved/restored. */ /* @@ -268,10 +296,10 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk * has set it up safely, so this makes sure interrupt etc flags are * inherited from protected mode. */ - VEFLAGS = info->regs.eflags; - info->regs.eflags &= SAFE_MASK; - info->regs.eflags |= info->regs32->eflags & ~SAFE_MASK; - info->regs.eflags |= VM_MASK; + VEFLAGS = info->regs.pt.eflags; + info->regs.pt.eflags &= SAFE_MASK; + info->regs.pt.eflags |= info->regs32->eflags & ~SAFE_MASK; + info->regs.pt.eflags |= VM_MASK; switch (info->cpu_type) { case CPU_286: @@ -294,7 +322,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk info->regs32->eax = 0; tsk->thread.saved_esp0 = tsk->thread.esp0; savesegment(fs, tsk->thread.saved_fs); - savesegment(gs, tsk->thread.saved_gs); + tsk->thread.saved_gs = info->regs32->xgs; tss = &per_cpu(init_tss, get_cpu()); tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; @@ -306,19 +334,18 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) mark_screen_rdonly(tsk->mm); - __asm__ __volatile__("xorl %eax,%eax; movl %eax,%fs; movl %eax,%gs\n\t"); - __asm__ __volatile__("movl %%eax, %0\n" :"=r"(eax)); /*call audit_syscall_exit since we do not exit via the normal paths */ if (unlikely(current->audit_context)) - audit_syscall_exit(AUDITSC_RESULT(eax), eax); + audit_syscall_exit(AUDITSC_RESULT(0), 0); __asm__ __volatile__( "movl %0,%%esp\n\t" "movl %1,%%ebp\n\t" + "mov %2, %%fs\n\t" "jmp resume_userspace" : /* no outputs */ - :"r" (&info->regs), "r" (task_thread_info(tsk))); + :"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0)); /* we never return here */ } @@ -348,12 +375,12 @@ static inline void clear_IF(struct kernel_vm86_regs * regs) static inline void clear_TF(struct kernel_vm86_regs * regs) { - regs->eflags &= ~TF_MASK; + regs->pt.eflags &= ~TF_MASK; } static inline void clear_AC(struct kernel_vm86_regs * regs) { - regs->eflags &= ~AC_MASK; + regs->pt.eflags &= ~AC_MASK; } /* It is correct to call set_IF(regs) from the set_vflags_* @@ -370,7 +397,7 @@ static inline void clear_AC(struct kernel_vm86_regs * regs) static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs) { set_flags(VEFLAGS, eflags, current->thread.v86mask); - set_flags(regs->eflags, eflags, SAFE_MASK); + set_flags(regs->pt.eflags, eflags, SAFE_MASK); if (eflags & IF_MASK) set_IF(regs); else @@ -380,7 +407,7 @@ static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs) { set_flags(VFLAGS, flags, current->thread.v86mask); - set_flags(regs->eflags, flags, SAFE_MASK); + set_flags(regs->pt.eflags, flags, SAFE_MASK); if (flags & IF_MASK) set_IF(regs); else @@ -389,7 +416,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg static inline unsigned long get_vflags(struct kernel_vm86_regs * regs) { - unsigned long flags = regs->eflags & RETURN_MASK; + unsigned long flags = regs->pt.eflags & RETURN_MASK; if (VEFLAGS & VIF_MASK) flags |= IF_MASK; @@ -493,7 +520,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i, unsigned long __user *intr_ptr; unsigned long segoffs; - if (regs->cs == BIOSSEG) + if (regs->pt.xcs == BIOSSEG) goto cannot_handle; if (is_revectored(i, &KVM86->int_revectored)) goto cannot_handle; @@ -505,9 +532,9 @@ static void do_int(struct kernel_vm86_regs *regs, int i, if ((segoffs >> 16) == BIOSSEG) goto cannot_handle; pushw(ssp, sp, get_vflags(regs), cannot_handle); - pushw(ssp, sp, regs->cs, cannot_handle); + pushw(ssp, sp, regs->pt.xcs, cannot_handle); pushw(ssp, sp, IP(regs), cannot_handle); - regs->cs = segoffs >> 16; + regs->pt.xcs = segoffs >> 16; SP(regs) -= 6; IP(regs) = segoffs & 0xffff; clear_TF(regs); @@ -524,7 +551,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno if (VMPI.is_vm86pus) { if ( (trapno==3) || (trapno==1) ) return_to_32bit(regs, VM86_TRAP + (trapno << 8)); - do_int(regs, trapno, (unsigned char __user *) (regs->ss << 4), SP(regs)); + do_int(regs, trapno, (unsigned char __user *) (regs->pt.xss << 4), SP(regs)); return 0; } if (trapno !=1) @@ -560,10 +587,10 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) handle_vm86_trap(regs, 0, 1); \ return; } while (0) - orig_flags = *(unsigned short *)®s->eflags; + orig_flags = *(unsigned short *)®s->pt.eflags; - csp = (unsigned char __user *) (regs->cs << 4); - ssp = (unsigned char __user *) (regs->ss << 4); + csp = (unsigned char __user *) (regs->pt.xcs << 4); + ssp = (unsigned char __user *) (regs->pt.xss << 4); sp = SP(regs); ip = IP(regs); @@ -650,7 +677,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code) SP(regs) += 6; } IP(regs) = newip; - regs->cs = newcs; + regs->pt.xcs = newcs; CHECK_IF_IN_TRAP; if (data32) { set_vflags_long(newflags, regs); -- cgit v1.2.3 From b2938f880890ebfcccad356275e0000193153623 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Implement smp_processor_id() with the PDA Use the cpu_number in the PDA to implement raw_smp_processor_id. This is a little simpler than using thread_info, though the cpu field in thread_info cannot be removed since it is used for things other than getting the current CPU in common code. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 4 +++- arch/i386/kernel/cpu/common.c | 2 ++ arch/i386/kernel/entry.S | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 9620872d353..85f1b038e9c 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -51,7 +51,6 @@ void foo(void) OFFSET(TI_exec_domain, thread_info, exec_domain); OFFSET(TI_flags, thread_info, flags); OFFSET(TI_status, thread_info, status); - OFFSET(TI_cpu, thread_info, cpu); OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); @@ -97,4 +96,7 @@ void foo(void) DEFINE(VDSO_PRELINK, VDSO_PRELINK); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); + + BLANK(); + OFFSET(PDA_cpu, i386_pda, cpu_number); } diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 4e63d8ce602..e476202b887 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -650,6 +650,7 @@ __cpuinit int alloc_gdt(int cpu) /* Initial PDA used by boot CPU */ struct i386_pda boot_pda = { ._pda = &boot_pda, + .cpu_number = 0, }; static inline void set_kernel_gs(void) @@ -694,6 +695,7 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle) memset(pda, 0, sizeof(*pda)); pda->_pda = pda; + pda->cpu_number = cpu; return 1; } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index b99d4a16007..d7423efaeea 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -524,8 +524,7 @@ syscall_badsys: #define FIXUP_ESPFIX_STACK \ /* since we are on a wrong stack, we cant make it a C code :( */ \ - GET_THREAD_INFO(%ebp); \ - movl TI_cpu(%ebp), %ebx; \ + movl %gs:PDA_cpu, %ebx; \ PER_CPU(cpu_gdt_descr, %ebx); \ movl GDS_address(%ebx), %ebx; \ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \ -- cgit v1.2.3 From ec7fcaabbfb3c5bd5189f857b6ac7bb9745ef291 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Implement "current" with the PDA Use the pcurrent field in the PDA to implement the "current" macro. This ends up compiling down to a single instruction to get the current task. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Andi Kleen Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden Cc: Jan Beulich Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/asm-offsets.c | 2 ++ arch/i386/kernel/cpu/common.c | 2 ++ arch/i386/kernel/process.c | 1 + 3 files changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 85f1b038e9c..0666eb0ed7b 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -15,6 +15,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -99,4 +100,5 @@ void foo(void) BLANK(); OFFSET(PDA_cpu, i386_pda, cpu_number); + OFFSET(PDA_pcurrent, i386_pda, pcurrent); } diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index e476202b887..6958ae5e2fa 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -651,6 +651,7 @@ __cpuinit int alloc_gdt(int cpu) struct i386_pda boot_pda = { ._pda = &boot_pda, .cpu_number = 0, + .pcurrent = &init_task, }; static inline void set_kernel_gs(void) @@ -696,6 +697,7 @@ __cpuinit int init_gdt(int cpu, struct task_struct *idle) memset(pda, 0, sizeof(*pda)); pda->_pda = pda; pda->cpu_number = cpu; + pda->pcurrent = idle; return 1; } diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index dc427254517..8749b10d380 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -684,6 +684,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas if (unlikely(prev->fs | next->fs)) loadsegment(fs, next->fs); + write_pda(pcurrent, next_p); /* * Restore IOPL if needed. -- cgit v1.2.3 From 72690a21188586022a9e65cb6f1cc8845167555a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] x86: Don't use nested idle loops Currently the idle loop has two nested loops -- one high level in cpu_idle and in some low level idle functions another one. Looping in the low level idle functions breaks the idle notifiers because interrupts waking up sleep states need to execute exit_idle() which is only in cpu_idle(). So don't do that, only loop in cpu_idle(). This only removes code. In some cases e.g. poll_idle the idle loop is a little longer now because cpu_idle checks more things. I hope that isn't a problem ACPI idle doesn't change behaviour because it never looped anyways. Cc: len.brown@intel.com Cc: eranian@hpl.hp.com Signed-off-by: Andi Kleen --- arch/i386/kernel/process.c | 30 +++++++++--------------------- arch/x86_64/kernel/process.c | 30 +++++++++--------------------- 2 files changed, 18 insertions(+), 42 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 8749b10d380..8f42659ef9d 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -100,22 +100,18 @@ EXPORT_SYMBOL(enable_hlt); */ void default_idle(void) { - local_irq_enable(); - if (!hlt_counter && boot_cpu_data.hlt_works_ok) { current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); - while (!need_resched()) { - local_irq_disable(); - if (!need_resched()) - safe_halt(); - else - local_irq_enable(); - } + local_irq_disable(); + if (!need_resched()) + safe_halt(); /* enables interrupts racelessly */ + else + local_irq_enable(); current_thread_info()->status |= TS_POLLING; } else { - while (!need_resched()) - cpu_relax(); + /* loop is done by the caller */ + cpu_relax(); } } #ifdef CONFIG_APM_MODULE @@ -129,14 +125,7 @@ EXPORT_SYMBOL(default_idle); */ static void poll_idle (void) { - local_irq_enable(); - - asm volatile( - "2:" - "testl %0, %1;" - "rep; nop;" - "je 2b;" - : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); + cpu_relax(); } #ifdef CONFIG_HOTPLUG_CPU @@ -257,8 +246,7 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) static void mwait_idle(void) { local_irq_enable(); - while (!need_resched()) - mwait_idle_with_hints(0, 0); + mwait_idle_with_hints(0, 0); } void __devinit select_idle_routine(const struct cpuinfo_x86 *c) diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 7451a4c43c1..0b7b4caa4f7 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -108,17 +108,15 @@ void exit_idle(void) */ static void default_idle(void) { - local_irq_enable(); - current_thread_info()->status &= ~TS_POLLING; smp_mb__after_clear_bit(); - while (!need_resched()) { - local_irq_disable(); - if (!need_resched()) - safe_halt(); - else - local_irq_enable(); - } + local_irq_disable(); + if (!need_resched()) { + /* Enables interrupts one instruction before HLT. + x86 special cases this so there is no race. */ + safe_halt(); + } else + local_irq_enable(); current_thread_info()->status |= TS_POLLING; } @@ -129,16 +127,7 @@ static void default_idle(void) */ static void poll_idle (void) { - local_irq_enable(); - - asm volatile( - "2:" - "testl %0,%1;" - "rep; nop;" - "je 2b;" - : : - "i" (_TIF_NEED_RESCHED), - "m" (current_thread_info()->flags)); + cpu_relax(); } void cpu_idle_wait(void) @@ -257,8 +246,7 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) static void mwait_idle(void) { local_irq_enable(); - while (!need_resched()) - mwait_idle_with_hints(0,0); + mwait_idle_with_hints(0,0); } void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) -- cgit v1.2.3 From 7cd8b6861eb586aabe4c725cc0c259ce2e653695 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] x86: remove last two pci_find offenders in the core code Resending as I believe the discussion about them established they were correct. Signed-off-by: Alan Cox Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/pci/irq.c | 4 +++- arch/x86_64/kernel/pci-calgary.c | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index e65551cd821..f2cb942f828 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -764,7 +764,7 @@ static void __init pirq_find_router(struct irq_router *r) DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n", rt->rtr_vendor, rt->rtr_device); - pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn); + pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn); if (!pirq_router_dev) { DBG(KERN_DEBUG "PCI: Interrupt router not found at " "%02x:%02x\n", rt->rtr_bus, rt->rtr_devfn); @@ -784,6 +784,8 @@ static void __init pirq_find_router(struct irq_router *r) pirq_router_dev->vendor, pirq_router_dev->device, pci_name(pirq_router_dev)); + + /* The device remains referenced for the kernel lifetime */ } static struct irq_info *pirq_get_info(struct pci_dev *dev) diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 37a770859e7..d2ea87a9526 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -921,7 +921,7 @@ static int __init calgary_init(void) error: do { - dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, + dev = pci_get_device_reverse(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); if (!dev) -- cgit v1.2.3 From 9c5f8be4625e73f17e28fea89399ed871a30e064 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] x86: Mention PCI instead of RAM in NMI parity error message On modern systems RAM errors don't cause NMIs, but it's usually caused by PCI SERR. Mention PCI instead of RAM in the printk. Reported by r_hayashi@ctc-g.co.jp (Ryutaro Hayashi) Cc: r_hayashi@ctc-g.co.jp Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 3 +-- arch/x86_64/kernel/traps.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 4a6fa2837df..237f4884a1e 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -708,8 +708,7 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) { printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " "CPU %d.\n", reason, smp_processor_id()); - printk(KERN_EMERG "You probably have a hardware problem with your RAM " - "chips\n"); + printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); if (panic_on_unrecovered_nmi) panic("NMI: Not continuing"); diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index e37b4d77d5a..70bfaab9822 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -793,8 +793,7 @@ mem_parity_error(unsigned char reason, struct pt_regs * regs) { printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", reason); - printk(KERN_EMERG "You probably have a hardware problem with your " - "RAM chips\n"); + printk(KERN_EMERG "You have some hardware problem, likely on the PCI bus.\n"); if (panic_on_unrecovered_nmi) panic("NMI: Not continuing"); -- cgit v1.2.3 From 6569580de7ae367def89b7671029cb97c1965574 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Distinguish absolute symbols Ld knows about 2 kinds of symbols, absolute and section relative. Section relative symbols symbols change value when a section is moved and absolute symbols do not. Currently in the linker script we have several labels marking the beginning and ending of sections that are outside of sections, making them absolute symbols. Having a mixture of absolute and section relative symbols refereing to the same data is currently harmless but it is confusing. This must be done carefully as newer revs of ld do not place symbols that appear in sections without data and instead ld makes those symbols global :( My ultimate goal is to build a relocatable kernel. The safest and least intrusive technique is to generate relocation entries so the kernel can be relocated at load time. The only penalty would be an increase in the size of the kernel binary. The problem is that if absolute and relocatable symbols are not properly specified absolute symbols will be relocated or section relative symbols won't be, which is fatal. The practical motivation is that when generating kernels that will run from a reserved area for analyzing what caused a kernel panic, it is simpler if you don't need to hard code the physical memory location they will run at, especially for the distributions. [AK: and merged:] o Also put a message so that in future people can be aware of it and avoid introducing absolute symbols. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 113 +++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index c6f84a0322b..cbd24860fbb 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -1,5 +1,11 @@ /* ld script to make i386 Linux kernel * Written by Martin Mares ; + * + * Don't define absolute symbols until and unless you know that symbol + * value is should remain constant even if kernel image is relocated + * at run time. Absolute symbols are not relocated. If symbol value should + * change if kernel is relocated, make the symbol section relative and + * put it inside the section definition. */ #define LOAD_OFFSET __PAGE_OFFSET @@ -24,31 +30,32 @@ SECTIONS . = __KERNEL_START; phys_startup_32 = startup_32 - LOAD_OFFSET; /* read-only */ - _text = .; /* Text and read-only data */ .text : AT(ADDR(.text) - LOAD_OFFSET) { + _text = .; /* Text and read-only data */ *(.text) SCHED_TEXT LOCK_TEXT KPROBES_TEXT *(.fixup) *(.gnu.warning) - } :text = 0x9090 - - _etext = .; /* End of text section */ + _etext = .; /* End of text section */ + } :text = 0x9090 . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } - __stop___ex_table = .; + __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { + __start___ex_table = .; + *(__ex_table) + __stop___ex_table = .; + } RODATA . = ALIGN(4); - __tracedata_start = .; .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { + __tracedata_start = .; *(.tracedata) + __tracedata_end = .; } - __tracedata_end = .; /* writeable */ . = ALIGN(4096); @@ -58,10 +65,12 @@ SECTIONS } :data . = ALIGN(4096); - __nosave_begin = .; - .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) } - . = ALIGN(4096); - __nosave_end = .; + .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { + __nosave_begin = .; + *(.data.nosave) + . = ALIGN(4096); + __nosave_end = .; + } . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -75,8 +84,10 @@ SECTIONS /* rarely changed data like cpu maps */ . = ALIGN(32); - .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } - _edata = .; /* End of data section */ + .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { + *(.data.read_mostly) + _edata = .; /* End of data section */ + } #ifdef CONFIG_STACK_UNWIND . = ALIGN(4); @@ -94,54 +105,56 @@ SECTIONS /* might get freed after init */ . = ALIGN(4096); - __smp_alt_begin = .; - __smp_alt_instructions = .; .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) { + __smp_alt_begin = .; + __smp_alt_instructions = .; *(.smp_altinstructions) + __smp_alt_instructions_end = .; } - __smp_alt_instructions_end = .; . = ALIGN(4); - __smp_locks = .; .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) { + __smp_locks = .; *(.smp_locks) + __smp_locks_end = .; } - __smp_locks_end = .; .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) { *(.smp_altinstr_replacement) + __smp_alt_end = .; } . = ALIGN(4096); - __smp_alt_end = .; /* will be freed after init */ . = ALIGN(4096); /* Init code and data */ - __init_begin = .; .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { + __init_begin = .; _sinittext = .; *(.init.text) _einittext = .; } .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) } . = ALIGN(16); - __setup_start = .; - .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) } - __setup_end = .; - __initcall_start = .; + .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { + __setup_start = .; + *(.init.setup) + __setup_end = .; + } .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) { + __initcall_start = .; INITCALLS + __initcall_end = .; } - __initcall_end = .; - __con_initcall_start = .; .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) { + __con_initcall_start = .; *(.con_initcall.init) + __con_initcall_end = .; } - __con_initcall_end = .; SECURITY_INIT . = ALIGN(4); - __alt_instructions = .; .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) { + __alt_instructions = .; *(.altinstructions) + __alt_instructions_end = .; } - __alt_instructions_end = .; .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } @@ -150,32 +163,32 @@ SECTIONS .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) } . = ALIGN(4096); - __initramfs_start = .; - .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } - __initramfs_end = .; + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { + __initramfs_start = .; + *(.init.ramfs) + __initramfs_end = .; + } . = ALIGN(L1_CACHE_BYTES); - __per_cpu_start = .; - .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } - __per_cpu_end = .; + .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { + __per_cpu_start = .; + *(.data.percpu) + __per_cpu_end = .; + } . = ALIGN(4096); - __init_end = .; /* freed after init ends here */ - __bss_start = .; /* BSS */ - .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) { - *(.bss.page_aligned) - } .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + __init_end = .; + __bss_start = .; /* BSS */ + *(.bss.page_aligned) *(.bss) + . = ALIGN(4); + __bss_stop = .; + _end = . ; + /* This is where the kernel creates the early boot page tables */ + . = ALIGN(4096); + pg0 = . ; } - . = ALIGN(4); - __bss_stop = .; - - _end = . ; - - /* This is where the kernel creates the early boot page tables */ - . = ALIGN(4096); - pg0 = .; /* Sections to be discarded */ /DISCARD/ : { -- cgit v1.2.3 From 6ed018845f1172cdc94f8a20ad807df901c6b7eb Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Add comment for align to vmlinux.lds Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index cbd24860fbb..c217e18f108 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -121,6 +121,12 @@ SECTIONS *(.smp_altinstr_replacement) __smp_alt_end = .; } + /* will be freed after init + * Following ALIGN() is required to make sure no other data falls on the + * same page where __smp_alt_end is pointing as that page might be freed + * after boot. Always make sure that ALIGN() directive is present after + * the section which contains __smp_alt_end. + */ . = ALIGN(4096); /* will be freed after init */ -- cgit v1.2.3 From 8621b81c744ff8880a1efe095a4dcd09763ddb5a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 7 Dec 2006 02:14:03 +0100 Subject: [PATCH] i386: Reserve kernel memory starting from _text Currently when we are reserving the memory the kernel text resides in we start at __PHYSICAL_START which happens to be correct but not very obvious. In addition when we start relocating the kernel __PHYSICAL_START is the wrong value, as it is an absolute symbol that does not get relocated. By starting the reservation at __pa_symbol(_text) the code is clearer and will be correct when relocated. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/kernel/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 141041dde74..61539afbdf2 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1118,8 +1118,8 @@ void __init setup_bootmem_allocator(void) * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ - reserve_bootmem(__PHYSICAL_START, (PFN_PHYS(min_low_pfn) + - bootmap_size + PAGE_SIZE-1) - (__PHYSICAL_START)); + reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + + bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); /* * reserve physical page 0 - it's a special BIOS page on many boxes, -- cgit v1.2.3 From 2a43f3ede48ea3d5790b863b719a1e21c90a3697 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: CONFIG_PHYSICAL_START cleanup Defining __PHYSICAL_START and __KERNEL_START in asm-i386/page.h works but it triggers a full kernel rebuild for the silliest of reasons. This modifies the users to directly use CONFIG_PHYSICAL_START and linux/config.h which prevents the full rebuild problem, which makes the code much more maintainer and hopefully user friendly. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/boot/compressed/head.S | 7 +++---- arch/i386/boot/compressed/misc.c | 7 +++---- arch/i386/kernel/vmlinux.lds.S | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index b5893e4ecd3..40a8de8270a 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S @@ -25,7 +25,6 @@ #include #include -#include .globl startup_32 @@ -75,7 +74,7 @@ startup_32: popl %esi # discard address popl %esi # real mode pointer xorl %ebx,%ebx - ljmp $(__BOOT_CS), $__PHYSICAL_START + ljmp $(__BOOT_CS), $CONFIG_PHYSICAL_START /* * We come here, if we were loaded high. @@ -100,7 +99,7 @@ startup_32: popl %ecx # lcount popl %edx # high_buffer_start popl %eax # hcount - movl $__PHYSICAL_START,%edi + movl $CONFIG_PHYSICAL_START,%edi cli # make sure we don't get interrupted ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine @@ -125,5 +124,5 @@ move_routine_start: movsl movl %ebx,%esi # Restore setup pointer xorl %ebx,%ebx - ljmp $(__BOOT_CS), $__PHYSICAL_START + ljmp $(__BOOT_CS), $CONFIG_PHYSICAL_START move_routine_end: diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index b2ccd543410..20970ff4411 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -13,7 +13,6 @@ #include #include #include -#include /* * gzip declarations @@ -303,7 +302,7 @@ static void setup_normal_output_buffer(void) #else if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); #endif - output_data = (unsigned char *)__PHYSICAL_START; /* Normally Points to 1M */ + output_data = (unsigned char *)CONFIG_PHYSICAL_START; /* Normally Points to 1M */ free_mem_end_ptr = (long)real_mode; } @@ -326,8 +325,8 @@ static void setup_output_buffer_if_we_run_high(struct moveparams *mv) low_buffer_size = low_buffer_end - LOW_BUFFER_START; high_loaded = 1; free_mem_end_ptr = (long)high_buffer_start; - if ( (__PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { - high_buffer_start = (uch *)(__PHYSICAL_START + low_buffer_size); + if ( (CONFIG_PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { + high_buffer_start = (uch *)(CONFIG_PHYSICAL_START + low_buffer_size); mv->hcount = 0; /* say: we need not to move high_buffer */ } else mv->hcount = -1; diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index c217e18f108..f8d61ec4c8c 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -27,7 +27,7 @@ PHDRS { } SECTIONS { - . = __KERNEL_START; + . = LOAD_OFFSET + CONFIG_PHYSICAL_START; phys_startup_32 = startup_32 - LOAD_OFFSET; /* read-only */ .text : AT(ADDR(.text) - LOAD_OFFSET) { -- cgit v1.2.3 From fd593d12770d4a0d1ff095d44b96436c18479ee8 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] relocatable kernel: Kallsyms generate relocatable symbols Print the addresses of non-absolute symbols relative to _text so that ld will generate relocations. Allowing a relocatable kernel to relocate them. We can't actually use the symbol names because kallsyms includes static symbols that are not exported from their object files. Add the _text symbol definitions to the architectures which don't define it otherwise linker will fail. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/h8300/kernel/vmlinux.lds.S | 1 + arch/m68knommu/kernel/vmlinux.lds.S | 1 + arch/powerpc/kernel/vmlinux.lds.S | 1 + arch/ppc/kernel/vmlinux.lds.S | 1 + arch/sparc/kernel/vmlinux.lds.S | 1 + arch/sparc64/kernel/vmlinux.lds.S | 1 + arch/v850/kernel/vmlinux.lds.S | 1 + 7 files changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/h8300/kernel/vmlinux.lds.S b/arch/h8300/kernel/vmlinux.lds.S index 756325dd480..f05288be887 100644 --- a/arch/h8300/kernel/vmlinux.lds.S +++ b/arch/h8300/kernel/vmlinux.lds.S @@ -70,6 +70,7 @@ SECTIONS #endif .text : { + _text = .; #if defined(CONFIG_ROMKERNEL) *(.int_redirect) #endif diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S index 58afa8be604..2b2a10da64a 100644 --- a/arch/m68knommu/kernel/vmlinux.lds.S +++ b/arch/m68knommu/kernel/vmlinux.lds.S @@ -60,6 +60,7 @@ SECTIONS { #endif .text : { + _text = .; _stext = . ; *(.text) SCHED_TEXT diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index e8342d86753..04b98671a06 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -33,6 +33,7 @@ SECTIONS /* Text and gots */ .text : { + _text = .; *(.text .text.*) SCHED_TEXT LOCK_TEXT diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 16e8661e1fe..61921268a0d 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -31,6 +31,7 @@ SECTIONS .plt : { *(.plt) } .text : { + _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 5cc5ff7f882..b73e6b9067e 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -11,6 +11,7 @@ SECTIONS . = 0x10000 + SIZEOF_HEADERS; .text 0xf0004000 : { + _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index bd9de8c2a2a..4a6063f33e7 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S @@ -13,6 +13,7 @@ SECTIONS . = 0x4000; .text 0x0000000000404000 : { + _text = .; *(.text) SCHED_TEXT LOCK_TEXT diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S index 88d087f527c..3a5fd07fe06 100644 --- a/arch/v850/kernel/vmlinux.lds.S +++ b/arch/v850/kernel/vmlinux.lds.S @@ -90,6 +90,7 @@ /* Kernel text segment, and some constant data areas. */ #define TEXT_CONTENTS \ + _text = .; \ __stext = . ; \ *(.text) \ SCHED_TEXT \ -- cgit v1.2.3 From 968de4f02621db35b8ae5239c8cfc6664fb872d8 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: Relocatable kernel support This patch modifies the i386 kernel so that if CONFIG_RELOCATABLE is selected it will be able to be loaded at any 4K aligned address below 1G. The technique used is to compile the decompressor with -fPIC and modify it so the decompressor is fully relocatable. For the main kernel relocations are generated. Resulting in a kernel that is relocatable with no runtime overhead and no need to modify the source code. A reserved 32bit word in the parameters has been assigned to serve as a stack so we figure out where are running. Signed-off-by: Eric W. Biederman Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 12 + arch/i386/Makefile | 4 +- arch/i386/boot/compressed/Makefile | 28 +- arch/i386/boot/compressed/head.S | 184 +++++++---- arch/i386/boot/compressed/misc.c | 261 ++++++++-------- arch/i386/boot/compressed/relocs.c | 563 ++++++++++++++++++++++++++++++++++ arch/i386/boot/compressed/vmlinux.lds | 43 +++ arch/i386/boot/compressed/vmlinux.scr | 3 +- arch/i386/boot/setup.S | 29 +- 9 files changed, 918 insertions(+), 209 deletions(-) create mode 100644 arch/i386/boot/compressed/relocs.c create mode 100644 arch/i386/boot/compressed/vmlinux.lds (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 8ff1c6fb5aa..d588ca874bb 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -773,6 +773,18 @@ config CRASH_DUMP PHYSICAL_START. For more details see Documentation/kdump/kdump.txt +config RELOCATABLE + bool "Build a relocatable kernel" + help + This build a kernel image that retains relocation information + so it can be loaded someplace besides the default 1MB. + The relocations tend to the kernel binary about 10% larger, + but are discarded at runtime. + + One use is for the kexec on panic case where the recovery kernel + must live at a different physical address than the primary + kernel. + config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 0677908dfa0..d1aca52bf69 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -26,7 +26,9 @@ endif LDFLAGS := -m elf_i386 OBJCOPYFLAGS := -O binary -R .note -R .comment -S -LDFLAGS_vmlinux := +ifdef CONFIG_RELOCATABLE +LDFLAGS_vmlinux := --emit-relocs +endif CHECKFLAGS += -D__i386__ CFLAGS += -pipe -msoft-float diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile index 258ea95224f..cc28da3a881 100644 --- a/arch/i386/boot/compressed/Makefile +++ b/arch/i386/boot/compressed/Makefile @@ -4,22 +4,42 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o +targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o \ + vmlinux.bin.all vmlinux.relocs EXTRA_AFLAGS := -traditional -LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup_32 +LDFLAGS_vmlinux := -T +CFLAGS_misc.o += -fPIC +hostprogs-y := relocs -$(obj)/vmlinux: $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE +$(obj)/vmlinux: $(src)/vmlinux.lds $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o FORCE $(call if_changed,ld) @: $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) +quiet_cmd_relocs = RELOCS $@ + cmd_relocs = $(obj)/relocs $< > $@ +$(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE + $(call if_changed,relocs) + +vmlinux.bin.all-y := $(obj)/vmlinux.bin +vmlinux.bin.all-$(CONFIG_RELOCATABLE) += $(obj)/vmlinux.relocs +quiet_cmd_relocbin = BUILD $@ + cmd_relocbin = cat $(filter-out FORCE,$^) > $@ +$(obj)/vmlinux.bin.all: $(vmlinux.bin.all-y) FORCE + $(call if_changed,relocbin) + +ifdef CONFIG_RELOCATABLE +$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin.all FORCE + $(call if_changed,gzip) +else $(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE $(call if_changed,gzip) +endif LDFLAGS_piggy.o := -r --format binary --oformat elf32-i386 -T -$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE +$(obj)/piggy.o: $(src)/vmlinux.scr $(obj)/vmlinux.bin.gz FORCE $(call if_changed,ld) diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index 40a8de8270a..e4dd7a6b9b0 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S @@ -25,9 +25,11 @@ #include #include +#include +.section ".text.head" .globl startup_32 - + startup_32: cld cli @@ -36,93 +38,141 @@ startup_32: movl %eax,%es movl %eax,%fs movl %eax,%gs + movl %eax,%ss - lss stack_start,%esp - xorl %eax,%eax -1: incl %eax # check that A20 really IS enabled - movl %eax,0x000000 # loop forever if it isn't - cmpl %eax,0x100000 - je 1b +/* Calculate the delta between where we were compiled to run + * at and where we were actually loaded at. This can only be done + * with a short local call on x86. Nothing else will tell us what + * address we are running at. The reserved chunk of the real-mode + * data at 0x34-0x3f are used as the stack for this calculation. + * Only 4 bytes are needed. + */ + leal 0x40(%esi), %esp + call 1f +1: popl %ebp + subl $1b, %ebp + +/* Compute the delta between where we were compiled to run at + * and where the code will actually run at. + */ + /* Start with the delta to where the kernel will run at. If we are + * a relocatable kernel this is the delta to our load address otherwise + * this is the delta to CONFIG_PHYSICAL start. + */ +#ifdef CONFIG_RELOCATABLE + movl %ebp, %ebx +#else + movl $(CONFIG_PHYSICAL_START - startup_32), %ebx +#endif + + /* Replace the compressed data size with the uncompressed size */ + subl input_len(%ebp), %ebx + movl output_len(%ebp), %eax + addl %eax, %ebx + /* Add 8 bytes for every 32K input block */ + shrl $12, %eax + addl %eax, %ebx + /* Add 32K + 18 bytes of extra slack */ + addl $(32768 + 18), %ebx + /* Align on a 4K boundary */ + addl $4095, %ebx + andl $~4095, %ebx + +/* Copy the compressed kernel to the end of our buffer + * where decompression in place becomes safe. + */ + pushl %esi + leal _end(%ebp), %esi + leal _end(%ebx), %edi + movl $(_end - startup_32), %ecx + std + rep + movsb + cld + popl %esi + +/* Compute the kernel start address. + */ +#ifdef CONFIG_RELOCATABLE + leal startup_32(%ebp), %ebp +#else + movl $CONFIG_PHYSICAL_START, %ebp +#endif /* - * Initialize eflags. Some BIOS's leave bits like NT set. This would - * confuse the debugger if this code is traced. - * XXX - best to initialize before switching to protected mode. + * Jump to the relocated address. */ - pushl $0 - popfl + leal relocated(%ebx), %eax + jmp *%eax +.section ".text" +relocated: + /* * Clear BSS */ xorl %eax,%eax - movl $_edata,%edi - movl $_end,%ecx + leal _edata(%ebx),%edi + leal _end(%ebx), %ecx subl %edi,%ecx cld rep stosb + +/* + * Setup the stack for the decompressor + */ + leal stack_end(%ebx), %esp + /* * Do the decompression, and jump to the new kernel.. */ - subl $16,%esp # place for structure on the stack - movl %esp,%eax + movl output_len(%ebx), %eax + pushl %eax + pushl %ebp # output address + movl input_len(%ebx), %eax + pushl %eax # input_len + leal input_data(%ebx), %eax + pushl %eax # input_data + leal _end(%ebx), %eax + pushl %eax # end of the image as third argument pushl %esi # real mode pointer as second arg - pushl %eax # address of structure as first arg call decompress_kernel - orl %eax,%eax - jnz 3f - popl %esi # discard address - popl %esi # real mode pointer - xorl %ebx,%ebx - ljmp $(__BOOT_CS), $CONFIG_PHYSICAL_START + addl $20, %esp + popl %ecx + +#if CONFIG_RELOCATABLE +/* Find the address of the relocations. + */ + movl %ebp, %edi + addl %ecx, %edi + +/* Calculate the delta between where vmlinux was compiled to run + * and where it was actually loaded. + */ + movl %ebp, %ebx + subl $CONFIG_PHYSICAL_START, %ebx /* - * We come here, if we were loaded high. - * We need to move the move-in-place routine down to 0x1000 - * and then start it with the buffer addresses in registers, - * which we got from the stack. + * Process relocations. */ -3: - movl $move_routine_start,%esi - movl $0x1000,%edi - movl $move_routine_end,%ecx - subl %esi,%ecx - addl $3,%ecx - shrl $2,%ecx - cld - rep - movsl - - popl %esi # discard the address - popl %ebx # real mode pointer - popl %esi # low_buffer_start - popl %ecx # lcount - popl %edx # high_buffer_start - popl %eax # hcount - movl $CONFIG_PHYSICAL_START,%edi - cli # make sure we don't get interrupted - ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine + +1: subl $4, %edi + movl 0(%edi), %ecx + testl %ecx, %ecx + jz 2f + addl %ebx, -__PAGE_OFFSET(%ebx, %ecx) + jmp 1b +2: +#endif /* - * Routine (template) for moving the decompressed kernel in place, - * if we were high loaded. This _must_ PIC-code ! + * Jump to the decompressed kernel. */ -move_routine_start: - movl %ecx,%ebp - shrl $2,%ecx - rep - movsl - movl %ebp,%ecx - andl $3,%ecx - rep - movsb - movl %edx,%esi - movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0 - addl $3,%ecx - shrl $2,%ecx - rep - movsl - movl %ebx,%esi # Restore setup pointer xorl %ebx,%ebx - ljmp $(__BOOT_CS), $CONFIG_PHYSICAL_START -move_routine_end: + jmp *%ebp + +.bss +.balign 4 +stack: + .fill 4096, 1, 0 +stack_end: diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 20970ff4411..4eac24e95a1 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -13,6 +13,88 @@ #include #include #include +#include + +/* WARNING!! + * This code is compiled with -fPIC and it is relocated dynamically + * at run time, but no relocation processing is performed. + * This means that it is not safe to place pointers in static structures. + */ + +/* + * Getting to provable safe in place decompression is hard. + * Worst case behaviours need to be analized. + * Background information: + * + * The file layout is: + * magic[2] + * method[1] + * flags[1] + * timestamp[4] + * extraflags[1] + * os[1] + * compressed data blocks[N] + * crc[4] orig_len[4] + * + * resulting in 18 bytes of non compressed data overhead. + * + * Files divided into blocks + * 1 bit (last block flag) + * 2 bits (block type) + * + * 1 block occurs every 32K -1 bytes or when there 50% compression has been achieved. + * The smallest block type encoding is always used. + * + * stored: + * 32 bits length in bytes. + * + * fixed: + * magic fixed tree. + * symbols. + * + * dynamic: + * dynamic tree encoding. + * symbols. + * + * + * The buffer for decompression in place is the length of the + * uncompressed data, plus a small amount extra to keep the algorithm safe. + * The compressed data is placed at the end of the buffer. The output + * pointer is placed at the start of the buffer and the input pointer + * is placed where the compressed data starts. Problems will occur + * when the output pointer overruns the input pointer. + * + * The output pointer can only overrun the input pointer if the input + * pointer is moving faster than the output pointer. A condition only + * triggered by data whose compressed form is larger than the uncompressed + * form. + * + * The worst case at the block level is a growth of the compressed data + * of 5 bytes per 32767 bytes. + * + * The worst case internal to a compressed block is very hard to figure. + * The worst case can at least be boundined by having one bit that represents + * 32764 bytes and then all of the rest of the bytes representing the very + * very last byte. + * + * All of which is enough to compute an amount of extra data that is required + * to be safe. To avoid problems at the block level allocating 5 extra bytes + * per 32767 bytes of data is sufficient. To avoind problems internal to a block + * adding an extra 32767 bytes (the worst case uncompressed block size) is + * sufficient, to ensure that in the worst case the decompressed data for + * block will stop the byte before the compressed data for a block begins. + * To avoid problems with the compressed data's meta information an extra 18 + * bytes are needed. Leading to the formula: + * + * extra_bytes = (uncompressed_size >> 12) + 32768 + 18 + decompressor_size. + * + * Adding 8 bytes per 32K is a bit excessive but much easier to calculate. + * Adding 32768 instead of 32767 just makes for round numbers. + * Adding the decompressor_size is necessary as it musht live after all + * of the data as well. Last I measured the decompressor is about 14K. + * 10K of actuall data and 4K of bss. + * + */ /* * gzip declarations @@ -29,15 +111,20 @@ typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; -#define WSIZE 0x8000 /* Window size must be at least 32k, */ - /* and a power of two */ +#define WSIZE 0x80000000 /* Window size must be at least 32k, + * and a power of two + * We don't actually have a window just + * a huge output buffer so I report + * a 2G windows size, as that should + * always be larger than our output buffer. + */ -static uch *inbuf; /* input buffer */ -static uch window[WSIZE]; /* Sliding window buffer */ +static uch *inbuf; /* input buffer */ +static uch *window; /* Sliding window buffer, (and final output buffer) */ -static unsigned insize = 0; /* valid bytes in inbuf */ -static unsigned inptr = 0; /* index of next byte to be processed in inbuf */ -static unsigned outcnt = 0; /* bytes in output buffer */ +static unsigned insize; /* valid bytes in inbuf */ +static unsigned inptr; /* index of next byte to be processed in inbuf */ +static unsigned outcnt; /* bytes in output buffer */ /* gzip flag byte */ #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ @@ -88,8 +175,6 @@ extern unsigned char input_data[]; extern int input_len; static long bytes_out = 0; -static uch *output_data; -static unsigned long output_ptr = 0; static void *malloc(int size); static void free(void *where); @@ -99,17 +184,10 @@ static void *memcpy(void *dest, const void *src, unsigned n); static void putstr(const char *); -extern int end; -static long free_mem_ptr = (long)&end; -static long free_mem_end_ptr; +static unsigned long free_mem_ptr; +static unsigned long free_mem_end_ptr; -#define INPLACE_MOVE_ROUTINE 0x1000 -#define LOW_BUFFER_START 0x2000 -#define LOW_BUFFER_MAX 0x90000 #define HEAP_SIZE 0x3000 -static unsigned int low_buffer_end, low_buffer_size; -static int high_loaded =0; -static uch *high_buffer_start /* = (uch *)(((ulg)&end) + HEAP_SIZE)*/; static char *vidmem = (char *)0xb8000; static int vidport; @@ -150,7 +228,7 @@ static void gzip_mark(void **ptr) static void gzip_release(void **ptr) { - free_mem_ptr = (long) *ptr; + free_mem_ptr = (unsigned long) *ptr; } static void scroll(void) @@ -178,7 +256,7 @@ static void putstr(const char *s) y--; } } else { - vidmem [ ( x + cols * y ) * 2 ] = c; + vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { @@ -223,58 +301,31 @@ static void* memcpy(void* dest, const void* src, unsigned n) */ static int fill_inbuf(void) { - if (insize != 0) { - error("ran out of input data"); - } - - inbuf = input_data; - insize = input_len; - inptr = 1; - return inbuf[0]; + error("ran out of input data"); + return 0; } /* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */ -static void flush_window_low(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, *out, ch; - - in = window; - out = &output_data[output_ptr]; - for (n = 0; n < outcnt; n++) { - ch = *out++ = *in++; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - output_ptr += (ulg)outcnt; - outcnt = 0; -} - -static void flush_window_high(void) -{ - ulg c = crc; /* temporary variable */ - unsigned n; - uch *in, ch; - in = window; - for (n = 0; n < outcnt; n++) { - ch = *output_data++ = *in++; - if ((ulg)output_data == low_buffer_end) output_data=high_buffer_start; - c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); - } - crc = c; - bytes_out += (ulg)outcnt; - outcnt = 0; -} - static void flush_window(void) { - if (high_loaded) flush_window_high(); - else flush_window_low(); + /* With my window equal to my output buffer + * I only need to compute the crc here. + */ + ulg c = crc; /* temporary variable */ + unsigned n; + uch *in, ch; + + in = window; + for (n = 0; n < outcnt; n++) { + ch = *in++; + c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); + } + crc = c; + bytes_out += (ulg)outcnt; + outcnt = 0; } static void error(char *x) @@ -286,66 +337,8 @@ static void error(char *x) while(1); /* Halt */ } -#define STACK_SIZE (4096) - -long user_stack [STACK_SIZE]; - -struct { - long * a; - short b; - } stack_start = { & user_stack [STACK_SIZE] , __BOOT_DS }; - -static void setup_normal_output_buffer(void) -{ -#ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < 1024) error("Less than 2MB of memory"); -#else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < 1024) error("Less than 2MB of memory"); -#endif - output_data = (unsigned char *)CONFIG_PHYSICAL_START; /* Normally Points to 1M */ - free_mem_end_ptr = (long)real_mode; -} - -struct moveparams { - uch *low_buffer_start; int lcount; - uch *high_buffer_start; int hcount; -}; - -static void setup_output_buffer_if_we_run_high(struct moveparams *mv) -{ - high_buffer_start = (uch *)(((ulg)&end) + HEAP_SIZE); -#ifdef STANDARD_MEMORY_BIOS_CALL - if (RM_EXT_MEM_K < (3*1024)) error("Less than 4MB of memory"); -#else - if ((RM_ALT_MEM_K > RM_EXT_MEM_K ? RM_ALT_MEM_K : RM_EXT_MEM_K) < (3*1024)) error("Less than 4MB of memory"); -#endif - mv->low_buffer_start = output_data = (unsigned char *)LOW_BUFFER_START; - low_buffer_end = ((unsigned int)real_mode > LOW_BUFFER_MAX - ? LOW_BUFFER_MAX : (unsigned int)real_mode) & ~0xfff; - low_buffer_size = low_buffer_end - LOW_BUFFER_START; - high_loaded = 1; - free_mem_end_ptr = (long)high_buffer_start; - if ( (CONFIG_PHYSICAL_START + low_buffer_size) > ((ulg)high_buffer_start)) { - high_buffer_start = (uch *)(CONFIG_PHYSICAL_START + low_buffer_size); - mv->hcount = 0; /* say: we need not to move high_buffer */ - } - else mv->hcount = -1; - mv->high_buffer_start = high_buffer_start; -} - -static void close_output_buffer_if_we_run_high(struct moveparams *mv) -{ - if (bytes_out > low_buffer_size) { - mv->lcount = low_buffer_size; - if (mv->hcount) - mv->hcount = bytes_out - low_buffer_size; - } else { - mv->lcount = bytes_out; - mv->hcount = 0; - } -} - -asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) +asmlinkage void decompress_kernel(void *rmode, unsigned long end, + uch *input_data, unsigned long input_len, uch *output) { real_mode = rmode; @@ -360,13 +353,25 @@ asmlinkage int decompress_kernel(struct moveparams *mv, void *rmode) lines = RM_SCREEN_INFO.orig_video_lines; cols = RM_SCREEN_INFO.orig_video_cols; - if (free_mem_ptr < 0x100000) setup_normal_output_buffer(); - else setup_output_buffer_if_we_run_high(mv); + window = output; /* Output buffer (Normally at 1M) */ + free_mem_ptr = end; /* Heap */ + free_mem_end_ptr = end + HEAP_SIZE; + inbuf = input_data; /* Input buffer */ + insize = input_len; + inptr = 0; + + if (((u32)output - CONFIG_PHYSICAL_START) & 0x3fffff) + error("Destination address not 4M aligned"); + if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) + error("Destination address too large"); +#ifndef CONFIG_RELOCATABLE + if ((u32)output != CONFIG_PHYSICAL_START) + error("Wrong destination address"); +#endif makecrc(); putstr("Uncompressing Linux... "); gunzip(); putstr("Ok, booting the kernel.\n"); - if (high_loaded) close_output_buffer_if_we_run_high(mv); - return high_loaded; + return; } diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c new file mode 100644 index 00000000000..0551ceb21be --- /dev/null +++ b/arch/i386/boot/compressed/relocs.c @@ -0,0 +1,563 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define USE_BSD +#include + +#define MAX_SHDRS 100 +static Elf32_Ehdr ehdr; +static Elf32_Shdr shdr[MAX_SHDRS]; +static Elf32_Sym *symtab[MAX_SHDRS]; +static Elf32_Rel *reltab[MAX_SHDRS]; +static char *strtab[MAX_SHDRS]; +static unsigned long reloc_count, reloc_idx; +static unsigned long *relocs; + +static void die(char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +static const char *sym_type(unsigned type) +{ + static const char *type_name[] = { +#define SYM_TYPE(X) [X] = #X + SYM_TYPE(STT_NOTYPE), + SYM_TYPE(STT_OBJECT), + SYM_TYPE(STT_FUNC), + SYM_TYPE(STT_SECTION), + SYM_TYPE(STT_FILE), + SYM_TYPE(STT_COMMON), + SYM_TYPE(STT_TLS), +#undef SYM_TYPE + }; + const char *name = "unknown sym type name"; + if (type < sizeof(type_name)/sizeof(type_name[0])) { + name = type_name[type]; + } + return name; +} + +static const char *sym_bind(unsigned bind) +{ + static const char *bind_name[] = { +#define SYM_BIND(X) [X] = #X + SYM_BIND(STB_LOCAL), + SYM_BIND(STB_GLOBAL), + SYM_BIND(STB_WEAK), +#undef SYM_BIND + }; + const char *name = "unknown sym bind name"; + if (bind < sizeof(bind_name)/sizeof(bind_name[0])) { + name = bind_name[bind]; + } + return name; +} + +static const char *sym_visibility(unsigned visibility) +{ + static const char *visibility_name[] = { +#define SYM_VISIBILITY(X) [X] = #X + SYM_VISIBILITY(STV_DEFAULT), + SYM_VISIBILITY(STV_INTERNAL), + SYM_VISIBILITY(STV_HIDDEN), + SYM_VISIBILITY(STV_PROTECTED), +#undef SYM_VISIBILITY + }; + const char *name = "unknown sym visibility name"; + if (visibility < sizeof(visibility_name)/sizeof(visibility_name[0])) { + name = visibility_name[visibility]; + } + return name; +} + +static const char *rel_type(unsigned type) +{ + static const char *type_name[] = { +#define REL_TYPE(X) [X] = #X + REL_TYPE(R_386_NONE), + REL_TYPE(R_386_32), + REL_TYPE(R_386_PC32), + REL_TYPE(R_386_GOT32), + REL_TYPE(R_386_PLT32), + REL_TYPE(R_386_COPY), + REL_TYPE(R_386_GLOB_DAT), + REL_TYPE(R_386_JMP_SLOT), + REL_TYPE(R_386_RELATIVE), + REL_TYPE(R_386_GOTOFF), + REL_TYPE(R_386_GOTPC), +#undef REL_TYPE + }; + const char *name = "unknown type rel type name"; + if (type < sizeof(type_name)/sizeof(type_name[0])) { + name = type_name[type]; + } + return name; +} + +static const char *sec_name(unsigned shndx) +{ + const char *sec_strtab; + const char *name; + sec_strtab = strtab[ehdr.e_shstrndx]; + name = ""; + if (shndx < ehdr.e_shnum) { + name = sec_strtab + shdr[shndx].sh_name; + } + else if (shndx == SHN_ABS) { + name = "ABSOLUTE"; + } + else if (shndx == SHN_COMMON) { + name = "COMMON"; + } + return name; +} + +static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) +{ + const char *name; + name = ""; + if (sym->st_name) { + name = sym_strtab + sym->st_name; + } + else { + name = sec_name(shdr[sym->st_shndx].sh_name); + } + return name; +} + + + +#if BYTE_ORDER == LITTLE_ENDIAN +#define le16_to_cpu(val) (val) +#define le32_to_cpu(val) (val) +#endif +#if BYTE_ORDER == BIG_ENDIAN +#define le16_to_cpu(val) bswap_16(val) +#define le32_to_cpu(val) bswap_32(val) +#endif + +static uint16_t elf16_to_cpu(uint16_t val) +{ + return le16_to_cpu(val); +} + +static uint32_t elf32_to_cpu(uint32_t val) +{ + return le32_to_cpu(val); +} + +static void read_ehdr(FILE *fp) +{ + if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) { + die("Cannot read ELF header: %s\n", + strerror(errno)); + } + if (memcmp(ehdr.e_ident, ELFMAG, 4) != 0) { + die("No ELF magic\n"); + } + if (ehdr.e_ident[EI_CLASS] != ELFCLASS32) { + die("Not a 32 bit executable\n"); + } + if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { + die("Not a LSB ELF executable\n"); + } + if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) { + die("Unknown ELF version\n"); + } + /* Convert the fields to native endian */ + ehdr.e_type = elf16_to_cpu(ehdr.e_type); + ehdr.e_machine = elf16_to_cpu(ehdr.e_machine); + ehdr.e_version = elf32_to_cpu(ehdr.e_version); + ehdr.e_entry = elf32_to_cpu(ehdr.e_entry); + ehdr.e_phoff = elf32_to_cpu(ehdr.e_phoff); + ehdr.e_shoff = elf32_to_cpu(ehdr.e_shoff); + ehdr.e_flags = elf32_to_cpu(ehdr.e_flags); + ehdr.e_ehsize = elf16_to_cpu(ehdr.e_ehsize); + ehdr.e_phentsize = elf16_to_cpu(ehdr.e_phentsize); + ehdr.e_phnum = elf16_to_cpu(ehdr.e_phnum); + ehdr.e_shentsize = elf16_to_cpu(ehdr.e_shentsize); + ehdr.e_shnum = elf16_to_cpu(ehdr.e_shnum); + ehdr.e_shstrndx = elf16_to_cpu(ehdr.e_shstrndx); + + if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) { + die("Unsupported ELF header type\n"); + } + if (ehdr.e_machine != EM_386) { + die("Not for x86\n"); + } + if (ehdr.e_version != EV_CURRENT) { + die("Unknown ELF version\n"); + } + if (ehdr.e_ehsize != sizeof(Elf32_Ehdr)) { + die("Bad Elf header size\n"); + } + if (ehdr.e_phentsize != sizeof(Elf32_Phdr)) { + die("Bad program header entry\n"); + } + if (ehdr.e_shentsize != sizeof(Elf32_Shdr)) { + die("Bad section header entry\n"); + } + if (ehdr.e_shstrndx >= ehdr.e_shnum) { + die("String table index out of bounds\n"); + } +} + +static void read_shdrs(FILE *fp) +{ + int i; + if (ehdr.e_shnum > MAX_SHDRS) { + die("%d section headers supported: %d\n", + ehdr.e_shnum, MAX_SHDRS); + } + if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { + die("Seek to %d failed: %s\n", + ehdr.e_shoff, strerror(errno)); + } + if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) { + die("Cannot read ELF section headers: %s\n", + strerror(errno)); + } + for(i = 0; i < ehdr.e_shnum; i++) { + shdr[i].sh_name = elf32_to_cpu(shdr[i].sh_name); + shdr[i].sh_type = elf32_to_cpu(shdr[i].sh_type); + shdr[i].sh_flags = elf32_to_cpu(shdr[i].sh_flags); + shdr[i].sh_addr = elf32_to_cpu(shdr[i].sh_addr); + shdr[i].sh_offset = elf32_to_cpu(shdr[i].sh_offset); + shdr[i].sh_size = elf32_to_cpu(shdr[i].sh_size); + shdr[i].sh_link = elf32_to_cpu(shdr[i].sh_link); + shdr[i].sh_info = elf32_to_cpu(shdr[i].sh_info); + shdr[i].sh_addralign = elf32_to_cpu(shdr[i].sh_addralign); + shdr[i].sh_entsize = elf32_to_cpu(shdr[i].sh_entsize); + } + +} + +static void read_strtabs(FILE *fp) +{ + int i; + for(i = 0; i < ehdr.e_shnum; i++) { + if (shdr[i].sh_type != SHT_STRTAB) { + continue; + } + strtab[i] = malloc(shdr[i].sh_size); + if (!strtab[i]) { + die("malloc of %d bytes for strtab failed\n", + shdr[i].sh_size); + } + if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { + die("Seek to %d failed: %s\n", + shdr[i].sh_offset, strerror(errno)); + } + if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { + die("Cannot read symbol table: %s\n", + strerror(errno)); + } + } +} + +static void read_symtabs(FILE *fp) +{ + int i,j; + for(i = 0; i < ehdr.e_shnum; i++) { + if (shdr[i].sh_type != SHT_SYMTAB) { + continue; + } + symtab[i] = malloc(shdr[i].sh_size); + if (!symtab[i]) { + die("malloc of %d bytes for symtab failed\n", + shdr[i].sh_size); + } + if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { + die("Seek to %d failed: %s\n", + shdr[i].sh_offset, strerror(errno)); + } + if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { + die("Cannot read symbol table: %s\n", + strerror(errno)); + } + for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) { + symtab[i][j].st_name = elf32_to_cpu(symtab[i][j].st_name); + symtab[i][j].st_value = elf32_to_cpu(symtab[i][j].st_value); + symtab[i][j].st_size = elf32_to_cpu(symtab[i][j].st_size); + symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx); + } + } +} + + +static void read_relocs(FILE *fp) +{ + int i,j; + for(i = 0; i < ehdr.e_shnum; i++) { + if (shdr[i].sh_type != SHT_REL) { + continue; + } + reltab[i] = malloc(shdr[i].sh_size); + if (!reltab[i]) { + die("malloc of %d bytes for relocs failed\n", + shdr[i].sh_size); + } + if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { + die("Seek to %d failed: %s\n", + shdr[i].sh_offset, strerror(errno)); + } + if (fread(reltab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { + die("Cannot read symbol table: %s\n", + strerror(errno)); + } + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { + reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); + reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info); + } + } +} + + +static void print_absolute_symbols(void) +{ + int i; + printf("Absolute symbols\n"); + printf(" Num: Value Size Type Bind Visibility Name\n"); + for(i = 0; i < ehdr.e_shnum; i++) { + char *sym_strtab; + Elf32_Sym *sh_symtab; + int j; + if (shdr[i].sh_type != SHT_SYMTAB) { + continue; + } + sh_symtab = symtab[i]; + sym_strtab = strtab[shdr[i].sh_link]; + for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) { + Elf32_Sym *sym; + const char *name; + sym = &symtab[i][j]; + name = sym_name(sym_strtab, sym); + if (sym->st_shndx != SHN_ABS) { + continue; + } + printf("%5d %08x %5d %10s %10s %12s %s\n", + j, sym->st_value, sym->st_size, + sym_type(ELF32_ST_TYPE(sym->st_info)), + sym_bind(ELF32_ST_BIND(sym->st_info)), + sym_visibility(ELF32_ST_VISIBILITY(sym->st_other)), + name); + } + } + printf("\n"); +} + +static void print_absolute_relocs(void) +{ + int i; + printf("Absolute relocations\n"); + printf("Offset Info Type Sym.Value Sym.Name\n"); + for(i = 0; i < ehdr.e_shnum; i++) { + char *sym_strtab; + Elf32_Sym *sh_symtab; + unsigned sec_applies, sec_symtab; + int j; + if (shdr[i].sh_type != SHT_REL) { + continue; + } + sec_symtab = shdr[i].sh_link; + sec_applies = shdr[i].sh_info; + if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { + continue; + } + sh_symtab = symtab[sec_symtab]; + sym_strtab = strtab[shdr[sec_symtab].sh_link]; + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { + Elf32_Rel *rel; + Elf32_Sym *sym; + const char *name; + rel = &reltab[i][j]; + sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; + name = sym_name(sym_strtab, sym); + if (sym->st_shndx != SHN_ABS) { + continue; + } + printf("%08x %08x %10s %08x %s\n", + rel->r_offset, + rel->r_info, + rel_type(ELF32_R_TYPE(rel->r_info)), + sym->st_value, + name); + } + } + printf("\n"); +} + +static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) +{ + int i; + /* Walk through the relocations */ + for(i = 0; i < ehdr.e_shnum; i++) { + char *sym_strtab; + Elf32_Sym *sh_symtab; + unsigned sec_applies, sec_symtab; + int j; + if (shdr[i].sh_type != SHT_REL) { + continue; + } + sec_symtab = shdr[i].sh_link; + sec_applies = shdr[i].sh_info; + if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { + continue; + } + sh_symtab = symtab[sec_symtab]; + sym_strtab = strtab[shdr[sec_symtab].sh_link]; + for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { + Elf32_Rel *rel; + Elf32_Sym *sym; + unsigned r_type; + rel = &reltab[i][j]; + sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; + r_type = ELF32_R_TYPE(rel->r_info); + /* Don't visit relocations to absolute symbols */ + if (sym->st_shndx == SHN_ABS) { + continue; + } + if (r_type == R_386_PC32) { + /* PC relative relocations don't need to be adjusted */ + } + else if (r_type == R_386_32) { + /* Visit relocations that need to be adjusted */ + visit(rel, sym); + } + else { + die("Unsupported relocation type: %d\n", r_type); + } + } + } +} + +static void count_reloc(Elf32_Rel *rel, Elf32_Sym *sym) +{ + reloc_count += 1; +} + +static void collect_reloc(Elf32_Rel *rel, Elf32_Sym *sym) +{ + /* Remember the address that needs to be adjusted. */ + relocs[reloc_idx++] = rel->r_offset; +} + +static int cmp_relocs(const void *va, const void *vb) +{ + const unsigned long *a, *b; + a = va; b = vb; + return (*a == *b)? 0 : (*a > *b)? 1 : -1; +} + +static void emit_relocs(int as_text) +{ + int i; + /* Count how many relocations I have and allocate space for them. */ + reloc_count = 0; + walk_relocs(count_reloc); + relocs = malloc(reloc_count * sizeof(relocs[0])); + if (!relocs) { + die("malloc of %d entries for relocs failed\n", + reloc_count); + } + /* Collect up the relocations */ + reloc_idx = 0; + walk_relocs(collect_reloc); + + /* Order the relocations for more efficient processing */ + qsort(relocs, reloc_count, sizeof(relocs[0]), cmp_relocs); + + /* Print the relocations */ + if (as_text) { + /* Print the relocations in a form suitable that + * gas will like. + */ + printf(".section \".data.reloc\",\"a\"\n"); + printf(".balign 4\n"); + for(i = 0; i < reloc_count; i++) { + printf("\t .long 0x%08lx\n", relocs[i]); + } + printf("\n"); + } + else { + unsigned char buf[4]; + buf[0] = buf[1] = buf[2] = buf[3] = 0; + /* Print a stop */ + printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + /* Now print each relocation */ + for(i = 0; i < reloc_count; i++) { + buf[0] = (relocs[i] >> 0) & 0xff; + buf[1] = (relocs[i] >> 8) & 0xff; + buf[2] = (relocs[i] >> 16) & 0xff; + buf[3] = (relocs[i] >> 24) & 0xff; + printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); + } + } +} + +static void usage(void) +{ + die("i386_reloc [--abs | --text] vmlinux\n"); +} + +int main(int argc, char **argv) +{ + int show_absolute; + int as_text; + const char *fname; + FILE *fp; + int i; + + show_absolute = 0; + as_text = 0; + fname = NULL; + for(i = 1; i < argc; i++) { + char *arg = argv[i]; + if (*arg == '-') { + if (strcmp(argv[1], "--abs") == 0) { + show_absolute = 1; + continue; + } + else if (strcmp(argv[1], "--text") == 0) { + as_text = 1; + continue; + } + } + else if (!fname) { + fname = arg; + continue; + } + usage(); + } + if (!fname) { + usage(); + } + fp = fopen(fname, "r"); + if (!fp) { + die("Cannot open %s: %s\n", + fname, strerror(errno)); + } + read_ehdr(fp); + read_shdrs(fp); + read_strtabs(fp); + read_symtabs(fp); + read_relocs(fp); + if (show_absolute) { + print_absolute_symbols(); + print_absolute_relocs(); + return 0; + } + emit_relocs(as_text); + return 0; +} diff --git a/arch/i386/boot/compressed/vmlinux.lds b/arch/i386/boot/compressed/vmlinux.lds new file mode 100644 index 00000000000..cc4854f6c6c --- /dev/null +++ b/arch/i386/boot/compressed/vmlinux.lds @@ -0,0 +1,43 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(startup_32) +SECTIONS +{ + /* Be careful parts of head.S assume startup_32 is at + * address 0. + */ + . = 0 ; + .text.head : { + _head = . ; + *(.text.head) + _ehead = . ; + } + .data.compressed : { + *(.data.compressed) + } + .text : { + _text = .; /* Text */ + *(.text) + *(.text.*) + _etext = . ; + } + .rodata : { + _rodata = . ; + *(.rodata) /* read-only data */ + *(.rodata.*) + _erodata = . ; + } + .data : { + _data = . ; + *(.data) + *(.data.*) + _edata = . ; + } + .bss : { + _bss = . ; + *(.bss) + *(.bss.*) + *(COMMON) + _end = . ; + } +} diff --git a/arch/i386/boot/compressed/vmlinux.scr b/arch/i386/boot/compressed/vmlinux.scr index 1ed9d791f86..707a88f7f29 100644 --- a/arch/i386/boot/compressed/vmlinux.scr +++ b/arch/i386/boot/compressed/vmlinux.scr @@ -1,9 +1,10 @@ SECTIONS { - .data : { + .data.compressed : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) + output_len = . - 4; input_data_end = .; } } diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 3aec4538a11..9aa8b051818 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -588,11 +588,6 @@ rmodeswtch_normal: call default_switch rmodeswtch_end: -# we get the code32 start address and modify the below 'jmpi' -# (loader may have changed it) - movl %cs:code32_start, %eax - movl %eax, %cs:code32 - # Now we move the system to its rightful place ... but we check if we have a # big-kernel. In that case we *must* not move it ... testb $LOADED_HIGH, %cs:loadflags @@ -788,11 +783,12 @@ a20_err_msg: a20_done: #endif /* CONFIG_X86_VOYAGER */ -# set up gdt and idt +# set up gdt and idt and 32bit start address lidt idt_48 # load idt with 0,0 xorl %eax, %eax # Compute gdt_base movw %ds, %ax # (Convert %ds:gdt to a linear ptr) shll $4, %eax + addl %eax, code32 addl $gdt, %eax movl %eax, (gdt_48+2) lgdt gdt_48 # load gdt with whatever is @@ -851,9 +847,26 @@ flush_instr: # Manual, Mixing 16-bit and 32-bit code, page 16-6) .byte 0x66, 0xea # prefix + jmpi-opcode -code32: .long 0x1000 # will be set to 0x100000 - # for big kernels +code32: .long startup_32 # will be set to %cs+startup_32 .word __BOOT_CS +.code32 +startup_32: + movl $(__BOOT_DS), %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + movl %eax, %ss + + xorl %eax, %eax +1: incl %eax # check that A20 really IS enabled + movl %eax, 0x00000000 # loop forever if it isn't + cmpl %eax, 0x00100000 + je 1b + + # Jump to the 32bit entry point + jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi) +.code16 # Here's a bunch of information about your current kernel.. kernel_version: .ascii UTS_RELEASE -- cgit v1.2.3 From 6a044b3a0a1829ef19bb29548ffe553f48e8d80c Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: Warn upon absolute relocations being present o Relocations generated w.r.t absolute symbols are not processed as by definition, absolute symbols are not to be relocated. Explicitly warn user about absolutions relocations present at compile time. o These relocations get introduced either due to linker optimizations or some programming oversights. o Also create a list of symbols which have been audited to be safe and don't emit warnings for these. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/boot/compressed/Makefile | 2 +- arch/i386/boot/compressed/relocs.c | 82 +++++++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile index cc28da3a881..a661217f33e 100644 --- a/arch/i386/boot/compressed/Makefile +++ b/arch/i386/boot/compressed/Makefile @@ -20,7 +20,7 @@ $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) quiet_cmd_relocs = RELOCS $@ - cmd_relocs = $(obj)/relocs $< > $@ + cmd_relocs = $(obj)/relocs $< > $@;$(obj)/relocs --abs-relocs $< $(obj)/vmlinux.relocs: vmlinux $(obj)/relocs FORCE $(call if_changed,relocs) diff --git a/arch/i386/boot/compressed/relocs.c b/arch/i386/boot/compressed/relocs.c index 0551ceb21be..468da89153c 100644 --- a/arch/i386/boot/compressed/relocs.c +++ b/arch/i386/boot/compressed/relocs.c @@ -19,6 +19,33 @@ static char *strtab[MAX_SHDRS]; static unsigned long reloc_count, reloc_idx; static unsigned long *relocs; +/* + * Following symbols have been audited. There values are constant and do + * not change if bzImage is loaded at a different physical address than + * the address for which it has been compiled. Don't warn user about + * absolute relocations present w.r.t these symbols. + */ +static const char* safe_abs_relocs[] = { + "__kernel_vsyscall", + "__kernel_rt_sigreturn", + "__kernel_sigreturn", + "SYSENTER_RETURN", +}; + +static int is_safe_abs_reloc(const char* sym_name) +{ + int i, array_size; + + array_size = sizeof(safe_abs_relocs)/sizeof(char*); + + for(i = 0; i < array_size; i++) { + if (!strcmp(sym_name, safe_abs_relocs[i])) + /* Match found */ + return 1; + } + return 0; +} + static void die(char *fmt, ...) { va_list ap; @@ -359,9 +386,8 @@ static void print_absolute_symbols(void) static void print_absolute_relocs(void) { - int i; - printf("Absolute relocations\n"); - printf("Offset Info Type Sym.Value Sym.Name\n"); + int i, printed = 0; + for(i = 0; i < ehdr.e_shnum; i++) { char *sym_strtab; Elf32_Sym *sh_symtab; @@ -387,6 +413,31 @@ static void print_absolute_relocs(void) if (sym->st_shndx != SHN_ABS) { continue; } + + /* Absolute symbols are not relocated if bzImage is + * loaded at a non-compiled address. Display a warning + * to user at compile time about the absolute + * relocations present. + * + * User need to audit the code to make sure + * some symbols which should have been section + * relative have not become absolute because of some + * linker optimization or wrong programming usage. + * + * Before warning check if this absolute symbol + * relocation is harmless. + */ + if (is_safe_abs_reloc(name)) + continue; + + if (!printed) { + printf("WARNING: Absolute relocations" + " present\n"); + printf("Offset Info Type Sym.Value " + "Sym.Name\n"); + printed = 1; + } + printf("%08x %08x %10s %08x %s\n", rel->r_offset, rel->r_info, @@ -395,7 +446,9 @@ static void print_absolute_relocs(void) name); } } - printf("\n"); + + if (printed) + printf("\n"); } static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) @@ -508,25 +561,31 @@ static void emit_relocs(int as_text) static void usage(void) { - die("i386_reloc [--abs | --text] vmlinux\n"); + die("relocs [--abs-syms |--abs-relocs | --text] vmlinux\n"); } int main(int argc, char **argv) { - int show_absolute; + int show_absolute_syms, show_absolute_relocs; int as_text; const char *fname; FILE *fp; int i; - show_absolute = 0; + show_absolute_syms = 0; + show_absolute_relocs = 0; as_text = 0; fname = NULL; for(i = 1; i < argc; i++) { char *arg = argv[i]; if (*arg == '-') { - if (strcmp(argv[1], "--abs") == 0) { - show_absolute = 1; + if (strcmp(argv[1], "--abs-syms") == 0) { + show_absolute_syms = 1; + continue; + } + + if (strcmp(argv[1], "--abs-relocs") == 0) { + show_absolute_relocs = 1; continue; } else if (strcmp(argv[1], "--text") == 0) { @@ -553,8 +612,11 @@ int main(int argc, char **argv) read_strtabs(fp); read_symtabs(fp); read_relocs(fp); - if (show_absolute) { + if (show_absolute_syms) { print_absolute_symbols(); + return 0; + } + if (show_absolute_relocs) { print_absolute_relocs(); return 0; } -- cgit v1.2.3 From e69f202d0a1419219198566e1c22218a5c71a9a6 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: Implement CONFIG_PHYSICAL_ALIGN o Now CONFIG_PHYSICAL_START is being replaced with CONFIG_PHYSICAL_ALIGN. Hardcoding the kernel physical start value creates a problem in relocatable kernel context due to boot loader limitations. For ex, if somebody compiles a relocatable kernel to be run from address 4MB, but this kernel will run from location 1MB as grub loads the kernel at physical address 1MB. Kernel thinks that I am a relocatable kernel and I should run from the address I have been loaded at. So somebody wanting to run kernel from 4MB alignment location (for improved performance regions) can't do that. o Hence, Eric proposed that probably CONFIG_PHYSICAL_ALIGN will make more sense in relocatable kernel context. At run time kernel will move itself to a physical addr location which meets user specified alignment restrictions. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 33 ++++++++++++++++++--------------- arch/i386/boot/compressed/head.S | 26 ++++++++++++++------------ arch/i386/boot/compressed/misc.c | 7 ++++--- arch/i386/kernel/vmlinux.lds.S | 3 ++- 4 files changed, 38 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d588ca874bb..fd2fa7a7ec5 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -785,23 +785,26 @@ config RELOCATABLE must live at a different physical address than the primary kernel. -config PHYSICAL_START - hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) - - default "0x1000000" if CRASH_DUMP +config PHYSICAL_ALIGN + hex "Alignment value to which kernel should be aligned" default "0x100000" + range 0x2000 0x400000 help - This gives the physical address where the kernel is loaded. Normally - for regular kernels this value is 0x100000 (1MB). But in the case - of kexec on panic the fail safe kernel needs to run at a different - address than the panic-ed kernel. This option is used to set the load - address for kernels used to capture crash dump on being kexec'ed - after panic. The default value for crash dump kernels is - 0x1000000 (16MB). This can also be set based on the "X" value as - specified in the "crashkernel=YM@XM" command line boot parameter - passed to the panic-ed kernel. Typically this parameter is set as - crashkernel=64M@16M. Please take a look at - Documentation/kdump/kdump.txt for more details about crash dumps. + This value puts the alignment restrictions on physical address + where kernel is loaded and run from. Kernel is compiled for an + address which meets above alignment restriction. + + If bootloader loads the kernel at a non-aligned address and + CONFIG_RELOCATABLE is set, kernel will move itself to nearest + address aligned to above value and run from there. + + If bootloader loads the kernel at a non-aligned address and + CONFIG_RELOCATABLE is not set, kernel will ignore the run time + load address and decompress itself to the address it has been + compiled for and run from there. The address for which kernel is + compiled already meets above alignment restrictions. Hence the + end result is that kernel runs from a physical address meeting + above alignment restrictions. Don't change this unless you know what you are doing. diff --git a/arch/i386/boot/compressed/head.S b/arch/i386/boot/compressed/head.S index e4dd7a6b9b0..f395a4bb38b 100644 --- a/arch/i386/boot/compressed/head.S +++ b/arch/i386/boot/compressed/head.S @@ -26,6 +26,7 @@ #include #include #include +#include .section ".text.head" .globl startup_32 @@ -52,17 +53,17 @@ startup_32: 1: popl %ebp subl $1b, %ebp -/* Compute the delta between where we were compiled to run at - * and where the code will actually run at. +/* %ebp contains the address we are loaded at by the boot loader and %ebx + * contains the address where we should move the kernel image temporarily + * for safe in-place decompression. */ - /* Start with the delta to where the kernel will run at. If we are - * a relocatable kernel this is the delta to our load address otherwise - * this is the delta to CONFIG_PHYSICAL start. - */ + #ifdef CONFIG_RELOCATABLE - movl %ebp, %ebx + movl %ebp, %ebx + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebx + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx #else - movl $(CONFIG_PHYSICAL_START - startup_32), %ebx + movl $LOAD_PHYSICAL_ADDR, %ebx #endif /* Replace the compressed data size with the uncompressed size */ @@ -94,9 +95,10 @@ startup_32: /* Compute the kernel start address. */ #ifdef CONFIG_RELOCATABLE - leal startup_32(%ebp), %ebp + addl $(CONFIG_PHYSICAL_ALIGN - 1), %ebp + andl $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp #else - movl $CONFIG_PHYSICAL_START, %ebp + movl $LOAD_PHYSICAL_ADDR, %ebp #endif /* @@ -150,8 +152,8 @@ relocated: * and where it was actually loaded. */ movl %ebp, %ebx - subl $CONFIG_PHYSICAL_START, %ebx - + subl $LOAD_PHYSICAL_ADDR, %ebx + jz 2f /* Nothing to be done if loaded at compiled addr. */ /* * Process relocations. */ diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index 4eac24e95a1..dc153893155 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -14,6 +14,7 @@ #include #include #include +#include /* WARNING!! * This code is compiled with -fPIC and it is relocated dynamically @@ -360,12 +361,12 @@ asmlinkage void decompress_kernel(void *rmode, unsigned long end, insize = input_len; inptr = 0; - if (((u32)output - CONFIG_PHYSICAL_START) & 0x3fffff) - error("Destination address not 4M aligned"); + if ((u32)output & (CONFIG_PHYSICAL_ALIGN -1)) + error("Destination address not CONFIG_PHYSICAL_ALIGN aligned"); if (end > ((-__PAGE_OFFSET-(512 <<20)-1) & 0x7fffffff)) error("Destination address too large"); #ifndef CONFIG_RELOCATABLE - if ((u32)output != CONFIG_PHYSICAL_START) + if ((u32)output != LOAD_PHYSICAL_ADDR) error("Wrong destination address"); #endif diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index f8d61ec4c8c..6860f20aa57 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -14,6 +14,7 @@ #include #include #include +#include OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) @@ -27,7 +28,7 @@ PHDRS { } SECTIONS { - . = LOAD_OFFSET + CONFIG_PHYSICAL_START; + . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR; phys_startup_32 = startup_32 - LOAD_OFFSET; /* read-only */ .text : AT(ADDR(.text) - LOAD_OFFSET) { -- cgit v1.2.3 From be274eeaf20b4c7155242645d5e2c48b023e609b Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: extend bzImage protocol for relocatable protected mode kernel Extend bzImage protocol to enable bootloaders to load a completely relocatable bzImage. Now protected mode component of kernel is also relocatable and a boot-loader can load the protected mode component at a differnt physical address than 1MB. (If kernel was built with CONFIG_RELOCATABLE) Kexec can make use of it to load this kernel at a different physical address to capture kernel crash dumps. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/boot/setup.S | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 9aa8b051818..06edf1c6624 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -81,7 +81,7 @@ start: # This is the setup header, and it must start at %cs:2 (old 0x9020:2) .ascii "HdrS" # header signature - .word 0x0204 # header version number (>= 0x0105) + .word 0x0205 # header version number (>= 0x0105) # or else old loadlin-1.5 will fail) realmode_swtch: .word 0, 0 # default_switch, SETUPSEG start_sys_seg: .word SYSSEG @@ -160,6 +160,17 @@ ramdisk_max: .long (-__PAGE_OFFSET-(512 << 20)-1) & 0x7fffffff # The highest safe address for # the contents of an initrd +kernel_alignment: .long CONFIG_PHYSICAL_ALIGN #physical addr alignment + #required for protected mode + #kernel +#ifdef CONFIG_RELOCATABLE +relocatable_kernel: .byte 1 +#else +relocatable_kernel: .byte 0 +#endif +pad2: .byte 0 +pad3: .word 0 + trampoline: call start_of_setup .align 16 # The offset at this point is 0x240 -- cgit v1.2.3 From 4c7aa6c3b25ef96bc1b723238041195e3d8bf047 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: Mark CONFIG_RELOCATABLE EXPERIMENTAL Signed-off-by: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index fd2fa7a7ec5..1f0f7b60995 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -774,7 +774,8 @@ config CRASH_DUMP For more details see Documentation/kdump/kdump.txt config RELOCATABLE - bool "Build a relocatable kernel" + bool "Build a relocatable kernel(EXPERIMENTAL)" + depends on EXPERIMENTAL help This build a kernel image that retains relocation information so it can be loaded someplace besides the default 1MB. -- cgit v1.2.3 From 74b47a7844501445d41d704fe7c626f4b1819508 Mon Sep 17 00:00:00 2001 From: Joe Korty Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] i386: Fix entry.S code with !CONFIG_VM86 The entry.S code at work_notifysig is surely wrong. It drops into unrelated code if the branch to work_notifysig_v86 is taken, and CONFIG_VM86=n. [PATCH] Make vm86 support optional tree 9b5daef5280800a0006343a17f63072658d91a1d pushed to git Jan 8, 2006, and first appears in 2.6.16 The 'fix' here is to also compile out the vm86 test & branch when CONFIG_VM86=n. Signed-off-by: Joe Korty Signed-off-by: Andi Kleen --- arch/i386/kernel/entry.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index d7423efaeea..0220bc8cbb4 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -457,6 +457,7 @@ work_resched: work_notifysig: # deal with pending signals and # notify-resume requests +#ifdef CONFIG_VM86 testl $VM_MASK, PT_EFLAGS(%esp) movl %esp, %eax jne work_notifysig_v86 # returning to kernel-space or @@ -467,17 +468,18 @@ work_notifysig: # deal with pending signals and ALIGN work_notifysig_v86: -#ifdef CONFIG_VM86 pushl %ecx # save ti_flags for do_notify_resume CFI_ADJUST_CFA_OFFSET 4 call save_v86_state # %eax contains pt_regs pointer popl %ecx CFI_ADJUST_CFA_OFFSET -4 movl %eax, %esp +#else + movl %esp, %eax +#endif xorl %edx, %edx call do_notify_resume jmp resume_userspace_sig -#endif # perform syscall exit tracing ALIGN -- cgit v1.2.3 From ea7322decb974a4a3e804f96a0201e893ff88ce3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:05 +0100 Subject: [PATCH] x86-64: Speed and clean up cache flushing in change_page_attr CLFLUSH is a lot faster than WBINVD so avoid the later if at all possible. Always pass the complete list of pages to other CPUs to cut down the number of IPIs. Minor other cleanup and sync with i386 version. Signed-off-by: Andi Kleen --- arch/x86_64/mm/pageattr.c | 58 ++++++++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 26 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index 3e231d762aa..ccb91dd996a 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c @@ -61,34 +61,40 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, return base; } - -static void flush_kernel_map(void *address) +static void cache_flush_page(void *adr) { - if (0 && address && cpu_has_clflush) { - /* is this worth it? */ - int i; - for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) - asm volatile("clflush (%0)" :: "r" (address + i)); - } else - asm volatile("wbinvd":::"memory"); - if (address) - __flush_tlb_one(address); - else - __flush_tlb_all(); + int i; + for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) + asm volatile("clflush (%0)" :: "r" (adr + i)); } +static void flush_kernel_map(void *arg) +{ + struct list_head *l = (struct list_head *)arg; + struct page *pg; + + /* When clflush is available always use it because it is + much cheaper than WBINVD */ + if (!cpu_has_clflush) + asm volatile("wbinvd" ::: "memory"); + list_for_each_entry(pg, l, lru) { + void *adr = page_address(pg); + if (cpu_has_clflush) + cache_flush_page(adr); + __flush_tlb_one(adr); + } +} -static inline void flush_map(unsigned long address) +static inline void flush_map(struct list_head *l) { - on_each_cpu(flush_kernel_map, (void *)address, 1, 1); + on_each_cpu(flush_kernel_map, l, 1, 1); } -static struct page *deferred_pages; /* protected by init_mm.mmap_sem */ +static LIST_HEAD(deferred_pages); /* protected by init_mm.mmap_sem */ static inline void save_page(struct page *fpage) { - fpage->lru.next = (struct list_head *)deferred_pages; - deferred_pages = fpage; + list_add(&fpage->lru, &deferred_pages); } /* @@ -207,18 +213,18 @@ int change_page_attr(struct page *page, int numpages, pgprot_t prot) void global_flush_tlb(void) { - struct page *dpage; + struct page *pg, *next; + struct list_head l; down_read(&init_mm.mmap_sem); - dpage = xchg(&deferred_pages, NULL); + list_replace_init(&deferred_pages, &l); up_read(&init_mm.mmap_sem); - flush_map((dpage && !dpage->lru.next) ? (unsigned long)page_address(dpage) : 0); - while (dpage) { - struct page *tmp = dpage; - dpage = (struct page *)dpage->lru.next; - ClearPagePrivate(tmp); - __free_page(tmp); + flush_map(&l); + + list_for_each_entry_safe(pg, next, &l, lru) { + ClearPagePrivate(pg); + __free_page(pg); } } -- cgit v1.2.3 From 770d132f03ac15b12919f1bac481f4beda13e094 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:05 +0100 Subject: [PATCH] i386: Retrieve CLFLUSH size from CPUID Also report it in /proc/cpuinfo similar to x86-64. Needed for followon patch Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/common.c | 3 +++ arch/i386/kernel/cpu/proc.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 6958ae5e2fa..cda41aef79a 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -309,6 +309,8 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 * c) #else c->apicid = (ebx >> 24) & 0xFF; #endif + if (c->x86_capability[0] & (1<<19)) + c->x86_clflush_size = ((ebx >> 8) & 0xff) * 8; } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -373,6 +375,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c) c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ c->x86_max_cores = 1; + c->x86_clflush_size = 32; memset(&c->x86_capability, 0, sizeof c->x86_capability); if (!have_cpuid_p()) { diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c index 76aac088a32..6624d8583c4 100644 --- a/arch/i386/kernel/cpu/proc.c +++ b/arch/i386/kernel/cpu/proc.c @@ -152,9 +152,10 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, " [%d]", i); } - seq_printf(m, "\nbogomips\t: %lu.%02lu\n\n", + seq_printf(m, "\nbogomips\t: %lu.%02lu\n", c->loops_per_jiffy/(500000/HZ), (c->loops_per_jiffy/(5000/HZ)) % 100); + seq_printf(m, "clflush size\t: %u\n\n", c->x86_clflush_size); return 0; } -- cgit v1.2.3 From 3760dd6efa75c98e223643da2eb7040406433053 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:05 +0100 Subject: [PATCH] i386: Use CLFLUSH instead of WBINVD in change_page_attr CLFLUSH is a lot faster than WBINVD so try to use that. Signed-off-by: Andi Kleen --- arch/i386/mm/pageattr.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 8564b6ae17e..ad91528bdc1 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -67,11 +67,17 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot, return base; } -static void flush_kernel_map(void *dummy) +static void flush_kernel_map(void *arg) { - /* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */ - if (boot_cpu_data.x86_model >= 4) + unsigned long adr = (unsigned long)arg; + + if (adr && cpu_has_clflush) { + int i; + for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size) + asm volatile("clflush (%0)" :: "r" (adr + i)); + } else if (boot_cpu_data.x86_model >= 4) wbinvd(); + /* Flush all to work around Errata in early athlons regarding * large page flushing. */ @@ -173,9 +179,9 @@ __change_page_attr(struct page *page, pgprot_t prot) return 0; } -static inline void flush_map(void) +static inline void flush_map(void *adr) { - on_each_cpu(flush_kernel_map, NULL, 1, 1); + on_each_cpu(flush_kernel_map, adr, 1, 1); } /* @@ -217,9 +223,13 @@ void global_flush_tlb(void) spin_lock_irq(&cpa_lock); list_replace_init(&df_list, &l); spin_unlock_irq(&cpa_lock); - flush_map(); - list_for_each_entry_safe(pg, next, &l, lru) + if (!cpu_has_clflush) + flush_map(0); + list_for_each_entry_safe(pg, next, &l, lru) { + if (cpu_has_clflush) + flush_map(page_address(pg)); __free_page(pg); + } } #ifdef CONFIG_DEBUG_PAGEALLOC -- cgit v1.2.3 From 5df0287ecc4f53e68bbd188fa8258b555e6b734f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:05 +0100 Subject: [PATCH] x86-64: Extend clear_irq_vector Clear the irq releated entries in irq_vector, irq_domain and vector_irq instead of clearing irq_vector only. So when new irq is created, it could reuse that vector. (actually is the second loop scanning from FIRST_DEVICE_VECTOR+8). This could avoid the vectors are used up with enough module inserting and removing Cc: Eric W. Biedierman Cc: Muli Ben-Yehuda Signed-off-By: Yinghai Lu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c80081a6ba4..f71461b1f03 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -750,6 +750,22 @@ static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) return vector; } +static void __clear_irq_vector(int irq) +{ + cpumask_t mask; + int cpu, vector; + + BUG_ON(!irq_vector[irq]); + + vector = irq_vector[irq]; + cpus_and(mask, irq_domain[irq], cpu_online_map); + for_each_cpu_mask(cpu, mask) + per_cpu(vector_irq, cpu)[vector] = -1; + + irq_vector[irq] = 0; + irq_domain[irq] = CPU_MASK_NONE; +} + void __setup_vector_irq(int cpu) { /* Initialize vector_irq on a new cpu */ @@ -1837,7 +1853,7 @@ void destroy_irq(unsigned int irq) dynamic_irq_cleanup(irq); spin_lock_irqsave(&vector_lock, flags); - irq_vector[irq] = 0; + __clear_irq_vector(irq); spin_unlock_irqrestore(&vector_lock, flags); } -- cgit v1.2.3 From ab2bf0c1c689905b628dca94d0acd9c50e152468 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] x86-64: Use probe_kernel_address in arch/x86_64/* Instead of open coded __get_user Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 2 +- arch/x86_64/mm/fault.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 70bfaab9822..264db33476a 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -30,9 +30,9 @@ #include #include #include +#include #include -#include #include #include #include diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 3751b4788e2..a65fc6f1dca 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -23,9 +23,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -96,7 +96,7 @@ void bust_spinlocks(int yes) static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned long error_code) { - unsigned char __user *instr; + unsigned char *instr; int scan_more = 1; int prefetch = 0; unsigned char *max_instr; @@ -116,7 +116,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned char instr_hi; unsigned char instr_lo; - if (__get_user(opcode, (char __user *)instr)) + if (probe_kernel_address(instr, opcode)) break; instr_hi = opcode & 0xf0; @@ -154,7 +154,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (__get_user(opcode, (char __user *)instr)) + if (probe_kernel_address(instr, opcode)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); @@ -170,7 +170,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, static int bad_address(void *p) { unsigned long dummy; - return __get_user(dummy, (unsigned long __user *)p); + return probe_kernel_address((unsigned long *)p, dummy); } void dump_pagetable(unsigned long address) -- cgit v1.2.3 From 11a4180c0b03e2ee0c948fd8430ee092dc1625b3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: Use probe_kernel_address instead of __get_user in fault paths Makes the intention of the code cleaner to read and avoids a potential deadlock on mmap_sem. Also change the types of the arguments to not include __user because they're really not user addresses. Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 24 +++++++++++++----------- arch/i386/mm/fault.c | 12 ++++++------ 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 237f4884a1e..7b2f9f02208 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -380,7 +380,7 @@ void show_registers(struct pt_regs *regs) * time of the fault.. */ if (in_kernel) { - u8 __user *eip; + u8 *eip; int code_bytes = 64; unsigned char c; @@ -389,18 +389,20 @@ void show_registers(struct pt_regs *regs) printk(KERN_EMERG "Code: "); - eip = (u8 __user *)regs->eip - 43; - if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { + eip = (u8 *)regs->eip - 43; + if (eip < (u8 *)PAGE_OFFSET || + probe_kernel_address(eip, c)) { /* try starting at EIP */ - eip = (u8 __user *)regs->eip; + eip = (u8 *)regs->eip; code_bytes = 32; } for (i = 0; i < code_bytes; i++, eip++) { - if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) { + if (eip < (u8 *)PAGE_OFFSET || + probe_kernel_address(eip, c)) { printk(" Bad EIP value."); break; } - if (eip == (u8 __user *)regs->eip) + if (eip == (u8 *)regs->eip) printk("<%02x> ", c); else printk("%02x ", c); @@ -416,7 +418,7 @@ static void handle_BUG(struct pt_regs *regs) if (eip < PAGE_OFFSET) return; - if (probe_kernel_address((unsigned short __user *)eip, ud2)) + if (probe_kernel_address((unsigned short *)eip, ud2)) return; if (ud2 != 0x0b0f) return; @@ -429,11 +431,11 @@ static void handle_BUG(struct pt_regs *regs) char *file; char c; - if (probe_kernel_address((unsigned short __user *)(eip + 2), - line)) + if (probe_kernel_address((unsigned short *)(eip + 2), line)) break; - if (__get_user(file, (char * __user *)(eip + 4)) || - (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) + if (probe_kernel_address((char **)(eip + 4), file) || + (unsigned long)file < PAGE_OFFSET || + probe_kernel_address(file, c)) file = ""; printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 2581575786c..aaaa4d225f7 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -22,9 +22,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -167,7 +167,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, static int __is_prefetch(struct pt_regs *regs, unsigned long addr) { unsigned long limit; - unsigned long instr = get_segment_eip (regs, &limit); + unsigned char *instr = (unsigned char *)get_segment_eip (regs, &limit); int scan_more = 1; int prefetch = 0; int i; @@ -177,9 +177,9 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) unsigned char instr_hi; unsigned char instr_lo; - if (instr > limit) + if (instr > (unsigned char *)limit) break; - if (__get_user(opcode, (unsigned char __user *) instr)) + if (probe_kernel_address(instr, opcode)) break; instr_hi = opcode & 0xf0; @@ -204,9 +204,9 @@ static int __is_prefetch(struct pt_regs *regs, unsigned long addr) case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (instr > limit) + if (instr > (unsigned char *)limit) break; - if (__get_user(opcode, (unsigned char __user *) instr)) + if (probe_kernel_address(instr, opcode)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); -- cgit v1.2.3 From b026872601976f666bae77b609dc490d1834bf77 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] x86-64: Try multiple timer variants in check_timer Instead of adding all kinds of more quirks try various timer routing variants in check_timer. In particular this tries to handle quirks from: - Nvidia NF2-4 reference BIOS: wrong timer override - Asus: Wrong timer override but no HPET table - ATI: require timer disabled in 8259 - Some boards: require timer enabled in 8259 We just try many of the the known variants in the hopefully right order in check_timer. Trying pin 0/2 on Nvidia suggested by Tim Hockin. TBD Experimental. Needs a lot of testing Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early-quirks.c | 5 -- arch/x86_64/kernel/io_apic.c | 124 ++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 78 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 68273bff58c..fb0c6da41b7 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -69,11 +69,6 @@ static void nvidia_bugs(void) static void ati_bugs(void) { - if (timer_over_8254 == 1) { - timer_over_8254 = 0; - printk(KERN_INFO - "ATI board detected. Disabling timer routing over 8254.\n"); - } } struct chipset { diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index f71461b1f03..88fcc4ebbf6 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -55,10 +55,6 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ static int no_timer_check; -static int disable_timer_pin_1 __initdata; - -int timer_over_8254 __initdata = 1; - /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; @@ -348,29 +344,6 @@ static int __init disable_ioapic_setup(char *str) } early_param("noapic", disable_ioapic_setup); -/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ -static int __init disable_timer_pin_setup(char *arg) -{ - disable_timer_pin_1 = 1; - return 1; -} -__setup("disable_timer_pin_1", disable_timer_pin_setup); - -static int __init setup_disable_8254_timer(char *s) -{ - timer_over_8254 = -1; - return 1; -} -static int __init setup_enable_8254_timer(char *s) -{ - timer_over_8254 = 2; - return 1; -} - -__setup("disable_8254_timer", setup_disable_8254_timer); -__setup("enable_8254_timer", setup_enable_8254_timer); - - /* * Find the IRQ entry number of a certain pin. */ @@ -1579,10 +1552,33 @@ static inline void unlock_ExtINT_logic(void) * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ * is so screwy. Thanks to Brian Perkins for testing/hacking this beast * fanatically on his truly buggy board. - * - * FIXME: really need to revamp this for modern platforms only. */ -static inline void check_timer(void) + +static int try_apic_pin(int apic, int pin, char *msg) +{ + apic_printk(APIC_VERBOSE, KERN_INFO + "..TIMER: trying IO-APIC=%d PIN=%d %s", + apic, pin, msg); + + /* + * Ok, does IRQ0 through the IOAPIC work? + */ + if (!no_timer_check && timer_irq_works()) { + nmi_watchdog_default(); + if (nmi_watchdog == NMI_IO_APIC) { + disable_8259A_irq(0); + setup_nmi(); + enable_8259A_irq(0); + } + return 1; + } + clear_IO_APIC_pin(apic, pin); + apic_printk(APIC_QUIET, KERN_ERR " .. failed\n"); + return 0; +} + +/* The function from hell */ +static void check_timer(void) { int apic1, pin1, apic2, pin2; int vector; @@ -1603,61 +1599,43 @@ static inline void check_timer(void) */ apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); - if (timer_over_8254 > 0) - enable_8259A_irq(0); pin1 = find_isa_irq_pin(0, mp_INT); apic1 = find_isa_irq_apic(0, mp_INT); pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; - apic_printk(APIC_VERBOSE,KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", - vector, apic1, pin1, apic2, pin2); + /* Do this first, otherwise we get double interrupts on ATI boards */ + if ((pin1 != -1) && try_apic_pin(apic1, pin1,"with 8259 IRQ0 disabled")) + return; - if (pin1 != -1) { - /* - * Ok, does IRQ0 through the IOAPIC work? - */ - unmask_IO_APIC_irq(0); - if (!no_timer_check && timer_irq_works()) { - nmi_watchdog_default(); - if (nmi_watchdog == NMI_IO_APIC) { - disable_8259A_irq(0); - setup_nmi(); - enable_8259A_irq(0); - } - if (disable_timer_pin_1 > 0) - clear_IO_APIC_pin(0, pin1); - return; - } - clear_IO_APIC_pin(apic1, pin1); - apic_printk(APIC_QUIET,KERN_ERR "..MP-BIOS bug: 8254 timer not " - "connected to IO-APIC\n"); - } + /* Now try again with IRQ0 8259A enabled. + Assumes timer is on IO-APIC 0 ?!? */ + enable_8259A_irq(0); + unmask_IO_APIC_irq(0); + if (try_apic_pin(apic1, pin1, "with 8259 IRQ0 enabled")) + return; + disable_8259A_irq(0); - apic_printk(APIC_VERBOSE,KERN_INFO "...trying to set up timer (IRQ0) " - "through the 8259A ... "); + /* Always try pin0 and pin2 on APIC 0 to handle buggy timer overrides + on Nvidia boards */ + if (!(apic1 == 0 && pin1 == 0) && + try_apic_pin(0, 0, "fallback with 8259 IRQ0 disabled")) + return; + if (!(apic1 == 0 && pin1 == 2) && + try_apic_pin(0, 2, "fallback with 8259 IRQ0 disabled")) + return; + + /* Then try pure 8259A routing on the 8259 as reported by BIOS*/ + enable_8259A_irq(0); if (pin2 != -1) { - apic_printk(APIC_VERBOSE,"\n..... (found apic %d pin %d) ...", - apic2, pin2); - /* - * legacy devices should be connected to IO APIC #0 - */ setup_ExtINT_IRQ0_pin(apic2, pin2, vector); - if (timer_irq_works()) { - apic_printk(APIC_VERBOSE," works.\n"); - nmi_watchdog_default(); - if (nmi_watchdog == NMI_IO_APIC) { - setup_nmi(); - } + if (try_apic_pin(apic2,pin2,"8259A broadcast ExtINT from BIOS")) return; - } - /* - * Cleanup, just in case ... - */ - clear_IO_APIC_pin(apic2, pin2); } - apic_printk(APIC_VERBOSE," failed.\n"); + + /* Tried all possibilities to go through the IO-APIC. Now come the + really cheesy fallbacks. */ if (nmi_watchdog == NMI_IO_APIC) { printk(KERN_WARNING "timer doesn't work through the IO-APIC - disabling NMI Watchdog!\n"); -- cgit v1.2.3 From 8e3de538eec95b57a5b86038988451c38ba83f7e Mon Sep 17 00:00:00 2001 From: Albert Cahalan Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] x86-64: Support -mregparm arguments for signals with SA_SIGINFO in compat mode The recent change to make x86_64 support i386 binaries compiled with -mregparm=3 only covered signal handlers without SA_SIGINFO. (the 3-arg "real-time" ones) To be compatible with i386, both types should be supported. Signed-off-by: Albert Cahalan Signed-off-by: Andi Kleen --- arch/x86_64/ia32/ia32_signal.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c index 0e0a266d976..ff499ef2a1b 100644 --- a/arch/x86_64/ia32/ia32_signal.c +++ b/arch/x86_64/ia32/ia32_signal.c @@ -584,6 +584,11 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->rdx = (unsigned long) &frame->info; regs->rcx = (unsigned long) &frame->uc; + /* Make -mregparm=3 work */ + regs->rax = sig; + regs->rdx = (unsigned long) &frame->info; + regs->rcx = (unsigned long) &frame->uc; + asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); -- cgit v1.2.3 From 269c2d81ed66af7c09a1619ffe165f03e7470a5b Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: i386 create e820.c to handle standard io/mem resources This patch creates new file named e820.c to hanle standard io/mem resources, moving request_standard_resources function from setup.c to e820.c. Also this patch modifies Makfile to compile file e820.c. Signed-off-by: bibo,mao Signed-off-by: Andi Kleen Makefile | 2 arch/i386/kernel/Makefile | 2 arch/i386/kernel/e820.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 276 ------------------------------------------- 3 files changed, 293 insertions(+), 274 deletions(-) --- arch/i386/kernel/Makefile | 2 +- arch/i386/kernel/e820.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 276 +------------------------------------------ 3 files changed, 293 insertions(+), 274 deletions(-) create mode 100644 arch/i386/kernel/e820.c (limited to 'arch') diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 1a884b6e6e5..f614854bd71 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o bootflag.o \ + pci-dma.o i386_ksyms.o i387.o bootflag.o e820.o\ quirks.o i8237.o topology.o alternative.o i8253.o tsc.o obj-$(CONFIG_STACKTRACE) += stacktrace.o diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c new file mode 100644 index 00000000000..cce70604948 --- /dev/null +++ b/arch/i386/kernel/e820.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_EFI +int efi_enabled = 0; +EXPORT_SYMBOL(efi_enabled); +#endif + +struct e820map e820; +struct resource data_resource = { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +struct resource code_resource = { + .name = "Kernel code", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource system_rom_resource = { + .name = "System ROM", + .start = 0xf0000, + .end = 0xfffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource extension_rom_resource = { + .name = "Extension ROM", + .start = 0xe0000, + .end = 0xeffff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource adapter_rom_resources[] = { { + .name = "Adapter ROM", + .start = 0xc8000, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}, { + .name = "Adapter ROM", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +} }; + +static struct resource video_rom_resource = { + .name = "Video ROM", + .start = 0xc0000, + .end = 0xc7fff, + .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM +}; + +static struct resource video_ram_resource = { + .name = "Video RAM area", + .start = 0xa0000, + .end = 0xbffff, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +static struct resource standard_io_resources[] = { { + .name = "dma1", + .start = 0x0000, + .end = 0x001f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic1", + .start = 0x0020, + .end = 0x0021, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer0", + .start = 0x0040, + .end = 0x0043, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "timer1", + .start = 0x0050, + .end = 0x0053, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "keyboard", + .start = 0x0060, + .end = 0x006f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma page reg", + .start = 0x0080, + .end = 0x008f, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "pic2", + .start = 0x00a0, + .end = 0x00a1, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "dma2", + .start = 0x00c0, + .end = 0x00df, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +}, { + .name = "fpu", + .start = 0x00f0, + .end = 0x00ff, + .flags = IORESOURCE_BUSY | IORESOURCE_IO +} }; + +#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) + +static int __init romchecksum(unsigned char *rom, unsigned long length) +{ + unsigned char *p, sum = 0; + + for (p = rom; p < rom + length; p++) + sum += *p; + return sum == 0; +} + +static void __init probe_roms(void) +{ + unsigned long start, length, upper; + unsigned char *rom; + int i; + + /* video rom */ + upper = adapter_rom_resources[0].start; + for (start = video_rom_resource.start; start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + video_rom_resource.start = start; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* if checksum okay, trust length byte */ + if (length && romchecksum(rom, length)) + video_rom_resource.end = start + length - 1; + + request_resource(&iomem_resource, &video_rom_resource); + break; + } + + start = (video_rom_resource.end + 1 + 2047) & ~2047UL; + if (start < upper) + start = upper; + + /* system rom */ + request_resource(&iomem_resource, &system_rom_resource); + upper = system_rom_resource.start; + + /* check for extension rom (ignore length byte!) */ + rom = isa_bus_to_virt(extension_rom_resource.start); + if (romsignature(rom)) { + length = extension_rom_resource.end - extension_rom_resource.start + 1; + if (romchecksum(rom, length)) { + request_resource(&iomem_resource, &extension_rom_resource); + upper = extension_rom_resource.start; + } + } + + /* check for adapter roms on 2k boundaries */ + for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { + rom = isa_bus_to_virt(start); + if (!romsignature(rom)) + continue; + + /* 0 < length <= 0x7f * 512, historically */ + length = rom[2] * 512; + + /* but accept any length that fits if checksum okay */ + if (!length || start + length > upper || !romchecksum(rom, length)) + continue; + + adapter_rom_resources[i].start = start; + adapter_rom_resources[i].end = start + length - 1; + request_resource(&iomem_resource, &adapter_rom_resources[i]); + + start = adapter_rom_resources[i++].end & ~2047UL; + } +} + +/* + * Request address space for all standard RAM and ROM resources + * and also for regions reported as reserved by the e820. + */ +static void __init +legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) +{ + int i; + + probe_roms(); + for (i = 0; i < e820.nr_map; i++) { + struct resource *res; +#ifndef CONFIG_RESOURCES_64BIT + if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) + continue; +#endif + res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + switch (e820.map[i].type) { + case E820_RAM: res->name = "System RAM"; break; + case E820_ACPI: res->name = "ACPI Tables"; break; + case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; + default: res->name = "reserved"; + } + res->start = e820.map[i].addr; + res->end = res->start + e820.map[i].size - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + if (request_resource(&iomem_resource, res)) { + kfree(res); + continue; + } + if (e820.map[i].type == E820_RAM) { + /* + * We don't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, code_resource); + request_resource(res, data_resource); +#ifdef CONFIG_KEXEC + request_resource(res, &crashk_res); +#endif + } + } +} + +/* + * Request address space for all standard resources + * + * This is called just before pcibios_init(), which is also a + * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). + */ +static int __init request_standard_resources(void) +{ + int i; + + printk("Setting up standard PCI resources\n"); + if (efi_enabled) + efi_initialize_iomem_resources(&code_resource, &data_resource); + else + legacy_init_iomem_resources(&code_resource, &data_resource); + + /* EFI systems may still have VGA */ + request_resource(&iomem_resource, &video_ram_resource); + + /* request I/O space for devices used on all i[345]86 PCs */ + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + request_resource(&ioport_resource, &standard_io_resources[i]); + return 0; +} + +subsys_initcall(request_standard_resources); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 61539afbdf2..acd2d9392ab 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -76,11 +76,9 @@ int disable_pse __devinitdata = 0; /* * Machine setup.. */ - -#ifdef CONFIG_EFI -int efi_enabled = 0; -EXPORT_SYMBOL(efi_enabled); -#endif +extern struct e820map e820; +extern struct resource code_resource; +extern struct resource data_resource; /* cpu data as detected by the assembly code in head.S */ struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; @@ -134,7 +132,6 @@ struct ist_info ist_info; defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) EXPORT_SYMBOL(ist_info); #endif -struct e820map e820; extern void early_cpu_init(void); extern int root_mountflags; @@ -149,203 +146,6 @@ static char command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; -static struct resource data_resource = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource code_resource = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource video_ram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer0", - .start = 0x0040, - .end = 0x0043, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer1", - .start = 0x0050, - .end = 0x0053, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x006f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) - -static int __init romchecksum(unsigned char *rom, unsigned long length) -{ - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; -} - -static void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && romchecksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (romchecksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !romchecksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - static void __init limit_regions(unsigned long long size) { unsigned long long current_addr = 0; @@ -1200,77 +1000,7 @@ void __init remapped_pgdat_init(void) } } -/* - * Request address space for all standard RAM and ROM resources - * and also for regions reported as reserved by the e820. - */ -static void __init -legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) -{ - int i; - - probe_roms(); - for (i = 0; i < e820.nr_map; i++) { - struct resource *res; -#ifndef CONFIG_RESOURCES_64BIT - if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) - continue; -#endif - res = kzalloc(sizeof(struct resource), GFP_ATOMIC); - switch (e820.map[i].type) { - case E820_RAM: res->name = "System RAM"; break; - case E820_ACPI: res->name = "ACPI Tables"; break; - case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; - default: res->name = "reserved"; - } - res->start = e820.map[i].addr; - res->end = res->start + e820.map[i].size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - if (request_resource(&iomem_resource, res)) { - kfree(res); - continue; - } - if (e820.map[i].type == E820_RAM) { - /* - * We don't know which RAM region contains kernel data, - * so we try it repeatedly and let the resource manager - * test it. - */ - request_resource(res, code_resource); - request_resource(res, data_resource); -#ifdef CONFIG_KEXEC - request_resource(res, &crashk_res); -#endif - } - } -} - -/* - * Request address space for all standard resources - * - * This is called just before pcibios_init(), which is also a - * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). - */ -static int __init request_standard_resources(void) -{ - int i; - - printk("Setting up standard PCI resources\n"); - if (efi_enabled) - efi_initialize_iomem_resources(&code_resource, &data_resource); - else - legacy_init_iomem_resources(&code_resource, &data_resource); - - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_resource); - - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) - request_resource(&ioport_resource, &standard_io_resources[i]); - return 0; -} -subsys_initcall(request_standard_resources); static void __init register_memory(void) { -- cgit v1.2.3 From 8e3342f736dd1c19ce7c28625dedd7d8730fc7ad Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: create e820.c for e820 map sanitize and copy function This patch moves bios e820 map sanitize and copy function from setup.c to e820.c Signed-off-by: bibo,mao Signed-off-by: Andi Kleen arch/i386/kernel/e820.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 240 -------------------------------------------- 2 files changed, 252 insertions(+), 240 deletions(-) --- arch/i386/kernel/e820.c | 252 +++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 240 -------------------------------------------- 2 files changed, 252 insertions(+), 240 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index cce70604948..0db95760b07 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -19,6 +19,14 @@ EXPORT_SYMBOL(efi_enabled); #endif struct e820map e820; +struct change_member { + struct e820entry *pbios; /* pointer to original bios entry */ + unsigned long long addr; /* address for this change point */ +}; +static struct change_member change_point_list[2*E820MAX] __initdata; +static struct change_member *change_point[2*E820MAX] __initdata; +static struct e820entry *overlap_list[E820MAX] __initdata; +static struct e820entry new_bios[E820MAX] __initdata; struct resource data_resource = { .name = "Kernel data", .start = 0, @@ -287,3 +295,247 @@ static int __init request_standard_resources(void) } subsys_initcall(request_standard_resources); + +void __init add_memory_region(unsigned long long start, + unsigned long long size, int type) +{ + int x; + + if (!efi_enabled) { + x = e820.nr_map; + + if (x == E820MAX) { + printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); + return; + } + + e820.map[x].addr = start; + e820.map[x].size = size; + e820.map[x].type = type; + e820.nr_map++; + } +} /* add_memory_region */ + +/* + * Sanitize the BIOS e820 map. + * + * Some e820 responses include overlapping entries. The following + * replaces the original e820 map with a new one, removing overlaps. + * + */ +int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) +{ + struct change_member *change_tmp; + unsigned long current_type, last_type; + unsigned long long last_addr; + int chgidx, still_changing; + int overlap_entries; + int new_bios_entry; + int old_nr, new_nr, chg_nr; + int i; + + /* + Visually we're performing the following (1,2,3,4 = memory types)... + + Sample memory map (w/overlaps): + ____22__________________ + ______________________4_ + ____1111________________ + _44_____________________ + 11111111________________ + ____________________33__ + ___________44___________ + __________33333_________ + ______________22________ + ___________________2222_ + _________111111111______ + _____________________11_ + _________________4______ + + Sanitized equivalent (no overlap): + 1_______________________ + _44_____________________ + ___1____________________ + ____22__________________ + ______11________________ + _________1______________ + __________3_____________ + ___________44___________ + _____________33_________ + _______________2________ + ________________1_______ + _________________4______ + ___________________2____ + ____________________33__ + ______________________4_ + */ + printk("sanitize start\n"); + /* if there's only one memory region, don't bother */ + if (*pnr_map < 2) { + printk("sanitize bail 0\n"); + return -1; + } + + old_nr = *pnr_map; + + /* bail out if we find any unreasonable addresses in bios map */ + for (i=0; iaddr = biosmap[i].addr; + change_point[chgidx++]->pbios = &biosmap[i]; + change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; + change_point[chgidx++]->pbios = &biosmap[i]; + } + } + chg_nr = chgidx; /* true number of change-points */ + + /* sort change-point list by memory addresses (low -> high) */ + still_changing = 1; + while (still_changing) { + still_changing = 0; + for (i=1; i < chg_nr; i++) { + /* if > , swap */ + /* or, if current= & last=, swap */ + if ((change_point[i]->addr < change_point[i-1]->addr) || + ((change_point[i]->addr == change_point[i-1]->addr) && + (change_point[i]->addr == change_point[i]->pbios->addr) && + (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) + ) + { + change_tmp = change_point[i]; + change_point[i] = change_point[i-1]; + change_point[i-1] = change_tmp; + still_changing=1; + } + } + } + + /* create a new bios memory map, removing overlaps */ + overlap_entries=0; /* number of entries in the overlap table */ + new_bios_entry=0; /* index for creating new bios map entries */ + last_type = 0; /* start with undefined memory type */ + last_addr = 0; /* start with 0 as last starting address */ + /* loop through change-points, determining affect on the new bios map */ + for (chgidx=0; chgidx < chg_nr; chgidx++) + { + /* keep track of all overlapping bios entries */ + if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) + { + /* add map entry to overlap list (> 1 entry implies an overlap) */ + overlap_list[overlap_entries++]=change_point[chgidx]->pbios; + } + else + { + /* remove entry from list (order independent, so swap with last) */ + for (i=0; ipbios) + overlap_list[i] = overlap_list[overlap_entries-1]; + } + overlap_entries--; + } + /* if there are overlapping entries, decide which "type" to use */ + /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ + current_type = 0; + for (i=0; itype > current_type) + current_type = overlap_list[i]->type; + /* continue building up new bios map based on this information */ + if (current_type != last_type) { + if (last_type != 0) { + new_bios[new_bios_entry].size = + change_point[chgidx]->addr - last_addr; + /* move forward only if the new size was non-zero */ + if (new_bios[new_bios_entry].size != 0) + if (++new_bios_entry >= E820MAX) + break; /* no more space left for new bios entries */ + } + if (current_type != 0) { + new_bios[new_bios_entry].addr = change_point[chgidx]->addr; + new_bios[new_bios_entry].type = current_type; + last_addr=change_point[chgidx]->addr; + } + last_type = current_type; + } + } + new_nr = new_bios_entry; /* retain count for new bios entries */ + + /* copy new bios mapping into original location */ + memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); + *pnr_map = new_nr; + + printk("sanitize end\n"); + return 0; +} + +/* + * Copy the BIOS e820 map into a safe place. + * + * Sanity-check it while we're at it.. + * + * If we're lucky and live on a modern system, the setup code + * will have given us a memory map that we can use to properly + * set up memory. If we aren't, we'll fake a memory map. + * + * We check to see that the memory map contains at least 2 elements + * before we'll use it, because the detection code in setup.S may + * not be perfect and most every PC known to man has two memory + * regions: one from 0 to 640k, and one from 1mb up. (The IBM + * thinkpad 560x, for example, does not cooperate with the memory + * detection code.) + */ +int __init copy_e820_map(struct e820entry * biosmap, int nr_map) +{ + /* Only one memory region (or negative)? Ignore it */ + if (nr_map < 2) + return -1; + + do { + unsigned long long start = biosmap->addr; + unsigned long long size = biosmap->size; + unsigned long long end = start + size; + unsigned long type = biosmap->type; + printk("copy_e820_map() start: %016Lx size: %016Lx end: %016Lx type: %ld\n", start, size, end, type); + + /* Overflow in 64 bits? Ignore the memory map. */ + if (start > end) + return -1; + + /* + * Some BIOSes claim RAM in the 640k - 1M region. + * Not right. Fix it up. + */ + if (type == E820_RAM) { + printk("copy_e820_map() type is E820_RAM\n"); + if (start < 0x100000ULL && end > 0xA0000ULL) { + printk("copy_e820_map() lies in range...\n"); + if (start < 0xA0000ULL) { + printk("copy_e820_map() start < 0xA0000ULL\n"); + add_memory_region(start, 0xA0000ULL-start, type); + } + if (end <= 0x100000ULL) { + printk("copy_e820_map() end <= 0x100000ULL\n"); + continue; + } + start = 0x100000ULL; + size = end - start; + } + } + add_memory_region(start, size, type); + } while (biosmap++,--nr_map); + return 0; +} + diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index acd2d9392ab..b7509aec0eb 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -191,26 +191,6 @@ static void __init limit_regions(unsigned long long size) } } -void __init add_memory_region(unsigned long long start, - unsigned long long size, int type) -{ - int x; - - if (!efi_enabled) { - x = e820.nr_map; - - if (x == E820MAX) { - printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); - return; - } - - e820.map[x].addr = start; - e820.map[x].size = size; - e820.map[x].type = type; - e820.nr_map++; - } -} /* add_memory_region */ - #define E820_DEBUG 1 static void __init print_memory_map(char *who) @@ -239,226 +219,6 @@ static void __init print_memory_map(char *who) } } -/* - * Sanitize the BIOS e820 map. - * - * Some e820 responses include overlapping entries. The following - * replaces the original e820 map with a new one, removing overlaps. - * - */ -struct change_member { - struct e820entry *pbios; /* pointer to original bios entry */ - unsigned long long addr; /* address for this change point */ -}; -static struct change_member change_point_list[2*E820MAX] __initdata; -static struct change_member *change_point[2*E820MAX] __initdata; -static struct e820entry *overlap_list[E820MAX] __initdata; -static struct e820entry new_bios[E820MAX] __initdata; - -int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) -{ - struct change_member *change_tmp; - unsigned long current_type, last_type; - unsigned long long last_addr; - int chgidx, still_changing; - int overlap_entries; - int new_bios_entry; - int old_nr, new_nr, chg_nr; - int i; - - /* - Visually we're performing the following (1,2,3,4 = memory types)... - - Sample memory map (w/overlaps): - ____22__________________ - ______________________4_ - ____1111________________ - _44_____________________ - 11111111________________ - ____________________33__ - ___________44___________ - __________33333_________ - ______________22________ - ___________________2222_ - _________111111111______ - _____________________11_ - _________________4______ - - Sanitized equivalent (no overlap): - 1_______________________ - _44_____________________ - ___1____________________ - ____22__________________ - ______11________________ - _________1______________ - __________3_____________ - ___________44___________ - _____________33_________ - _______________2________ - ________________1_______ - _________________4______ - ___________________2____ - ____________________33__ - ______________________4_ - */ - - /* if there's only one memory region, don't bother */ - if (*pnr_map < 2) - return -1; - - old_nr = *pnr_map; - - /* bail out if we find any unreasonable addresses in bios map */ - for (i=0; iaddr = biosmap[i].addr; - change_point[chgidx++]->pbios = &biosmap[i]; - change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; - change_point[chgidx++]->pbios = &biosmap[i]; - } - } - chg_nr = chgidx; /* true number of change-points */ - - /* sort change-point list by memory addresses (low -> high) */ - still_changing = 1; - while (still_changing) { - still_changing = 0; - for (i=1; i < chg_nr; i++) { - /* if > , swap */ - /* or, if current= & last=, swap */ - if ((change_point[i]->addr < change_point[i-1]->addr) || - ((change_point[i]->addr == change_point[i-1]->addr) && - (change_point[i]->addr == change_point[i]->pbios->addr) && - (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) - ) - { - change_tmp = change_point[i]; - change_point[i] = change_point[i-1]; - change_point[i-1] = change_tmp; - still_changing=1; - } - } - } - - /* create a new bios memory map, removing overlaps */ - overlap_entries=0; /* number of entries in the overlap table */ - new_bios_entry=0; /* index for creating new bios map entries */ - last_type = 0; /* start with undefined memory type */ - last_addr = 0; /* start with 0 as last starting address */ - /* loop through change-points, determining affect on the new bios map */ - for (chgidx=0; chgidx < chg_nr; chgidx++) - { - /* keep track of all overlapping bios entries */ - if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) - { - /* add map entry to overlap list (> 1 entry implies an overlap) */ - overlap_list[overlap_entries++]=change_point[chgidx]->pbios; - } - else - { - /* remove entry from list (order independent, so swap with last) */ - for (i=0; ipbios) - overlap_list[i] = overlap_list[overlap_entries-1]; - } - overlap_entries--; - } - /* if there are overlapping entries, decide which "type" to use */ - /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ - current_type = 0; - for (i=0; itype > current_type) - current_type = overlap_list[i]->type; - /* continue building up new bios map based on this information */ - if (current_type != last_type) { - if (last_type != 0) { - new_bios[new_bios_entry].size = - change_point[chgidx]->addr - last_addr; - /* move forward only if the new size was non-zero */ - if (new_bios[new_bios_entry].size != 0) - if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ - } - if (current_type != 0) { - new_bios[new_bios_entry].addr = change_point[chgidx]->addr; - new_bios[new_bios_entry].type = current_type; - last_addr=change_point[chgidx]->addr; - } - last_type = current_type; - } - } - new_nr = new_bios_entry; /* retain count for new bios entries */ - - /* copy new bios mapping into original location */ - memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); - *pnr_map = new_nr; - - return 0; -} - -/* - * Copy the BIOS e820 map into a safe place. - * - * Sanity-check it while we're at it.. - * - * If we're lucky and live on a modern system, the setup code - * will have given us a memory map that we can use to properly - * set up memory. If we aren't, we'll fake a memory map. - * - * We check to see that the memory map contains at least 2 elements - * before we'll use it, because the detection code in setup.S may - * not be perfect and most every PC known to man has two memory - * regions: one from 0 to 640k, and one from 1mb up. (The IBM - * thinkpad 560x, for example, does not cooperate with the memory - * detection code.) - */ -int __init copy_e820_map(struct e820entry * biosmap, int nr_map) -{ - /* Only one memory region (or negative)? Ignore it */ - if (nr_map < 2) - return -1; - - do { - unsigned long long start = biosmap->addr; - unsigned long long size = biosmap->size; - unsigned long long end = start + size; - unsigned long type = biosmap->type; - - /* Overflow in 64 bits? Ignore the memory map. */ - if (start > end) - return -1; - - /* - * Some BIOSes claim RAM in the 640k - 1M region. - * Not right. Fix it up. - */ - if (type == E820_RAM) { - if (start < 0x100000ULL && end > 0xA0000ULL) { - if (start < 0xA0000ULL) - add_memory_region(start, 0xA0000ULL-start, type); - if (end <= 0x100000ULL) - continue; - start = 0x100000ULL; - size = end - start; - } - } - add_memory_region(start, size, type); - } while (biosmap++,--nr_map); - return 0; -} - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE -- cgit v1.2.3 From b2dff6a88cbed59d787a8ca7367c76ba385e1187 Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: Move find_max_pfn function to e820.c Move more code from setup.c into e820.c Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/e820.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 55 ------------------------------------------------ 2 files changed, 52 insertions(+), 55 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 0db95760b07..be4934f6f85 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -539,3 +540,54 @@ int __init copy_e820_map(struct e820entry * biosmap, int nr_map) return 0; } +/* + * Callback for efi_memory_walk. + */ +static int __init +efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) +{ + unsigned long *max_pfn = arg, pfn; + + if (start < end) { + pfn = PFN_UP(end -1); + if (pfn > *max_pfn) + *max_pfn = pfn; + } + return 0; +} + +static int __init +efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) +{ + memory_present(0, PFN_UP(start), PFN_DOWN(end)); + return 0; +} + +/* + * Find the highest page frame number we have available + */ +void __init find_max_pfn(void) +{ + int i; + + max_pfn = 0; + if (efi_enabled) { + efi_memmap_walk(efi_find_max_pfn, &max_pfn); + efi_memmap_walk(efi_memory_present_wrapper, NULL); + return; + } + + for (i = 0; i < e820.nr_map; i++) { + unsigned long start, end; + /* RAM? */ + if (e820.map[i].type != E820_RAM) + continue; + start = PFN_UP(e820.map[i].addr); + end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + if (start >= end) + continue; + if (end > max_pfn) + max_pfn = end; + memory_present(0, start, end); + } +} diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index b7509aec0eb..3d808054fdf 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -63,9 +63,6 @@ #include #include -/* Forward Declaration. */ -void __init find_max_pfn(void); - /* This value is set up by the early boot code to point to the value immediately after the boot time page tables. It contains a *physical* address, and must not be in the .bss segment! */ @@ -387,29 +384,6 @@ static int __init parse_reservetop(char *arg) } early_param("reservetop", parse_reservetop); -/* - * Callback for efi_memory_walk. - */ -static int __init -efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) -{ - unsigned long *max_pfn = arg, pfn; - - if (start < end) { - pfn = PFN_UP(end -1); - if (pfn > *max_pfn) - *max_pfn = pfn; - } - return 0; -} - -static int __init -efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) -{ - memory_present(0, PFN_UP(start), PFN_DOWN(end)); - return 0; -} - /* * This function checks if the entire range is mapped with type. * @@ -442,35 +416,6 @@ e820_all_mapped(unsigned long s, unsigned long e, unsigned type) return 0; } -/* - * Find the highest page frame number we have available - */ -void __init find_max_pfn(void) -{ - int i; - - max_pfn = 0; - if (efi_enabled) { - efi_memmap_walk(efi_find_max_pfn, &max_pfn); - efi_memmap_walk(efi_memory_present_wrapper, NULL); - return; - } - - for (i = 0; i < e820.nr_map; i++) { - unsigned long start, end; - /* RAM? */ - if (e820.map[i].type != E820_RAM) - continue; - start = PFN_UP(e820.map[i].addr); - end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - if (start >= end) - continue; - if (end > max_pfn) - max_pfn = end; - memory_present(0, start, end); - } -} - /* * Determine low and high memory ranges: */ -- cgit v1.2.3 From b5b2405706005cc7765f6ecd00965d29e93f090a Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: Move e820/efi memmap walking code to e820.c This patch moves e820/efi memmap table walking function from setup.c to e820.c, also this patch adds extern declaration in header file. Signed-off-by: bibo,mao Signed-off-by: Andi Kleen arch/i386/kernel/e820.c | 115 +++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 118 ----------------------------------- include/asm-i386/e820.h | 2 arch/i386/kernel/e820.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 118 ----------------------------------------------- include/asm-i386/e820.h | 2 3 files changed, 117 insertions(+), 118 deletions(-) --- arch/i386/kernel/e820.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 118 ----------------------------------------------- 2 files changed, 115 insertions(+), 118 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index be4934f6f85..47c495bf0cb 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -28,6 +28,11 @@ static struct change_member change_point_list[2*E820MAX] __initdata; static struct change_member *change_point[2*E820MAX] __initdata; static struct e820entry *overlap_list[E820MAX] __initdata; static struct e820entry new_bios[E820MAX] __initdata; +/* For PCI or other memory-mapped resources */ +unsigned long pci_mem_start = 0x10000000; +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_mem_start); +#endif struct resource data_resource = { .name = "Kernel data", .start = 0, @@ -591,3 +596,113 @@ void __init find_max_pfn(void) memory_present(0, start, end); } } + +/* + * Free all available memory for boot time allocation. Used + * as a callback function by efi_memory_walk() + */ + +static int __init +free_available_memory(unsigned long start, unsigned long end, void *arg) +{ + /* check max_low_pfn */ + if (start >= (max_low_pfn << PAGE_SHIFT)) + return 0; + if (end >= (max_low_pfn << PAGE_SHIFT)) + end = max_low_pfn << PAGE_SHIFT; + if (start < end) + free_bootmem(start, end - start); + + return 0; +} +/* + * Register fully available low RAM pages with the bootmem allocator. + */ +void __init register_bootmem_low_pages(unsigned long max_low_pfn) +{ + int i; + + if (efi_enabled) { + efi_memmap_walk(free_available_memory, NULL); + return; + } + for (i = 0; i < e820.nr_map; i++) { + unsigned long curr_pfn, last_pfn, size; + /* + * Reserve usable low memory + */ + if (e820.map[i].type != E820_RAM) + continue; + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(e820.map[i].addr); + if (curr_pfn >= max_low_pfn) + continue; + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + + /* + * .. finally, did all the rounding and playing + * around just make the area go away? + */ + if (last_pfn <= curr_pfn) + continue; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } +} + +void __init register_memory(void) +{ + unsigned long gapstart, gapsize, round; + unsigned long long last; + int i; + + /* + * Search for the bigest gap in the low 32 bits of the e820 + * memory space. + */ + last = 0x100000000ull; + gapstart = 0x10000000; + gapsize = 0x400000; + i = e820.nr_map; + while (--i >= 0) { + unsigned long long start = e820.map[i].addr; + unsigned long long end = start + e820.map[i].size; + + /* + * Since "last" is at most 4GB, we know we'll + * fit in 32 bits if this condition is true + */ + if (last > end) { + unsigned long gap = last - end; + + if (gap > gapsize) { + gapsize = gap; + gapstart = end; + } + } + if (start < last) + last = start; + } + + /* + * See how much we want to round up: start off with + * rounding to the next 1MB area. + */ + round = 0x100000; + while ((gapsize >> 4) > round) + round += round; + /* Fun with two's complement */ + pci_mem_start = (gapstart + round) & -round; + + printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", + pci_mem_start, gapstart, gapsize); +} diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 3d808054fdf..51ed015a1f3 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -94,12 +94,6 @@ unsigned int machine_submodel_id; unsigned int BIOS_revision; unsigned int mca_pentium_flag; -/* For PCI or other memory-mapped resources */ -unsigned long pci_mem_start = 0x10000000; -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_mem_start); -#endif - /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -475,68 +469,6 @@ unsigned long __init find_max_low_pfn(void) return max_low_pfn; } -/* - * Free all available memory for boot time allocation. Used - * as a callback function by efi_memory_walk() - */ - -static int __init -free_available_memory(unsigned long start, unsigned long end, void *arg) -{ - /* check max_low_pfn */ - if (start >= (max_low_pfn << PAGE_SHIFT)) - return 0; - if (end >= (max_low_pfn << PAGE_SHIFT)) - end = max_low_pfn << PAGE_SHIFT; - if (start < end) - free_bootmem(start, end - start); - - return 0; -} -/* - * Register fully available low RAM pages with the bootmem allocator. - */ -static void __init register_bootmem_low_pages(unsigned long max_low_pfn) -{ - int i; - - if (efi_enabled) { - efi_memmap_walk(free_available_memory, NULL); - return; - } - for (i = 0; i < e820.nr_map; i++) { - unsigned long curr_pfn, last_pfn, size; - /* - * Reserve usable low memory - */ - if (e820.map[i].type != E820_RAM) - continue; - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(e820.map[i].addr); - if (curr_pfn >= max_low_pfn) - continue; - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - /* - * .. finally, did all the rounding and playing - * around just make the area go away? - */ - if (last_pfn <= curr_pfn) - continue; - - size = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); - } -} - /* * workaround for Dell systems that neglect to reserve EBDA */ @@ -705,56 +637,6 @@ void __init remapped_pgdat_init(void) } } - - -static void __init register_memory(void) -{ - unsigned long gapstart, gapsize, round; - unsigned long long last; - int i; - - /* - * Search for the bigest gap in the low 32 bits of the e820 - * memory space. - */ - last = 0x100000000ull; - gapstart = 0x10000000; - gapsize = 0x400000; - i = e820.nr_map; - while (--i >= 0) { - unsigned long long start = e820.map[i].addr; - unsigned long long end = start + e820.map[i].size; - - /* - * Since "last" is at most 4GB, we know we'll - * fit in 32 bits if this condition is true - */ - if (last > end) { - unsigned long gap = last - end; - - if (gap > gapsize) { - gapsize = gap; - gapstart = end; - } - } - if (start < last) - last = start; - } - - /* - * See how much we want to round up: start off with - * rounding to the next 1MB area. - */ - round = 0x100000; - while ((gapsize >> 4) > round) - round += round; - /* Fun with two's complement */ - pci_mem_start = (gapstart + round) & -round; - - printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", - pci_mem_start, gapstart, gapsize); -} - #ifdef CONFIG_MCA static void set_mca_bus(int x) { -- cgit v1.2.3 From cef518e88b8ed94ea483c436ef5e5b151a3fabc6 Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] i386: Move memory map printing and other code to e820.c This patch moves e820 memory map print and memmap boot param parsing function from setup.c to e820.c, also adds limit_regions and print_memory_map declaration in header file. Signed-off-by: bibo,mao Signed-off-by: Andi Kleen arch/i386/kernel/e820.c | 152 +++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 158 --------------------------------- include/asm-i386/e820.h | 2 arch/i386/kernel/e820.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 153 ----------------------------------------------- include/asm-i386/e820.h | 2 3 files changed, 155 insertions(+), 152 deletions(-) --- arch/i386/kernel/e820.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 153 +---------------------------------------------- 2 files changed, 153 insertions(+), 152 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index 47c495bf0cb..b755255f272 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -33,6 +33,7 @@ unsigned long pci_mem_start = 0x10000000; #ifdef CONFIG_PCI EXPORT_SYMBOL(pci_mem_start); #endif +extern int user_defined_memmap; struct resource data_resource = { .name = "Kernel data", .start = 0, @@ -706,3 +707,154 @@ void __init register_memory(void) printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", pci_mem_start, gapstart, gapsize); } + +void __init print_memory_map(char *who) +{ + int i; + + for (i = 0; i < e820.nr_map; i++) { + printk(" %s: %016Lx - %016Lx ", who, + e820.map[i].addr, + e820.map[i].addr + e820.map[i].size); + switch (e820.map[i].type) { + case E820_RAM: printk("(usable)\n"); + break; + case E820_RESERVED: + printk("(reserved)\n"); + break; + case E820_ACPI: + printk("(ACPI data)\n"); + break; + case E820_NVS: + printk("(ACPI NVS)\n"); + break; + default: printk("type %lu\n", e820.map[i].type); + break; + } + } +} + +void __init limit_regions(unsigned long long size) +{ + unsigned long long current_addr = 0; + int i; + + print_memory_map("limit_regions start"); + if (efi_enabled) { + efi_memory_desc_t *md; + void *p; + + for (p = memmap.map, i = 0; p < memmap.map_end; + p += memmap.desc_size, i++) { + md = p; + current_addr = md->phys_addr + (md->num_pages << 12); + if (md->type == EFI_CONVENTIONAL_MEMORY) { + if (current_addr >= size) { + md->num_pages -= + (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); + memmap.nr_map = i + 1; + return; + } + } + } + } + for (i = 0; i < e820.nr_map; i++) { + current_addr = e820.map[i].addr + e820.map[i].size; + if (current_addr < size) + continue; + + if (e820.map[i].type != E820_RAM) + continue; + + if (e820.map[i].addr >= size) { + /* + * This region starts past the end of the + * requested size, skip it completely. + */ + e820.nr_map = i; + } else { + e820.nr_map = i + 1; + e820.map[i].size -= current_addr - size; + } + print_memory_map("limit_regions endfor"); + return; + } + print_memory_map("limit_regions endfunc"); +} + + /* + * This function checks if the entire range is mapped with type. + * + * Note: this function only works correct if the e820 table is sorted and + * not-overlapping, which is the case + */ +int __init +e820_all_mapped(unsigned long s, unsigned long e, unsigned type) +{ + u64 start = s; + u64 end = e; + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + if (type && ei->type != type) + continue; + /* is the region (part) in overlap with the current region ?*/ + if (ei->addr >= end || ei->addr + ei->size <= start) + continue; + /* if the region is at the beginning of we move + * start to the end of the region since it's ok until there + */ + if (ei->addr <= start) + start = ei->addr + ei->size; + /* if start is now at or beyond end, we're done, full + * coverage */ + if (start >= end) + return 1; /* we're done */ + } + return 0; +} + +static int __init parse_memmap(char *arg) +{ + if (!arg) + return -EINVAL; + + if (strcmp(arg, "exactmap") == 0) { +#ifdef CONFIG_CRASH_DUMP + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + find_max_pfn(); + saved_max_pfn = max_pfn; +#endif + e820.nr_map = 0; + user_defined_memmap = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long start_at, mem_size; + + mem_size = memparse(arg, &arg); + if (*arg == '@') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_RAM); + } else if (*arg == '#') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_ACPI); + } else if (*arg == '$') { + start_at = memparse(arg+1, &arg); + add_memory_region(start_at, mem_size, E820_RESERVED); + } else { + limit_regions(mem_size); + user_defined_memmap = 1; + } + } + return 0; +} +early_param("memmap", parse_memmap); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 51ed015a1f3..e5bb87aa5a4 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -73,7 +73,6 @@ int disable_pse __devinitdata = 0; /* * Machine setup.. */ -extern struct e820map e820; extern struct resource code_resource; extern struct resource data_resource; @@ -137,79 +136,6 @@ static char command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; -static void __init limit_regions(unsigned long long size) -{ - unsigned long long current_addr = 0; - int i; - - if (efi_enabled) { - efi_memory_desc_t *md; - void *p; - - for (p = memmap.map, i = 0; p < memmap.map_end; - p += memmap.desc_size, i++) { - md = p; - current_addr = md->phys_addr + (md->num_pages << 12); - if (md->type == EFI_CONVENTIONAL_MEMORY) { - if (current_addr >= size) { - md->num_pages -= - (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); - memmap.nr_map = i + 1; - return; - } - } - } - } - for (i = 0; i < e820.nr_map; i++) { - current_addr = e820.map[i].addr + e820.map[i].size; - if (current_addr < size) - continue; - - if (e820.map[i].type != E820_RAM) - continue; - - if (e820.map[i].addr >= size) { - /* - * This region starts past the end of the - * requested size, skip it completely. - */ - e820.nr_map = i; - } else { - e820.nr_map = i + 1; - e820.map[i].size -= current_addr - size; - } - return; - } -} - -#define E820_DEBUG 1 - -static void __init print_memory_map(char *who) -{ - int i; - - for (i = 0; i < e820.nr_map; i++) { - printk(" %s: %016Lx - %016Lx ", who, - e820.map[i].addr, - e820.map[i].addr + e820.map[i].size); - switch (e820.map[i].type) { - case E820_RAM: printk("(usable)\n"); - break; - case E820_RESERVED: - printk("(reserved)\n"); - break; - case E820_ACPI: - printk("(ACPI data)\n"); - break; - case E820_NVS: - printk("(ACPI NVS)\n"); - break; - default: printk("type %lu\n", e820.map[i].type); - break; - } - } -} - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -233,7 +159,7 @@ static inline void copy_edd(void) } #endif -static int __initdata user_defined_memmap = 0; +int __initdata user_defined_memmap = 0; /* * "mem=nopentium" disables the 4MB page tables. @@ -270,51 +196,6 @@ static int __init parse_mem(char *arg) } early_param("mem", parse_mem); -static int __init parse_memmap(char *arg) -{ - if (!arg) - return -EINVAL; - - if (strcmp(arg, "exactmap") == 0) { -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - find_max_pfn(); - saved_max_pfn = max_pfn; -#endif - e820.nr_map = 0; - user_defined_memmap = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. - */ - unsigned long long start_at, mem_size; - - mem_size = memparse(arg, &arg); - if (*arg == '@') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RAM); - } else if (*arg == '#') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_ACPI); - } else if (*arg == '$') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RESERVED); - } else { - limit_regions(mem_size); - user_defined_memmap = 1; - } - } - return 0; -} -early_param("memmap", parse_memmap); - #ifdef CONFIG_PROC_VMCORE /* elfcorehdr= specifies the location of elf core header * stored by the crashed kernel. @@ -378,38 +259,6 @@ static int __init parse_reservetop(char *arg) } early_param("reservetop", parse_reservetop); - /* - * This function checks if the entire range is mapped with type. - * - * Note: this function only works correct if the e820 table is sorted and - * not-overlapping, which is the case - */ -int __init -e820_all_mapped(unsigned long s, unsigned long e, unsigned type) -{ - u64 start = s; - u64 end = e; - int i; - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - if (type && ei->type != type) - continue; - /* is the region (part) in overlap with the current region ?*/ - if (ei->addr >= end || ei->addr + ei->size <= start) - continue; - /* if the region is at the beginning of we move - * start to the end of the region since it's ok until there - */ - if (ei->addr <= start) - start = ei->addr + ei->size; - /* if start is now at or beyond end, we're done, full - * coverage */ - if (start >= end) - return 1; /* we're done */ - } - return 0; -} - /* * Determine low and high memory ranges: */ -- cgit v1.2.3 From 58db85482743f5e3495d168c641c60ce1d3dfb06 Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] calgary: phb_shift can be int Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-calgary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index d2ea87a9526..f53b581dfd0 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -740,7 +740,7 @@ static void __init calgary_increase_split_completion_timeout(void __iomem *bbar, { u64 val64; void __iomem *target; - unsigned long phb_shift = -1; + unsigned int phb_shift = ~0; /* silence gcc */ u64 mask; switch (busno_to_phbid(busnum)) { -- cgit v1.2.3 From b34e90b8f0f30151349134f87b5dc6ef75a5218c Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] Calgary: use BIOS supplied BBARs and topology information Find the BBAR register address of each Calgary using the "Extended BIOS Data Area" rather than calculating it ourselves. Also get the bus topology (what PHB each bus is on) from Calgary rather than calculating it ourselves. This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=7407. Signed-off-by: Laurent Vivier Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-calgary.c | 161 ++++++++++++++++++++++++++++++--------- 1 file changed, 125 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index f53b581dfd0..afc0a53505f 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -41,6 +41,7 @@ #include #include #include +#include #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 #define PCI_VENDOR_DEVICE_ID_CALGARY \ @@ -115,14 +116,35 @@ static const unsigned long phb_offsets[] = { 0xB000 /* PHB3 */ }; +/* PHB debug registers */ + +static const unsigned long phb_debug_offsets[] = { + 0x4000 /* PHB 0 DEBUG */, + 0x5000 /* PHB 1 DEBUG */, + 0x6000 /* PHB 2 DEBUG */, + 0x7000 /* PHB 3 DEBUG */ +}; + +/* + * STUFF register for each debug PHB, + * byte 1 = start bus number, byte 2 = end bus number + */ + +#define PHB_DEBUG_STUFF_OFFSET 0x0020 + unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; static int translate_empty_slots __read_mostly = 0; static int calgary_detected __read_mostly = 0; +static struct rio_table_hdr *rio_table_hdr __initdata; +static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; +static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; + struct calgary_bus_info { void *tce_space; unsigned char translation_disabled; signed char phbid; + void __iomem *bbar; }; static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; @@ -475,6 +497,11 @@ static struct dma_mapping_ops calgary_dma_ops = { .unmap_sg = calgary_unmap_sg, }; +static inline void __iomem * busno_to_bbar(unsigned char num) +{ + return bus_info[num].bbar; +} + static inline int busno_to_phbid(unsigned char num) { return bus_info[num].phbid; @@ -828,31 +855,9 @@ static void __init calgary_disable_translation(struct pci_dev *dev) del_timer_sync(&tbl->watchdog_timer); } -static inline unsigned int __init locate_register_space(struct pci_dev *dev) +static inline void __iomem * __init locate_register_space(struct pci_dev *dev) { - int rionodeid; - u32 address; - - /* - * Each Calgary has four busses. The first four busses (first Calgary) - * have RIO node ID 2, then the next four (second Calgary) have RIO - * node ID 3, the next four (third Calgary) have node ID 2 again, etc. - * We use a gross hack - relying on the dev->bus->number ordering, - * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1, - * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the - * second (id 3), and then it repeats modulo 14. - */ - rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2; - /* - * register space address calculation as follows: - * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) - * ChassisBase is always zero for x366/x260/x460 - * RioNodeId is 2 for first Calgary, 3 for second Calgary - */ - address = START_ADDRESS - - (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) + - (0x100000) * (rionodeid - CHASSIS_BASE); - return address; + return busno_to_bbar(dev->bus->number); } static void __init calgary_init_one_nontraslated(struct pci_dev *dev) @@ -864,15 +869,12 @@ static void __init calgary_init_one_nontraslated(struct pci_dev *dev) static int __init calgary_init_one(struct pci_dev *dev) { - u32 address; void __iomem *bbar; int ret; BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - address = locate_register_space(dev); - /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(address, 1024 * 1024); + bbar = locate_register_space(dev); if (!bbar) { ret = -ENODATA; goto done; @@ -898,6 +900,35 @@ static int __init calgary_init(void) { int ret = -ENODEV; struct pci_dev *dev = NULL; + int rio, phb, bus; + void __iomem *bbar; + void __iomem *target; + u8 start_bus, end_bus; + u32 val; + + for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) { + + if ( (rio_devs[rio]->type != COMPAT_CALGARY) && + (rio_devs[rio]->type != ALT_CALGARY) ) + continue; + + /* map entire 1MB of Calgary config space */ + bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024); + + for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { + + target = calgary_reg(bbar, phb_debug_offsets[phb] | + PHB_DEBUG_STUFF_OFFSET); + val = be32_to_cpu(readl(target)); + start_bus = (u8)((val & 0x00FF0000) >> 16); + end_bus = (u8)((val & 0x0000FF00) >> 8); + for (bus = start_bus; bus <= end_bus; bus++) { + bus_info[bus].bbar = bbar; + bus_info[bus].phbid = phb; + } + } + } + do { dev = pci_get_device(PCI_VENDOR_ID_IBM, @@ -962,13 +993,55 @@ static inline int __init determine_tce_table_size(u64 ram) return ret; } +static int __init build_detail_arrays(void) +{ + unsigned long ptr; + int i, scal_detail_size, rio_detail_size; + + if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ + printk(KERN_WARNING + "Calgary: MAX_NUMNODES too low! Defined as %d, " + "but system has %d nodes.\n", + MAX_NUMNODES, rio_table_hdr->num_scal_dev); + return -ENODEV; + } + + switch (rio_table_hdr->version){ + default: + printk(KERN_WARNING + "Calgary: Invalid Rio Grande Table Version: %d\n", + rio_table_hdr->version); + return -ENODEV; + case 2: + scal_detail_size = 11; + rio_detail_size = 13; + break; + case 3: + scal_detail_size = 12; + rio_detail_size = 15; + break; + } + + ptr = ((unsigned long)rio_table_hdr) + 3; + for (i = 0; i < rio_table_hdr->num_scal_dev; + i++, ptr += scal_detail_size) + scal_devs[i] = (struct scal_detail *)ptr; + + for (i = 0; i < rio_table_hdr->num_rio_dev; + i++, ptr += rio_detail_size) + rio_devs[i] = (struct rio_detail *)ptr; + + return 0; +} + void __init detect_calgary(void) { u32 val; int bus; void *tbl; int calgary_found = 0; - int phb = -1; + unsigned long ptr; + int offset; /* * if the user specified iommu=off or iommu=soft or we found @@ -980,6 +1053,29 @@ void __init detect_calgary(void) if (!early_pci_allowed()) return; + ptr = (unsigned long)phys_to_virt(get_bios_ebda()); + + rio_table_hdr = NULL; + offset = 0x180; + while (offset) { + /* The block id is stored in the 2nd word */ + if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ + /* set the pointer past the offset & block id */ + rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4); + break; + } + /* The next offset is stored in the 1st word. 0 means no more */ + offset = *((unsigned short *)(ptr + offset)); + } + if (!rio_table_hdr){ + printk(KERN_ERR "Calgary: Unable to locate " + "Rio Grande Table in EBDA - bailing!\n"); + return; + } + + if (build_detail_arrays()) + return; + specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { @@ -990,12 +1086,6 @@ void __init detect_calgary(void) if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; - /* - * There are 4 PHBs per Calgary chip. Set phb to which phb (0-3) - * it is connected to releative to the clagary chip. - */ - phb = (phb + 1) % PHBS_PER_CALGARY; - if (info->translation_disabled) continue; @@ -1010,7 +1100,6 @@ void __init detect_calgary(void) if (!tbl) goto cleanup; info->tce_space = tbl; - info->phbid = phb; calgary_found = 1; break; } -- cgit v1.2.3 From eae93755540bae18aff46b8a0e621b5d65bd5380 Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] Calgary: check BBAR ioremap success when ioremapping This patch cleans up the previous "Use BIOS supplied BBAR information" patch. Mostly stylistic clenaups, but also check for ioremap failure when we ioremap the BBAR rather than when trying to use it. Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen Acked-by: Laurent Vivier --- arch/x86_64/kernel/pci-calgary.c | 85 +++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index afc0a53505f..8a1e4f35bc3 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -138,7 +138,7 @@ static int calgary_detected __read_mostly = 0; static struct rio_table_hdr *rio_table_hdr __initdata; static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; -static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; +static struct rio_detail *rio_devs[MAX_NUMNODES * 4] __initdata; struct calgary_bus_info { void *tce_space; @@ -855,11 +855,6 @@ static void __init calgary_disable_translation(struct pci_dev *dev) del_timer_sync(&tbl->watchdog_timer); } -static inline void __iomem * __init locate_register_space(struct pci_dev *dev) -{ - return busno_to_bbar(dev->bus->number); -} - static void __init calgary_init_one_nontraslated(struct pci_dev *dev) { pci_dev_get(dev); @@ -874,15 +869,10 @@ static int __init calgary_init_one(struct pci_dev *dev) BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - bbar = locate_register_space(dev); - if (!bbar) { - ret = -ENODATA; - goto done; - } - + bbar = busno_to_bbar(dev->bus->number); ret = calgary_setup_tar(dev, bbar); if (ret) - goto iounmap; + goto done; pci_dev_get(dev); dev->bus->self = dev; @@ -890,38 +880,39 @@ static int __init calgary_init_one(struct pci_dev *dev) return 0; -iounmap: - iounmap(bbar); done: return ret; } -static int __init calgary_init(void) +static int __init calgary_locate_bbars(void) { - int ret = -ENODEV; - struct pci_dev *dev = NULL; - int rio, phb, bus; + int ret; + int rioidx, phb, bus; void __iomem *bbar; void __iomem *target; + unsigned long offset; u8 start_bus, end_bus; u32 val; - for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) { + ret = -ENODATA; + for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) { + struct rio_detail *rio = rio_devs[rioidx]; - if ( (rio_devs[rio]->type != COMPAT_CALGARY) && - (rio_devs[rio]->type != ALT_CALGARY) ) + if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY)) continue; /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024); + bbar = ioremap_nocache(rio->BBAR, 1024 * 1024); + if (!bbar) + goto error; for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { + offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET; + target = calgary_reg(bbar, offset); - target = calgary_reg(bbar, phb_debug_offsets[phb] | - PHB_DEBUG_STUFF_OFFSET); val = be32_to_cpu(readl(target)); start_bus = (u8)((val & 0x00FF0000) >> 16); - end_bus = (u8)((val & 0x0000FF00) >> 8); + end_bus = (u8)((val & 0x0000FF00) >> 8); for (bus = start_bus; bus <= end_bus; bus++) { bus_info[bus].bbar = bbar; bus_info[bus].phbid = phb; @@ -929,6 +920,25 @@ static int __init calgary_init(void) } } + return 0; + +error: + /* scan bus_info and iounmap any bbars we previously ioremap'd */ + for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++) + if (bus_info[bus].bbar) + iounmap(bus_info[bus].bbar); + + return ret; +} + +static int __init calgary_init(void) +{ + int ret; + struct pci_dev *dev = NULL; + + ret = calgary_locate_bbars(); + if (ret) + return ret; do { dev = pci_get_device(PCI_VENDOR_ID_IBM, @@ -1000,18 +1010,13 @@ static int __init build_detail_arrays(void) if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ printk(KERN_WARNING - "Calgary: MAX_NUMNODES too low! Defined as %d, " + "Calgary: MAX_NUMNODES too low! Defined as %d, " "but system has %d nodes.\n", MAX_NUMNODES, rio_table_hdr->num_scal_dev); return -ENODEV; } switch (rio_table_hdr->version){ - default: - printk(KERN_WARNING - "Calgary: Invalid Rio Grande Table Version: %d\n", - rio_table_hdr->version); - return -ENODEV; case 2: scal_detail_size = 11; rio_detail_size = 13; @@ -1020,6 +1025,11 @@ static int __init build_detail_arrays(void) scal_detail_size = 12; rio_detail_size = 15; break; + default: + printk(KERN_WARNING + "Calgary: Invalid Rio Grande Table Version: %d\n", + rio_table_hdr->version); + return -EPROTO; } ptr = ((unsigned long)rio_table_hdr) + 3; @@ -1042,6 +1052,7 @@ void __init detect_calgary(void) int calgary_found = 0; unsigned long ptr; int offset; + int ret; /* * if the user specified iommu=off or iommu=soft or we found @@ -1061,27 +1072,29 @@ void __init detect_calgary(void) /* The block id is stored in the 2nd word */ if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ /* set the pointer past the offset & block id */ - rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4); + rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); break; } /* The next offset is stored in the 1st word. 0 means no more */ offset = *((unsigned short *)(ptr + offset)); } - if (!rio_table_hdr){ + if (!rio_table_hdr) { printk(KERN_ERR "Calgary: Unable to locate " "Rio Grande Table in EBDA - bailing!\n"); return; } - if (build_detail_arrays()) + ret = build_detail_arrays(); + if (ret) { + printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret); return; + } specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { int dev; struct calgary_bus_info *info = &bus_info[bus]; - info->phbid = -1; if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; -- cgit v1.2.3 From bff6547bb6a4e82c399d74e7fba78b12d2f162ed Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] Calgary: allow compiling Calgary in but not using it by default This patch makes it possible to compile Calgary in but not use it by default. In this mode, use 'iommu=calgary' to activate it. Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 11 +++++++++++ arch/x86_64/kernel/pci-calgary.c | 9 +++++++++ arch/x86_64/kernel/pci-dma.c | 5 +++++ 3 files changed, 25 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 010d2265f1c..5cb509dbffe 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -455,6 +455,17 @@ config CALGARY_IOMMU Normally the kernel will make the right choice by itself. If unsure, say Y. +config CALGARY_IOMMU_ENABLED_BY_DEFAULT + bool "Should Calgary be enabled by default?" + default y + depends on CALGARY_IOMMU + help + Should Calgary be enabled by default? if you choose 'y', Calgary + will be used (if it exists). If you choose 'n', Calgary will not be + used even if it exists. If you choose 'n' and would like to use + Calgary anyway, pass 'iommu=calgary' on the kernel command line. + If unsure, say Y. + # need this always selected by IOMMU for the VIA workaround config SWIOTLB bool diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 8a1e4f35bc3..0ddf29dae7e 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -43,6 +43,12 @@ #include #include +#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT +int use_calgary __read_mostly = 1; +#else +int use_calgary __read_mostly = 0; +#endif /* CONFIG_CALGARY_DEFAULT_ENABLED */ + #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 #define PCI_VENDOR_DEVICE_ID_CALGARY \ (PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16) @@ -1061,6 +1067,9 @@ void __init detect_calgary(void) if (swiotlb || no_iommu || iommu_detected) return; + if (!use_calgary) + return; + if (!early_pci_allowed()) return; diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index f8d857453f8..683b7a5c1ab 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c @@ -296,6 +296,11 @@ __init int iommu_setup(char *p) gart_parse_options(p); #endif +#ifdef CONFIG_CALGARY_IOMMU + if (!strncmp(p, "calgary", 7)) + use_calgary = 1; +#endif /* CONFIG_CALGARY_IOMMU */ + p += strcspn(p, ","); if (*p == ',') ++p; -- cgit v1.2.3 From b9a8d94a47f8a41766f6f7944adfb1d641349903 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] x86-64: Make x86_64 udelay() round up instead of down. Port two patches from i386 to x86_64 delay.c to make sure all rounding is done upward instead of downward. There is no sign in commit messages that the mismatch was done on purpose, and "delay() guarantees sleeping at least for the specified time" is still a valid rule IMHO. The original x86 patches are both from pre-GIT era, i.e.: "[PATCH] round up in __udelay()" in commit 54c7e1f5cc6771ff644d7bc21a2b829308bd126f "[PATCH] add 1 in __const_udelay()" in commit 42c77a9801b8877d8b90f65f75db758822a0bccc (both commits are from converted BK repository to x86_64). AK: fixed gcc warning linux/arch/x86_64/lib/delay.c:43: warning: suggest parentheses around + or - inside shift (did this actually work?) Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andi Kleen --- arch/x86_64/lib/delay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index 50be90975d0..2dbebd30834 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c @@ -40,13 +40,13 @@ EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { - __delay((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32); + __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1); } EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ } EXPORT_SYMBOL(__udelay); -- cgit v1.2.3 From d15512f442ef1ea60f6195b0444fb27b3cf8d0e6 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] i386: Fix race in IO-APIC routing entry setup. Interrupt could happen between setting the IO-APIC entry and setting its interrupt data. Pointed out by Linus. Signed-off-by: Andi Kleen --- arch/i386/kernel/io_apic.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 3b7a63e0ed1..e33b7a84529 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -153,14 +153,20 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) * the interrupt, and we need to make sure the entry is fully populated * before that happens. */ -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +static void +__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { - unsigned long flags; union entry_union eu; eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11 + 2*pin, eu.w2); io_apic_write(apic, 0x10 + 2*pin, eu.w1); +} + +static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +{ + unsigned long flags; + spin_lock_irqsave(&ioapic_lock, flags); + __ioapic_write_entry(apic, pin, e); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1360,8 +1366,8 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } - ioapic_write_entry(apic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + __ioapic_write_entry(apic, pin, entry); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -2856,8 +2862,8 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a if (!ioapic && (irq < 16)) disable_8259A_irq(irq); - ioapic_write_entry(ioapic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + __ioapic_write_entry(ioapic, pin, entry); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); -- cgit v1.2.3 From 516d2836434d279fef164bb1b964e83425d312d2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] x86-64: Fix race in IO-APIC routing entry setup. Interrupt could happen between setting the IO-APIC entry and setting its interrupt data. Pointed out by Linus. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 88fcc4ebbf6..eaf0b708e67 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -174,14 +174,20 @@ static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) * the interrupt, and we need to make sure the entry is fully populated * before that happens. */ -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +static void +__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) { - unsigned long flags; union entry_union eu; eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11 + 2*pin, eu.w2); io_apic_write(apic, 0x10 + 2*pin, eu.w1); +} + +static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) +{ + unsigned long flags; + spin_lock_irqsave(&ioapic_lock, flags); + __ioapic_write_entry(apic, pin, e); spin_unlock_irqrestore(&ioapic_lock, flags); } -- cgit v1.2.3 From 8c89812684de3b47066d800031dfd7098abbdc74 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] i386: remove IOPL check on task switch IOPL is implicitly saved and restored on task switch, so explicit check is no longer needed. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andi Kleen --- arch/i386/kernel/process.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 8f42659ef9d..99308510a17 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c @@ -674,12 +674,6 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas write_pda(pcurrent, next_p); - /* - * Restore IOPL if needed. - */ - if (unlikely(prev->iopl != next->iopl)) - set_iopl_mask(next->iopl); - /* * Now maybe handle debug registers and/or IO bitmaps */ -- cgit v1.2.3 From b6bcc4bb1cdfbc3c8612aad63a8703ac3d59f61a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] x86-64: Don't force inlining of do_csum It's two big and used by two callers. Calls should be cheap enough anyways. Signed-off-by: Andi Kleen --- arch/x86_64/lib/csum-partial.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/lib/csum-partial.c b/arch/x86_64/lib/csum-partial.c index 06ae630de82..bc503f50690 100644 --- a/arch/x86_64/lib/csum-partial.c +++ b/arch/x86_64/lib/csum-partial.c @@ -9,8 +9,6 @@ #include #include -#define __force_inline inline __attribute__((always_inline)) - static inline unsigned short from32to16(unsigned a) { unsigned short b = a >> 16; @@ -33,7 +31,7 @@ static inline unsigned short from32to16(unsigned a) * Unrolling to an 128 bytes inner loop. * Using interleaving with more registers to break the carry chains. */ -static __force_inline unsigned do_csum(const unsigned char *buff, unsigned len) +static unsigned do_csum(const unsigned char *buff, unsigned len) { unsigned odd, count; unsigned long result = 0; -- cgit v1.2.3 From 3529833f1ca8790df06ce218b5d9d438776696ed Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] i386: substitute __va lookup with pfn_to_kaddr Substitutes allocate_pgdat virtual address lookup with pfn_to_kaddr macro. Signed-off-by: David Rientjes Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/mm/discontig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c index ddbdb0336f2..103b76e56a9 100644 --- a/arch/i386/mm/discontig.c +++ b/arch/i386/mm/discontig.c @@ -168,7 +168,7 @@ static void __init allocate_pgdat(int nid) if (nid && node_has_online_mem(nid)) NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid]; else { - NODE_DATA(nid) = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT)); + NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(min_low_pfn)); min_low_pfn += PFN_UP(sizeof(pg_data_t)); } } -- cgit v1.2.3 From db91b882aabd0b3b55a87cbfb344f2798bb740b4 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] i386: Fix double #includes in arch/i386 Fix double #includes in arch/i386 Signed-off-by: Nicolas Kaiser Signed-off-by: Andi Kleen --- arch/i386/kernel/cpuid.c | 1 - arch/i386/kernel/tsc.c | 1 - 2 files changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index ab0c327e79d..5c5d4507ee7 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index fbc95828cd7..7f22e03253e 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -13,7 +13,6 @@ #include #include -#include #include #include "mach_timer.h" -- cgit v1.2.3 From d3561b7fa0fb0fc583bab0eeda32bec9e4c4056d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] paravirt: header and stubs for paravirtualisation Create a paravirt.h header for all the critical operations which need to be replaced with hypervisor calls, and include that instead of defining native operations, when CONFIG_PARAVIRT. This patch does the dumbest possible replacement of paravirtualized instructions: calls through a "paravirt_ops" structure. Currently these are function implementations of native hardware: hypervisors will override the ops structure with their own variants. All the pv-ops functions are declared "fastcall" so that a specific register-based ABI is used, to make inlining assember easier. And: +From: Andy Whitcroft The paravirt ops introduce a 'weak' attribute onto memory_setup(). Code ordering leads to the following warnings on x86: arch/i386/kernel/setup.c:651: warning: weak declaration of `memory_setup' after first use results in unspecified behavior Move memory_setup() to avoid this. Signed-off-by: Rusty Russell Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Jeremy Fitzhardinge Cc: Zachary Amsden Signed-off-by: Andrew Morton Signed-off-by: Andy Whitcroft --- arch/i386/Kconfig | 11 ++ arch/i386/boot/compressed/misc.c | 1 + arch/i386/kernel/Makefile | 1 + arch/i386/kernel/asm-offsets.c | 10 + arch/i386/kernel/entry.S | 34 +++- arch/i386/kernel/i8259.c | 5 +- arch/i386/kernel/paravirt.c | 404 +++++++++++++++++++++++++++++++++++++++ arch/i386/kernel/setup.c | 8 +- arch/i386/kernel/smpboot.c | 5 + arch/i386/kernel/time.c | 15 +- arch/i386/power/cpu.c | 8 +- 11 files changed, 479 insertions(+), 23 deletions(-) create mode 100644 arch/i386/kernel/paravirt.c (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 1f0f7b60995..bb1fa061c6c 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -182,6 +182,17 @@ config X86_ES7000 endchoice +config PARAVIRT + bool "Paravirtualization support (EXPERIMENTAL)" + depends on EXPERIMENTAL + help + Paravirtualization is a way of running multiple instances of + Linux on the same machine, under a hypervisor. This option + changes the kernel so it can modify itself when it is run + under a hypervisor, improving performance significantly. + However, when run without a hypervisor the kernel is + theoretically slower. If in doubt, say N. + config ACPI_SRAT bool default y diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index dc153893155..c6798c75c67 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -9,6 +9,7 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ +#undef CONFIG_PARAVIRT #include #include #include diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index f614854bd71..40661213604 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o +obj-$(CONFIG_PARAVIRT) += paravirt.o EXTRA_AFLAGS := -traditional diff --git a/arch/i386/kernel/asm-offsets.c b/arch/i386/kernel/asm-offsets.c index 0666eb0ed7b..1b2f3cd3327 100644 --- a/arch/i386/kernel/asm-offsets.c +++ b/arch/i386/kernel/asm-offsets.c @@ -101,4 +101,14 @@ void foo(void) BLANK(); OFFSET(PDA_cpu, i386_pda, cpu_number); OFFSET(PDA_pcurrent, i386_pda, pcurrent); + +#ifdef CONFIG_PARAVIRT + BLANK(); + OFFSET(PARAVIRT_enabled, paravirt_ops, paravirt_enabled); + OFFSET(PARAVIRT_irq_disable, paravirt_ops, irq_disable); + OFFSET(PARAVIRT_irq_enable, paravirt_ops, irq_enable); + OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit); + OFFSET(PARAVIRT_iret, paravirt_ops, iret); + OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0); +#endif } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index 0220bc8cbb4..d274612e05c 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -62,13 +62,6 @@ DF_MASK = 0x00000400 NT_MASK = 0x00004000 VM_MASK = 0x00020000 -/* These are replaces for paravirtualization */ -#define DISABLE_INTERRUPTS cli -#define ENABLE_INTERRUPTS sti -#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit -#define INTERRUPT_RETURN iret -#define GET_CR0_INTO_EAX movl %cr0, %eax - #ifdef CONFIG_PREEMPT #define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF #else @@ -416,6 +409,20 @@ ldt_ss: jnz restore_nocheck testl $0x00400000, %eax # returning to 32bit stack? jnz restore_nocheck # allright, normal return + +#ifdef CONFIG_PARAVIRT + /* + * The kernel can't run on a non-flat stack if paravirt mode + * is active. Rather than try to fixup the high bits of + * ESP, bypass this code entirely. This may break DOSemu + * and/or Wine support in a paravirt VM, although the option + * is still available to implement the setting of the high + * 16-bits in the INTERRUPT_RETURN paravirt-op. + */ + cmpl $0, paravirt_ops+PARAVIRT_enabled + jne restore_nocheck +#endif + /* If returning to userspace with 16bit stack, * try to fix the higher word of ESP, as the CPU * won't restore it. @@ -833,6 +840,19 @@ nmi_espfix_stack: .previous KPROBE_END(nmi) +#ifdef CONFIG_PARAVIRT +ENTRY(native_iret) +1: iret +.section __ex_table,"a" + .align 4 + .long 1b,iret_exc +.previous + +ENTRY(native_irq_enable_sysexit) + sti + sysexit +#endif + KPROBE_ENTRY(int3) RING0_INT_FRAME pushl $-1 # mark this as an int diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index 62996cd1708..c8d45821c78 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c @@ -381,7 +381,10 @@ void __init init_ISA_irqs (void) } } -void __init init_IRQ(void) +/* Overridden in paravirt.c */ +void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); + +void __init native_init_IRQ(void) { int i; diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c new file mode 100644 index 00000000000..478192cd4b9 --- /dev/null +++ b/arch/i386/kernel/paravirt.c @@ -0,0 +1,404 @@ +/* Paravirtualization interfaces + Copyright (C) 2006 Rusty Russell IBM Corporation + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* nop stub */ +static void native_nop(void) +{ +} + +static void __init default_banner(void) +{ + printk(KERN_INFO "Booting paravirtualized kernel on %s\n", + paravirt_ops.name); +} + +char *memory_setup(void) +{ + return paravirt_ops.memory_setup(); +} + +static fastcall unsigned long native_get_debugreg(int regno) +{ + unsigned long val = 0; /* Damn you, gcc! */ + + switch (regno) { + case 0: + asm("movl %%db0, %0" :"=r" (val)); break; + case 1: + asm("movl %%db1, %0" :"=r" (val)); break; + case 2: + asm("movl %%db2, %0" :"=r" (val)); break; + case 3: + asm("movl %%db3, %0" :"=r" (val)); break; + case 6: + asm("movl %%db6, %0" :"=r" (val)); break; + case 7: + asm("movl %%db7, %0" :"=r" (val)); break; + default: + BUG(); + } + return val; +} + +static fastcall void native_set_debugreg(int regno, unsigned long value) +{ + switch (regno) { + case 0: + asm("movl %0,%%db0" : /* no output */ :"r" (value)); + break; + case 1: + asm("movl %0,%%db1" : /* no output */ :"r" (value)); + break; + case 2: + asm("movl %0,%%db2" : /* no output */ :"r" (value)); + break; + case 3: + asm("movl %0,%%db3" : /* no output */ :"r" (value)); + break; + case 6: + asm("movl %0,%%db6" : /* no output */ :"r" (value)); + break; + case 7: + asm("movl %0,%%db7" : /* no output */ :"r" (value)); + break; + default: + BUG(); + } +} + +void init_IRQ(void) +{ + paravirt_ops.init_IRQ(); +} + +static fastcall void native_clts(void) +{ + asm volatile ("clts"); +} + +static fastcall unsigned long native_read_cr0(void) +{ + unsigned long val; + asm volatile("movl %%cr0,%0\n\t" :"=r" (val)); + return val; +} + +static fastcall void native_write_cr0(unsigned long val) +{ + asm volatile("movl %0,%%cr0": :"r" (val)); +} + +static fastcall unsigned long native_read_cr2(void) +{ + unsigned long val; + asm volatile("movl %%cr2,%0\n\t" :"=r" (val)); + return val; +} + +static fastcall void native_write_cr2(unsigned long val) +{ + asm volatile("movl %0,%%cr2": :"r" (val)); +} + +static fastcall unsigned long native_read_cr3(void) +{ + unsigned long val; + asm volatile("movl %%cr3,%0\n\t" :"=r" (val)); + return val; +} + +static fastcall void native_write_cr3(unsigned long val) +{ + asm volatile("movl %0,%%cr3": :"r" (val)); +} + +static fastcall unsigned long native_read_cr4(void) +{ + unsigned long val; + asm volatile("movl %%cr4,%0\n\t" :"=r" (val)); + return val; +} + +static fastcall unsigned long native_read_cr4_safe(void) +{ + unsigned long val; + /* This could fault if %cr4 does not exist */ + asm("1: movl %%cr4, %0 \n" + "2: \n" + ".section __ex_table,\"a\" \n" + ".long 1b,2b \n" + ".previous \n" + : "=r" (val): "0" (0)); + return val; +} + +static fastcall void native_write_cr4(unsigned long val) +{ + asm volatile("movl %0,%%cr4": :"r" (val)); +} + +static fastcall unsigned long native_save_fl(void) +{ + unsigned long f; + asm volatile("pushfl ; popl %0":"=g" (f): /* no input */); + return f; +} + +static fastcall void native_restore_fl(unsigned long f) +{ + asm volatile("pushl %0 ; popfl": /* no output */ + :"g" (f) + :"memory", "cc"); +} + +static fastcall void native_irq_disable(void) +{ + asm volatile("cli": : :"memory"); +} + +static fastcall void native_irq_enable(void) +{ + asm volatile("sti": : :"memory"); +} + +static fastcall void native_safe_halt(void) +{ + asm volatile("sti; hlt": : :"memory"); +} + +static fastcall void native_halt(void) +{ + asm volatile("hlt": : :"memory"); +} + +static fastcall void native_wbinvd(void) +{ + asm volatile("wbinvd": : :"memory"); +} + +static fastcall unsigned long long native_read_msr(unsigned int msr, int *err) +{ + unsigned long long val; + + asm volatile("2: rdmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %3,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=r" (*err), "=A" (val) + : "c" (msr), "i" (-EFAULT)); + + return val; +} + +static fastcall int native_write_msr(unsigned int msr, unsigned long long val) +{ + int err; + asm volatile("2: wrmsr ; xorl %0,%0\n" + "1:\n\t" + ".section .fixup,\"ax\"\n\t" + "3: movl %4,%0 ; jmp 1b\n\t" + ".previous\n\t" + ".section __ex_table,\"a\"\n" + " .align 4\n\t" + " .long 2b,3b\n\t" + ".previous" + : "=a" (err) + : "c" (msr), "0" ((u32)val), "d" ((u32)(val>>32)), + "i" (-EFAULT)); + return err; +} + +static fastcall unsigned long long native_read_tsc(void) +{ + unsigned long long val; + asm volatile("rdtsc" : "=A" (val)); + return val; +} + +static fastcall unsigned long long native_read_pmc(void) +{ + unsigned long long val; + asm volatile("rdpmc" : "=A" (val)); + return val; +} + +static fastcall void native_load_tr_desc(void) +{ + asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8)); +} + +static fastcall void native_load_gdt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lgdt %0"::"m" (*dtr)); +} + +static fastcall void native_load_idt(const struct Xgt_desc_struct *dtr) +{ + asm volatile("lidt %0"::"m" (*dtr)); +} + +static fastcall void native_store_gdt(struct Xgt_desc_struct *dtr) +{ + asm ("sgdt %0":"=m" (*dtr)); +} + +static fastcall void native_store_idt(struct Xgt_desc_struct *dtr) +{ + asm ("sidt %0":"=m" (*dtr)); +} + +static fastcall unsigned long native_store_tr(void) +{ + unsigned long tr; + asm ("str %0":"=r" (tr)); + return tr; +} + +static fastcall void native_load_tls(struct thread_struct *t, unsigned int cpu) +{ +#define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i] + C(0); C(1); C(2); +#undef C +} + +static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high) +{ + u32 *lp = (u32 *)((char *)dt + entry*8); + lp[0] = entry_low; + lp[1] = entry_high; +} + +static fastcall void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static fastcall void native_write_gdt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static fastcall void native_write_idt_entry(void *dt, int entrynum, u32 low, u32 high) +{ + native_write_dt_entry(dt, entrynum, low, high); +} + +static fastcall void native_load_esp0(struct tss_struct *tss, + struct thread_struct *thread) +{ + tss->esp0 = thread->esp0; + + /* This can only happen when SEP is enabled, no need to test "SEP"arately */ + if (unlikely(tss->ss1 != thread->sysenter_cs)) { + tss->ss1 = thread->sysenter_cs; + wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); + } +} + +static fastcall void native_io_delay(void) +{ + asm volatile("outb %al,$0x80"); +} + +/* These are in entry.S */ +extern fastcall void native_iret(void); +extern fastcall void native_irq_enable_sysexit(void); + +static int __init print_banner(void) +{ + paravirt_ops.banner(); + return 0; +} +core_initcall(print_banner); + +struct paravirt_ops paravirt_ops = { + .name = "bare hardware", + .paravirt_enabled = 0, + .kernel_rpl = 0, + + .banner = default_banner, + .arch_setup = native_nop, + .memory_setup = machine_specific_memory_setup, + .get_wallclock = native_get_wallclock, + .set_wallclock = native_set_wallclock, + .time_init = time_init_hook, + .init_IRQ = native_init_IRQ, + + .cpuid = native_cpuid, + .get_debugreg = native_get_debugreg, + .set_debugreg = native_set_debugreg, + .clts = native_clts, + .read_cr0 = native_read_cr0, + .write_cr0 = native_write_cr0, + .read_cr2 = native_read_cr2, + .write_cr2 = native_write_cr2, + .read_cr3 = native_read_cr3, + .write_cr3 = native_write_cr3, + .read_cr4 = native_read_cr4, + .read_cr4_safe = native_read_cr4_safe, + .write_cr4 = native_write_cr4, + .save_fl = native_save_fl, + .restore_fl = native_restore_fl, + .irq_disable = native_irq_disable, + .irq_enable = native_irq_enable, + .safe_halt = native_safe_halt, + .halt = native_halt, + .wbinvd = native_wbinvd, + .read_msr = native_read_msr, + .write_msr = native_write_msr, + .read_tsc = native_read_tsc, + .read_pmc = native_read_pmc, + .load_tr_desc = native_load_tr_desc, + .set_ldt = native_set_ldt, + .load_gdt = native_load_gdt, + .load_idt = native_load_idt, + .store_gdt = native_store_gdt, + .store_idt = native_store_idt, + .store_tr = native_store_tr, + .load_tls = native_load_tls, + .write_ldt_entry = native_write_ldt_entry, + .write_gdt_entry = native_write_gdt_entry, + .write_idt_entry = native_write_idt_entry, + .load_esp0 = native_load_esp0, + + .set_iopl_mask = native_set_iopl_mask, + .io_delay = native_io_delay, + .const_udelay = __const_udelay, + + .irq_enable_sysexit = native_irq_enable_sysexit, + .iret = native_iret, +}; +EXPORT_SYMBOL(paravirt_ops); diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index e5bb87aa5a4..695d53fd14d 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -495,6 +495,12 @@ static void set_mca_bus(int x) static void set_mca_bus(int x) { } #endif +/* Overridden in paravirt.c if CONFIG_PARAVIRT */ +char * __attribute__((weak)) memory_setup(void) +{ + return machine_specific_memory_setup(); +} + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -547,7 +553,7 @@ void __init setup_arch(char **cmdline_p) efi_init(); else { printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - print_memory_map(machine_specific_memory_setup()); + print_memory_map(memory_setup()); } copy_edd(); diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 095636620fa..cd7de9c9654 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -33,6 +33,11 @@ * Dave Jones : Report invalid combinations of Athlon CPUs. * Rusty Russell : Hacked into shape for new "hotplug" boot process. */ + +/* SMP boot always wants to use real time delay to allow sufficient time for + * the APs to come online */ +#define USE_REAL_TIME_DELAY + #include #include #include diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index 78af572fd17..c505b16c099 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -56,6 +56,7 @@ #include #include #include +#include #include "mach_time.h" @@ -116,10 +117,7 @@ static int set_rtc_mmss(unsigned long nowtime) /* gets recalled with irq locally disabled */ /* XXX - does irqsave resolve this? -johnstul */ spin_lock_irqsave(&rtc_lock, flags); - if (efi_enabled) - retval = efi_set_rtc_mmss(nowtime); - else - retval = mach_set_rtc_mmss(nowtime); + retval = set_wallclock(nowtime); spin_unlock_irqrestore(&rtc_lock, flags); return retval; @@ -223,10 +221,7 @@ unsigned long get_cmos_time(void) spin_lock_irqsave(&rtc_lock, flags); - if (efi_enabled) - retval = efi_get_time(); - else - retval = mach_get_cmos_time(); + retval = get_wallclock(); spin_unlock_irqrestore(&rtc_lock, flags); @@ -370,7 +365,7 @@ static void __init hpet_time_init(void) printk("Using HPET for base-timer\n"); } - time_init_hook(); + do_time_init(); } #endif @@ -392,5 +387,5 @@ void __init time_init(void) do_settimeofday(&ts); - time_init_hook(); + do_time_init(); } diff --git a/arch/i386/power/cpu.c b/arch/i386/power/cpu.c index 5a1abeff033..2c15500f871 100644 --- a/arch/i386/power/cpu.c +++ b/arch/i386/power/cpu.c @@ -26,8 +26,8 @@ void __save_processor_state(struct saved_context *ctxt) /* * descriptor tables */ - store_gdt(&ctxt->gdt_limit); - store_idt(&ctxt->idt_limit); + store_gdt(&ctxt->gdt); + store_idt(&ctxt->idt); store_tr(ctxt->tr); /* @@ -99,8 +99,8 @@ void __restore_processor_state(struct saved_context *ctxt) * now restore the descriptor tables to their proper values * ltr is done i fix_processor_context(). */ - load_gdt(&ctxt->gdt_limit); - load_idt(&ctxt->idt_limit); + load_gdt(&ctxt->gdt); + load_idt(&ctxt->idt); /* * segment registers -- cgit v1.2.3 From 139ec7c416248b9ea227d21839235344edfee1e0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Patch inline replacements for paravirt intercepts It turns out that the most called ops, by several orders of magnitude, are the interrupt manipulation ops. These are obvious candidates for patching, so mark them up and create infrastructure for it. The method used is that the ops structure has a patch function, which is called for each place which needs to be patched: this returns a number of instructions (the rest are NOP-padded). Usually we can spare a register (%eax) for the binary patched code to use, but in a couple of critical places in entry.S we can't: we make the clobbers explicit at the call site, and manually clobber the allowed registers in debug mode as an extra check. And: Don't abuse CONFIG_DEBUG_KERNEL, add CONFIG_DEBUG_PARAVIRT. And: AK: Fix warnings in x86-64 alternative.c build And: AK: Fix compilation with defconfig And: ^From: Andrew Morton Some binutlises still like to emit references to __stop_parainstructions and __start_parainstructions. And: AK: Fix warnings about unused variables when PARAVIRT is disabled. Signed-off-by: Rusty Russell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Chris Wright Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/Kconfig.debug | 10 +++++++ arch/i386/kernel/alternative.c | 63 ++++++++++++++++++++++++++++++++++-------- arch/i386/kernel/entry.S | 39 +++++++++++++++++--------- arch/i386/kernel/module.c | 11 +++++++- arch/i386/kernel/paravirt.c | 44 +++++++++++++++++++++++++++++ arch/i386/kernel/vmlinux.lds.S | 6 ++++ 6 files changed, 148 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index b31c0802e1c..f68cc6f215f 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug @@ -85,4 +85,14 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. +config DEBUG_PARAVIRT + bool "Enable some paravirtualization debugging" + default y + depends on PARAVIRT && DEBUG_KERNEL + help + Currently deliberately clobbers regs which are allowed to be + clobbered in inlined paravirt hooks, even in native mode. + If turning this off solves a problem, then DISABLE_INTERRUPTS() or + ENABLE_INTERRUPTS() is lying about what registers can be clobbered. + endmenu diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 535f9794fba..9eca21b49f6 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -124,6 +124,20 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ +static void nop_out(void *insns, unsigned int len) +{ + unsigned char **noptable = find_nop_table(); + + while (len > 0) { + unsigned int noplen = len; + if (noplen > ASM_NOP_MAX) + noplen = ASM_NOP_MAX; + memcpy(insns, noptable[noplen], noplen); + insns += noplen; + len -= noplen; + } +} + extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; extern u8 *__smp_locks[], *__smp_locks_end[]; @@ -138,10 +152,9 @@ extern u8 __smp_alt_begin[], __smp_alt_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { - unsigned char **noptable = find_nop_table(); struct alt_instr *a; u8 *instr; - int diff, i, k; + int diff; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { @@ -159,13 +172,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) #endif memcpy(instr, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); - } + nop_out(instr + a->replacementlen, diff); } } @@ -209,7 +216,6 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { - unsigned char **noptable = find_nop_table(); u8 **ptr; for (ptr = start; ptr < end; ptr++) { @@ -217,7 +223,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end continue; if (*ptr > text_end) continue; - **ptr = noptable[1][0]; + nop_out(*ptr, 1); }; } @@ -343,6 +349,40 @@ void alternatives_smp_switch(int smp) #endif +#ifdef CONFIG_PARAVIRT +void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +{ + struct paravirt_patch *p; + + for (p = start; p < end; p++) { + unsigned int used; + + used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, + p->len); +#ifdef CONFIG_DEBUG_PARAVIRT + { + int i; + /* Deliberately clobber regs using "not %reg" to find bugs. */ + for (i = 0; i < 3; i++) { + if (p->len - used >= 2 && (p->clobbers & (1 << i))) { + memcpy(p->instr + used, "\xf7\xd0", 2); + p->instr[used+1] |= i; + used += 2; + } + } + } +#endif + /* Pad the rest with nops */ + nop_out(p->instr + used, p->len - used); + } + + /* Sync to be conservative, in case we patched following instructions */ + sync_core(); +} +extern struct paravirt_patch __start_parainstructions[], + __stop_parainstructions[]; +#endif /* CONFIG_PARAVIRT */ + void __init alternative_instructions(void) { unsigned long flags; @@ -390,5 +430,6 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif + apply_paravirt(__start_parainstructions, __stop_parainstructions); local_irq_restore(flags); } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index d274612e05c..de34b7fed3c 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -53,6 +53,19 @@ #include #include "irq_vectors.h" +/* + * We use macros for low-level operations which need to be overridden + * for paravirtualization. The following will never clobber any registers: + * INTERRUPT_RETURN (aka. "iret") + * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") + * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). + * + * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must + * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). + * Allowing a register to be clobbered can shrink the paravirt replacement + * enough to patch inline, increasing performance. + */ + #define nr_syscalls ((syscall_table_size)/4) CF_MASK = 0x00000001 @@ -63,9 +76,9 @@ NT_MASK = 0x00004000 VM_MASK = 0x00020000 #ifdef CONFIG_PREEMPT -#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF +#define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF #else -#define preempt_stop +#define preempt_stop(clobbers) #define resume_kernel restore_nocheck #endif @@ -226,7 +239,7 @@ ENTRY(ret_from_fork) ALIGN RING0_PTREGS_FRAME ret_from_exception: - preempt_stop + preempt_stop(CLBR_ANY) ret_from_intr: GET_THREAD_INFO(%ebp) check_userspace: @@ -237,7 +250,7 @@ check_userspace: jb resume_kernel # not returning to v8086 or userspace ENTRY(resume_userspace) - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -248,7 +261,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_ANY) cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: @@ -277,7 +290,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - ENABLE_INTERRUPTS + ENABLE_INTERRUPTS(CLBR_NONE) pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/ @@ -322,7 +335,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx @@ -364,7 +377,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) # store the return value syscall_exit: - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -393,7 +406,7 @@ restore_nocheck_notrace: .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - ENABLE_INTERRUPTS + ENABLE_INTERRUPTS(CLBR_NONE) pushl $0 # no error code pushl $do_iret_error jmp error_code @@ -436,7 +449,7 @@ ldt_ss: CFI_ADJUST_CFA_OFFSET 4 pushl %eax CFI_ADJUST_CFA_OFFSET 4 - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_EAX) TRACE_IRQS_OFF lss (%esp), %esp CFI_ADJUST_CFA_OFFSET -8 @@ -451,7 +464,7 @@ work_pending: jz work_notifysig work_resched: call schedule - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -509,7 +522,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - ENABLE_INTERRUPTS # could let do_syscall_trace() call + ENABLE_INTERRUPTS(CLBR_ANY) # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -693,7 +706,7 @@ ENTRY(device_not_available) GET_CR0_INTO_EAX testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate - preempt_stop + preempt_stop(CLBR_ANY) call math_state_restore jmp ret_from_exception device_not_available_emulate: diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 470cf97e7cd..d7d9c8b23f7 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -108,7 +108,8 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; + const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, + *para = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -118,6 +119,8 @@ int module_finalize(const Elf_Ehdr *hdr, alt = s; if (!strcmp(".smp_locks", secstrings + s->sh_name)) locks= s; + if (!strcmp(".parainstructions", secstrings + s->sh_name)) + para = s; } if (alt) { @@ -132,6 +135,12 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } + + if (para) { + void *pseg = (void *)para->sh_addr; + apply_paravirt(pseg, pseg + para->sh_size); + } + return 0; } diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 478192cd4b9..d4646042644 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -45,6 +45,49 @@ char *memory_setup(void) return paravirt_ops.memory_setup(); } +/* Simple instruction patching code. */ +#define DEF_NATIVE(name, code) \ + extern const char start_##name[], end_##name[]; \ + asm("start_" #name ": " code "; end_" #name ":") +DEF_NATIVE(cli, "cli"); +DEF_NATIVE(sti, "sti"); +DEF_NATIVE(popf, "push %eax; popf"); +DEF_NATIVE(pushf, "pushf; pop %eax"); +DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli"); +DEF_NATIVE(iret, "iret"); +DEF_NATIVE(sti_sysexit, "sti; sysexit"); + +static const struct native_insns +{ + const char *start, *end; +} native_insns[] = { + [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli }, + [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti }, + [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf }, + [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf }, + [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli }, + [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret }, + [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit }, +}; + +static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) +{ + unsigned int insn_len; + + /* Don't touch it if we don't have a replacement */ + if (type >= ARRAY_SIZE(native_insns) || !native_insns[type].start) + return len; + + insn_len = native_insns[type].end - native_insns[type].start; + + /* Similarly if we can't fit replacement. */ + if (len < insn_len) + return len; + + memcpy(insns, native_insns[type].start, insn_len); + return insn_len; +} + static fastcall unsigned long native_get_debugreg(int regno) { unsigned long val = 0; /* Damn you, gcc! */ @@ -349,6 +392,7 @@ struct paravirt_ops paravirt_ops = { .paravirt_enabled = 0, .kernel_rpl = 0, + .patch = native_patch, .banner = default_banner, .arch_setup = native_nop, .memory_setup = machine_specific_memory_setup, diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 6860f20aa57..5c69cf0e594 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -165,6 +165,12 @@ SECTIONS .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } + . = ALIGN(4); + __start_parainstructions = .; + .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { + *(.parainstructions) + } + __stop_parainstructions = .; /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } -- cgit v1.2.3 From d7cd56111f30259e1b532a12e06f59f8e0a20355 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] i386: cpu_detect extraction Both lhype and Xen want to call the core of the x86 cpu detect code before calling start_kernel. (extracted from larger patch) AK: folded in start_kernel header patch Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Jeremy Fitzhardinge Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index cda41aef79a..68bcb687019 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -236,29 +236,14 @@ static int __cpuinit have_cpuid_p(void) return flag_is_changeable_p(X86_EFLAGS_ID); } -/* Do minimum CPU detection early. - Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. - The others are not touched to avoid unwanted side effects. - - WARNING: this function is only called on the BP. Don't add code here - that is supposed to run on all CPUs. */ -static void __init early_cpu_detect(void) +void __init cpu_detect(struct cpuinfo_x86 *c) { - struct cpuinfo_x86 *c = &boot_cpu_data; - - c->x86_cache_alignment = 32; - - if (!have_cpuid_p()) - return; - /* Get vendor name */ cpuid(0x00000000, &c->cpuid_level, (int *)&c->x86_vendor_id[0], (int *)&c->x86_vendor_id[8], (int *)&c->x86_vendor_id[4]); - get_cpu_vendor(c, 1); - c->x86 = 4; if (c->cpuid_level >= 0x00000001) { u32 junk, tfms, cap0, misc; @@ -275,6 +260,26 @@ static void __init early_cpu_detect(void) } } +/* Do minimum CPU detection early. + Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment. + The others are not touched to avoid unwanted side effects. + + WARNING: this function is only called on the BP. Don't add code here + that is supposed to run on all CPUs. */ +static void __init early_cpu_detect(void) +{ + struct cpuinfo_x86 *c = &boot_cpu_data; + + c->x86_cache_alignment = 32; + + if (!have_cpuid_p()) + return; + + cpu_detect(c); + + get_cpu_vendor(c, 1); +} + static void __cpuinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; -- cgit v1.2.3 From c9ccf30d77f04064fe5436027ab9d2230c7cdd94 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Add startup infrastructure for paravirtualization 1) Each hypervisor writes a probe function to detect whether we are running under that hypervisor. paravirt_probe() registers this function. 2) If vmlinux is booted with ring != 0, we call all the probe functions (with registers except %esp intact) in link order: the winner will not return. Signed-off-by: Rusty Russell Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Jeremy Fitzhardinge Cc: Zachary Amsden Signed-off-by: Andrew Morton --- arch/i386/kernel/Makefile | 2 ++ arch/i386/kernel/head.S | 33 +++++++++++++++++++++++++++++++++ arch/i386/kernel/paravirt.c | 4 ++++ arch/i386/kernel/vmlinux.lds.S | 6 ++++++ 4 files changed, 45 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 40661213604..1e8988e558c 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -39,6 +39,8 @@ obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_HPET_TIMER) += hpet.o obj-$(CONFIG_K8_NB) += k8.o + +# Make sure this is linked after any other paravirt_ops structs: see head.S obj-$(CONFIG_PARAVIRT) += paravirt.o EXTRA_AFLAGS := -traditional diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 5b14e95ac8b..edef5084ce1 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -55,6 +55,12 @@ */ ENTRY(startup_32) +#ifdef CONFIG_PARAVIRT + movl %cs, %eax + testl $0x3, %eax + jnz startup_paravirt +#endif + /* * Set segments to known values. */ @@ -486,6 +492,33 @@ ignore_int: #endif iret +#ifdef CONFIG_PARAVIRT +startup_paravirt: + cld + movl $(init_thread_union+THREAD_SIZE),%esp + + /* We take pains to preserve all the regs. */ + pushl %edx + pushl %ecx + pushl %eax + + /* paravirt.o is last in link, and that probe fn never returns */ + pushl $__start_paravirtprobe +1: + movl 0(%esp), %eax + pushl (%eax) + movl 8(%esp), %eax + call *(%esp) + popl %eax + + movl 4(%esp), %eax + movl 8(%esp), %ecx + movl 12(%esp), %edx + + addl $4, (%esp) + jmp 1b +#endif + /* * Real beginning of normal "text" segment */ diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index d4646042644..5a9bd3250a1 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -387,6 +388,9 @@ static int __init print_banner(void) } core_initcall(print_banner); +/* We simply declare start_kernel to be the paravirt probe of last resort. */ +paravirt_probe(start_kernel); + struct paravirt_ops paravirt_ops = { .name = "bare hardware", .paravirt_enabled = 0, diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 5c69cf0e594..877dc5cfe3a 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -65,6 +65,12 @@ SECTIONS CONSTRUCTORS } :data + __start_paravirtprobe = .; + .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) { + *(.paravirtprobe) + } + __stop_paravirtprobe = .; + . = ALIGN(4096); .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { __nosave_begin = .; -- cgit v1.2.3 From 4f205fd45a5c192907188d6f8f6d7e66db859248 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Allow selected bug checks to be Allow selected bug checks to be skipped by paravirt kernels. The two most important are the F00F workaround (which is either done by the hypervisor, or not required), and the 'hlt' instruction check, which can break under some hypervisors. Signed-off-by: Zachary Amsden Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 798c2f617e8..3ae795e9056 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -107,7 +107,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) * Note that the workaround only should be initialized once... */ c->f00f_bug = 0; - if ( c->x86 == 5 ) { + if (!paravirt_enabled() && c->x86 == 5) { static int f00f_workaround_enabled = 0; c->f00f_bug = 1; -- cgit v1.2.3 From 3bbf54725467d604698721384d858b5983b87e8f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Disable vdso by default when CONFIG_PARAVIRT is enabled They don't work together and this way even glibc still works. Signed-off-by: Andi Kleen --- arch/i386/kernel/sysenter.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 713ba39d32c..92849c7def5 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -27,7 +27,11 @@ * Should the kernel map a VDSO page into processes and pass its * address down to glibc upon exec()? */ +#ifdef CONFIG_PARAVIRT +unsigned int __read_mostly vdso_enabled = 0; +#else unsigned int __read_mostly vdso_enabled = 1; +#endif EXPORT_SYMBOL_GPL(vdso_enabled); -- cgit v1.2.3 From 6020c8f315709a508b027ef6749e85b125190947 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Allow disable power management under hypervisor Two legacy power management modes are much easier to just explicitly disable when running in paravirtualized mode - neither APM nor PnP is still relevant. The status of ACPI is still debatable, and noacpi is still a common enough boot parameter that it is not necessary to explicitly disable ACPI. Signed-off-by: Zachary Amsden Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/apm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index a60358fe9a4..a97847da9ed 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -231,6 +231,7 @@ #include #include #include +#include #include "io_ports.h" @@ -2235,7 +2236,7 @@ static int __init apm_init(void) dmi_check_system(apm_dmi_table); - if (apm_info.bios.version == 0) { + if (apm_info.bios.version == 0 || paravirt_enabled()) { printk(KERN_INFO "apm: BIOS not found.\n"); return -ENODEV; } -- cgit v1.2.3 From 13623d79309dd82e1964458fa017979d16f33fa8 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Add APIC accessors to paravirt-ops. Add APIC accessors to paravirt-ops. Unfortunately, we need two write functions, as some older broken hardware requires workarounds for Pentium APIC errata - this is the purpose of apic_write_atomic. AK: replaced __inline with inline Signed-off-by: Zachary Amsden Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/paravirt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 5a9bd3250a1..fe82eb3adf4 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include /* nop stub */ static void native_nop(void) @@ -446,6 +448,12 @@ struct paravirt_ops paravirt_ops = { .io_delay = native_io_delay, .const_udelay = __const_udelay, +#ifdef CONFIG_X86_LOCAL_APIC + .apic_write = native_apic_write, + .apic_write_atomic = native_apic_write_atomic, + .apic_read = native_apic_read, +#endif + .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, }; -- cgit v1.2.3 From da181a8b3916aa7f2e3c5775d2bd2fe3454cf82d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Add MMU virtualization to paravirt_ops Add the three bare TLB accessor functions to paravirt-ops. Most amusingly, flush_tlb is redefined on SMP, so I can't call the paravirt op flush_tlb. Instead, I chose to indicate the actual flush type, kernel (global) vs. user (non-global). Global in this sense means using the global bit in the page table entry, which makes TLB entries persistent across CR3 reloads, not global as in the SMP sense of invoking remote shootdowns, so the term is confusingly overloaded. AK: folded in fix from Zach for PAE compilation Signed-off-by: Zachary Amsden Signed-off-by: Chris Wright Signed-off-by: Andi Kleen Cc: Rusty Russell Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/paravirt.c | 109 ++++++++++++++++++++++++++++++++++++++++++++ arch/i386/mm/boot_ioremap.c | 1 + 2 files changed, 110 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index fe82eb3adf4..3dceab5828f 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -31,6 +31,7 @@ #include #include #include +#include /* nop stub */ static void native_nop(void) @@ -379,6 +380,97 @@ static fastcall void native_io_delay(void) asm volatile("outb %al,$0x80"); } +static fastcall void native_flush_tlb(void) +{ + __native_flush_tlb(); +} + +/* + * Global pages have to be flushed a bit differently. Not a real + * performance problem because this does not happen often. + */ +static fastcall void native_flush_tlb_global(void) +{ + __native_flush_tlb_global(); +} + +static fastcall void native_flush_tlb_single(u32 addr) +{ + __native_flush_tlb_single(addr); +} + +#ifndef CONFIG_X86_PAE +static fastcall void native_set_pte(pte_t *ptep, pte_t pteval) +{ + *ptep = pteval; +} + +static fastcall void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval) +{ + *ptep = pteval; +} + +static fastcall void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) +{ + *pmdp = pmdval; +} + +#else /* CONFIG_X86_PAE */ + +static fastcall void native_set_pte(pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static fastcall void native_set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pte) +{ + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static fastcall void native_set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = pte.pte_high; + smp_wmb(); + ptep->pte_low = pte.pte_low; +} + +static fastcall void native_set_pte_atomic(pte_t *ptep, pte_t pteval) +{ + set_64bit((unsigned long long *)ptep,pte_val(pteval)); +} + +static fastcall void native_set_pmd(pmd_t *pmdp, pmd_t pmdval) +{ + set_64bit((unsigned long long *)pmdp,pmd_val(pmdval)); +} + +static fastcall void native_set_pud(pud_t *pudp, pud_t pudval) +{ + *pudp = pudval; +} + +static fastcall void native_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + ptep->pte_low = 0; + smp_wmb(); + ptep->pte_high = 0; +} + +static fastcall void native_pmd_clear(pmd_t *pmd) +{ + u32 *tmp = (u32 *)pmd; + *tmp = 0; + smp_wmb(); + *(tmp + 1) = 0; +} +#endif /* CONFIG_X86_PAE */ + /* These are in entry.S */ extern fastcall void native_iret(void); extern fastcall void native_irq_enable_sysexit(void); @@ -454,6 +546,23 @@ struct paravirt_ops paravirt_ops = { .apic_read = native_apic_read, #endif + .flush_tlb_user = native_flush_tlb, + .flush_tlb_kernel = native_flush_tlb_global, + .flush_tlb_single = native_flush_tlb_single, + + .set_pte = native_set_pte, + .set_pte_at = native_set_pte_at, + .set_pmd = native_set_pmd, + .pte_update = (void *)native_nop, + .pte_update_defer = (void *)native_nop, +#ifdef CONFIG_X86_PAE + .set_pte_atomic = native_set_pte_atomic, + .set_pte_present = native_set_pte_present, + .set_pud = native_set_pud, + .pte_clear = native_pte_clear, + .pmd_clear = native_pmd_clear, +#endif + .irq_enable_sysexit = native_irq_enable_sysexit, .iret = native_iret, }; diff --git a/arch/i386/mm/boot_ioremap.c b/arch/i386/mm/boot_ioremap.c index 4de11f508c3..4de95a17a7d 100644 --- a/arch/i386/mm/boot_ioremap.c +++ b/arch/i386/mm/boot_ioremap.c @@ -16,6 +16,7 @@ */ #undef CONFIG_X86_PAE +#undef CONFIG_PARAVIRT #include #include #include -- cgit v1.2.3 From bd472c794bbf6771c3fc1c58f188bc16c393d2fe Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Be careful about touching BIOS address space BIOS ROM areas may not be mapped into the guest address space, so be careful when touching those addresses to make sure they appear to be mapped. [akpm@osdl.org: fix unused var warning] AK: Changed __get_user to probe_kernel_address Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Rusty Russell Signed-off-by: Andi Kleen Cc: Jeremy Fitzhardinge Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/e820.c | 10 +++++++++- arch/i386/pci/pcbios.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index b755255f272..b704790f796 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -155,7 +156,14 @@ static struct resource standard_io_resources[] = { { .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) +static int romsignature(const unsigned char *x) +{ + unsigned short sig; + int ret = 0; + if (probe_kernel_address((const unsigned short *)x, sig) == 0) + ret = (sig == 0xaa55); + return ret; +} static int __init romchecksum(unsigned char *rom, unsigned long length) { diff --git a/arch/i386/pci/pcbios.c b/arch/i386/pci/pcbios.c index ed1512a175a..5f5193401be 100644 --- a/arch/i386/pci/pcbios.c +++ b/arch/i386/pci/pcbios.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "pci.h" #include "pci-functions.h" @@ -314,6 +315,10 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) for (check = (union bios32 *) __va(0xe0000); check <= (union bios32 *) __va(0xffff0); ++check) { + long sig; + if (probe_kernel_address(&check->fields.signature, sig)) + continue; + if (check->fields.signature != BIOS32_SIGNATURE) continue; length = check->fields.length * 16; @@ -331,11 +336,13 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) } DBG("PCI: BIOS32 Service Directory structure at 0x%p\n", check); if (check->fields.entry >= 0x100000) { - printk("PCI: BIOS32 entry (0x%p) in high memory, cannot use.\n", check); + printk("PCI: BIOS32 entry (0x%p) in high memory, " + "cannot use.\n", check); return NULL; } else { unsigned long bios32_entry = check->fields.entry; - DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", bios32_entry); + DBG("PCI: BIOS32 Service Directory entry at 0x%lx\n", + bios32_entry); bios32_indirect.address = bios32_entry + PAGE_OFFSET; if (check_pcibios()) return &pci_bios_access; -- cgit v1.2.3 From 8542b200cbe5609edd7aae0c304c091a1c290452 Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] paravirt: Add option to allow skipping the timer check Add a way to disable the timer IRQ routing check via a boot option. The VMI timer code uses this to avoid triggering the pester Mingo code, which probes for some very unusual and broken motherboard routings. It fires 100% of the time when using a paravirtual delay mechanism instead of using a realtime delay, since there is no elapsed real time, and the 4 timer IRQs have not yet been delivered. In addition, it is entirely possible, though improbable, that this bug could surface on real hardware which picks a particularly bad time to enter SMM mode, causing a long latency during one of the timer IRQs. While here, make check_timer be __init. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen [chrisw: use no_timer_check to bring inline with x86_64 as per Andi's request] Signed-off-by: Chris Wright Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/io_apic.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e33b7a84529..993150f206e 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1932,6 +1932,15 @@ static void __init setup_ioapic_ids_from_mpc(void) static void __init setup_ioapic_ids_from_mpc(void) { } #endif +static int no_timer_check __initdata; + +static int __init notimercheck(char *s) +{ + no_timer_check = 1; + return 1; +} +__setup("no_timer_check", notimercheck); + /* * There is a nasty bug in some older SMP boards, their mptable lies * about the timer IRQ. We do the following to work around the situation: @@ -1940,10 +1949,13 @@ static void __init setup_ioapic_ids_from_mpc(void) { } * - if this function detects that timer IRQs are defunct, then we fall * back to ISA timer IRQs */ -static int __init timer_irq_works(void) +int __init timer_irq_works(void) { unsigned long t1 = jiffies; + if (no_timer_check) + return 1; + local_irq_enable(); /* Let ten ticks pass... */ mdelay((10 * 1000) / HZ); @@ -2214,7 +2226,7 @@ int timer_uses_ioapic_pin_0; * is so screwy. Thanks to Brian Perkins for testing/hacking this beast * fanatically on his truly buggy board. */ -static inline void check_timer(void) +static inline void __init check_timer(void) { int apic1, pin1, apic2, pin2; int vector; -- cgit v1.2.3 From 713819989aa4dd141a37074dbc369e7c620bc619 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: Add option to compile for Core2 Add an option to compile for Intel's Core 2 The Kconfig help is a mouthful due to the inventiveness of Intel's product naming department. Mainly for the 64bit cache line sizes because gcc doesn't support optimizing for core2 yet. However it will and then the kernel should be ready by passing the right option Also fix the old MPSC help text to confirm better to reality. Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 27 +++++++++++++++++++++------ arch/x86_64/Makefile | 4 ++++ 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 5cb509dbffe..6eece27d579 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -122,7 +122,7 @@ endchoice choice prompt "Processor family" - default MK8 + default GENERIC_CPU config MK8 bool "AMD-Opteron/Athlon64" @@ -130,16 +130,31 @@ config MK8 Optimize for AMD Opteron/Athlon64/Hammer/K8 CPUs. config MPSC - bool "Intel EM64T" + bool "Intel P4 / older Netburst based Xeon" help - Optimize for Intel Pentium 4 and Xeon CPUs with Intel - Extended Memory 64 Technology(EM64T). For details see + Optimize for Intel Pentium 4 and older Nocona/Dempsey Xeon CPUs + with Intel Extended Memory 64 Technology(EM64T). For details see . + Note the the latest Xeons (Xeon 51xx and 53xx) are not based on the + Netburst core and shouldn't use this option. You can distingush them + using the cpu family field + in /proc/cpuinfo. Family 15 is a older Xeon, Family 6 a newer one + (this rule only applies to system that support EM64T) + +config MCORE2 + bool "Intel Core2 / newer Xeon" + help + Optimize for Intel Core2 and newer Xeons (51xx) + You can distingush the newer Xeons from the older ones using + the cpu family field in /proc/cpuinfo. 15 is a older Xeon + (use CONFIG_MPSC then), 6 is a newer one. This rule only + applies to CPUs that support EM64T. config GENERIC_CPU bool "Generic-x86-64" help Generic x86-64 CPU. + Run equally well on all x86-64 CPUs. endchoice @@ -149,12 +164,12 @@ endchoice config X86_L1_CACHE_BYTES int default "128" if GENERIC_CPU || MPSC - default "64" if MK8 + default "64" if MK8 || MCORE2 config X86_L1_CACHE_SHIFT int default "7" if GENERIC_CPU || MPSC - default "6" if MK8 + default "6" if MK8 || MCORE2 config X86_INTERNODE_CACHE_BYTES int diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 6e38d4daeed..b471b8550d0 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -30,6 +30,10 @@ cflags-y := cflags-kernel-y := cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8) cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona) +# gcc doesn't support -march=core2 yet as of gcc 4.3, but I hope it +# will eventually. Use -mtune=generic as fallback +cflags-$(CONFIG_MCORE2) += \ + $(call cc-option,-march=core2,$(call cc-option,-mtune=generic)) cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic) cflags-y += -m64 -- cgit v1.2.3 From c55d92d141b9c40c67db249de91f5c224eb49859 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] i386: Add support for compilation for Core2 gcc doesn't support -mtune=core2 yet, but will be soon. Use -mtune=generic or -mtune=i686 as fallback TBD need benchmarking for INTEL_USERCOPY etc. So far I used the same defaults as MPENTIUMM Signed-off-by: Andi Kleen --- arch/i386/Kconfig.cpu | 19 +++++++++++++------ arch/i386/Makefile.cpu | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index fc4f2abccf0..821fd269ca5 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -103,8 +103,15 @@ config MPENTIUMM Select this for Intel Pentium M (not Pentium-4 M) notebook chips. +config MCORE2 + bool "Core 2/newer Xeon" + help + Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and 53xx) + CPUs. You can distingush newer from older Xeons by the CPU family + in /proc/cpuinfo. Newer ones have 6. + config MPENTIUM4 - bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/Xeon" + bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon" help Select this for Intel Pentium 4 chips. This includes the Pentium 4, P4-based Celeron and Xeon, and Pentium-4 M @@ -229,7 +236,7 @@ config X86_L1_CACHE_SHIFT default "7" if MPENTIUM4 || X86_GENERIC default "4" if X86_ELAN || M486 || M386 || MGEODEGX1 default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX - default "6" if MK7 || MK8 || MPENTIUMM + default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 config RWSEM_GENERIC_SPINLOCK bool @@ -287,17 +294,17 @@ config X86_ALIGNMENT_16 config X86_GOOD_APIC bool - depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON + depends on MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || MK8 || MEFFICEON || MCORE2 default y config X86_INTEL_USERCOPY bool - depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON + depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2 default y config X86_USE_PPRO_CHECKSUM bool - depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX + depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MEFFICEON || MGEODE_LX || MCORE2 default y config X86_USE_3DNOW @@ -312,5 +319,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX || MCORE2) && !X86_NUMAQ default y diff --git a/arch/i386/Makefile.cpu b/arch/i386/Makefile.cpu index a11befba26d..a32c031c90d 100644 --- a/arch/i386/Makefile.cpu +++ b/arch/i386/Makefile.cpu @@ -32,6 +32,7 @@ cflags-$(CONFIG_MWINCHIP2) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586) cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) +cflags-$(CONFIG_MCORE2) += -march=i686 $(call cc-option,-mtune=core2,$(call cc-option,-mtune=generic,-mtune=i686)) # AMD Elan support cflags-$(CONFIG_X86_ELAN) += -march=i486 -- cgit v1.2.3 From 103efcd9aac1de4da6a1477f2f3b9fcf35273a18 Mon Sep 17 00:00:00 2001 From: Ernie Petrides Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: fix perms/range of vsyscall vma in /proc/*/maps The final line of /proc//maps on x86_64 for native 64-bit tasks shows an incorrect ending address and incorrect permissions. There is only a single page mapped in this vsyscall region, and it is accessible for both read and execute. The patch below fixes this. (Since 32-bit-compat tasks have a real vma with correct perms/range, no change is necessary for that scenario.) Before the patch, a "cat /proc/self/maps | tail -1" shows this: ffffffffff600000-ffffffffffe00000 ---p 00000000 [...] After the patch, this is the output: ffffffffff600000-ffffffffff601000 r-xp 00000000 [...] Signed-off-by: Ernie Petrides Signed-off-by: Andi Kleen --- arch/x86_64/kernel/vsyscall.c | 1 + arch/x86_64/mm/init.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 92546c1526f..c3de9a09cd9 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -290,6 +290,7 @@ static void __init map_vsyscall(void) extern char __vsyscall_0; unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); + /* Note that VSYSCALL_MAPPED_PAGES must agree with the code below. */ __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4c0c00ef3ca..2968b90ef8a 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -730,14 +730,15 @@ static __init int x8664_sysctl_init(void) __initcall(x8664_sysctl_init); #endif -/* A pseudo VMAs to allow ptrace access for the vsyscall page. This only +/* A pseudo VMA to allow ptrace access for the vsyscall page. This only covers the 64bit vsyscall page now. 32bit has a real VMA now and does not need special handling anymore. */ static struct vm_area_struct gate_vma = { .vm_start = VSYSCALL_START, - .vm_end = VSYSCALL_END, - .vm_page_prot = PAGE_READONLY + .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT), + .vm_page_prot = PAGE_READONLY_EXEC, + .vm_flags = VM_READ | VM_EXEC }; struct vm_area_struct *get_gate_vma(struct task_struct *tsk) -- cgit v1.2.3 From 9a457324229db34d3bcb0b67360130c287289401 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: Rate limit no irq handler messages Signed-off-by: Andi Kleen --- arch/x86_64/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index e46c55856d4..0c06af6c13b 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c @@ -120,7 +120,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) if (likely(irq < NR_IRQS)) generic_handle_irq(irq); - else + else if (printk_ratelimit()) printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n", __func__, smp_processor_id(), vector); -- cgit v1.2.3 From b0bfece40b1988aa8e3d910938691dce7859d82d Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] i386: clear_fixmap() should not use set_pte() While not strictly required with the current code (as the upper half of page table entries generated by __set_fixmap() cannot be non-zero due to the second parameter of this function being 'unsigned long'), the use of set_pte() in __set_fixmap() in the context of clear_fixmap() is still improper with CONFIG_X86_PAE (see the respective comment in include/asm-i386/pgtable-3level.h) and would turn into a bug if that second parameter ever gets changed to a 64-bit type. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/mm/pgtable.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 10126e3f817..65b5c095903 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -95,8 +95,11 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags) return; } pte = pte_offset_kernel(pmd, vaddr); - /* stored as-is, to permit clearing entries */ - set_pte(pte, pfn_pte(pfn, flags)); + if (pgprot_val(flags)) + /* stored as-is, to permit clearing entries */ + set_pte(pte, pfn_pte(pfn, flags)); + else + pte_clear(&init_mm, vaddr, pte); /* * It's enough to flush this one mapping. -- cgit v1.2.3 From c6ea396de6836bdeb2d2433368130642bf0f6e15 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] i386: Don't touch per cpu memory of offline CPUs in touch_nmi_watchdog Just like on x86-64, don't touch foreign CPUs' memory if the watchdog isn't enabled at all. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 171194ccb7b..f5bc7e1be80 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -870,14 +870,16 @@ static unsigned int void touch_nmi_watchdog (void) { - int i; + if (nmi_watchdog > 0) { + unsigned cpu; - /* - * Just reset the alert counters, (other CPUs might be - * spinning on locks we hold): - */ - for_each_possible_cpu(i) - alert_counter[i] = 0; + /* + * Just reset the alert counters, (other CPUs might be + * spinning on locks we hold): + */ + for_each_present_cpu (cpu) + alert_counter[cpu] = 0; + } /* * Tickle the softlockup detector too: -- cgit v1.2.3 From 475850c86b908ae026d5a4be02a1b1e9c408c75a Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] i386: conditionalize inclusion of some MTRR flavors Avoid inclusion of code that's dead for x86-64. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/mtrr/Makefile | 4 +--- arch/i386/kernel/cpu/mtrr/main.c | 6 ++++++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/Makefile b/arch/i386/kernel/cpu/mtrr/Makefile index a25b701ab84..191fc053364 100644 --- a/arch/i386/kernel/cpu/mtrr/Makefile +++ b/arch/i386/kernel/cpu/mtrr/Makefile @@ -1,5 +1,3 @@ obj-y := main.o if.o generic.o state.o -obj-y += amd.o -obj-y += cyrix.o -obj-y += centaur.o +obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 2b8b0b361cc..a4de30b9d3d 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -59,7 +59,11 @@ struct mtrr_ops * mtrr_if = NULL; static void set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type type); +#ifndef CONFIG_X86_64 extern int arr3_protected; +#else +#define arr3_protected 0 +#endif void set_mtrr_ops(struct mtrr_ops * ops) { @@ -544,9 +548,11 @@ extern void centaur_init_mtrr(void); static void __init init_ifs(void) { +#ifndef CONFIG_X86_64 amd_init_mtrr(); cyrix_init_mtrr(); centaur_init_mtrr(); +#endif } /* The suspend/resume methods are only for CPU without MTRR. CPU using generic -- cgit v1.2.3 From 365bff806e9faba000fb4956c7486fbf3a746d96 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] i386: fix MTRR code Until not so long ago, there were system log messages pointing to inconsistent MTRR setup of the video frame buffer caused by the way vesafb and X worked. While vesafb was fixed meanwhile, I believe fixing it there only hides a shortcoming in the MTRR code itself, in that that code is not symmetric with respect to the ordering of attempts to set up two (or more) regions where one contains the other. In the current shape, it permits only setting up sub-regions of pre-exisiting ones. The patch below makes this symmetric. While working on that I noticed a few more inconsistencies in that code, namely - use of 'unsigned int' for sizes in many, but not all places (the patch is converting this to use 'unsigned long' everywhere, which specifically might be necessary for x86-64 once a processor supporting more than 44 physical address bits would become available) - the code to correct inconsistent settings during secondary processor startup tried (if necessary) to correct, among other things, the value in IA32_MTRR_DEF_TYPE, however the newly computed value would never get used (i.e. stored in the respective MSR) - the generic range validation code checked that the end of the to-be-added range would be above 1MB; the value checked should have been the start of the range - when contained regions are detected, previously this was allowed only when the old region was uncacheable; this can be symmetric (i.e. the new region can also be uncacheable) and even further as per Intel's documentation write-trough and write-back for either region is also compatible with the respective opposite in the other Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/mtrr/amd.c | 2 +- arch/i386/kernel/cpu/mtrr/centaur.c | 9 +++-- arch/i386/kernel/cpu/mtrr/cyrix.c | 25 +++++++++--- arch/i386/kernel/cpu/mtrr/generic.c | 78 +++++++++++++++++++++++++++++++------ arch/i386/kernel/cpu/mtrr/if.c | 28 +++++++------ arch/i386/kernel/cpu/mtrr/main.c | 55 +++++++++++++++++++------- arch/i386/kernel/cpu/mtrr/mtrr.h | 25 ++++++------ 7 files changed, 162 insertions(+), 60 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/amd.c b/arch/i386/kernel/cpu/mtrr/amd.c index 1a1e04b6fd0..0949cdbf848 100644 --- a/arch/i386/kernel/cpu/mtrr/amd.c +++ b/arch/i386/kernel/cpu/mtrr/amd.c @@ -7,7 +7,7 @@ static void amd_get_mtrr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) + unsigned long *size, mtrr_type * type) { unsigned long low, high; diff --git a/arch/i386/kernel/cpu/mtrr/centaur.c b/arch/i386/kernel/cpu/mtrr/centaur.c index 33f00ac314e..cb9aa3a7a7a 100644 --- a/arch/i386/kernel/cpu/mtrr/centaur.c +++ b/arch/i386/kernel/cpu/mtrr/centaur.c @@ -17,7 +17,7 @@ static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ */ static int -centaur_get_free_region(unsigned long base, unsigned long size) +centaur_get_free_region(unsigned long base, unsigned long size, int replace_reg) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. The size (in bytes) of the region. @@ -26,10 +26,11 @@ centaur_get_free_region(unsigned long base, unsigned long size) { int i, max; mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; + unsigned long lbase, lsize; max = num_var_ranges; + if (replace_reg >= 0 && replace_reg < max) + return replace_reg; for (i = 0; i < max; ++i) { if (centaur_mcr_reserved & (1 << i)) continue; @@ -49,7 +50,7 @@ mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) static void centaur_get_mcr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) + unsigned long *size, mtrr_type * type) { *base = centaur_mcr[reg].high >> PAGE_SHIFT; *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 9027a987006..0737a596db4 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c @@ -9,7 +9,7 @@ int arr3_protected; static void cyrix_get_arr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) + unsigned long *size, mtrr_type * type) { unsigned long flags; unsigned char arr, ccr3, rcr, shift; @@ -77,7 +77,7 @@ cyrix_get_arr(unsigned int reg, unsigned long *base, } static int -cyrix_get_free_region(unsigned long base, unsigned long size) +cyrix_get_free_region(unsigned long base, unsigned long size, int replace_reg) /* [SUMMARY] Get a free ARR. The starting (base) address of the region. The size (in bytes) of the region. @@ -86,9 +86,24 @@ cyrix_get_free_region(unsigned long base, unsigned long size) { int i; mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; + unsigned long lbase, lsize; + switch (replace_reg) { + case 7: + if (size < 0x40) + break; + case 6: + case 5: + case 4: + return replace_reg; + case 3: + if (arr3_protected) + break; + case 2: + case 1: + case 0: + return replace_reg; + } /* If we are to set up a region >32M then look at ARR7 immediately */ if (size > 0x2000) { cyrix_get_arr(7, &lbase, &lsize, <ype); @@ -214,7 +229,7 @@ static void cyrix_set_arr(unsigned int reg, unsigned long base, typedef struct { unsigned long base; - unsigned int size; + unsigned long size; mtrr_type type; } arr_state_t; diff --git a/arch/i386/kernel/cpu/mtrr/generic.c b/arch/i386/kernel/cpu/mtrr/generic.c index ee8dc675395..f77fc53db65 100644 --- a/arch/i386/kernel/cpu/mtrr/generic.c +++ b/arch/i386/kernel/cpu/mtrr/generic.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -15,12 +16,19 @@ struct mtrr_state { struct mtrr_var_range *var_ranges; mtrr_type fixed_ranges[NUM_FIXED_RANGES]; unsigned char enabled; + unsigned char have_fixed; mtrr_type def_type; }; static unsigned long smp_changes_mask; static struct mtrr_state mtrr_state = {}; +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "mtrr." + +static __initdata int mtrr_show; +module_param_named(show, mtrr_show, bool, 0); + /* Get the MSR pair relating to a var range */ static void __init get_mtrr_var_range(unsigned int index, struct mtrr_var_range *vr) @@ -43,6 +51,14 @@ get_fixed_ranges(mtrr_type * frs) rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i * 2], p[7 + i * 2]); } +static void __init print_fixed(unsigned base, unsigned step, const mtrr_type*types) +{ + unsigned i; + + for (i = 0; i < 8; ++i, ++types, base += step) + printk(KERN_INFO "MTRR %05X-%05X %s\n", base, base + step - 1, mtrr_attrib_to_str(*types)); +} + /* Grab all of the MTRR state for this CPU into *state */ void __init get_mtrr_state(void) { @@ -58,13 +74,49 @@ void __init get_mtrr_state(void) } vrs = mtrr_state.var_ranges; + rdmsr(MTRRcap_MSR, lo, dummy); + mtrr_state.have_fixed = (lo >> 8) & 1; + for (i = 0; i < num_var_ranges; i++) get_mtrr_var_range(i, &vrs[i]); - get_fixed_ranges(mtrr_state.fixed_ranges); + if (mtrr_state.have_fixed) + get_fixed_ranges(mtrr_state.fixed_ranges); rdmsr(MTRRdefType_MSR, lo, dummy); mtrr_state.def_type = (lo & 0xff); mtrr_state.enabled = (lo & 0xc00) >> 10; + + if (mtrr_show) { + int high_width; + + printk(KERN_INFO "MTRR default type: %s\n", mtrr_attrib_to_str(mtrr_state.def_type)); + if (mtrr_state.have_fixed) { + printk(KERN_INFO "MTRR fixed ranges %sabled:\n", + mtrr_state.enabled & 1 ? "en" : "dis"); + print_fixed(0x00000, 0x10000, mtrr_state.fixed_ranges + 0); + for (i = 0; i < 2; ++i) + print_fixed(0x80000 + i * 0x20000, 0x04000, mtrr_state.fixed_ranges + (i + 1) * 8); + for (i = 0; i < 8; ++i) + print_fixed(0xC0000 + i * 0x08000, 0x01000, mtrr_state.fixed_ranges + (i + 3) * 8); + } + printk(KERN_INFO "MTRR variable ranges %sabled:\n", + mtrr_state.enabled & 2 ? "en" : "dis"); + high_width = ((size_or_mask ? ffs(size_or_mask) - 1 : 32) - (32 - PAGE_SHIFT) + 3) / 4; + for (i = 0; i < num_var_ranges; ++i) { + if (mtrr_state.var_ranges[i].mask_lo & (1 << 11)) + printk(KERN_INFO "MTRR %u base %0*X%05X000 mask %0*X%05X000 %s\n", + i, + high_width, + mtrr_state.var_ranges[i].base_hi, + mtrr_state.var_ranges[i].base_lo >> 12, + high_width, + mtrr_state.var_ranges[i].mask_hi, + mtrr_state.var_ranges[i].mask_lo >> 12, + mtrr_attrib_to_str(mtrr_state.var_ranges[i].base_lo & 0xff)); + else + printk(KERN_INFO "MTRR %u disabled\n", i); + } + } } /* Some BIOS's are fucked and don't set all MTRRs the same! */ @@ -95,7 +147,7 @@ void mtrr_wrmsr(unsigned msr, unsigned a, unsigned b) smp_processor_id(), msr, a, b); } -int generic_get_free_region(unsigned long base, unsigned long size) +int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg) /* [SUMMARY] Get a free MTRR. The starting (base) address of the region. The size (in bytes) of the region. @@ -104,10 +156,11 @@ int generic_get_free_region(unsigned long base, unsigned long size) { int i, max; mtrr_type ltype; - unsigned long lbase; - unsigned lsize; + unsigned long lbase, lsize; max = num_var_ranges; + if (replace_reg >= 0 && replace_reg < max) + return replace_reg; for (i = 0; i < max; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); if (lsize == 0) @@ -117,7 +170,7 @@ int generic_get_free_region(unsigned long base, unsigned long size) } static void generic_get_mtrr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) + unsigned long *size, mtrr_type *type) { unsigned int mask_lo, mask_hi, base_lo, base_hi; @@ -202,7 +255,9 @@ static int set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr) return changed; } -static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) +static u32 deftype_lo, deftype_hi; + +static unsigned long set_mtrr_state(void) /* [SUMMARY] Set the MTRR state for this CPU. The MTRR state information to read. Some relevant CPU context. @@ -217,14 +272,14 @@ static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) if (set_mtrr_var_ranges(i, &mtrr_state.var_ranges[i])) change_mask |= MTRR_CHANGE_MASK_VARIABLE; - if (set_fixed_ranges(mtrr_state.fixed_ranges)) + if (mtrr_state.have_fixed && set_fixed_ranges(mtrr_state.fixed_ranges)) change_mask |= MTRR_CHANGE_MASK_FIXED; /* Set_mtrr_restore restores the old value of MTRRdefType, so to set it we fiddle with the saved value */ if ((deftype_lo & 0xff) != mtrr_state.def_type || ((deftype_lo & 0xc00) >> 10) != mtrr_state.enabled) { - deftype_lo |= (mtrr_state.def_type | mtrr_state.enabled << 10); + deftype_lo = (deftype_lo & ~0xcff) | mtrr_state.def_type | (mtrr_state.enabled << 10); change_mask |= MTRR_CHANGE_MASK_DEFTYPE; } @@ -233,7 +288,6 @@ static unsigned long set_mtrr_state(u32 deftype_lo, u32 deftype_hi) static unsigned long cr4 = 0; -static u32 deftype_lo, deftype_hi; static DEFINE_SPINLOCK(set_atomicity_lock); /* @@ -271,7 +325,7 @@ static void prepare_set(void) __acquires(set_atomicity_lock) rdmsr(MTRRdefType_MSR, deftype_lo, deftype_hi); /* Disable MTRRs, and set the default type to uncached */ - mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & 0xf300UL, deftype_hi); + mtrr_wrmsr(MTRRdefType_MSR, deftype_lo & ~0xcff, deftype_hi); } static void post_set(void) __releases(set_atomicity_lock) @@ -300,7 +354,7 @@ static void generic_set_all(void) prepare_set(); /* Actually set the state */ - mask = set_mtrr_state(deftype_lo,deftype_hi); + mask = set_mtrr_state(); post_set(); local_irq_restore(flags); @@ -374,7 +428,7 @@ int generic_validate_add_page(unsigned long base, unsigned long size, unsigned i } } - if (base < 0x100) { + if (base + size < 0x100) { printk(KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n", base, size); return -EINVAL; diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c index 5ac051bb9d5..9753bc6a1f3 100644 --- a/arch/i386/kernel/cpu/mtrr/if.c +++ b/arch/i386/kernel/cpu/mtrr/if.c @@ -17,7 +17,7 @@ extern unsigned int *usage_table; #define FILE_FCOUNT(f) (((struct seq_file *)((f)->private_data))->private) -static char *mtrr_strings[MTRR_NUM_TYPES] = +static const char *const mtrr_strings[MTRR_NUM_TYPES] = { "uncachable", /* 0 */ "write-combining", /* 1 */ @@ -28,7 +28,7 @@ static char *mtrr_strings[MTRR_NUM_TYPES] = "write-back", /* 6 */ }; -char *mtrr_attrib_to_str(int x) +const char *mtrr_attrib_to_str(int x) { return (x <= 6) ? mtrr_strings[x] : "?"; } @@ -155,6 +155,7 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) { int err = 0; mtrr_type type; + unsigned long size; struct mtrr_sentry sentry; struct mtrr_gentry gentry; void __user *arg = (void __user *) __arg; @@ -235,15 +236,15 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) case MTRRIOC_GET_ENTRY: if (gentry.regnum >= num_var_ranges) return -EINVAL; - mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); + mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); /* Hide entries that go above 4GB */ - if (gentry.base + gentry.size > 0x100000 - || gentry.size == 0x100000) + if (gentry.base + size - 1 >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT)) + || size >= (1UL << (8 * sizeof(gentry.size) - PAGE_SHIFT))) gentry.base = gentry.size = gentry.type = 0; else { gentry.base <<= PAGE_SHIFT; - gentry.size <<= PAGE_SHIFT; + gentry.size = size << PAGE_SHIFT; gentry.type = type; } @@ -273,8 +274,14 @@ mtrr_ioctl(struct file *file, unsigned int cmd, unsigned long __arg) case MTRRIOC_GET_PAGE_ENTRY: if (gentry.regnum >= num_var_ranges) return -EINVAL; - mtrr_if->get(gentry.regnum, &gentry.base, &gentry.size, &type); - gentry.type = type; + mtrr_if->get(gentry.regnum, &gentry.base, &size, &type); + /* Hide entries that would overflow */ + if (size != (__typeof__(gentry.size))size) + gentry.base = gentry.size = gentry.type = 0; + else { + gentry.size = size; + gentry.type = type; + } break; } @@ -353,8 +360,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) char factor; int i, max, len; mtrr_type type; - unsigned long base; - unsigned int size; + unsigned long base, size; len = 0; max = num_var_ranges; @@ -373,7 +379,7 @@ static int mtrr_seq_show(struct seq_file *seq, void *offset) } /* RED-PEN: base can be > 32bit */ len += seq_printf(seq, - "reg%02i: base=0x%05lx000 (%4liMB), size=%4i%cB: %s, count=%d\n", + "reg%02i: base=0x%05lx000 (%4luMB), size=%4lu%cB: %s, count=%d\n", i, base, base >> (20 - PAGE_SHIFT), size, factor, mtrr_attrib_to_str(type), usage_table[i]); } diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index a4de30b9d3d..aeea23e8a05 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -172,6 +172,13 @@ static void ipi_handler(void *info) #endif +static inline int types_compatible(mtrr_type type1, mtrr_type type2) { + return type1 == MTRR_TYPE_UNCACHABLE || + type2 == MTRR_TYPE_UNCACHABLE || + (type1 == MTRR_TYPE_WRTHROUGH && type2 == MTRR_TYPE_WRBACK) || + (type1 == MTRR_TYPE_WRBACK && type2 == MTRR_TYPE_WRTHROUGH); +} + /** * set_mtrr - update mtrrs on all processors * @reg: mtrr in question @@ -304,11 +311,9 @@ static void set_mtrr(unsigned int reg, unsigned long base, int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, char increment) { - int i; + int i, replace, error; mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; - int error; + unsigned long lbase, lsize; if (!mtrr_if) return -ENXIO; @@ -328,12 +333,18 @@ int mtrr_add_page(unsigned long base, unsigned long size, return -ENOSYS; } + if (!size) { + printk(KERN_WARNING "mtrr: zero sized request\n"); + return -EINVAL; + } + if (base & size_or_mask || size & size_or_mask) { printk(KERN_WARNING "mtrr: base or size exceeds the MTRR width\n"); return -EINVAL; } error = -EINVAL; + replace = -1; /* No CPU hotplug when we change MTRR entries */ lock_cpu_hotplug(); @@ -341,21 +352,28 @@ int mtrr_add_page(unsigned long base, unsigned long size, mutex_lock(&mtrr_mutex); for (i = 0; i < num_var_ranges; ++i) { mtrr_if->get(i, &lbase, &lsize, <ype); - if (base >= lbase + lsize) - continue; - if ((base < lbase) && (base + size <= lbase)) + if (!lsize || base > lbase + lsize - 1 || base + size - 1 < lbase) continue; /* At this point we know there is some kind of overlap/enclosure */ - if ((base < lbase) || (base + size > lbase + lsize)) { + if (base < lbase || base + size - 1 > lbase + lsize - 1) { + if (base <= lbase && base + size - 1 >= lbase + lsize - 1) { + /* New region encloses an existing region */ + if (type == ltype) { + replace = replace == -1 ? i : -2; + continue; + } + else if (types_compatible(type, ltype)) + continue; + } printk(KERN_WARNING "mtrr: 0x%lx000,0x%lx000 overlaps existing" - " 0x%lx000,0x%x000\n", base, size, lbase, + " 0x%lx000,0x%lx000\n", base, size, lbase, lsize); goto out; } /* New region is enclosed by an existing region */ if (ltype != type) { - if (type == MTRR_TYPE_UNCACHABLE) + if (types_compatible(type, ltype)) continue; printk (KERN_WARNING "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n", base, size, mtrr_attrib_to_str(ltype), @@ -368,10 +386,18 @@ int mtrr_add_page(unsigned long base, unsigned long size, goto out; } /* Search for an empty MTRR */ - i = mtrr_if->get_free_region(base, size); + i = mtrr_if->get_free_region(base, size, replace); if (i >= 0) { set_mtrr(i, base, size, type); - usage_table[i] = 1; + if (likely(replace < 0)) + usage_table[i] = 1; + else { + usage_table[i] = usage_table[replace] + !!increment; + if (unlikely(replace != i)) { + set_mtrr(replace, 0, 0, 0); + usage_table[replace] = 0; + } + } } else printk(KERN_INFO "mtrr: no more MTRRs available\n"); error = i; @@ -459,8 +485,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) { int i, max; mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; + unsigned long lbase, lsize; int error = -EINVAL; if (!mtrr_if) @@ -561,7 +586,7 @@ static void __init init_ifs(void) struct mtrr_value { mtrr_type ltype; unsigned long lbase; - unsigned int lsize; + unsigned long lsize; }; static struct mtrr_value * mtrr_state; diff --git a/arch/i386/kernel/cpu/mtrr/mtrr.h b/arch/i386/kernel/cpu/mtrr/mtrr.h index 99c9f268204..d61ea9db6cf 100644 --- a/arch/i386/kernel/cpu/mtrr/mtrr.h +++ b/arch/i386/kernel/cpu/mtrr/mtrr.h @@ -43,15 +43,16 @@ struct mtrr_ops { void (*set_all)(void); void (*get)(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type); - int (*get_free_region) (unsigned long base, unsigned long size); - + unsigned long *size, mtrr_type * type); + int (*get_free_region)(unsigned long base, unsigned long size, + int replace_reg); int (*validate_add_page)(unsigned long base, unsigned long size, unsigned int type); int (*have_wrcomb)(void); }; -extern int generic_get_free_region(unsigned long base, unsigned long size); +extern int generic_get_free_region(unsigned long base, unsigned long size, + int replace_reg); extern int generic_validate_add_page(unsigned long base, unsigned long size, unsigned int type); @@ -62,17 +63,17 @@ extern int positive_have_wrcomb(void); /* library functions for processor-specific routines */ struct set_mtrr_context { unsigned long flags; - unsigned long deftype_lo; - unsigned long deftype_hi; unsigned long cr4val; - unsigned long ccr3; + u32 deftype_lo; + u32 deftype_hi; + u32 ccr3; }; struct mtrr_var_range { - unsigned long base_lo; - unsigned long base_hi; - unsigned long mask_lo; - unsigned long mask_hi; + u32 base_lo; + u32 base_hi; + u32 mask_lo; + u32 mask_hi; }; void set_mtrr_done(struct set_mtrr_context *ctxt); @@ -92,6 +93,6 @@ extern struct mtrr_ops * mtrr_if; extern unsigned int num_var_ranges; void mtrr_state_warn(void); -char *mtrr_attrib_to_str(int x); +const char *mtrr_attrib_to_str(int x); void mtrr_wrmsr(unsigned, unsigned, unsigned); -- cgit v1.2.3 From ba10650a880c2df23bd1db6c0570ddb66f389641 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] i386: alloc_gdt() static Make the needlessly global alloc_gdt() static. (against) pda-percpu-init Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton --- arch/i386/kernel/cpu/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 68bcb687019..1b34c56f812 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c @@ -609,7 +609,7 @@ struct pt_regs * __devinit idle_regs(struct pt_regs *regs) return regs; } -__cpuinit int alloc_gdt(int cpu) +static __cpuinit int alloc_gdt(int cpu) { struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); struct desc_struct *gdt; -- cgit v1.2.3 From 79929fd1c1887d2a057cbb80d487a2e2f1c01a02 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] i386: Convert more absolute symbols to section relative o Convert more absolute symbols to section relative to keep the theme in vmlinux.lds.S file and to avoid problem if kernel is relocated. o Also put a message so that in future people can be aware of it and avoid introducing absolute symbols. Signed-off-by: Vivek Goyal Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/kernel/vmlinux.lds.S | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 877dc5cfe3a..25581e87c60 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -8,6 +8,12 @@ * put it inside the section definition. */ +/* Don't define absolute symbols until and unless you know that symbol + * value is should remain constant even if kernel image is relocated + * at run time. Absolute symbols are not relocated. If symbol value should + * change if kernel is relocated, make the symbol section relative and + * put it inside the section definition. + */ #define LOAD_OFFSET __PAGE_OFFSET #include @@ -65,11 +71,11 @@ SECTIONS CONSTRUCTORS } :data - __start_paravirtprobe = .; .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) { + __start_paravirtprobe = .; *(.paravirtprobe) + __stop_paravirtprobe = .; } - __stop_paravirtprobe = .; . = ALIGN(4096); .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { @@ -172,11 +178,11 @@ SECTIONS *(.altinstr_replacement) } . = ALIGN(4); - __start_parainstructions = .; .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { + __start_parainstructions = .; *(.parainstructions) + __stop_parainstructions = .; } - __stop_parainstructions = .; /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } -- cgit v1.2.3 From 274e1bbdeeaf16e71418f11f5f305ab26061f2c2 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86: add write_pci_config_byte() to direct PCI access routines Mechanism of selecting physical mode in genapic when cpu hotplug is enabled on x86_64, broke the quirk(quirk_intel_irqbalance()) introduced for working around the transposing interrupt message errata in E7520/E7320/E7525 (revision ID 0x9 and below. errata #23 in http://download.intel.com/design/chipsets/specupdt/30304203.pdf). This errata requires the mode to be in logical flat, so that interrupts can be directed to more than one cpu(and thus use hardware IRQ balancing enabled by BIOS on these platforms). Following four patches fixes this by moving the quirk to early quirk and forcing the x86_64 genapic selection to logical flat on these platforms. Thanks to Shaohua for pointing out the breakage. This patch: Add write_pci_config_byte() to direct PCI access routines Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/pci/early.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/i386/pci/early.c b/arch/i386/pci/early.c index 713d6c866ca..42df4b6606d 100644 --- a/arch/i386/pci/early.c +++ b/arch/i386/pci/early.c @@ -45,6 +45,13 @@ void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, outl(val, 0xcfc); } +void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) +{ + PDprintk("%x writing to %x: %x\n", slot, offset, val); + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + outb(val, 0xcfc); +} + int early_pci_allowed(void) { return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == -- cgit v1.2.3 From fd6d7d26897dec834d0b9fbdc59819b0332a1257 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] i386: introduce the mechanism of disabling cpu hotplug control Add 'enable_cpu_hotplug' flag and when cleared, the hotplug control file ("online") will not be added under /sys/devices/system/cpu/cpuX/ Next patch doing PCI quirks will use this. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/kernel/topology.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c index 07d6da36a82..844c08fdb22 100644 --- a/arch/i386/kernel/topology.c +++ b/arch/i386/kernel/topology.c @@ -40,14 +40,18 @@ int arch_register_cpu(int num) * restrictions and assumptions in kernel. This basically * doesnt add a control file, one cannot attempt to offline * BSP. + * + * Also certain PCI quirks require not to enable hotplug control + * for all CPU's. */ - if (!num) + if (!num || !enable_cpu_hotplug) cpu_devices[num].cpu.no_control = 1; return register_cpu(&cpu_devices[num].cpu, num); } #ifdef CONFIG_HOTPLUG_CPU +int enable_cpu_hotplug = 1; void arch_unregister_cpu(int num) { return unregister_cpu(&cpu_devices[num].cpu); -- cgit v1.2.3 From 72486f1f8f0a2bc828b9d30cf4690cf2dd6807fc Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] i386: change the 'no_control' field to 'hotpluggable' in the struct cpu Change the 'no_control' field in the cpu struct to a more positive and better term 'hotpluggable'. And change(/cleanup) the logic accordingly. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/kernel/topology.c | 4 ++-- arch/ia64/kernel/topology.c | 8 ++++---- arch/powerpc/kernel/sysfs.c | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/topology.c b/arch/i386/kernel/topology.c index 844c08fdb22..79cf608e14c 100644 --- a/arch/i386/kernel/topology.c +++ b/arch/i386/kernel/topology.c @@ -44,8 +44,8 @@ int arch_register_cpu(int num) * Also certain PCI quirks require not to enable hotplug control * for all CPU's. */ - if (!num || !enable_cpu_hotplug) - cpu_devices[num].cpu.no_control = 1; + if (num && enable_cpu_hotplug) + cpu_devices[num].cpu.hotpluggable = 1; return register_cpu(&cpu_devices[num].cpu, num); } diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 5629b45e89c..687500ddb4b 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c @@ -31,11 +31,11 @@ int arch_register_cpu(int num) { #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* - * If CPEI cannot be re-targetted, and this is - * CPEI target, then dont create the control file + * If CPEI can be re-targetted or if this is not + * CPEI target, then it is hotpluggable */ - if (!can_cpei_retarget() && is_cpu_cpei_target(num)) - sysfs_cpus[num].cpu.no_control = 1; + if (can_cpei_retarget() || !is_cpu_cpei_target(num)) + sysfs_cpus[num].cpu.hotpluggable = 1; map_cpu_to_node(num, node_cpuid[num].nid); #endif diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 22123a0d541..63ed265b7f0 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -239,7 +239,7 @@ static void unregister_cpu_online(unsigned int cpu) struct cpu *c = &per_cpu(cpu_devices, cpu); struct sys_device *s = &c->sysdev; - BUG_ON(c->no_control); + BUG_ON(!c->hotpluggable); if (!firmware_has_feature(FW_FEATURE_ISERIES) && cpu_has_feature(CPU_FTR_SMT)) @@ -424,10 +424,10 @@ static int __init topology_init(void) * CPU. For instance, the boot cpu might never be valid * for hotplugging. */ - if (!ppc_md.cpu_die) - c->no_control = 1; + if (ppc_md.cpu_die) + c->hotpluggable = 1; - if (cpu_online(cpu) || (c->no_control == 0)) { + if (cpu_online(cpu) || c->hotpluggable) { register_cpu(c, cpu); sysdev_create_file(&c->sysdev, &attr_physical_id); -- cgit v1.2.3 From 9899f826fc90beba4f78083f6230e06cbe1050c9 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86-64: add genapic_force Add genapic_force. Used by the next Intel quirks patch. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/genapic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 8e78a75d186..b007433f96b 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -33,7 +33,7 @@ extern struct genapic apic_flat; extern struct genapic apic_physflat; struct genapic *genapic = &apic_flat; - +struct genapic *genapic_force; /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. @@ -46,6 +46,13 @@ void __init clustered_apic_check(void) u8 cluster_cnt[NUM_APIC_CLUSTERS]; int max_apic = 0; + /* genapic selection can be forced because of certain quirks. + */ + if (genapic_force) { + genapic = genapic_force; + goto print; + } + #if defined(CONFIG_ACPI) /* * Some x86_64 machines use physical APIC mode regardless of how many -- cgit v1.2.3 From b0d0a4ba45760b10ecee9035ed45b442c1a6cc84 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86: fix the irqbalance quirk for E7320/E7520/E7525 Move the irqbalance quirks for E7320/E7520/E7525(Errata 23 in http://download.intel.com/design/chipsets/specupdt/30304203.pdf) to early quirks. And add a PCI quirk for these platforms to check(which happens very late during the boot) if the APIC routing is indeed set to default flat mode. This fixes the breakage(in x86_64) of this quirk due to cpu hotplug which selects physical mode instead of the logical flat(as needed for this errata workaround). Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/kernel/acpi/earlyquirk.c | 21 +++++++++++++++++ arch/i386/kernel/quirks.c | 46 +++++++++++++++++++++++++++++--------- arch/i386/kernel/smpboot.c | 7 ++++++ arch/x86_64/kernel/early-quirks.c | 13 +++++++++++ arch/x86_64/kernel/smpboot.c | 8 +++++++ 5 files changed, 84 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index c9841692bb7..4b60af7f91d 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_ACPI @@ -49,6 +50,24 @@ static int __init check_bridge(int vendor, int device) return 0; } +static void check_intel(void) +{ + u16 vendor, device; + + vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); + + if (vendor != PCI_VENDOR_ID_INTEL) + return; + + device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + void __init check_acpi_pci(void) { int num, slot, func; @@ -60,6 +79,8 @@ void __init check_acpi_pci(void) if (!early_pci_allowed()) return; + check_intel(); + /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index 9f6ab1789bb..a01320a7b63 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -3,10 +3,23 @@ */ #include #include +#include +#include +#include #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) +static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) +{ +#ifdef CONFIG_X86_64 + if (genapic != &apic_flat) + panic("APIC mode must be flat on this system\n"); +#elif defined(CONFIG_X86_GENERICARCH) + if (genapic != &apic_default) + panic("APIC mode must be default(flat) on this system. Use apic=default\n"); +#endif +} -static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) +void __init quirk_intel_irqbalance(void) { u8 config, rev; u32 word; @@ -16,18 +29,18 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) * based platforms. * Disable SW irqbalance/affinity on those platforms. */ - pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); + rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION); if (rev > 0x9) return; printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space*/ - pci_read_config_byte(dev, 0xf4, &config); - pci_write_config_byte(dev, 0xf4, config|0x2); + /* enable access to config space */ + config = read_pci_config_byte(0, 0, 0, 0xf4); + write_pci_config_byte(0, 0, 0, 0xf4, config|0x2); /* read xTPR register */ - raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); + word = read_pci_config_16(0, 0, 0x40, 0x4c); if (!(word & (1 << 13))) { printk(KERN_INFO "Disabling irq balancing and affinity\n"); @@ -37,14 +50,25 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) noirqdebug_setup(""); #ifdef CONFIG_PROC_FS no_irq_affinity = 1; +#endif +#ifdef CONFIG_HOTPLUG_CPU + printk(KERN_INFO "Disabling cpu hotplug control\n"); + enable_cpu_hotplug = 0; +#endif +#ifdef CONFIG_X86_64 + /* force the genapic selection to flat mode so that + * interrupts can be redirected to more than one CPU. + */ + genapic_force = &apic_flat; #endif } - /* put back the original value for config space*/ + /* put back the original value for config space */ if (!(config & 0x2)) - pci_write_config_byte(dev, 0xf4, config); + write_pci_config_byte(0, 0, 0, 0xf4, config); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance); + #endif diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index cd7de9c9654..346f27f4c79 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -1482,6 +1483,12 @@ int __devinit __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); + +#ifdef CONFIG_X86_GENERICARCH + if (num_online_cpus() > 8 && genapic == &apic_default) + panic("Default flat APIC routing can't be used with > 8 cpus\n"); +#endif + return 0; } diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index fb0c6da41b7..829698f6d04 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -71,6 +71,18 @@ static void ati_bugs(void) { } +static void intel_bugs(void) +{ + u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); + +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + struct chipset { u16 vendor; void (*f)(void); @@ -80,6 +92,7 @@ static struct chipset early_qrk[] = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, + { PCI_VENDOR_ID_INTEL, intel_bugs}, {} }; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 62c2e747af5..4c161c208d5 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -60,6 +60,7 @@ #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -1167,6 +1168,13 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); + + if (num_online_cpus() > 8 && genapic == &apic_flat) { + printk(KERN_WARNING + "flat APIC routing can't be used with > 8 cpus\n"); + BUG(); + } + err = 0; return err; -- cgit v1.2.3 From e1cccf48b182dd743c3c83a4fdf8dc570a43b393 Mon Sep 17 00:00:00 2001 From: Artiom Myaskouvskey Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: call efi_get_time during suspend Function efi_get_time called not only during init kernel phase but also during suspend (from get_cmos_time). When it is called from get_cmos_time the corresponding runtime service should be called in virtual and not in physical mode. Signed-off-by: Artiom Myaskouvskey Signed-off-by: Andi Kleen Cc: "Narayanan, Chandramouli" Cc: "Jiossy, Rami" Cc: "Satt, Shai" Cc: Andi Kleen Cc: Matt Domsch Signed-off-by: Andrew Morton --- arch/i386/kernel/efi.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c index 8b40648d0ef..b92c7f0a358 100644 --- a/arch/i386/kernel/efi.c +++ b/arch/i386/kernel/efi.c @@ -194,17 +194,24 @@ inline int efi_set_rtc_mmss(unsigned long nowtime) return 0; } /* - * This should only be used during kernel init and before runtime - * services have been remapped, therefore, we'll need to call in physical - * mode. Note, this call isn't used later, so mark it __init. + * This is used during kernel init before runtime + * services have been remapped and also during suspend, therefore, + * we'll need to call both in physical and virtual modes. */ -inline unsigned long __init efi_get_time(void) +inline unsigned long efi_get_time(void) { efi_status_t status; efi_time_t eft; efi_time_cap_t cap; - status = phys_efi_get_time(&eft, &cap); + if (efi.get_time) { + /* if we are in virtual mode use remapped function */ + status = efi.get_time(&eft, &cap); + } else { + /* we are in physical mode */ + status = phys_efi_get_time(&eft, &cap); + } + if (status != EFI_SUCCESS) printk("Oops: efitime: can't read time status: 0x%lx\n",status); -- cgit v1.2.3 From 956fb53197f82257974f1f9835485aeeef4510b3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: handle a negative return value The Coverity checker noted that bad things might happen if find_isa_irq_apic() returned -1. [akpm@osdl.org: add debugging checks] Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Cc: Andi Kleen Acked-by: Ingo Molnar Signed-off-by: Andrew Morton --- arch/i386/kernel/io_apic.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 993150f206e..7bfd6c3ec87 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2179,9 +2179,15 @@ static inline void unlock_ExtINT_logic(void) unsigned char save_control, save_freq_select; pin = find_isa_irq_pin(8, mp_INT); + if (pin == -1) { + WARN_ON_ONCE(1); + return; + } apic = find_isa_irq_apic(8, mp_INT); - if (pin == -1) + if (apic == -1) { + WARN_ON_ONCE(1); return; + } entry0 = ioapic_read_entry(apic, pin); clear_IO_APIC_pin(apic, pin); -- cgit v1.2.3 From 7e95b593a1aeb6fe1d3904e799d23a45261f2c19 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: Make irq_vector static irq_vector[] can now become static. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Acked-by: Eric W. Biederman Acked-by: Ingo Molnar Signed-off-by: Andrew Morton --- arch/i386/kernel/io_apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 7bfd6c3ec87..56f571c9fc0 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -1241,7 +1241,7 @@ static inline int IO_APIC_irq_trigger(int irq) } /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; +static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; static int __assign_irq_vector(int irq) { -- cgit v1.2.3 From ee58fad51a2a767cb2567706ace967705233d881 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86-64: x86-64 add Intel BTS cpufeature bit and detection (take 2) Here is a small patch for x86-64 which adds a cpufeature flag and detection code for Intel's Branch Trace Store (BTS) feature. This feature can be found on Intel P4 and Core 2 processors among others. It can also be used by perfmon. changelog: - add CPU_FEATURE_BTS - add Branch Trace Store detection signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 619af2e2fa2..a570c81c831 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -838,6 +838,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has_ds) { unsigned int l1, l2; rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<11))) + set_bit(X86_FEATURE_BTS, c->x86_capability); if (!(l1 & (1<<12))) set_bit(X86_FEATURE_PEBS, c->x86_capability); } -- cgit v1.2.3 From 538f188e03c821c93b355c9fc346806cdd34e286 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: i386 add Intel BTS cpufeature bit and detection (take 2) Here is a small patch for i386 which adds a cpufeature flag and detection code for Intel's Branch Trace Store (BTS) feature. This feature can be found on Intel P4 and Core 2 processors among others. It can also be used by perfmon. changelog: - add CPU_FEATURE_BTS - add Branch Trace Store detection signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/intel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 3ae795e9056..56fe2658495 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -199,6 +199,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has_ds) { unsigned int l1; rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<11))) + set_bit(X86_FEATURE_BTS, c->x86_capability); if (!(l1 & (1<<12))) set_bit(X86_FEATURE_PEBS, c->x86_capability); } -- cgit v1.2.3 From 9a8cb626a08f2c8251291f3c0a049b29665895d2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: Avoid boot warning with apic=debug There are two consumers of apic=: the apic debug level and the low level generic architecture code. early_param would warn when the low level code rejected "debug". Avoid this. Signed-off-by: Andi Kleen --- arch/i386/mach-generic/probe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/mach-generic/probe.c b/arch/i386/mach-generic/probe.c index 94b1fd9cbe3..a7b3999bb37 100644 --- a/arch/i386/mach-generic/probe.c +++ b/arch/i386/mach-generic/probe.c @@ -45,7 +45,9 @@ static int __init parse_apic(char *arg) return 0; } } - return -ENOENT; + + /* Parsed again by __setup for debug/verbose */ + return 0; } early_param("apic", parse_apic); -- cgit v1.2.3 From f990fff427d68af3e4e1d16fe799c106abc0bf53 Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86: Regard MSRs in lapic_suspend()/lapic_resume() Read/Write APIC_LVTPC and APIC_LVTTHMR only, if get_maxlvt() returns certain values. This is done like everywhere else in i386/kernel/apic.c, so I guess its correct. Suspends/Resumes to disk fine and eleminates an smp_error_interrupt() here on a K8. AK: ported to x86-64 too Signed-off-by: Karsten Wiese Signed-off-by: Andi Kleen --- arch/i386/kernel/apic.c | 22 ++++++++++++++++++---- arch/x86_64/kernel/apic.c | 22 ++++++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 2fd4b7d927c..776d9be26af 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -647,23 +647,30 @@ static struct { static int lapic_suspend(struct sys_device *dev, pm_message_t state) { unsigned long flags; + int maxlvt; if (!apic_pm_state.active) return 0; + maxlvt = get_maxlvt(); + apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); - apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); + if (maxlvt >= 4) + apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); - apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +#ifdef CONFIG_X86_MCE_P4THERMAL + if (maxlvt >= 5) + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +#endif local_irq_save(flags); disable_local_APIC(); @@ -675,10 +682,13 @@ static int lapic_resume(struct sys_device *dev) { unsigned int l, h; unsigned long flags; + int maxlvt; if (!apic_pm_state.active) return 0; + maxlvt = get_maxlvt(); + local_irq_save(flags); /* @@ -700,8 +710,12 @@ static int lapic_resume(struct sys_device *dev) apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); - apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); - apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); +#ifdef CONFIG_X86_MCE_P4THERMAL + if (maxlvt >= 5) + apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); +#endif + if (maxlvt >= 4) + apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 5c468971e64..f0b00d8731c 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -459,23 +459,30 @@ static struct { static int lapic_suspend(struct sys_device *dev, pm_message_t state) { unsigned long flags; + int maxlvt; if (!apic_pm_state.active) return 0; + maxlvt = get_maxlvt(); + apic_pm_state.apic_id = apic_read(APIC_ID); apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI); apic_pm_state.apic_ldr = apic_read(APIC_LDR); apic_pm_state.apic_dfr = apic_read(APIC_DFR); apic_pm_state.apic_spiv = apic_read(APIC_SPIV); apic_pm_state.apic_lvtt = apic_read(APIC_LVTT); - apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); + if (maxlvt >= 4) + apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC); apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0); apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1); apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR); apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); - apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +#ifdef CONFIG_X86_MCE_INTEL + if (maxlvt >= 5) + apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); +#endif local_irq_save(flags); disable_local_APIC(); local_irq_restore(flags); @@ -486,10 +493,13 @@ static int lapic_resume(struct sys_device *dev) { unsigned int l, h; unsigned long flags; + int maxlvt; if (!apic_pm_state.active) return 0; + maxlvt = get_maxlvt(); + local_irq_save(flags); rdmsr(MSR_IA32_APICBASE, l, h); l &= ~MSR_IA32_APICBASE_BASE; @@ -503,8 +513,12 @@ static int lapic_resume(struct sys_device *dev) apic_write(APIC_SPIV, apic_pm_state.apic_spiv); apic_write(APIC_LVT0, apic_pm_state.apic_lvt0); apic_write(APIC_LVT1, apic_pm_state.apic_lvt1); - apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); - apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); +#ifdef CONFIG_X86_MCE_INTEL + if (maxlvt >= 5) + apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr); +#endif + if (maxlvt >= 4) + apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc); apic_write(APIC_LVTT, apic_pm_state.apic_lvtt); apic_write(APIC_TDCR, apic_pm_state.apic_tdcr); apic_write(APIC_TMICT, apic_pm_state.apic_tmict); -- cgit v1.2.3 From bf7e6a196318316e921f357557fca9d11d15f486 Mon Sep 17 00:00:00 2001 From: Artiom Myaskouvskey Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: Preserve EFI run time regions with memmap parameter When using memmap kernel parameter in EFI boot we should also add to memory map memory regions of runtime services to enable their mapping later. AK: merged and cleaned up the patch Signed-off-by: Artiom Myaskouvskey Signed-off-by: Andi Kleen --- arch/i386/kernel/e820.c | 60 +++++++++++++++++++++++++++++++++++-------------- arch/i386/mm/init.c | 2 -- 2 files changed, 43 insertions(+), 19 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/e820.c b/arch/i386/kernel/e820.c index b704790f796..2f7d0a92fd7 100644 --- a/arch/i386/kernel/e820.c +++ b/arch/i386/kernel/e820.c @@ -742,29 +742,55 @@ void __init print_memory_map(char *who) } } -void __init limit_regions(unsigned long long size) +static __init __always_inline void efi_limit_regions(unsigned long long size) { unsigned long long current_addr = 0; + efi_memory_desc_t *md, *next_md; + void *p, *p1; + int i, j; + + j = 0; + p1 = memmap.map; + for (p = p1, i = 0; p < memmap.map_end; p += memmap.desc_size, i++) { + md = p; + next_md = p1; + current_addr = md->phys_addr + + PFN_PHYS(md->num_pages); + if (is_available_memory(md)) { + if (md->phys_addr >= size) continue; + memcpy(next_md, md, memmap.desc_size); + if (current_addr >= size) { + next_md->num_pages -= + PFN_UP(current_addr-size); + } + p1 += memmap.desc_size; + next_md = p1; + j++; + } else if ((md->attribute & EFI_MEMORY_RUNTIME) == + EFI_MEMORY_RUNTIME) { + /* In order to make runtime services + * available we have to include runtime + * memory regions in memory map */ + memcpy(next_md, md, memmap.desc_size); + p1 += memmap.desc_size; + next_md = p1; + j++; + } + } + memmap.nr_map = j; + memmap.map_end = memmap.map + + (memmap.nr_map * memmap.desc_size); +} + +void __init limit_regions(unsigned long long size) +{ + unsigned long long current_addr; int i; print_memory_map("limit_regions start"); if (efi_enabled) { - efi_memory_desc_t *md; - void *p; - - for (p = memmap.map, i = 0; p < memmap.map_end; - p += memmap.desc_size, i++) { - md = p; - current_addr = md->phys_addr + (md->num_pages << 12); - if (md->type == EFI_CONVENTIONAL_MEMORY) { - if (current_addr >= size) { - md->num_pages -= - (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); - memmap.nr_map = i + 1; - return; - } - } - } + efi_limit_regions(size); + return; } for (i = 0; i < e820.nr_map; i++) { current_addr = e820.map[i].addr + e820.map[i].size; diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 167416155ee..f4dd048187f 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -192,8 +192,6 @@ static inline int page_kills_ppro(unsigned long pagenr) return 0; } -extern int is_available_memory(efi_memory_desc_t *); - int page_is_ram(unsigned long pagenr) { int i; -- cgit v1.2.3 From 6df0532eef0187c293d3ab1d4c158f92e8f24f8a Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] i386: remove duplicate printk We do the exact same printk about a dozen lines above with no intermediate printk's. Signed-off-by: Dave Jones Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/amd.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index e4758095d87..41cfea57232 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c @@ -104,10 +104,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) f_vide(); rdtscl(d2); d = d2-d; - - /* Knock these two lines out if it debugs out ok */ - printk(KERN_INFO "AMD K6 stepping B detected - "); - /* -- cut here -- */ + if (d > 20*K6_BUG_LOOP) printk("system stability may be impaired when more than 32 MB are used.\n"); else -- cgit v1.2.3 From 86bd58bf4c383fde4e99b83ce917b091a072040d Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86-64: Remove unused GET_APIC_VERSION call from clear_local_APIC Remove unused GET_APIC_VERSION call from clear_local_APIC() and __setup_APIC_LVTT(). Reported by D Binderman . Cc: Andi Kleen Cc: Ingo Molnar Signed-off-by: David Rientjes Signed-off-by: Andi Kleen --- arch/x86_64/kernel/apic.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index f0b00d8731c..124b2d27b4a 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c @@ -140,7 +140,6 @@ void clear_local_APIC(void) apic_write(APIC_LVTERR, APIC_LVT_MASKED); if (maxlvt >= 4) apic_write(APIC_LVTPC, APIC_LVT_MASKED); - v = GET_APIC_VERSION(apic_read(APIC_LVR)); apic_write(APIC_ESR, 0); apic_read(APIC_ESR); } @@ -736,10 +735,9 @@ void __init init_apic_mappings(void) static void __setup_APIC_LVTT(unsigned int clocks) { - unsigned int lvtt_value, tmp_value, ver; + unsigned int lvtt_value, tmp_value; int cpu = smp_processor_id(); - ver = GET_APIC_VERSION(apic_read(APIC_LVR)); lvtt_value = APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR; if (cpu_isset(cpu, timer_interrupt_broadcast_ipi_mask)) -- cgit v1.2.3 From 0741f4d207a644482d7a040f05cd264c98cf7ee8 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86: add sysctl for kstack_depth_to_print Add sysctl for kstack_depth_to_print. This lets users change the amount of raw stack data printed in dump_stack() without having to reboot. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 2 +- arch/x86_64/kernel/traps.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 7b2f9f02208..1d48a75fa33 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -91,7 +91,7 @@ asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); -static int kstack_depth_to_print = 24; +int kstack_depth_to_print = 24; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 264db33476a..75ceccee178 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -108,7 +108,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) preempt_enable_no_resched(); } -static int kstack_depth_to_print = 12; +int kstack_depth_to_print = 12; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else -- cgit v1.2.3 From 3df0af0eb064a16bbdbe81b46bc72a4089f88d54 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86_64: clear_bss before set_intr_gate with early_idt_handler idt_table is in the .bss section, so clear_bss need to called at first Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/head64.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c index 9561eb3c5b5..cc230b93cd1 100644 --- a/arch/x86_64/kernel/head64.c +++ b/arch/x86_64/kernel/head64.c @@ -57,10 +57,12 @@ void __init x86_64_start_kernel(char * real_mode_data) { int i; - for (i = 0; i < 256; i++) + /* clear bss before set_intr_gate with early_idt_handler */ + clear_bss(); + + for (i = 0; i < IDT_ENTRIES; i++) set_intr_gate(i, early_idt_handler); asm volatile("lidt %0" :: "m" (idt_descr)); - clear_bss(); early_printk("Kernel alive\n"); -- cgit v1.2.3 From 8fb6e5f5db860113e71ce7b854382ed40559395b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86_64: interrupt array size should be aligned to NR_VECTORS interrupt array is referred for idt vectors instead of NR_IRQS, so change size to NR_VECTORS - FIRST_EXTERNAL_VECTOR. Also change to static. Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/i8259.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index c4ef801b765..d73c79e821f 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c @@ -76,7 +76,8 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) -void (*interrupt[NR_IRQS])(void) = { +/* for the irq vectors */ +static void (*interrupt[NR_VECTORS - FIRST_EXTERNAL_VECTOR])(void) = { IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), -- cgit v1.2.3 From 026c66bdda5f07959da7d74d29b18a7c480242f7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86-64: remove duplicate ARCH_DISCONTIGMEM_ENABLE option One ARCH_DISCONTIGMEM_ENABLE option is enough. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen --- arch/x86_64/Kconfig | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 6eece27d579..bfbb9bcae12 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -359,11 +359,6 @@ config ARCH_DISCONTIGMEM_ENABLE depends on NUMA default y - -config ARCH_DISCONTIGMEM_ENABLE - def_bool y - depends on NUMA - config ARCH_DISCONTIGMEM_DEFAULT def_bool y depends on NUMA -- cgit v1.2.3 From d4c45718b3c0d3045eab803cd15fabbed1ea5bcd Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86-64: Fix kobject_init() WARN_ON on resume from disk Make mce_remove_device() clean up the kobject in per_cpu(device_mce, cpu) after it has been unregistered. Signed-off-by: Rafael J. Wysocki Signed-off-by: Andi Kleen --- arch/x86_64/kernel/mce.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index bbea88801d8..a7440cb9c14 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -652,6 +652,7 @@ static void mce_remove_device(unsigned int cpu) sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant); sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval); sysdev_unregister(&per_cpu(device_mce,cpu)); + memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); } /* Get notified when a cpu comes on/off. Be hotplug friendly. */ -- cgit v1.2.3 From a36df98ab1cdd8a9e7daa4c1b5c48ffa2ad6ea09 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] i386: touch softlockup during backtracing Sometimes the soft watchdog fires after we're done oopsing. See http://projects.info-pull.com/mokb/MOKB-25-11-2006.html for an example. AK: changed to touch_nmi_watchdog() Signed-off-by: Dave Jones Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 1d48a75fa33..86d8476be4f 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -29,6 +29,7 @@ #include #include #include +#include #ifdef CONFIG_EISA #include @@ -248,6 +249,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, stack = (unsigned long*)context->previous_esp; if (!stack) break; + touch_nmi_watchdog(); } } EXPORT_SYMBOL(dump_trace); -- cgit v1.2.3 From 73ad8355d7db6a3cdcf313d4a4586a8f81b19c2f Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86-64: remove unused acpi_found_madt in mparse. remove unused acpi_found_madt in mparse.c Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/mpparse.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index b147ab19fbd..08072568847 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -35,8 +35,6 @@ int smp_found_config; unsigned int __initdata maxcpus = NR_CPUS; -int acpi_found_madt; - /* * Various Linux-internal data structures created from the * MP-table. -- cgit v1.2.3 From a1a70c25bed75ed36ed48bbe18b9029428d2452d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] i386: always enable regparm -mregparm=3 has been enabled by default for some time on i386, and AFAIK there aren't any problems with it left. This patch removes the REGPARM config option and sets -mregparm=3 unconditionally. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen --- arch/i386/Kconfig | 14 -------------- arch/i386/Makefile | 4 +--- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index bb1fa061c6c..b6b2df40ca7 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -721,20 +721,6 @@ config BOOT_IOREMAP depends on (((X86_SUMMIT || X86_GENERICARCH) && NUMA) || (X86 && EFI)) default y -config REGPARM - bool "Use register arguments" - default y - help - Compile the kernel with -mregparm=3. This instructs gcc to use - a more efficient function call ABI which passes the first three - arguments of a function call via registers, which results in denser - and faster code. - - If this option is disabled, then the default ABI of passing - arguments via the stack is used. - - If unsure, say Y. - config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS diff --git a/arch/i386/Makefile b/arch/i386/Makefile index d1aca52bf69..f7ac1aea1d8 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -31,7 +31,7 @@ LDFLAGS_vmlinux := --emit-relocs endif CHECKFLAGS += -D__i386__ -CFLAGS += -pipe -msoft-float +CFLAGS += -pipe -msoft-float -mregparm=3 # prevent gcc from keeping the stack 16 byte aligned CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) @@ -39,8 +39,6 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu -cflags-$(CONFIG_REGPARM) += -mregparm=3 - # temporary until string.h is fixed cflags-y += -ffreestanding -- cgit v1.2.3 From 616779656989cb8c59177e35cb13e87028b1edc8 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86-64: Synchronize RDTSC on single core AMD There is no guarantee that two RDTSCs in a row are monotonic, so don't assume it on single core AMD systems. This will make gettimeofday slower again Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index a570c81c831..05eaca41802 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -732,11 +732,8 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* Fix cpuid4 emulation for more */ num_cache_leaves = 3; - /* When there is only one core no need to synchronize RDTSC */ - if (num_possible_cpus() == 1) - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - else - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + /* RDTSC can be speculated around */ + clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) -- cgit v1.2.3 From e496a0da7f8110054d0ad4039245b0f49f9540f5 Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] Calgary: remove unused variables Spotted by d binderman . Signed-off-by: Muli Ben-Yehuda Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-calgary.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 0ddf29dae7e..3215675ab12 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -653,14 +653,9 @@ static void __init calgary_reserve_peripheral_mem_2(struct pci_dev *dev) static void __init calgary_reserve_regions(struct pci_dev *dev) { unsigned int npages; - void __iomem *bbar; - unsigned char busnum; u64 start; struct iommu_table *tbl = dev->sysdata; - bbar = tbl->bbar; - busnum = dev->bus->number; - /* reserve bad_dma_address in case it's a legal address */ iommu_range_reserve(tbl, bad_dma_address, 1); -- cgit v1.2.3 From f3d73707a1e84f0687a05144b70b660441e999c7 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] x86-64: Mark rdtsc as sync only for netburst, not for core2 On the Core2 cpus, the rdtsc instruction is not serializing (as defined in the architecture reference since rdtsc exists) and due to the deep speculation of these cores, it's possible that you can observe time go backwards between cores due to this speculation. Since the kernel already deals with this with the SYNC_RDTSC flag, the solution is simple, only assume that the instruction is serializing on family 15... The price one pays for this is a slightly slower gettimeofday (by a dozen or two cycles), but that increase is quite small to pay for a really-going-forward tsc counter. Signed-off-by: Arjan van de Ven Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 05eaca41802..6595a4ebe7f 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -860,7 +860,10 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); if (c->x86 == 6) set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + if (c->x86 == 15) + set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + else + clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); srat_detect_node(); -- cgit v1.2.3 From 446f713ba1afd68568139ae4691335ba273fa7f4 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:12 +0100 Subject: [PATCH] unwinder: always use unlocked module list access in unwinder fallback We're already well protected against module unloads because module unload uses stop_machine(). The only exception is NMIs, but other users already risk lockless accesses here. This avoids some hackery in lockdep and also a potential deadlock This matches what i386 does. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 75ceccee178..9864d195c40 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -317,9 +317,9 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ - if (oops_in_progress ? \ - __kernel_text_address(addr) : \ - kernel_text_address(addr)) { \ + /* Use unlocked access here because except for NMIs \ + we should be already protected against module unloads */ \ + if (__kernel_text_address(addr)) { \ /* \ * If the address is either in the text segment of the \ * kernel, or in the region which contains vmalloc'ed \ -- cgit v1.2.3 From 359ad0d4015a9ab39243f2ebc4eb07915bd618b2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] unwinder: more sanity checks in Dwarf2 unwinder Tighten the requirements on both input to and output from the Dwarf2 unwinder. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 7 +++++++ arch/x86_64/kernel/traps.c | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 86d8476be4f..c447807e2a4 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -161,12 +161,19 @@ dump_trace_unwind(struct unwind_frame_info *info, void *data) { struct ops_and_data *oad = (struct ops_and_data *)data; int n = 0; + unsigned long sp = UNW_SP(info); + if (arch_unw_user_mode(info)) + return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) + && sp > UNW_SP(info)) + break; + sp = UNW_SP(info); } return n; } diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 9864d195c40..4fdd162f0be 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -225,12 +225,19 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) { struct ops_and_data *oad = (struct ops_and_data *)context; int n = 0; + unsigned long sp = UNW_SP(info); + if (arch_unw_user_mode(info)) + return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) + && sp > UNW_SP(info)) + break; + sp = UNW_SP(info); } return n; } -- cgit v1.2.3 From a0429d0d7a6116dedcb71d9128da904bf135f189 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Remove unwind stack pointer alignment forcing again This was added as a workaround for the fallback unwinder not supporting unaligned stack pointers properly. But now it was fixed to do that, so it's not needed anymore Cc: mingo@elte.hu Signed-off-by: Andi Kleen --- arch/x86_64/kernel/traps.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 4fdd162f0be..a1641ffdffc 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -309,12 +309,6 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, if (tsk && tsk != current) stack = (unsigned long *)tsk->thread.rsp; } - /* - * Align the stack pointer on word boundary, later loops - * rely on that (and corruption / debug info bugs can cause - * unaligned values here): - */ - stack = (unsigned long *)((unsigned long)stack & ~(sizeof(long)-1)); /* * Print function call entries within a stack. 'cond' is the -- cgit v1.2.3 From d331e739f5ad2aaa9d8553891ba6ca823bdbce37 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Fix interrupt race in idle callback (3rd try) Idle callbacks has some races when enter_idle() sets isidle and subsequent interrupts that can happen on that CPU, before CPU goes to idle. Due to this, an IDLE_END can get called before IDLE_START. To avoid these races, disable interrupts before enter_idle and make sure that all idle routines do not enable interrupts before entering idle. Note that poll_idle() still has a this race as it has to enable interrupts before going to idle. But, all other idle routines have the race fixed. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Andi Kleen --- arch/x86_64/kernel/process.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 0b7b4caa4f7..a418ee4c8c6 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -127,6 +127,7 @@ static void default_idle(void) */ static void poll_idle (void) { + local_irq_enable(); cpu_relax(); } @@ -208,6 +209,12 @@ void cpu_idle (void) idle = default_idle; if (cpu_is_offline(smp_processor_id())) play_dead(); + /* + * Idle routines should keep interrupts disabled + * from here on, until they go to idle. + * Otherwise, idle callbacks can misfire. + */ + local_irq_disable(); enter_idle(); idle(); /* In many cases the interrupt that ended idle @@ -245,8 +252,16 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { - local_irq_enable(); - mwait_idle_with_hints(0,0); + if (!need_resched()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) + __sti_mwait(0, 0); + else + local_irq_enable(); + } else { + local_irq_enable(); + } } void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) -- cgit v1.2.3 From 3807fd46e94ab9f09e5ee3bff5e6515a94e9b3c7 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Clarify error message in GART code - Remove "Disabling IOMMU" message because it confuses people - Clarify that the GART IOMMU is refered to in other message Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-gart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 16261a8a330..fc1960f1f24 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -601,10 +601,9 @@ void __init gart_iommu_init(void) (!force_iommu && end_pfn <= MAX_DMA32_PFN) || !iommu_aperture || (no_agp && init_k8_gatt(&info) < 0)) { - printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); if (end_pfn > MAX_DMA32_PFN) { printk(KERN_ERR "WARNING more than 4GB of memory " - "but IOMMU not available.\n" + "but GART IOMMU not available.\n" KERN_ERR "WARNING 32bit PCI may malfunction.\n"); } return; -- cgit v1.2.3 From d5d2448d896fbb9a427ee12eb8e5f6309f2473f7 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Fix numaq build error CC arch/i386/boot/compressed/misc.o arch/i386/boot/compressed/misc.c:120: error: static declaration of 'xquad_portio' follows non-static declaration include/asm/io.h:275: error: previous declaration of 'xquad_portio' was here make[2]: *** [arch/i386/boot/compressed/misc.o] Error 1 Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/boot/compressed/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c index c6798c75c67..1ce7017fd62 100644 --- a/arch/i386/boot/compressed/misc.c +++ b/arch/i386/boot/compressed/misc.c @@ -196,7 +196,7 @@ static int vidport; static int lines, cols; #ifdef CONFIG_X86_NUMAQ -static void * xquad_portio = NULL; +void *xquad_portio; #endif #include "../../../../lib/inflate.c" -- cgit v1.2.3 From 9cfa5b5dfafcfe64c1a48906f243cdd302f82471 Mon Sep 17 00:00:00 2001 From: Burman Yan Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: replace kmalloc+memset with kzalloc in MTRR code Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/mtrr/if.c | 3 +-- arch/i386/kernel/cpu/mtrr/main.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mtrr/if.c b/arch/i386/kernel/cpu/mtrr/if.c index 9753bc6a1f3..5ae1705eafa 100644 --- a/arch/i386/kernel/cpu/mtrr/if.c +++ b/arch/i386/kernel/cpu/mtrr/if.c @@ -44,10 +44,9 @@ mtrr_file_add(unsigned long base, unsigned long size, max = num_var_ranges; if (fcount == NULL) { - fcount = kmalloc(max * sizeof *fcount, GFP_KERNEL); + fcount = kzalloc(max * sizeof *fcount, GFP_KERNEL); if (!fcount) return -ENOMEM; - memset(fcount, 0, max * sizeof *fcount); FILE_FCOUNT(file) = fcount; } if (!page) { diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index aeea23e8a05..16bb7ea8714 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c @@ -596,10 +596,8 @@ static int mtrr_save(struct sys_device * sysdev, pm_message_t state) int i; int size = num_var_ranges * sizeof(struct mtrr_value); - mtrr_state = kmalloc(size,GFP_ATOMIC); - if (mtrr_state) - memset(mtrr_state,0,size); - else + mtrr_state = kzalloc(size,GFP_ATOMIC); + if (!mtrr_state) return -ENOMEM; for (i = 0; i < num_var_ranges; i++) { -- cgit v1.2.3 From f475ff352c5e05d473c462b97c3a13a5b803af5a Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: remove unused variable Remove unused variable in msr_write(). Reported by D Binderman . Cc: H. Peter Anvin Signed-off-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/msr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index a773f776c9e..fd45059c908 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -195,7 +195,6 @@ static ssize_t msr_write(struct file *file, const char __user *buf, { const u32 __user *tmp = (const u32 __user *)buf; u32 data[2]; - size_t rv; u32 reg = *ppos; int cpu = iminor(file->f_dentry->d_inode); int err; @@ -203,7 +202,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, if (count % 8) return -EINVAL; /* Invalid chunk size */ - for (rv = 0; count; count -= 8) { + for (; count; count -= 8) { if (copy_from_user(&data, tmp, 8)) return -EFAULT; err = do_wrmsr(cpu, reg, data[0], data[1]); -- cgit v1.2.3 From d7fb02712818643bab79a6b3cb8270a747d0227b Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] x86-64: remove remaining pc98 code Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/io_apic.c | 23 ++--------------------- arch/i386/kernel/mpparse.c | 2 -- 2 files changed, 2 insertions(+), 23 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 56f571c9fc0..7f015a71ab5 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -842,8 +842,7 @@ static int __init find_isa_irq_pin(int irq, int type) if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA || - mp_bus_id_to_type[lbus] == MP_BUS_NEC98 + mp_bus_id_to_type[lbus] == MP_BUS_MCA ) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -862,8 +861,7 @@ static int __init find_isa_irq_apic(int irq, int type) if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || mp_bus_id_to_type[lbus] == MP_BUS_EISA || - mp_bus_id_to_type[lbus] == MP_BUS_MCA || - mp_bus_id_to_type[lbus] == MP_BUS_NEC98 + mp_bus_id_to_type[lbus] == MP_BUS_MCA ) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -993,12 +991,6 @@ static int EISA_ELCR(unsigned int irq) #define default_MCA_trigger(idx) (1) #define default_MCA_polarity(idx) (0) -/* NEC98 interrupts are always polarity zero edge triggered, - * when listed as conforming in the MP table. */ - -#define default_NEC98_trigger(idx) (0) -#define default_NEC98_polarity(idx) (0) - static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; @@ -1033,11 +1025,6 @@ static int __init MPBIOS_polarity(int idx) polarity = default_MCA_polarity(idx); break; } - case MP_BUS_NEC98: /* NEC 98 pin */ - { - polarity = default_NEC98_polarity(idx); - break; - } default: { printk(KERN_WARNING "broken BIOS!!\n"); @@ -1107,11 +1094,6 @@ static int MPBIOS_trigger(int idx) trigger = default_MCA_trigger(idx); break; } - case MP_BUS_NEC98: /* NEC 98 pin */ - { - trigger = default_NEC98_trigger(idx); - break; - } default: { printk(KERN_WARNING "broken BIOS!!\n"); @@ -1173,7 +1155,6 @@ static int pin_2_irq(int idx, int apic, int pin) case MP_BUS_ISA: /* ISA pin */ case MP_BUS_EISA: case MP_BUS_MCA: - case MP_BUS_NEC98: { irq = mp_irqs[idx].mpc_srcbusirq; break; diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 442aaf8c77e..2ce67228dff 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -249,8 +249,6 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mp_current_pci_id++; } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; - } else if (strncmp(str, BUSTYPE_NEC98, sizeof(BUSTYPE_NEC98)-1) == 0) { - mp_bus_id_to_type[m->mpc_busid] = MP_BUS_NEC98; } else { printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); } -- cgit v1.2.3 From 116780fc04d9f6cd3ceeab0251681f1dfda53367 Mon Sep 17 00:00:00 2001 From: Burman Yan Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] i386: replace kmalloc+memset with kzalloc Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/cpu/intel_cacheinfo.c | 11 +++-------- arch/i386/kernel/mca.c | 13 ++++--------- arch/i386/kernel/pci-dma.c | 6 ++---- arch/i386/mach-voyager/voyager_cat.c | 6 ++---- 4 files changed, 11 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 5c43be47587..80b4c5d421b 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -480,12 +480,10 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) if (num_cache_leaves == 0) return -ENOENT; - cpuid4_info[cpu] = kmalloc( + cpuid4_info[cpu] = kzalloc( sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); if (unlikely(cpuid4_info[cpu] == NULL)) return -ENOMEM; - memset(cpuid4_info[cpu], 0, - sizeof(struct _cpuid4_info) * num_cache_leaves); oldmask = current->cpus_allowed; retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); @@ -658,17 +656,14 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) return -ENOENT; /* Allocate all required memory */ - cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL); + cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); if (unlikely(cache_kobject[cpu] == NULL)) goto err_out; - memset(cache_kobject[cpu], 0, sizeof(struct kobject)); - index_kobject[cpu] = kmalloc( + index_kobject[cpu] = kzalloc( sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); if (unlikely(index_kobject[cpu] == NULL)) goto err_out; - memset(index_kobject[cpu], 0, - sizeof(struct _index_kobject) * num_cache_leaves); return 0; diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c index eb57a851789..b83672b8952 100644 --- a/arch/i386/kernel/mca.c +++ b/arch/i386/kernel/mca.c @@ -283,10 +283,9 @@ static int __init mca_init(void) bus->f.mca_transform_memory = mca_dummy_transform_memory; /* get the motherboard device */ - mca_dev = kmalloc(sizeof(struct mca_device), GFP_KERNEL); + mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); if(unlikely(!mca_dev)) goto out_nomem; - memset(mca_dev, 0, sizeof(struct mca_device)); /* * We do not expect many MCA interrupts during initialization, @@ -310,11 +309,9 @@ static int __init mca_init(void) mca_dev->slot = MCA_MOTHERBOARD; mca_register_device(MCA_PRIMARY_BUS, mca_dev); - mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; - memset(mca_dev, 0, sizeof(struct mca_device)); - /* Put motherboard into video setup mode, read integrated video * POS registers, and turn motherboard setup off. @@ -349,10 +346,9 @@ static int __init mca_init(void) } if(which_scsi) { /* found a scsi card */ - mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; - memset(mca_dev, 0, sizeof(struct mca_device)); for(j = 0; j < 8; j++) mca_dev->pos[j] = pos[j]; @@ -378,10 +374,9 @@ static int __init mca_init(void) if(!mca_read_and_store_pos(pos)) continue; - mca_dev = kmalloc(sizeof(struct mca_device), GFP_ATOMIC); + mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); if(unlikely(!mca_dev)) goto out_unlock_nomem; - memset(mca_dev, 0, sizeof(struct mca_device)); for(j=0; j<8; j++) mca_dev->pos[j]=pos[j]; diff --git a/arch/i386/kernel/pci-dma.c b/arch/i386/kernel/pci-dma.c index 5c8c6ef1fc5..41af692c158 100644 --- a/arch/i386/kernel/pci-dma.c +++ b/arch/i386/kernel/pci-dma.c @@ -92,14 +92,12 @@ int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr, if (!mem_base) goto out; - dev->dma_mem = kmalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); + dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); if (!dev->dma_mem) goto out; - memset(dev->dma_mem, 0, sizeof(struct dma_coherent_mem)); - dev->dma_mem->bitmap = kmalloc(bitmap_size, GFP_KERNEL); + dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL); if (!dev->dma_mem->bitmap) goto free1_out; - memset(dev->dma_mem->bitmap, 0, bitmap_size); dev->dma_mem->virt_base = mem_base; dev->dma_mem->device_base = device_addr; diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c index f50c6c6ad68..943a9473b13 100644 --- a/arch/i386/mach-voyager/voyager_cat.c +++ b/arch/i386/mach-voyager/voyager_cat.c @@ -776,7 +776,7 @@ voyager_cat_init(void) for(asic=0; asic < (*modpp)->num_asics; asic++) { int j; voyager_asic_t *asicp = *asicpp - = kmalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/ + = kzalloc(sizeof(voyager_asic_t), GFP_KERNEL); /*&voyager_asic_storage[asic_count++];*/ voyager_sp_table_t *sp_table; voyager_at_t *asic_table; voyager_jtt_t *jtag_table; @@ -785,7 +785,6 @@ voyager_cat_init(void) printk("**WARNING** kmalloc failure in cat_init\n"); continue; } - memset(asicp, 0, sizeof(voyager_asic_t)); asicpp = &(asicp->next); asicp->asic_location = asic; sp_table = (voyager_sp_table_t *)(eprom_buf + sp_offset); @@ -851,8 +850,7 @@ voyager_cat_init(void) #endif { - struct resource *res = kmalloc(sizeof(struct resource),GFP_KERNEL); - memset(res, 0, sizeof(struct resource)); + struct resource *res = kzalloc(sizeof(struct resource),GFP_KERNEL); res->name = kmalloc(128, GFP_KERNEL); sprintf((char *)res->name, "Voyager %s Quad CPI", cat_module_name(i)); res->start = qic_addr; -- cgit v1.2.3 From f6ca8083c261864fc9de94ef99c3311ea259c5c3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] x86-64: Make ix86 default to HIGHMEM4G instead of NOHIGHMEM Generally better for allmodconfig coverage. Signed-off-by: Randy Dunlap Signed-off-by: Andi Kleen Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index b6b2df40ca7..ea70359b02d 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -454,7 +454,8 @@ source "drivers/firmware/Kconfig" choice prompt "High Memory Support" - default NOHIGHMEM + default HIGHMEM4G if !X86_NUMAQ + default HIGHMEM64G if X86_NUMAQ config NOHIGHMEM bool "off" -- cgit v1.2.3 From ad892f5e0d01f3c3b475a688d1ddc211cf3ea56d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] x86-64: check vector in setup_ioapic_dest to verify if need setup_IO_APIC_irq setup_IO_APIC_irqs could fail to get vector for some device when you have too many devices, because at that time only boot cpu is online. So check vector for irq in setup_ioapic_dest and call setup_IO_APIC_irq to make sure IO-APIC irq-routing table is initialized. Also seperate setup_IO_APIC_irq from setup_IO_APIC_irqs. Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Eric W. Biederman" Cc: Ingo Molnar Signed-off-by: Andrew Morton --- arch/x86_64/kernel/io_apic.c | 104 +++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 43 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index eaf0b708e67..2a1dcd5f69c 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -789,27 +789,65 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) handle_edge_irq, "edge"); } } - -static void __init setup_IO_APIC_irqs(void) +static void __init setup_IO_APIC_irq(int apic, int pin, int idx, int irq) { struct IO_APIC_route_entry entry; - int apic, pin, idx, irq, first_notcon = 1, vector; + int vector; unsigned long flags; - apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); - for (apic = 0; apic < nr_ioapics; apic++) { - for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { + /* + * add it to the IO-APIC irq-routing table: + */ + memset(&entry,0,sizeof(entry)); - /* - * add it to the IO-APIC irq-routing table: - */ - memset(&entry,0,sizeof(entry)); + entry.delivery_mode = INT_DELIVERY_MODE; + entry.dest_mode = INT_DEST_MODE; + entry.mask = 0; /* enable IRQ */ + entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); + + entry.trigger = irq_trigger(idx); + entry.polarity = irq_polarity(idx); - entry.delivery_mode = INT_DELIVERY_MODE; - entry.dest_mode = INT_DEST_MODE; - entry.mask = 0; /* enable IRQ */ + if (irq_trigger(idx)) { + entry.trigger = 1; + entry.mask = 1; entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); + } + + if (!apic && !IO_APIC_IRQ(irq)) + return; + + if (IO_APIC_IRQ(irq)) { + cpumask_t mask; + vector = assign_irq_vector(irq, TARGET_CPUS, &mask); + if (vector < 0) + return; + + entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask); + entry.vector = vector; + + ioapic_register_intr(irq, vector, IOAPIC_AUTO); + if (!apic && (irq < 16)) + disable_8259A_irq(irq); + } + + ioapic_write_entry(apic, pin, entry); + + spin_lock_irqsave(&ioapic_lock, flags); + set_native_irq_info(irq, TARGET_CPUS); + spin_unlock_irqrestore(&ioapic_lock, flags); + +} + +static void __init setup_IO_APIC_irqs(void) +{ + int apic, pin, idx, irq, first_notcon = 1; + + apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n"); + + for (apic = 0; apic < nr_ioapics; apic++) { + for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { idx = find_irq_entry(apic,pin,mp_INT); if (idx == -1) { @@ -821,39 +859,11 @@ static void __init setup_IO_APIC_irqs(void) continue; } - entry.trigger = irq_trigger(idx); - entry.polarity = irq_polarity(idx); - - if (irq_trigger(idx)) { - entry.trigger = 1; - entry.mask = 1; - entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS); - } - irq = pin_2_irq(idx, apic, pin); add_pin_to_irq(irq, apic, pin); - if (!apic && !IO_APIC_IRQ(irq)) - continue; + setup_IO_APIC_irq(apic, pin, idx, irq); - if (IO_APIC_IRQ(irq)) { - cpumask_t mask; - vector = assign_irq_vector(irq, TARGET_CPUS, &mask); - if (vector < 0) - continue; - - entry.dest.logical.logical_dest = cpu_mask_to_apicid(mask); - entry.vector = vector; - - ioapic_register_intr(irq, vector, IOAPIC_AUTO); - if (!apic && (irq < 16)) - disable_8259A_irq(irq); - } - ioapic_write_entry(apic, pin, entry); - - spin_lock_irqsave(&ioapic_lock, flags); - set_native_irq_info(irq, TARGET_CPUS); - spin_unlock_irqrestore(&ioapic_lock, flags); } } @@ -2139,7 +2149,15 @@ void __init setup_ioapic_dest(void) if (irq_entry == -1) continue; irq = pin_2_irq(irq_entry, ioapic, pin); - set_ioapic_affinity_irq(irq, TARGET_CPUS); + + /* setup_IO_APIC_irqs could fail to get vector for some device + * when you have too many devices, because at that time only boot + * cpu is online. + */ + if(!irq_vector[irq]) + setup_IO_APIC_irq(ioapic, pin, irq_entry, irq); + else + set_ioapic_affinity_irq(irq, TARGET_CPUS); } } -- cgit v1.2.3 From 6bedb2ccb02dcc70ffc8eb76df71c746378190ad Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] x86-64: don't use set_irq_regs() We don't need to setup _irq_regs in smp_xxx_interrupt (except apic timer). These handlers run with irqs disabled and do not call functions which need "struct pt_regs". Signed-off-by: Oleg Nesterov Signed-off-by: Andi Kleen Acked-by: Ingo Molnar Cc: Andi Kleen Acked-By: David Howells Signed-off-by: Andrew Morton --- arch/i386/kernel/smp.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 31e5c6573aa..1b080ab8a49 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -321,7 +321,6 @@ static inline void leave_mm (unsigned long cpu) fastcall void smp_invalidate_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); unsigned long cpu; cpu = get_cpu(); @@ -352,7 +351,6 @@ fastcall void smp_invalidate_interrupt(struct pt_regs *regs) smp_mb__after_clear_bit(); out: put_cpu_no_resched(); - set_irq_regs(old_regs); } static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, @@ -607,14 +605,11 @@ void smp_send_stop(void) */ fastcall void smp_reschedule_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); ack_APIC_irq(); - set_irq_regs(old_regs); } fastcall void smp_call_function_interrupt(struct pt_regs *regs) { - struct pt_regs *old_regs = set_irq_regs(regs); void (*func) (void *info) = call_data->func; void *info = call_data->info; int wait = call_data->wait; @@ -637,7 +632,6 @@ fastcall void smp_call_function_interrupt(struct pt_regs *regs) mb(); atomic_inc(&call_data->finished); } - set_irq_regs(old_regs); } /* -- cgit v1.2.3 From b65780e123ba9b762276482bbfb52836e4d41fd9 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] unwinder: move .eh_frame to RODATA The .eh_frame section contents is never written to, so it can as well benefit from CONFIG_DEBUG_RODATA. Diff-ed against firstfloor tree. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 9 --------- arch/x86_64/kernel/vmlinux.lds.S | 9 --------- 2 files changed, 18 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 25581e87c60..56e6ad5cb04 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -102,15 +102,6 @@ SECTIONS _edata = .; /* End of data section */ } -#ifdef CONFIG_STACK_UNWIND - . = ALIGN(4); - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { - __start_unwind = .; - *(.eh_frame) - __end_unwind = .; - } -#endif - . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index d9534e750d4..6a1f8f491e5 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -51,15 +51,6 @@ SECTIONS RODATA -#ifdef CONFIG_STACK_UNWIND - . = ALIGN(8); - .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { - __start_unwind = .; - *(.eh_frame) - __end_unwind = .; - } -#endif - . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { -- cgit v1.2.3 From d9408cefe677636bc1c100fdcfac0b2ab9ff87bf Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] i386: Clean up smp_tune_scheduling() - remove the write-only local variable "bandwidth" - don't set "max_cache_size" in the (cachesize < 0) case: that's already handled in kernel/sched.c:measure_migration_cost() Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen Acked-by: Ingo Molnar Signed-off-by: Andrew Morton --- arch/i386/kernel/smpboot.c | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 346f27f4c79..b4e6f32de45 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1130,34 +1130,15 @@ exit: } #endif -static void smp_tune_scheduling (void) +static void smp_tune_scheduling(void) { unsigned long cachesize; /* kB */ - unsigned long bandwidth = 350; /* MB/s */ - /* - * Rough estimation for SMP scheduling, this is the number of - * cycles it takes for a fully memory-limited process to flush - * the SMP-local cache. - * - * (For a P5 this pretty much means we will choose another idle - * CPU almost always at wakeup time (this is due to the small - * L1 cache), on PIIs it's around 50-100 usecs, depending on - * the cache size) - */ - if (!cpu_khz) { - /* - * this basically disables processor-affinity - * scheduling on SMP without a TSC. - */ - return; - } else { + if (cpu_khz) { cachesize = boot_cpu_data.x86_cache_size; - if (cachesize == -1) { - cachesize = 16; /* Pentiums, 2x8kB cache */ - bandwidth = 100; - } - max_cache_size = cachesize * 1024; + + if (cachesize > 0) + max_cache_size = cachesize * 1024; } } -- cgit v1.2.3 From 64a26a731235b59c9d73bbe82c1f896d57400d37 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:19 +0100 Subject: [PATCH] x86-64: Export smp_call_function_single smp_call_function() is exported, makes sense to export this one too. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 9f74c883568..1bf0e094f43 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -385,6 +385,7 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, put_cpu(); return 0; } +EXPORT_SYMBOL(smp_call_function_single); /* * this function sends a 'generic call function' IPI to all other CPUs -- cgit v1.2.3 From 5636810d6f17493717ef0f03efc0315026db934d Mon Sep 17 00:00:00 2001 From: "George G. Davis" Date: Tue, 5 Dec 2006 18:28:04 +0100 Subject: [ARM] 3982/2: Explicitly select 32-bit ARM ISA (-marm) Do not assume that the ARM GCC toolchain defaults to building for the 32-bit ARM ISA (-marm) case. Instead, explicitly select -marm in CFLAGS since the toolchain default can be for the 16-bit Thumb ISA (-mthumb) in some odd/rare cases. Signed-off-by: George G. Davis Signed-off-by: Russell King --- arch/arm/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6f4f8bf3607..b6001f97c80 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -15,6 +15,8 @@ CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 #CFLAGS +=-pipe +# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: +CFLAGS +=$(call cc-option,-marm,) # Do not use arch/arm/defconfig - it's always outdated. # Select a platform tht is kept up-to-date -- cgit v1.2.3 From 47d7e524b7d51aa77b381fbc9b9c5d3f309e434e Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 6 Dec 2006 23:07:13 +0100 Subject: [ARM] 3993/1: ep93xx: add cirrus logic edb9302a support Add support for the Cirrus Logic EDB9302A Evaluation Board. Confirmed to work by Chase Douglas. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-ep93xx/Kconfig | 6 +++ arch/arm/mach-ep93xx/Makefile | 1 + arch/arm/mach-ep93xx/edb9302a.c | 91 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 arch/arm/mach-ep93xx/edb9302a.c (limited to 'arch') diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig index fcc5e2500dc..af7904b3d0a 100644 --- a/arch/arm/mach-ep93xx/Kconfig +++ b/arch/arm/mach-ep93xx/Kconfig @@ -21,6 +21,12 @@ config MACH_EDB9302 Say 'Y' here if you want your kernel to support the Cirrus Logic EDB9302 Evaluation Board. +config MACH_EDB9302A + bool "Support Cirrus Logic EDB9302A" + help + Say 'Y' here if you want your kernel to support the Cirrus + Logic EDB9302A Evaluation Board. + config MACH_EDB9312 bool "Support Cirrus Logic EDB9312" help diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile index bd09cddbc52..b06641dd450 100644 --- a/arch/arm/mach-ep93xx/Makefile +++ b/arch/arm/mach-ep93xx/Makefile @@ -8,6 +8,7 @@ obj- := obj-$(CONFIG_MACH_ADSSPHERE) += adssphere.o obj-$(CONFIG_MACH_EDB9302) += edb9302.o +obj-$(CONFIG_MACH_EDB9302A) += edb9302a.o obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o diff --git a/arch/arm/mach-ep93xx/edb9302a.c b/arch/arm/mach-ep93xx/edb9302a.c new file mode 100644 index 00000000000..62e064bab1d --- /dev/null +++ b/arch/arm/mach-ep93xx/edb9302a.c @@ -0,0 +1,91 @@ +/* + * arch/arm/mach-ep93xx/edb9302a.c + * Cirrus Logic EDB9302A support. + * + * Copyright (C) 2006 Lennert Buytenhek + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct physmap_flash_data edb9302a_flash_data = { + .width = 2, +}; + +static struct resource edb9302a_flash_resource = { + .start = 0x60000000, + .end = 0x60ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device edb9302a_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edb9302a_flash_data, + }, + .num_resources = 1, + .resource = &edb9302a_flash_resource, +}; + +static struct ep93xx_eth_data edb9302a_eth_data = { + .phy_id = 1, +}; + +static struct resource edb9302a_eth_resource[] = { + { + .start = EP93XX_ETHERNET_PHYS_BASE, + .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_EP93XX_ETHERNET, + .end = IRQ_EP93XX_ETHERNET, + .flags = IORESOURCE_IRQ, + } +}; + +static struct platform_device edb9302a_eth_device = { + .name = "ep93xx-eth", + .id = -1, + .dev = { + .platform_data = &edb9302a_eth_data, + }, + .num_resources = 2, + .resource = edb9302a_eth_resource, +}; + +static void __init edb9302a_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&edb9302a_flash); + + memcpy(edb9302a_eth_data.dev_addr, + (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); + platform_device_register(&edb9302a_eth_device); +} + +MACHINE_START(EDB9302A, "Cirrus Logic EDB9302A Evaluation Board") + /* Maintainer: Lennert Buytenhek */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = edb9302a_init_machine, +MACHINE_END -- cgit v1.2.3 From 2f1675c11a0a214855ff6cba23aca239eef7a5fb Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 4 Dec 2006 20:25:47 +0100 Subject: [ARM] 3979/1: extend the SA11x0 sched_clock implementation from 32 to 63 bit period This provides a 63 bit clock counter guaranteed to be monotonic over a period of 370 days instead of a clock wrap every 19.4 minutes, as long as sched_clock() is called at least once every 9.7 minutes which shouldn't be a problem in practice. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-sa1100/generic.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 4575f316e14..e510295c258 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -118,15 +119,21 @@ EXPORT_SYMBOL(cpufreq_get); /* * This is the SA11x0 sched_clock implementation. This has - * a resolution of 271ns, and a maximum value of 1165s. + * a resolution of 271ns, and a maximum value of 32025597s (370 days). + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 582 seconds between successive + * calls to this function. + * * ( * 1E9 / 3686400 => * 78125 / 288) */ unsigned long long sched_clock(void) { - unsigned long long v; + unsigned long long v = cnt32_to_63(OSCR); - v = (unsigned long long)OSCR * 78125; - do_div(v, 288); + /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ + v *= 78125<<1; + do_div(v, 288<<1); return v; } -- cgit v1.2.3 From 752bee178ee107aa3dd87a9aeba970444034c6fb Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 4 Dec 2006 20:29:21 +0100 Subject: [ARM] 3980/1: extend the ARM Versatile sched_clock implementation from 32 to 63 bit period This provides a 63 bit clock counter guaranteed to be monotonic over a period of 35583 days instead of a clock wrap every 179 seconds, as long as sched_clock() is called at least once every 89 seconds. This should not be a problem in practice, although a kernel timer could be scheduled every 80 seconds for example simply to call sched_clock() making sure top bits are always synchronized if need be. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-versatile/core.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3b8576111c1..998b398df30 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -228,14 +229,19 @@ void __init versatile_map_io(void) /* * This is the Versatile sched_clock implementation. This has - * a resolution of 41.7ns, and a maximum value of about 179s. + * a resolution of 41.7ns, and a maximum value of about 35583 days. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 89 seconds between successive + * calls to this function. */ unsigned long long sched_clock(void) { - unsigned long long v; + unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER)); - v = (unsigned long long)readl(VERSATILE_REFCOUNTER) * 125; - do_div(v, 3); + /* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */ + v *= 125<<1; + do_div(v, 3<<1); return v; } -- cgit v1.2.3 From 2dc20a51dc1e2da6eae1182cfe4c4835fca26017 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Mon, 4 Dec 2006 20:42:09 +0100 Subject: [ARM] 3981/1: sched_clock for PXA2xx Here's a 63-bit implementation of shed_clock() for PXA2xx. The actual period depends on the value of CLOCK_TICK_RATE and whether or not reduced scaling factors were provided for it. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/generic.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 45fb2c3bcf8..6ae605857ca 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -25,6 +25,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -40,6 +44,62 @@ #include "generic.h" +/* + * This is the PXA2xx sched_clock implementation. This has a resolution + * of at least 308ns and a maximum value that depends on the value of + * CLOCK_TICK_RATE. + * + * The return value is guaranteed to be monotonic in that range as + * long as there is always less than 582 seconds between successive + * calls to this function. + */ +unsigned long long sched_clock(void) +{ + unsigned long long v = cnt32_to_63(OSCR); + /* Note: top bit ov v needs cleared unless multiplier is even. */ + +#if CLOCK_TICK_RATE == 3686400 + /* 1E9 / 3686400 => 78125 / 288, max value = 32025597s (370 days). */ + /* The <<1 is used to get rid of tick.hi top bit */ + v *= 78125<<1; + do_div(v, 288<<1); +#elif CLOCK_TICK_RATE == 3250000 + /* 1E9 / 3250000 => 4000 / 13, max value = 709490156s (8211 days) */ + v *= 4000; + do_div(v, 13); +#elif CLOCK_TICK_RATE == 3249600 + /* 1E9 / 3249600 => 625000 / 2031, max value = 4541295s (52 days) */ + v *= 625000; + do_div(v, 2031); +#else +#warning "consider fixing sched_clock for your value of CLOCK_TICK_RATE" + /* + * 96-bit math to perform tick * NSEC_PER_SEC / CLOCK_TICK_RATE for + * any value of CLOCK_TICK_RATE. Max value is in the 80 thousand + * years range which is nice, but with higher computation cost. + */ + { + union { + unsigned long long val; + struct { unsigned long lo, hi; }; + } x; + unsigned long long y; + + x.val = v; + x.hi &= 0x7fffffff; + y = (unsigned long long)x.lo * NSEC_PER_SEC; + x.lo = y; + y = (y >> 32) + (unsigned long long)x.hi * NSEC_PER_SEC; + x.hi = do_div(y, CLOCK_TICK_RATE); + do_div(x.val, CLOCK_TICK_RATE); + x.hi += y; + v = x.val; + } +#endif + + return v; +} + /* * Handy function to set GPIO alternate functions */ -- cgit v1.2.3 From 46156e04def20749c46efd8fc40e3527eae97b49 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 6 Dec 2006 23:11:33 +0100 Subject: [ARM] 3994/1: ixp23xx: fix handling of pci master aborts The PCI master abort handling issue that affected ixp2000 also affects ixp23xx. Signed-off-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-ixp23xx/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 3b34fa35e36..ac7d43d23c2 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c @@ -36,7 +36,7 @@ extern int (*external_fault) (unsigned long, struct pt_regs *); -static int pci_master_aborts = 0; +static volatile int pci_master_aborts = 0; #ifdef DEBUG #define DBG(x...) printk(x) -- cgit v1.2.3 From f9a8ca1cabf09316d79cab7f04e1390261ff9035 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 6 Dec 2006 00:45:07 +0100 Subject: [ARM] 3985/1: ixp4xx clocksource cleanup Rather than using a device_initcall() for the clocksource initialization, just call the init from the sys_timer init function. Signed-off-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 1cf3bde1a5d..2ec9a9e9a04 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -40,6 +40,8 @@ #include #include +static int __init ixp4xx_clocksource_init(void); + /************************************************************************* * IXP4xx chipset I/O mapping *************************************************************************/ @@ -281,6 +283,8 @@ static void __init ixp4xx_timer_init(void) /* Connect the interrupt handler and enable the interrupt */ setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); + + ixp4xx_clocksource_init(); } struct sys_timer ixp4xx_timer = { @@ -404,5 +408,3 @@ static int __init ixp4xx_clocksource_init(void) return 0; } - -device_initcall(ixp4xx_clocksource_init); -- cgit v1.2.3 From 9073341c2ba5d5e77b3d05d84cf9e3a16e8a7902 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 6 Dec 2006 01:50:24 +0100 Subject: [ARM] 3986/1: H1940: suspend to RAM support Add support to suspend and resume, using the H1940's bootloader Signed-off-by: Ben Dooks Signed-off-by: Arnaud Patard Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Makefile | 2 +- arch/arm/mach-s3c2410/mach-h1940.c | 8 +++++++- arch/arm/mach-s3c2410/pm-h1940.S | 33 +++++++++++++++++++++++++++++++++ arch/arm/mach-s3c2410/s3c2410-pm.c | 14 ++++++++++++++ arch/arm/mm/mmu.c | 5 +++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 arch/arm/mach-s3c2410/pm-h1940.S (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index d66013365b6..0cd71dfec44 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -77,7 +77,7 @@ obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o -obj-$(CONFIG_ARCH_H1940) += mach-h1940.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o pm-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 8c895c077d2..f5b98099a5d 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -41,6 +42,7 @@ #include "clock.h" #include "devs.h" #include "cpu.h" +#include "pm.h" static struct map_desc h1940_iodesc[] __initdata = { [0] = { @@ -164,12 +166,16 @@ static void __init h1940_map_io(void) s3c24xx_init_clocks(0); s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs)); s3c24xx_set_board(&h1940_board); + + /* setup PM */ + + memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); + s3c2410_pm_init(); } static void __init h1940_init_irq(void) { s3c24xx_init_irq(); - } static void __init h1940_init(void) diff --git a/arch/arm/mach-s3c2410/pm-h1940.S b/arch/arm/mach-s3c2410/pm-h1940.S new file mode 100644 index 00000000000..7d66de7ff7d --- /dev/null +++ b/arch/arm/mach-s3c2410/pm-h1940.S @@ -0,0 +1,33 @@ +/* linux/arch/arm/mach-s3c2410/pm-h1940.S + * + * Copyright (c) 2006 Ben Dooks + * + * H1940 Suspend to RAM + * + * 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 + * + * 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 + + .text + .global h1940_pm_return + +h1940_pm_return: + mov r0, #S3C2410_PA_GPIO + ldr pc, [ r0, #S3C2410_GSTATUS3 - S3C24XX_VA_GPIO ] diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c index e51d7666951..9cd0c104f1c 100644 --- a/arch/arm/mach-s3c2410/s3c2410-pm.c +++ b/arch/arm/mach-s3c2410/s3c2410-pm.c @@ -32,6 +32,7 @@ #include #include +#include #include "cpu.h" #include "pm.h" @@ -52,6 +53,19 @@ static void s3c2410_pm_prepare(void) DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + if (machine_is_h1940()) { + void *base = phys_to_virt(H1940_SUSPEND_CHECK); + unsigned long ptr; + unsigned long calc = 0; + + /* generate check for the bootloader to check on resume */ + + for (ptr = 0; ptr < 0x40000; ptr += 0x400) + calc += __raw_readl(base+ptr); + + __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + } + if ( machine_is_aml_m5900() ) s3c2410_gpio_setpin(S3C2410_GPF2, 1); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 445bc3b951e..f2d0d6f7897 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -619,6 +619,11 @@ void __init reserve_node_zero(pg_data_t *pgdat) if (machine_is_p720t()) res_size = 0x00014000; + if (machine_is_h1940()) { + reserve_bootmem_node(pgdat, 0x30003000, 0x1000); + reserve_bootmem_node(pgdat, 0x30081000, 0x1000); + } + #ifdef CONFIG_SA1111 /* * Because of the SA1111 DMA bug, we want to preserve our -- cgit v1.2.3 From 5c894cd1c89fc10907febd93e6ef35cd3c65e25e Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Wed, 6 Dec 2006 17:08:27 +0100 Subject: [ARM] 3990/1: i.MX/MX1 more precise PLL decode The future high resolution support inclusion utilizes imx_decode_pll() in timer base frequency computation. This use requires more precise computation without discarding 10 bits by shifting left. Signed-off-by: Pavel Pisa Acked-by: Sascha Hauer Signed-off-by: Russell King --- arch/arm/mach-imx/generic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 12ea58a3b84..b5aa49d00ca 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -104,6 +104,9 @@ EXPORT_SYMBOL(imx_gpio_mode); */ static unsigned int imx_decode_pll(unsigned int pll) { + unsigned long long ll; + unsigned long quot; + u32 mfi = (pll >> 10) & 0xf; u32 mfn = pll & 0x3ff; u32 mfd = (pll >> 16) & 0x3ff; @@ -112,7 +115,11 @@ static unsigned int imx_decode_pll(unsigned int pll) mfi = mfi <= 5 ? 5 : mfi; - return (2 * (f_ref>>10) * ( (mfi<<10) + (mfn<<10) / (mfd+1) )) / (pd+1); + ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) ); + quot = (pd+1) * (1<<16); + ll += quot / 2; + do_div(ll, quot); + return (unsigned int) ll; } unsigned int imx_get_system_clk(void) -- cgit v1.2.3 From 86987d5bf4db7850a8dfb073c6a3506d4e0d2bcc Mon Sep 17 00:00:00 2001 From: Pavel Pisa Date: Wed, 6 Dec 2006 17:19:44 +0100 Subject: [ARM] 3991/1: i.MX/MX1 high resolution time source Enhanced resolution for time measurement functions. Signed-off-by: Pavel Pisa Signed-off-by: Sascha Hauer Signed-off-by: Russell King --- arch/arm/mach-imx/time.c | 86 ++++++++++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c index 8ae4a2c5066..40039b2a90b 100644 --- a/arch/arm/mach-imx/time.c +++ b/arch/arm/mach-imx/time.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -24,33 +25,7 @@ /* Use timer 1 as system timer */ #define TIMER_BASE IMX_TIM1_BASE -/* - * Returns number of us since last clock interrupt. Note that interrupts - * will have been disabled by do_gettimeoffset() - */ -static unsigned long imx_gettimeoffset(void) -{ - unsigned long ticks; - - /* - * Get the current number of ticks. Note that there is a race - * condition between us reading the timer and checking for - * an interrupt. We get around this by ensuring that the - * counter has not reloaded between our two reads. - */ - ticks = IMX_TCN(TIMER_BASE); - - /* - * Interrupt pending? If so, we've reloaded once already. - */ - if (IMX_TSTAT(TIMER_BASE) & TSTAT_COMP) - ticks += LATCH; - - /* - * Convert the ticks to usecs - */ - return (1000000 / CLK32) * ticks; -} +static unsigned long evt_diff; /* * IRQ handler for the timer @@ -58,14 +33,23 @@ static unsigned long imx_gettimeoffset(void) static irqreturn_t imx_timer_interrupt(int irq, void *dev_id) { - write_seqlock(&xtime_lock); + uint32_t tstat; /* clear the interrupt */ - if (IMX_TSTAT(TIMER_BASE)) - IMX_TSTAT(TIMER_BASE) = 0; + tstat = IMX_TSTAT(TIMER_BASE); + IMX_TSTAT(TIMER_BASE) = 0; + + if (tstat & TSTAT_COMP) { + do { + + write_seqlock(&xtime_lock); + timer_tick(); + write_sequnlock(&xtime_lock); + IMX_TCMP(TIMER_BASE) += evt_diff; - timer_tick(); - write_sequnlock(&xtime_lock); + } while (unlikely((int32_t)(IMX_TCMP(TIMER_BASE) + - IMX_TCN(TIMER_BASE)) < 0)); + } return IRQ_HANDLED; } @@ -77,9 +61,9 @@ static struct irqaction imx_timer_irq = { }; /* - * Set up timer interrupt, and return the current time in seconds. + * Set up timer hardware into expected mode and state. */ -static void __init imx_timer_init(void) +static void __init imx_timer_hardware_init(void) { /* * Initialise to a known state (all timers off, and timing reset) @@ -87,7 +71,38 @@ static void __init imx_timer_init(void) IMX_TCTL(TIMER_BASE) = 0; IMX_TPRER(TIMER_BASE) = 0; IMX_TCMP(TIMER_BASE) = LATCH - 1; - IMX_TCTL(TIMER_BASE) = TCTL_CLK_32 | TCTL_IRQEN | TCTL_TEN; + + IMX_TCTL(TIMER_BASE) = TCTL_FRR | TCTL_CLK_PCLK1 | TCTL_IRQEN | TCTL_TEN; + evt_diff = LATCH; +} + +cycle_t imx_get_cycles(void) +{ + return IMX_TCN(TIMER_BASE); +} + +static struct clocksource clocksource_imx = { + .name = "imx_timer1", + .rating = 200, + .read = imx_get_cycles, + .mask = 0xFFFFFFFF, + .shift = 20, + .is_continuous = 1, +}; + +static int __init imx_clocksource_init(void) +{ + clocksource_imx.mult = + clocksource_hz2mult(imx_get_perclk1(), clocksource_imx.shift); + clocksource_register(&clocksource_imx); + + return 0; +} + +static void __init imx_timer_init(void) +{ + imx_timer_hardware_init(); + imx_clocksource_init(); /* * Make irqs happen for the system timer @@ -97,5 +112,4 @@ static void __init imx_timer_init(void) struct sys_timer imx_timer = { .init = imx_timer_init, - .offset = imx_gettimeoffset, }; -- cgit v1.2.3 From 05f96ef1189ecbf2e8548056a0ca016e4f630cef Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Nov 2006 20:44:49 +0000 Subject: [ARM] Allow gcc to optimise arm_add_memory a little more For some reason, gcc was calculating meminfo.bank[meminfo.nr_banks] repeatedly. Use a pointer to it instead. Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 29efc9f8205..75f1764933a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -441,16 +441,19 @@ __early_param("initrd=", early_initrd); static void __init arm_add_memory(unsigned long start, unsigned long size) { + struct membank *bank; + /* * Ensure that start/size are aligned to a page boundary. * Size is appropriately rounded down, start is rounded up. */ size -= start & ~PAGE_MASK; - meminfo.bank[meminfo.nr_banks].start = PAGE_ALIGN(start); - meminfo.bank[meminfo.nr_banks].size = size & PAGE_MASK; - meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); - meminfo.nr_banks += 1; + bank = &meminfo.bank[meminfo.nr_banks++]; + + bank->start = PAGE_ALIGN(start); + bank->size = size & PAGE_MASK; + bank->node = PHYS_TO_NID(start); } /* -- cgit v1.2.3 From a2ce774096110ccc5c02cbdc05897d005fcd3db8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 6 Dec 2006 20:31:36 -0800 Subject: [PATCH] uml: workqueue build fix arch/um/drivers/chan_kern.c:643: error: conflicting types for 'chan_interrupt' arch/um/include/chan_kern.h:31: error: previous declaration of 'chan_interrupt' Cc: David Howells Cc: Jeff Dike Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 6 +++--- arch/um/include/chan_kern.h | 2 +- arch/um/include/line.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 426633e5d6e..aa3090d05a8 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -31,9 +31,9 @@ static irqreturn_t line_interrupt(int irq, void *data) return IRQ_HANDLED; } -static void line_timer_cb(void *arg) +static void line_timer_cb(struct work_struct *work) { - struct line *line = arg; + struct line *line = container_of(work, struct line, task.work); if(!line->throttled) chan_interrupt(&line->chan_list, &line->task, line->tty, @@ -443,7 +443,7 @@ int line_open(struct line *lines, struct tty_struct *tty) * is registered. */ enable_chan(line); - INIT_WORK(&line->task, line_timer_cb, line); + INIT_DELAYED_WORK(&line->task, line_timer_cb); if(!line->sigio){ chan_enable_winch(&line->chan_list, tty); diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h index 572d286ed2c..9003a343e14 100644 --- a/arch/um/include/chan_kern.h +++ b/arch/um/include/chan_kern.h @@ -27,7 +27,7 @@ struct chan { void *data; }; -extern void chan_interrupt(struct list_head *chans, struct work_struct *task, +extern void chan_interrupt(struct list_head *chans, struct delayed_work *task, struct tty_struct *tty, int irq); extern int parse_chan_pair(char *str, struct line *line, int device, const struct chan_opts *opts); diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 7be24811bb3..214ee76c40d 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h @@ -51,7 +51,7 @@ struct line { char *tail; int sigio; - struct work_struct task; + struct delayed_work task; const struct line_driver *driver; int have_irq; }; -- cgit v1.2.3 From 39dde65c9940c97fcd178a3d2b1c57ed8b7b68aa Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Wed, 6 Dec 2006 20:32:03 -0800 Subject: [PATCH] shared page table for hugetlb page Following up with the work on shared page table done by Dave McCracken. This set of patch target shared page table for hugetlb memory only. The shared page table is particular useful in the situation of large number of independent processes sharing large shared memory segments. In the normal page case, the amount of memory saved from process' page table is quite significant. For hugetlb, the saving on page table memory is not the primary objective (as hugetlb itself already cuts down page table overhead significantly), instead, the purpose of using shared page table on hugetlb is to allow faster TLB refill and smaller cache pollution upon TLB miss. With PT sharing, pte entries are shared among hundreds of processes, the cache consumption used by all the page table is smaller and in return, application gets much higher cache hit ratio. One other effect is that cache hit ratio with hardware page walker hitting on pte in cache will be higher and this helps to reduce tlb miss latency. These two effects contribute to higher application performance. Signed-off-by: Ken Chen Acked-by: Hugh Dickins Cc: Dave McCracken Cc: William Lee Irwin III Cc: "Luck, Tony" Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: David Gibson Cc: Adam Litke Cc: Paul Mundt Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/hugetlbpage.c | 112 +++++++++++++++++++++++++++++++++++++++++- arch/ia64/mm/hugetlbpage.c | 5 ++ arch/powerpc/mm/hugetlbpage.c | 5 ++ arch/sh/mm/hugetlbpage.c | 5 ++ arch/sh64/mm/hugetlbpage.c | 5 ++ arch/sparc64/mm/hugetlbpage.c | 5 ++ 6 files changed, 136 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/mm/hugetlbpage.c b/arch/i386/mm/hugetlbpage.c index 1719a8141f8..34728e4afe4 100644 --- a/arch/i386/mm/hugetlbpage.c +++ b/arch/i386/mm/hugetlbpage.c @@ -17,6 +17,113 @@ #include #include +static unsigned long page_table_shareable(struct vm_area_struct *svma, + struct vm_area_struct *vma, + unsigned long addr, pgoff_t idx) +{ + unsigned long saddr = ((idx - svma->vm_pgoff) << PAGE_SHIFT) + + svma->vm_start; + unsigned long sbase = saddr & PUD_MASK; + unsigned long s_end = sbase + PUD_SIZE; + + /* + * match the virtual addresses, permission and the alignment of the + * page table page. + */ + if (pmd_index(addr) != pmd_index(saddr) || + vma->vm_flags != svma->vm_flags || + sbase < svma->vm_start || svma->vm_end < s_end) + return 0; + + return saddr; +} + +static int vma_shareable(struct vm_area_struct *vma, unsigned long addr) +{ + unsigned long base = addr & PUD_MASK; + unsigned long end = base + PUD_SIZE; + + /* + * check on proper vm_flags and page table alignment + */ + if (vma->vm_flags & VM_MAYSHARE && + vma->vm_start <= base && end <= vma->vm_end) + return 1; + return 0; +} + +/* + * search for a shareable pmd page for hugetlb. + */ +static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) +{ + struct vm_area_struct *vma = find_vma(mm, addr); + struct address_space *mapping = vma->vm_file->f_mapping; + pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) + + vma->vm_pgoff; + struct prio_tree_iter iter; + struct vm_area_struct *svma; + unsigned long saddr; + pte_t *spte = NULL; + + if (!vma_shareable(vma, addr)) + return; + + spin_lock(&mapping->i_mmap_lock); + vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { + if (svma == vma) + continue; + + saddr = page_table_shareable(svma, vma, addr, idx); + if (saddr) { + spte = huge_pte_offset(svma->vm_mm, saddr); + if (spte) { + get_page(virt_to_page(spte)); + break; + } + } + } + + if (!spte) + goto out; + + spin_lock(&mm->page_table_lock); + if (pud_none(*pud)) + pud_populate(mm, pud, (unsigned long) spte & PAGE_MASK); + else + put_page(virt_to_page(spte)); + spin_unlock(&mm->page_table_lock); +out: + spin_unlock(&mapping->i_mmap_lock); +} + +/* + * unmap huge page backed by shared pte. + * + * Hugetlb pte page is ref counted at the time of mapping. If pte is shared + * indicated by page_count > 1, unmap is achieved by clearing pud and + * decrementing the ref count. If count == 1, the pte page is not shared. + * + * called with vma->vm_mm->page_table_lock held. + * + * returns: 1 successfully unmapped a shared pte page + * 0 the underlying pte page is not shared, or it is the last user + */ +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + pgd_t *pgd = pgd_offset(mm, *addr); + pud_t *pud = pud_offset(pgd, *addr); + + BUG_ON(page_count(virt_to_page(ptep)) == 0); + if (page_count(virt_to_page(ptep)) == 1) + return 0; + + pud_clear(pud); + put_page(virt_to_page(ptep)); + *addr = ALIGN(*addr, HPAGE_SIZE * PTRS_PER_PTE) - HPAGE_SIZE; + return 1; +} + pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; @@ -25,8 +132,11 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); - if (pud) + if (pud) { + if (pud_none(*pud)) + huge_pmd_share(mm, addr, pud); pte = (pte_t *) pmd_alloc(mm, pud, addr); + } BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); return pte; diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c index f3a9585e98a..0c7e94edc20 100644 --- a/arch/ia64/mm/hugetlbpage.c +++ b/arch/ia64/mm/hugetlbpage.c @@ -64,6 +64,11 @@ huge_pte_offset (struct mm_struct *mm, unsigned long addr) return pte; } +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + return 0; +} + #define mk_pte_huge(entry) { pte_val(entry) |= _PAGE_P; } /* diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 506d89768d4..424a8f57e15 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -146,6 +146,11 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) return hugepte_offset(hpdp, addr); } +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + return 0; +} + static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp) { pte_t *hugepte = hugepd_page(*hpdp); diff --git a/arch/sh/mm/hugetlbpage.c b/arch/sh/mm/hugetlbpage.c index 329059d6b54..cf2c2ee35a3 100644 --- a/arch/sh/mm/hugetlbpage.c +++ b/arch/sh/mm/hugetlbpage.c @@ -63,6 +63,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + return 0; +} + struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { diff --git a/arch/sh64/mm/hugetlbpage.c b/arch/sh64/mm/hugetlbpage.c index 187cf01750b..4b455f61114 100644 --- a/arch/sh64/mm/hugetlbpage.c +++ b/arch/sh64/mm/hugetlbpage.c @@ -53,6 +53,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + return 0; +} + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 53b9b1f528e..33fd0b265e7 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -235,6 +235,11 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) return pte; } +int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep) +{ + return 0; +} + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { -- cgit v1.2.3 From 6edaf68a87d17570790fd55f0c451a29ec1d6703 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Dec 2006 20:32:18 -0800 Subject: [PATCH] mm: arch do_page_fault() vs in_atomic() In light of the recent pagefault and filemap_copy_from_user work I've gone through all the arch pagefault handlers to make sure the inc_preempt_count() 'feature' works as expected. Several sections of code (including the new filemap_copy_from_user) rely on the fact that faults do not take locks under increased preempt count. arch/x86_64 - good arch/powerpc - good arch/cris - fixed arch/i386 - good arch/parisc - fixed arch/sh - good arch/sparc - good arch/s390 - good arch/m68k - fixed arch/ppc - good arch/alpha - fixed arch/mips - good arch/sparc64 - good arch/ia64 - good arch/arm - fixed arch/um - good arch/avr32 - good arch/h8300 - NA arch/m32r - good arch/v850 - good arch/frv - fixed arch/m68knommu - NA arch/arm26 - fixed arch/sh64 - fixed arch/xtensa - good Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/mm/fault.c | 2 +- arch/arm/mm/fault.c | 2 +- arch/arm26/mm/fault.c | 2 +- arch/cris/mm/fault.c | 2 +- arch/frv/mm/fault.c | 2 +- arch/m68k/mm/fault.c | 2 +- arch/parisc/mm/fault.c | 2 +- arch/sh64/mm/fault.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index 8871529a34e..8aa9db834c1 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c @@ -108,7 +108,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, /* If we're in an interrupt context, or have no user context, we must not take the fault. */ - if (!mm || in_interrupt()) + if (!mm || in_atomic()) goto no_context; #ifdef CONFIG_ALPHA_LARGE_VMALLOC diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 5e658a87449..9fd6d2eafb4 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -230,7 +230,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; /* diff --git a/arch/arm26/mm/fault.c b/arch/arm26/mm/fault.c index a1f6d8a9cc3..93c0cee0fb5 100644 --- a/arch/arm26/mm/fault.c +++ b/arch/arm26/mm/fault.c @@ -215,7 +215,7 @@ int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c index 934c51078cc..c73e91f1299 100644 --- a/arch/cris/mm/fault.c +++ b/arch/cris/mm/fault.c @@ -232,7 +232,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs, * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c index 8b3eb50c510..3f12296c368 100644 --- a/arch/frv/mm/fault.c +++ b/arch/frv/mm/fault.c @@ -78,7 +78,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c index 911f2ce3f53..2adbeb16e1b 100644 --- a/arch/m68k/mm/fault.c +++ b/arch/m68k/mm/fault.c @@ -99,7 +99,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 64785e46f93..641f9c920ee 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -152,7 +152,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, const struct exception_table_entry *fix; unsigned long acc_type; - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; down_read(&mm->mmap_sem); diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c index 8e2f6c28b73..4f72ab33bb2 100644 --- a/arch/sh64/mm/fault.c +++ b/arch/sh64/mm/fault.c @@ -154,7 +154,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * If we're in an interrupt or have no user * context, we must not take the fault.. */ - if (in_interrupt() || !mm) + if (in_atomic() || !mm) goto no_context; /* TLB misses upon some cache flushes get done under cli() */ -- cgit v1.2.3 From a866374aecc90c7d90619727ccd851ac096b2fc7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Dec 2006 20:32:20 -0800 Subject: [PATCH] mm: pagefault_{disable,enable}() Introduce pagefault_{disable,enable}() and use these where previously we did manual preempt increments/decrements to make the pagefault handler do the atomic thing. Currently they still rely on the increased preempt count, but do not rely on the disabled preemption, this might go away in the future. (NOTE: the extra barrier() in pagefault_disable might fix some holes on machines which have too many registers for their own good) [heiko.carstens@de.ibm.com: s390 fix] Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Cc: Martin Schwidefsky Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/futex.c | 4 ++-- arch/i386/mm/highmem.c | 10 ++++------ arch/mips/mm/highmem.c | 10 ++++------ arch/s390/lib/uaccess_std.c | 6 +++--- arch/sparc/mm/highmem.c | 8 +++----- 5 files changed, 16 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index eae874a970c..53dc5ed1ebd 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -200,7 +200,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -223,7 +223,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) break; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index f9f647cdbc7..178bbfe6cba 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -52,8 +52,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #ifdef CONFIG_DEBUG_HIGHMEM if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -68,8 +67,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) */ kpte_clear_flush(kmap_pte-idx, vaddr); - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } /* This is the same as kmap_atomic() but can map memory that doesn't @@ -80,7 +78,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - inc_preempt_count(); + pagefault_disable(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 99ebf3ccc22..675502ada5a 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -39,7 +39,7 @@ void *__kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -62,8 +62,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -78,8 +77,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) local_flush_tlb_one(vaddr); #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } #ifndef CONFIG_LIMITED_DMA @@ -92,7 +90,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - inc_preempt_count(); + pagefault_disable(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 2d549ed2e11..bbaca66fa29 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #ifndef __s390x__ @@ -258,7 +258,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) { int oldval = 0, newval, ret; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -284,7 +284,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) default: ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); *old = oldval; return ret; } diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index 4d8ed9c6518..01fc6c25429 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c @@ -35,7 +35,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -70,8 +70,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -97,8 +96,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } /* We may be fed a pagetable here by ptep_to_xxx and others. */ -- cgit v1.2.3 From 3b17979bda74493633364c2c263b452b7788e350 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 6 Dec 2006 20:32:22 -0800 Subject: [PATCH] Fix kunmap_atomic's use of kpte_clear_flush() kunmap_atomic() will call kpte_clear_flush with vaddr/ptep arguments which don't correspond if the vaddr is just a normal lowmem address (ie, not in the KMAP area). This patch makes sure that the pte is only cleared if kmap area was actually used for the mapping. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Rusty Russell Cc: Zachary Amsden Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mm/highmem.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index 178bbfe6cba..e0fa6cb655a 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -50,22 +50,20 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); -#ifdef CONFIG_DEBUG_HIGHMEM - if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { - pagefault_enable(); - return; - } - - if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) - BUG(); -#endif /* * Force other mappings to Oops if they'll try to access this pte * without first remap it. Keeping stale mappings around is a bad idea * also, in case the page changes cacheability attributes or becomes * a protected page in a hypervisor. */ - kpte_clear_flush(kmap_pte-idx, vaddr); + if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) + kpte_clear_flush(kmap_pte-idx, vaddr); + else { +#ifdef CONFIG_DEBUG_HIGHMEM + BUG_ON(vaddr < PAGE_OFFSET); + BUG_ON(vaddr >= (unsigned long)high_memory); +#endif + } pagefault_enable(); } -- cgit v1.2.3 From a120586873d3d64de93bd6d593d237e131994e58 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 6 Dec 2006 20:32:37 -0800 Subject: [PATCH] Allow NULL pointers in percpu_free The patch (as824b) makes percpu_free() ignore NULL arguments, as one would expect for a deallocation routine. (Note that free_percpu is #defined as percpu_free in include/linux/percpu.h.) A few callers are updated to remove now-unneeded tests for NULL. A few other callers already seem to assume that passing a NULL pointer to percpu_free() is okay! The patch also removes an unnecessary NULL check in percpu_depopulate(). Signed-off-by: Alan Stern Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/cstate.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c index 4664b55f623..12e937c1ce4 100644 --- a/arch/i386/kernel/acpi/cstate.c +++ b/arch/i386/kernel/acpi/cstate.c @@ -156,10 +156,8 @@ static int __init ffh_cstate_init(void) static void __exit ffh_cstate_exit(void) { - if (cpu_cstate_entry) { - free_percpu(cpu_cstate_entry); - cpu_cstate_entry = NULL; - } + free_percpu(cpu_cstate_entry); + cpu_cstate_entry = NULL; } arch_initcall(ffh_cstate_init); -- cgit v1.2.3 From e94b1766097d53e6f3ccfb36c8baa562ffeda3fc Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 6 Dec 2006 20:33:17 -0800 Subject: [PATCH] slab: remove SLAB_KERNEL SLAB_KERNEL is an alias of GFP_KERNEL. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/sysenter.c | 2 +- arch/ia64/ia32/binfmt_elf32.c | 8 ++++---- arch/ia64/kernel/perfmon.c | 2 +- arch/ia64/mm/init.c | 4 ++-- arch/powerpc/kernel/vdso.c | 2 +- arch/powerpc/platforms/cell/spufs/inode.c | 2 +- arch/sh/kernel/vsyscall/vsyscall.c | 2 +- arch/x86_64/ia32/ia32_binfmt.c | 2 +- arch/x86_64/ia32/syscall32.c | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/sysenter.c b/arch/i386/kernel/sysenter.c index 713ba39d32c..0bbacd0ec17 100644 --- a/arch/i386/kernel/sysenter.c +++ b/arch/i386/kernel/sysenter.c @@ -132,7 +132,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) goto up_fail; } - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { ret = -ENOMEM; goto up_fail; diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index daa6b91bc92..578737ec762 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -91,7 +91,7 @@ ia64_elf32_init (struct pt_regs *regs) * it with privilege level 3 because the IVE uses non-privileged accesses to these * tables. IA-32 segmentation is used to protect against IA-32 accesses to them. */ - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -117,7 +117,7 @@ ia64_elf32_init (struct pt_regs *regs) * code is locked in specific gate page, which is pointed by pretcode * when setup_frame_ia32 */ - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -142,7 +142,7 @@ ia64_elf32_init (struct pt_regs *regs) * Install LDT as anonymous memory. This gives us all-zero segment descriptors * until a task modifies them via modify_ldt(). */ - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -214,7 +214,7 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) bprm->loader += stack_base; bprm->exec += stack_base; - mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (!mpnt) return -ENOMEM; diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 3aaede0d698..e2321536ee4 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2302,7 +2302,7 @@ pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned lon DPRINT(("smpl_buf @%p\n", smpl_buf)); /* allocate vma */ - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (!vma) { DPRINT(("Cannot allocate vma\n")); goto error_kmem; diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index ff87a5cba39..56dc2024220 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -156,7 +156,7 @@ ia64_init_addr_space (void) * the problem. When the process attempts to write to the register backing store * for the first time, it will get a SEGFAULT in this case. */ - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; @@ -175,7 +175,7 @@ ia64_init_addr_space (void) /* map NaT-page at address zero to speed up speculative dereferencing of NULL: */ if (!(current->personality & MMAP_PAGE_ZERO)) { - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (vma) { memset(vma, 0, sizeof(*vma)); vma->vm_mm = current->mm; diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index c913ad5cad2..a4b28c73bba 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -264,7 +264,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, /* Allocate a VMA structure and fill it up */ - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (vma == NULL) { rc = -ENOMEM; goto fail_mmapsem; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index c7d010749a1..7edfcc9d285 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -48,7 +48,7 @@ spufs_alloc_inode(struct super_block *sb) { struct spufs_inode_info *ei; - ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); + ei = kmem_cache_alloc(spufs_inode_cache, GFP_KERNEL); if (!ei) return NULL; diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index 075d6cc1a2d..deb46941f31 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c @@ -97,7 +97,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, goto up_fail; } - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { ret = -ENOMEM; goto up_fail; diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 82ef182de6a..932a62ad6c8 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -351,7 +351,7 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, bprm->loader += stack_base; bprm->exec += stack_base; - mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (!mpnt) return -ENOMEM; diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index 3a01329473a..3e5ed20cba4 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c @@ -49,7 +49,7 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) struct mm_struct *mm = current->mm; int ret; - vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); if (!vma) return -ENOMEM; -- cgit v1.2.3 From e18b890bb0881bbab6f4f1a6cd20d9c60d66b003 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 6 Dec 2006 20:33:20 -0800 Subject: [PATCH] slab: remove kmem_cache_t Replace all uses of kmem_cache_t with struct kmem_cache. The patch was generated using the following script: #!/bin/sh # # Replace one string by another in all the kernel sources. # set -e for file in `find * -name "*.c" -o -name "*.h"|xargs grep -l $1`; do quilt add $file sed -e "1,\$s/$1/$2/g" $file >/tmp/$$ mv /tmp/$$ $file quilt refresh done The script was run like this sh replace kmem_cache_t "struct kmem_cache" Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-s3c2410/dma.c | 4 ++-- arch/arm26/mm/memc.c | 6 +++--- arch/frv/mm/pgalloc.c | 6 +++--- arch/i386/mm/init.c | 4 ++-- arch/i386/mm/pgtable.c | 6 +++--- arch/ia64/ia32/ia32_support.c | 2 +- arch/ia64/ia32/sys_ia32.c | 2 +- arch/powerpc/kernel/rtas_flash.c | 4 ++-- arch/powerpc/mm/hugetlbpage.c | 2 +- arch/powerpc/mm/init_64.c | 6 +++--- arch/powerpc/platforms/cell/spufs/inode.c | 4 ++-- arch/sh/kernel/cpu/sh4/sq.c | 2 +- arch/sh/mm/pmb.c | 6 +++--- arch/sparc64/mm/init.c | 4 ++-- arch/sparc64/mm/tsb.c | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 3d211dc2f2f..01abb0ace23 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -40,7 +40,7 @@ /* io map for dma */ static void __iomem *dma_base; -static kmem_cache_t *dma_kmem; +static struct kmem_cache *dma_kmem; struct s3c24xx_dma_selection dma_sel; @@ -1271,7 +1271,7 @@ struct sysdev_class dma_sysclass = { /* kmem cache implementation */ -static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) +static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f) { memset(p, 0, sizeof(struct s3c2410_dma_buf)); } diff --git a/arch/arm26/mm/memc.c b/arch/arm26/mm/memc.c index 34def6397c3..f2901581d4d 100644 --- a/arch/arm26/mm/memc.c +++ b/arch/arm26/mm/memc.c @@ -24,7 +24,7 @@ #define MEMC_TABLE_SIZE (256*sizeof(unsigned long)) -kmem_cache_t *pte_cache, *pgd_cache; +struct kmem_cache *pte_cache, *pgd_cache; int page_nr; /* @@ -162,12 +162,12 @@ void __init create_memmap_holes(struct meminfo *mi) { } -static void pte_cache_ctor(void *pte, kmem_cache_t *cache, unsigned long flags) +static void pte_cache_ctor(void *pte, struct kmem_cache *cache, unsigned long flags) { memzero(pte, sizeof(pte_t) * PTRS_PER_PTE); } -static void pgd_cache_ctor(void *pgd, kmem_cache_t *cache, unsigned long flags) +static void pgd_cache_ctor(void *pgd, struct kmem_cache *cache, unsigned long flags) { memzero(pgd + MEMC_TABLE_SIZE, USER_PTRS_PER_PGD * sizeof(pgd_t)); } diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index f76dd03ddd9..19b13be114a 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c @@ -18,7 +18,7 @@ #include pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); -kmem_cache_t *pgd_cache; +struct kmem_cache *pgd_cache; pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { @@ -100,7 +100,7 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long) pprev); } -void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) +void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; @@ -120,7 +120,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) } /* never called when PTRS_PER_PMD > 1 */ -void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) +void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index 167416155ee..a6a8e397dd8 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -699,8 +699,8 @@ int remove_memory(u64 start, u64 size) #endif #endif -kmem_cache_t *pgd_cache; -kmem_cache_t *pmd_cache; +struct kmem_cache *pgd_cache; +struct kmem_cache *pmd_cache; void __init pgtable_cache_init(void) { diff --git a/arch/i386/mm/pgtable.c b/arch/i386/mm/pgtable.c index 10126e3f817..33be236fc6a 100644 --- a/arch/i386/mm/pgtable.c +++ b/arch/i386/mm/pgtable.c @@ -193,7 +193,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) return pte; } -void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags) +void pmd_ctor(void *pmd, struct kmem_cache *cache, unsigned long flags) { memset(pmd, 0, PTRS_PER_PMD*sizeof(pmd_t)); } @@ -233,7 +233,7 @@ static inline void pgd_list_del(pgd_t *pgd) set_page_private(next, (unsigned long)pprev); } -void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) +void pgd_ctor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; @@ -253,7 +253,7 @@ void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) } /* never called when PTRS_PER_PMD > 1 */ -void pgd_dtor(void *pgd, kmem_cache_t *cache, unsigned long unused) +void pgd_dtor(void *pgd, struct kmem_cache *cache, unsigned long unused) { unsigned long flags; /* can be called from interrupt context */ diff --git a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c index c187743965a..6af400a12ca 100644 --- a/arch/ia64/ia32/ia32_support.c +++ b/arch/ia64/ia32/ia32_support.c @@ -249,7 +249,7 @@ ia32_init (void) #if PAGE_SHIFT > IA32_PAGE_SHIFT { - extern kmem_cache_t *partial_page_cachep; + extern struct kmem_cache *partial_page_cachep; partial_page_cachep = kmem_cache_create("partial_page_cache", sizeof(struct partial_page), 0, 0, diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index 9d6a3f21014..a4a6e1463af 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -254,7 +254,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro } /* SLAB cache for partial_page structures */ -kmem_cache_t *partial_page_cachep; +struct kmem_cache *partial_page_cachep; /* * init partial_page_list. diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index b9561d30051..7d0f13fecc0 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -101,7 +101,7 @@ struct flash_block_list_header { /* just the header of flash_block_list */ static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; /* Use slab cache to guarantee 4k alignment */ -static kmem_cache_t *flash_block_cache = NULL; +static struct kmem_cache *flash_block_cache = NULL; #define FLASH_BLOCK_LIST_VERSION (1UL) @@ -286,7 +286,7 @@ static ssize_t rtas_flash_read(struct file *file, char __user *buf, } /* constructor for flash_block_cache */ -void rtas_block_ctor(void *ptr, kmem_cache_t *cache, unsigned long flags) +void rtas_block_ctor(void *ptr, struct kmem_cache *cache, unsigned long flags) { memset(ptr, 0, RTAS_BLK_SIZE); } diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 424a8f57e15..89c836d5480 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -1047,7 +1047,7 @@ repeat: return err; } -static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) +static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) { memset(addr, 0, kmem_cache_size(cache)); } diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 9a178549cbc..d12a87ec5ae 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -141,7 +141,7 @@ static int __init setup_kcore(void) } module_init(setup_kcore); -static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) +static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) { memset(addr, 0, kmem_cache_size(cache)); } @@ -166,9 +166,9 @@ static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = { /* Hugepages need one extra cache, initialized in hugetlbpage.c. We * can't put into the tables above, because HPAGE_SHIFT is not compile * time constant. */ -kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1]; +struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1]; #else -kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; +struct kmem_cache *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; #endif void pgtable_cache_init(void) diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 7edfcc9d285..e3af9112c02 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -40,7 +40,7 @@ #include "spufs.h" -static kmem_cache_t *spufs_inode_cache; +static struct kmem_cache *spufs_inode_cache; char *isolated_loader; static struct inode * @@ -65,7 +65,7 @@ spufs_destroy_inode(struct inode *inode) } static void -spufs_init_once(void *p, kmem_cache_t * cachep, unsigned long flags) +spufs_init_once(void *p, struct kmem_cache * cachep, unsigned long flags) { struct spufs_inode_info *ei = p; diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 55f43506995..0c9ea38d2ca 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -38,7 +38,7 @@ struct sq_mapping { static struct sq_mapping *sq_mapping_list; static DEFINE_SPINLOCK(sq_mapping_lock); -static kmem_cache_t *sq_cache; +static struct kmem_cache *sq_cache; static unsigned long *sq_bitmap; #define store_queue_barrier() \ diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 92e745341e4..b60ad83a763 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -30,7 +30,7 @@ #define NR_PMB_ENTRIES 16 -static kmem_cache_t *pmb_cache; +static struct kmem_cache *pmb_cache; static unsigned long pmb_map; static struct pmb_entry pmb_init_map[] = { @@ -283,7 +283,7 @@ void pmb_unmap(unsigned long addr) } while (pmbe); } -static void pmb_cache_ctor(void *pmb, kmem_cache_t *cachep, unsigned long flags) +static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, unsigned long flags) { struct pmb_entry *pmbe = pmb; @@ -297,7 +297,7 @@ static void pmb_cache_ctor(void *pmb, kmem_cache_t *cachep, unsigned long flags) spin_unlock_irq(&pmb_list_lock); } -static void pmb_cache_dtor(void *pmb, kmem_cache_t *cachep, unsigned long flags) +static void pmb_cache_dtor(void *pmb, struct kmem_cache *cachep, unsigned long flags) { spin_lock_irq(&pmb_list_lock); pmb_list_del(pmb); diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 09cb7fccc03..a8e8802eed4 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -176,9 +176,9 @@ unsigned long sparc64_kern_sec_context __read_mostly; int bigkernel = 0; -kmem_cache_t *pgtable_cache __read_mostly; +struct kmem_cache *pgtable_cache __read_mostly; -static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags) +static void zero_ctor(void *addr, struct kmem_cache *cache, unsigned long flags) { clear_page(addr); } diff --git a/arch/sparc64/mm/tsb.c b/arch/sparc64/mm/tsb.c index beaa02810f0..236d02f41a0 100644 --- a/arch/sparc64/mm/tsb.c +++ b/arch/sparc64/mm/tsb.c @@ -239,7 +239,7 @@ static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsign } } -static kmem_cache_t *tsb_caches[8] __read_mostly; +static struct kmem_cache *tsb_caches[8] __read_mostly; static const char *tsb_cache_names[8] = { "tsb_8KB", -- cgit v1.2.3 From e9c1528a429c831458e54c8701a0b80ba563a7a8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 6 Dec 2006 20:33:50 -0800 Subject: [PATCH] arch/frv/kernel/futex.c must #include This patch fixes the following compile error with -Werror-implicit-function-declaration (without -Werror-implicit-function-declaration it's a link error): ... CC arch/frv/kernel/futex.o /home/bunk/linux/kernel-2.6/linux-2.6.19-rc6-mm2/arch/frv/kernel/futex.c: In function 'futex_atomic_op_inuser': /home/bunk/linux/kernel-2.6/linux-2.6.19-rc6-mm2/arch/frv/kernel/futex.c:203: error: implicit declaration of function 'pagefault_disable' /home/bunk/linux/kernel-2.6/linux-2.6.19-rc6-mm2/arch/frv/kernel/futex.c:226: error: implicit declaration of function 'pagefault_enable' make[2]: *** [arch/frv/kernel/futex.o] Error 1 ... Signed-off-by: Adrian Bunk Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/futex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index 53dc5ed1ebd..14f64b054c7 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -10,9 +10,9 @@ */ #include +#include #include #include -#include /* * the various futex operations; MMU fault checking is ignored under no-MMU -- cgit v1.2.3 From 4d3eeeac97a6e4fc1ff3ad184f1c3bf328de7cb6 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 6 Dec 2006 20:33:54 -0800 Subject: [PATCH] avr32: fixup kprobes preemption handling While working on SH kprobes, I noticed that avr32 got the preemption handling wrong in the no probe case. The idea is that upon entry of kprobe_handler() preemption is disabled outright across the life of the kprobe, only to be re-enabled in post_kprobe_handler(). However, in the event that the probe is never activated, there's never any chance of hitting the post probe handler, which allows for the current avr32 implementation to disable preemption indefinitely, as it's currently missing a re-enable when no probe is activated. Signed-off-by: Paul Mundt Cc: Haavard Skinnemoen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/avr32/kernel/kprobes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c index ca41fc1edbe..d0abbcaf1c1 100644 --- a/arch/avr32/kernel/kprobes.c +++ b/arch/avr32/kernel/kprobes.c @@ -154,6 +154,7 @@ ss_probe: return 1; no_kprobe: + preempt_enable_no_resched(); return ret; } -- cgit v1.2.3 From 3869aa292fbd24103b8338937cb351459efe3f82 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Wed, 6 Dec 2006 20:33:57 -0800 Subject: [PATCH] h8300 stray bracket fix Signed-off-by: Mariusz Kozlowski Cc: Yoshinori Sato Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/h8300/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/h8300/kernel/setup.c b/arch/h8300/kernel/setup.c index 1077b71d522..6adf8f41d2a 100644 --- a/arch/h8300/kernel/setup.c +++ b/arch/h8300/kernel/setup.c @@ -116,7 +116,7 @@ void __init setup_arch(char **cmdline_p) #endif #else if ((memory_end < CONFIG_BLKDEV_RESERVE_ADDRESS) && - (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS) + (memory_end > CONFIG_BLKDEV_RESERVE_ADDRESS)) /* overlap userarea */ memory_end = CONFIG_BLKDEV_RESERVE_ADDRESS; #endif -- cgit v1.2.3 From 074cec54d1049ab580ecd0026623b553e0e270c4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 6 Dec 2006 20:33:59 -0800 Subject: [PATCH] alpha: switch to pci_get API Now that we have pci_get_bus_and_slot we can do the job correctly. Note that some of these calls intentionally leak a device - this is because the device in question is always needed from boot to reboot. Signed-off-by: Alan Cox Cc: Richard Henderson Cc: Ivan Kokshaysky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/pci.c | 3 ++- arch/alpha/kernel/sys_miata.c | 10 +++++++--- arch/alpha/kernel/sys_nautilus.c | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index ffb7d5423cc..3c10b9a1ddf 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -516,10 +516,11 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn) if (bus == 0 && dfn == 0) { hose = pci_isa_hose; } else { - dev = pci_find_slot(bus, dfn); + dev = pci_get_bus_and_slot(bus, dfn); if (!dev) return -ENODEV; hose = dev->sysdata; + pci_dev_put(dev); } } diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c index b8b817feb1e..910b43cd63e 100644 --- a/arch/alpha/kernel/sys_miata.c +++ b/arch/alpha/kernel/sys_miata.c @@ -183,11 +183,15 @@ miata_map_irq(struct pci_dev *dev, u8 slot, u8 pin) if((slot == 7) && (PCI_FUNC(dev->devfn) == 3)) { u8 irq=0; - - if(pci_read_config_byte(pci_find_slot(dev->bus->number, dev->devfn & ~(7)), 0x40,&irq)!=PCIBIOS_SUCCESSFUL) + struct pci_dev *pdev = pci_get_slot(dev->bus, dev->devfn & ~7); + if(pdev == NULL || pci_read_config_byte(pdev, 0x40,&irq) != PCIBIOS_SUCCESSFUL) { + pci_dev_put(pdev); return -1; - else + } + else { + pci_dev_put(pdev); return irq; + } } return COMMON_TABLE_LOOKUP; diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 93744bab73f..e7594a7cf58 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -200,7 +200,7 @@ nautilus_init_pci(void) bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); hose->bus = bus; - irongate = pci_find_slot(0, 0); + irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; bus->resource[1] = &irongate_mem; -- cgit v1.2.3 From 7dfb71030f7636a0d65200158113c37764552f93 Mon Sep 17 00:00:00 2001 From: Nigel Cunningham Date: Wed, 6 Dec 2006 20:34:23 -0800 Subject: [PATCH] Add include/linux/freezer.h and move definitions from sched.h Move process freezing functions from include/linux/sched.h to freezer.h, so that modifications to the freezer or the kernel configuration don't require recompiling just about everything. [akpm@osdl.org: fix ueagle driver] Signed-off-by: Nigel Cunningham Cc: "Rafael J. Wysocki" Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/kernel/signal.c | 1 + arch/avr32/kernel/signal.c | 2 +- arch/frv/kernel/signal.c | 2 +- arch/h8300/kernel/signal.c | 2 +- arch/i386/kernel/io_apic.c | 1 + arch/m32r/kernel/signal.c | 2 +- arch/powerpc/kernel/signal_32.c | 2 +- arch/sh/kernel/signal.c | 1 + arch/sh64/kernel/signal.c | 2 +- 9 files changed, 9 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 48cf7fffddf..f38a60a03b8 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c index 33096651c24..0ec14854a20 100644 --- a/arch/avr32/kernel/signal.c +++ b/arch/avr32/kernel/signal.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index b8a5882b862..85baeae9666 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 7787f70a05b..02955604d76 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 3b7a63e0ed1..44c5a3206b2 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index b60cea4aeba..092ea86bb07 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 320353f0926..e4ebe1a6228 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -36,7 +36,7 @@ #include #include #include -#include +#include #endif #include diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 50d7c4993be..bb1c480a59c 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index 9e2ffc45c0e..1666d3efb52 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include #include -- cgit v1.2.3 From 2d4a34c9365c6e3f94a5b26ce296e1fce9b66c8b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 6 Dec 2006 20:34:29 -0800 Subject: [PATCH] swsusp: Support i386 systems with PAE or without PSE Make swsusp support i386 systems with PAE or without PSE. This is done by creating temporary page tables located in resume-safe page frames before the suspend image is restored in the same way as x86_64 does it. Signed-off-by: Rafael J. Wysocki Cc: Andi Kleen Cc: Dave Jones Cc: Nigel Cunningham Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/power/Makefile | 2 +- arch/i386/power/suspend.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++ arch/i386/power/swsusp.S | 9 ++- 3 files changed, 166 insertions(+), 3 deletions(-) create mode 100644 arch/i386/power/suspend.c (limited to 'arch') diff --git a/arch/i386/power/Makefile b/arch/i386/power/Makefile index 8cfa4e8a719..2de7bbf03cd 100644 --- a/arch/i386/power/Makefile +++ b/arch/i386/power/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_PM) += cpu.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o suspend.o diff --git a/arch/i386/power/suspend.c b/arch/i386/power/suspend.c new file mode 100644 index 00000000000..db5e98d2eb7 --- /dev/null +++ b/arch/i386/power/suspend.c @@ -0,0 +1,158 @@ +/* + * Suspend support specific for i386 - temporary page tables + * + * Distribute under GPLv2 + * + * Copyright (c) 2006 Rafael J. Wysocki + */ + +#include +#include + +#include +#include +#include + +/* Defined in arch/i386/power/swsusp.S */ +extern int restore_image(void); + +/* Pointer to the temporary resume page tables */ +pgd_t *resume_pg_dir; + +/* The following three functions are based on the analogous code in + * arch/i386/mm/init.c + */ + +/* + * Create a middle page table on a resume-safe page and put a pointer to it in + * the given global directory entry. This only returns the gd entry + * in non-PAE compilation mode, since the middle layer is folded. + */ +static pmd_t *resume_one_md_table_init(pgd_t *pgd) +{ + pud_t *pud; + pmd_t *pmd_table; + +#ifdef CONFIG_X86_PAE + pmd_table = (pmd_t *)get_safe_page(GFP_ATOMIC); + if (!pmd_table) + return NULL; + + set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT)); + pud = pud_offset(pgd, 0); + + BUG_ON(pmd_table != pmd_offset(pud, 0)); +#else + pud = pud_offset(pgd, 0); + pmd_table = pmd_offset(pud, 0); +#endif + + return pmd_table; +} + +/* + * Create a page table on a resume-safe page and place a pointer to it in + * a middle page directory entry. + */ +static pte_t *resume_one_page_table_init(pmd_t *pmd) +{ + if (pmd_none(*pmd)) { + pte_t *page_table = (pte_t *)get_safe_page(GFP_ATOMIC); + if (!page_table) + return NULL; + + set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE)); + + BUG_ON(page_table != pte_offset_kernel(pmd, 0)); + + return page_table; + } + + return pte_offset_kernel(pmd, 0); +} + +/* + * This maps the physical memory to kernel virtual address space, a total + * of max_low_pfn pages, by creating page tables starting from address + * PAGE_OFFSET. The page tables are allocated out of resume-safe pages. + */ +static int resume_physical_mapping_init(pgd_t *pgd_base) +{ + unsigned long pfn; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + int pgd_idx, pmd_idx; + + pgd_idx = pgd_index(PAGE_OFFSET); + pgd = pgd_base + pgd_idx; + pfn = 0; + + for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) { + pmd = resume_one_md_table_init(pgd); + if (!pmd) + return -ENOMEM; + + if (pfn >= max_low_pfn) + continue; + + for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD; pmd++, pmd_idx++) { + if (pfn >= max_low_pfn) + break; + + /* Map with big pages if possible, otherwise create + * normal page tables. + * NOTE: We can mark everything as executable here + */ + if (cpu_has_pse) { + set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC)); + pfn += PTRS_PER_PTE; + } else { + pte_t *max_pte; + + pte = resume_one_page_table_init(pmd); + if (!pte) + return -ENOMEM; + + max_pte = pte + PTRS_PER_PTE; + for (; pte < max_pte; pte++, pfn++) { + if (pfn >= max_low_pfn) + break; + + set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC)); + } + } + } + } + return 0; +} + +static inline void resume_init_first_level_page_table(pgd_t *pg_dir) +{ +#ifdef CONFIG_X86_PAE + int i; + + /* Init entries of the first-level page table to the zero page */ + for (i = 0; i < PTRS_PER_PGD; i++) + set_pgd(pg_dir + i, + __pgd(__pa(empty_zero_page) | _PAGE_PRESENT)); +#endif +} + +int swsusp_arch_resume(void) +{ + int error; + + resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); + if (!resume_pg_dir) + return -ENOMEM; + + resume_init_first_level_page_table(resume_pg_dir); + error = resume_physical_mapping_init(resume_pg_dir); + if (error) + return error; + + /* We have got enough memory and from now on we cannot recover */ + restore_image(); + return 0; +} diff --git a/arch/i386/power/swsusp.S b/arch/i386/power/swsusp.S index 8a2b50a0aaa..53662e05b39 100644 --- a/arch/i386/power/swsusp.S +++ b/arch/i386/power/swsusp.S @@ -28,8 +28,9 @@ ENTRY(swsusp_arch_suspend) call swsusp_save ret -ENTRY(swsusp_arch_resume) - movl $swsusp_pg_dir-__PAGE_OFFSET, %ecx +ENTRY(restore_image) + movl resume_pg_dir, %ecx + subl $__PAGE_OFFSET, %ecx movl %ecx, %cr3 movl restore_pblist, %edx @@ -51,6 +52,10 @@ copy_loop: .p2align 4,,7 done: + /* go back to the original page tables */ + movl $swapper_pg_dir, %ecx + subl $__PAGE_OFFSET, %ecx + movl %ecx, %cr3 /* Flush TLB, including "global" things (vmalloc) */ movl mmu_cr4_features, %eax movl %eax, %edx -- cgit v1.2.3 From 8bcbdf603bc4bf24c2bcfa071871afb03dd3ae80 Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Wed, 6 Dec 2006 20:34:51 -0800 Subject: [PATCH] m68k: replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman Cc: Roman Zippel Cc: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m68k/amiga/chipram.c | 3 +-- arch/m68k/atari/hades-pci.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index de1304c9111..fa015d80161 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -52,10 +52,9 @@ void *amiga_chip_alloc(unsigned long size, const char *name) #ifdef DEBUG printk("amiga_chip_alloc: allocate %ld bytes\n", size); #endif - res = kmalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc(sizeof(struct resource), GFP_KERNEL); if (!res) return NULL; - memset(res, 0, sizeof(struct resource)); res->name = name; if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) { diff --git a/arch/m68k/atari/hades-pci.c b/arch/m68k/atari/hades-pci.c index 6ca57b6564d..bee2b1443e3 100644 --- a/arch/m68k/atari/hades-pci.c +++ b/arch/m68k/atari/hades-pci.c @@ -375,10 +375,9 @@ struct pci_bus_info * __init init_hades_pci(void) * Allocate memory for bus info structure. */ - bus = kmalloc(sizeof(struct pci_bus_info), GFP_KERNEL); + bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL); if (!bus) return NULL; - memset(bus, 0, sizeof(struct pci_bus_info)); /* * Claim resources. The m68k has no separate I/O space, both -- cgit v1.2.3 From 54f9a398e18a49e302e2187fa694043250391d80 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 6 Dec 2006 20:34:52 -0800 Subject: [PATCH] uml: include stddef.h correctly We were not including stddef.h in files that used offsetof. One file was also including linux/stddef.h for no perciptible reason. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/ldt.c | 1 - arch/um/sys-i386/ptrace_user.c | 2 +- arch/um/sys-i386/user-offsets.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index e299ee5a753..49057d8bc66 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -3,7 +3,6 @@ * Licensed under the GPL */ -#include "linux/stddef.h" #include "linux/sched.h" #include "linux/slab.h" #include "linux/types.h" diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c index 5f3cc668582..01212c88fcc 100644 --- a/arch/um/sys-i386/ptrace_user.c +++ b/arch/um/sys-i386/ptrace_user.c @@ -4,9 +4,9 @@ */ #include +#include #include #include -#include #include "ptrace_user.h" /* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */ #include diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c index 6f4ef2b7fa4..447306b20ae 100644 --- a/arch/um/sys-i386/user-offsets.c +++ b/arch/um/sys-i386/user-offsets.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #define DEFINE(sym, val) \ -- cgit v1.2.3 From 7b65fee21c6bff68711b48e0aa1cfd42b3198312 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 6 Dec 2006 20:34:53 -0800 Subject: [PATCH] uml: include asm/page.h in order to get PAGE_SHIFT Include the proper header to get a definition of PAGE_SHIFT. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/stub.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h index b492b12b4a1..4fffae75ba5 100644 --- a/arch/um/include/sysdep-i386/stub.h +++ b/arch/um/include/sysdep-i386/stub.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "stub-data.h" #include "kern_constants.h" #include "uml-config.h" -- cgit v1.2.3 From e46962fdd28f8b30b465e507b657627aa4c1a409 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 6 Dec 2006 20:34:54 -0800 Subject: [PATCH] uml: size register files correctly We were using the wrong symbol to size register files. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/sysdep-i386/ptrace.h | 2 +- arch/um/include/sysdep-x86_64/ptrace.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 6670cc992ec..52b398bcafc 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h @@ -75,7 +75,7 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - unsigned long regs[HOST_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; unsigned long fp[HOST_FP_SIZE]; unsigned long xfp[HOST_XFP_SIZE]; struct faultinfo faultinfo; diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 617bb9efc93..66cb400c2c9 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h @@ -108,7 +108,7 @@ union uml_pt_regs { * file size, while i386 uses FRAME_SIZE. Therefore, we need * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. */ - unsigned long regs[UM_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; long syscall; -- cgit v1.2.3 From 8210fd2a9fe4b36e99ab777a1a81eb47b703c235 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Wed, 6 Dec 2006 20:34:55 -0800 Subject: [PATCH] uml: use get_random_bytes() after random pool is seeded When the UML network driver generates random MACs for its devices, it was possible for a number of UMLs to get the same MACs because the ethernet initialization was done before the random pool was properly seeded. This patch moves the initialization later so that it gets better randomness. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/daemon_kern.c | 2 +- arch/um/drivers/mcast_kern.c | 2 +- arch/um/drivers/pcap_kern.c | 2 +- arch/um/drivers/slip_kern.c | 2 +- arch/um/drivers/slirp_kern.c | 2 +- arch/um/os-Linux/drivers/ethertap_kern.c | 2 +- arch/um/os-Linux/drivers/tuntap_kern.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c index 824386974f8..9c2e7a758f2 100644 --- a/arch/um/drivers/daemon_kern.c +++ b/arch/um/drivers/daemon_kern.c @@ -98,4 +98,4 @@ static int register_daemon(void) return 0; } -__initcall(register_daemon); +late_initcall(register_daemon); diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c index c090fbd464e..52ccb7b53cd 100644 --- a/arch/um/drivers/mcast_kern.c +++ b/arch/um/drivers/mcast_kern.c @@ -127,4 +127,4 @@ static int register_mcast(void) return 0; } -__initcall(register_mcast); +late_initcall(register_mcast); diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c index 6e1ef855828..e67362acf0e 100644 --- a/arch/um/drivers/pcap_kern.c +++ b/arch/um/drivers/pcap_kern.c @@ -109,4 +109,4 @@ static int register_pcap(void) return 0; } -__initcall(register_pcap); +late_initcall(register_pcap); diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 788da5439a2..25634bd1f58 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c @@ -95,4 +95,4 @@ static int register_slip(void) return 0; } -__initcall(register_slip); +late_initcall(register_slip); diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index ae322e1c8a8..b3ed8fb874a 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c @@ -119,4 +119,4 @@ static int register_slirp(void) return 0; } -__initcall(register_slirp); +late_initcall(register_slirp); diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c index 16385e2ada8..70541821775 100644 --- a/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/arch/um/os-Linux/drivers/ethertap_kern.c @@ -105,4 +105,4 @@ static int register_ethertap(void) return 0; } -__initcall(register_ethertap); +late_initcall(register_ethertap); diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c index 0edbac63c52..76570a2c25c 100644 --- a/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/arch/um/os-Linux/drivers/tuntap_kern.c @@ -90,4 +90,4 @@ static int register_tuntap(void) return 0; } -__initcall(register_tuntap); +late_initcall(register_tuntap); -- cgit v1.2.3 From 4cf303487d5dddaace2daca8437c555f3f0bc1aa Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 6 Dec 2006 20:36:06 -0800 Subject: [PATCH] Export pm_suspend for the shared APM emulation The new shared APM emulation just like its ARM and MIPS predecessors uses pm_suspend() which was only exported on SH. Move export to close to it's definition where it really should be anyway. Signed-off-by: Ralf Baechle Cc: Russell King Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/kernel/sh_ksyms.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index c706f3bfd89..ceee7914340 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -99,10 +99,6 @@ EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(synchronize_irq); #endif -#ifdef CONFIG_PM -EXPORT_SYMBOL(pm_suspend); -#endif - EXPORT_SYMBOL(csum_partial); #ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); -- cgit v1.2.3 From 6cfd76a26d9fe2ba54b9d496a48c1d9285e5c5ed Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Dec 2006 20:37:22 -0800 Subject: [PATCH] lockdep: name some old style locks Name some of the remaning 'old_style_spin_init' locks Signed-off-by: Peter Zijlstra Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index fe9c5e8e7e6..3124f1b04d6 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -452,7 +452,7 @@ void die(const char * str, struct pt_regs * regs, long err) u32 lock_owner; int lock_owner_depth; } die = { - .lock = SPIN_LOCK_UNLOCKED, + .lock = __SPIN_LOCK_UNLOCKED(die.lock), .lock_owner = -1, .lock_owner_depth = 0 }; -- cgit v1.2.3 From f5738ceed46782aea7663d62cb6398eb05fc4ce0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Dec 2006 20:37:29 -0800 Subject: [PATCH] remove kernel syscalls The last thing we agreed on was to remove the macros entirely for 2.6.19, on all architectures. Unfortunately, I think nobody actually _did_ that, so they are still there. [akpm@osdl.org: x86_64 fix] Cc: David Woodhouse Cc: Greg Schafer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/vsyscall.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 92546c1526f..630036c06c7 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -42,6 +42,7 @@ #include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) +#define __syscall_clobber "r11","rcx","memory" int __sysctl_vsyscall __section_sysctl_vsyscall = 1; seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; -- cgit v1.2.3 From 19e5d9c0d2194b4b47189cbec2921cbf72b0bd1c Mon Sep 17 00:00:00 2001 From: Henry Nestler Date: Wed, 6 Dec 2006 20:37:45 -0800 Subject: [PATCH] initrd: remove unused false condition for initrd_start After LOADER_TYPE && INITRD_START are true, the short if-condition for INITRD_START can never be false. Remove unused code from the else condition. Signed-off-by: Henry Nestler Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/setup.c | 2 +- arch/i386/kernel/setup.c | 3 +-- arch/m32r/kernel/setup.c | 4 +--- arch/m32r/mm/discontig.c | 4 +--- arch/sh/kernel/setup.c | 3 +-- arch/sh64/kernel/setup.c | 4 +--- arch/x86_64/kernel/setup.c | 3 +-- 7 files changed, 7 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index a8c61dac1ce..1a5eb6c301c 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c @@ -947,7 +947,7 @@ static void __init setup_linux_memory(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (low_top_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start + INITRD_SIZE; } else { diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 141041dde74..97bb869307b 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1162,8 +1162,7 @@ void __init setup_bootmem_allocator(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = - INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start+INITRD_SIZE; } else { diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index 0e7778be33c..936205f7aba 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c @@ -196,9 +196,7 @@ static unsigned long __init setup_memory(void) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START ? - INITRD_START + PAGE_OFFSET : 0; - + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start + INITRD_SIZE; printk("initrd:start[%08lx],size[%08lx]\n", initrd_start, INITRD_SIZE); diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c index abb34ccd598..c7efdb0aefc 100644 --- a/arch/m32r/mm/discontig.c +++ b/arch/m32r/mm/discontig.c @@ -105,9 +105,7 @@ unsigned long __init setup_memory(void) if (INITRD_START + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START, INITRD_SIZE); - initrd_start = INITRD_START ? - INITRD_START + PAGE_OFFSET : 0; - + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start + INITRD_SIZE; printk("initrd:start[%08lx],size[%08lx]\n", initrd_start, INITRD_SIZE); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 696ca75752d..f8dd6b7bfab 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -332,8 +332,7 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); - initrd_start = - INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0; + initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " diff --git a/arch/sh64/kernel/setup.c b/arch/sh64/kernel/setup.c index ffb310e33ce..b9e7d54d7b8 100644 --- a/arch/sh64/kernel/setup.c +++ b/arch/sh64/kernel/setup.c @@ -243,9 +243,7 @@ void __init setup_arch(char **cmdline_p) if (INITRD_START + INITRD_SIZE <= (PFN_PHYS(last_pfn))) { reserve_bootmem_node(NODE_DATA(0), INITRD_START + __MEMORY_START, INITRD_SIZE); - initrd_start = - (long) INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0; - + initrd_start = (long) INITRD_START + PAGE_OFFSET + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index fc944b5e8f4..f12f266f3e9 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -471,8 +471,7 @@ void __init setup_arch(char **cmdline_p) if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { reserve_bootmem_generic(INITRD_START, INITRD_SIZE); - initrd_start = - INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start+INITRD_SIZE; } else { -- cgit v1.2.3 From 386d9a7edd9f3492c99124b0a659e9ed7abb30f9 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Dec 2006 20:37:53 -0800 Subject: [PATCH] elf: Always define elf_addr_t in linux/elf.h Define elf_addr_t in linux/elf.h. The size of the type is determined using ELF_CLASS. This allows us to remove the defines that today are spread all over .c and .h files. Signed-off-by: Magnus Damm Cc: Daniel Jacobowitz Cc: Roland McGrath Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/ia32/ia32priv.h | 2 -- arch/mips/kernel/binfmt_elfn32.c | 1 - arch/mips/kernel/binfmt_elfo32.c | 1 - arch/mips/kernel/irixelf.c | 4 ---- arch/parisc/kernel/binfmt_elf32.c | 1 - arch/s390/kernel/binfmt_elf32.c | 1 - arch/sparc64/kernel/binfmt_elf32.c | 1 - arch/x86_64/ia32/ia32_binfmt.c | 2 -- 8 files changed, 13 deletions(-) (limited to 'arch') diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h index 703a67c934f..cfa0bc0026b 100644 --- a/arch/ia64/ia32/ia32priv.h +++ b/arch/ia64/ia32/ia32priv.h @@ -330,8 +330,6 @@ struct old_linux32_dirent { void ia64_elf32_init(struct pt_regs *regs); #define ELF_PLAT_INIT(_r, load_addr) ia64_elf32_init(_r) -#define elf_addr_t u32 - /* This macro yields a bitmask that programs can use to figure out what instruction set this CPU supports. */ #define ELF_HWCAP 0 diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 4a9f1ecefaf..9b34238d41c 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -90,7 +90,6 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; -#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elfn32_binfmt diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index e3181377989..993f7ec70f3 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -92,7 +92,6 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; -#define elf_addr_t u32 #define elf_caddr_t u32 #define init_elf_binfmt init_elf32_binfmt diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index ab12c8f0151..a82fae221ce 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -52,10 +52,6 @@ static struct linux_binfmt irix_format = { irix_core_dump, PAGE_SIZE }; -#ifndef elf_addr_t -#define elf_addr_t unsigned long -#endif - #ifdef DEBUG /* Debugging routines. */ static char *get_elf_p_type(Elf32_Word p_type) diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c index 1e64e7b8811..ecb10a4f63c 100644 --- a/arch/parisc/kernel/binfmt_elf32.c +++ b/arch/parisc/kernel/binfmt_elf32.c @@ -75,7 +75,6 @@ struct elf_prpsinfo32 char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ }; -#define elf_addr_t unsigned int #define init_elf_binfmt init_elf32_binfmt #define ELF_PLATFORM ("PARISC32\0") diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c index 9565a2dcfad..5c46054195c 100644 --- a/arch/s390/kernel/binfmt_elf32.c +++ b/arch/s390/kernel/binfmt_elf32.c @@ -176,7 +176,6 @@ struct elf_prpsinfo32 #include -#define elf_addr_t u32 /* #define init_elf_binfmt init_elf32_binfmt */ diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c index a98f3ae175a..9ad84ff10a1 100644 --- a/arch/sparc64/kernel/binfmt_elf32.c +++ b/arch/sparc64/kernel/binfmt_elf32.c @@ -141,7 +141,6 @@ cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) value->tv_sec = jiffies / HZ; } -#define elf_addr_t u32 #undef start_thread #define start_thread start_thread32 #define init_elf_binfmt init_elf32_binfmt diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index 932a62ad6c8..543ef4f405e 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -305,8 +305,6 @@ MODULE_AUTHOR("Eric Youngdale, Andi Kleen"); #undef MODULE_DESCRIPTION #undef MODULE_AUTHOR -#define elf_addr_t __u32 - static void elf32_init(struct pt_regs *); #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 -- cgit v1.2.3 From 584236ac7cdddeec0fdff25d2e475471ef91d028 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Dec 2006 20:37:56 -0800 Subject: [PATCH] elf: include terminating zero in n_namesz The ELF32 spec says we should plus we include the zero on other platforms. Signed-off-by: Magnus Damm Cc: Daniel Jacobowitz Cc: Roland McGrath Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/irixelf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index a82fae221ce..1bbefbf4337 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1009,7 +1009,7 @@ static int notesize(struct memelfnote *en) int sz; sz = sizeof(struct elf_note); - sz += roundup(strlen(en->name), 4); + sz += roundup(strlen(en->name) + 1, 4); sz += roundup(en->datasz, 4); return sz; @@ -1028,7 +1028,7 @@ static int writenote(struct memelfnote *men, struct file *file) { struct elf_note en; - en.n_namesz = strlen(men->name); + en.n_namesz = strlen(men->name) + 1; en.n_descsz = men->datasz; en.n_type = men->type; -- cgit v1.2.3 From b4c6c34a530b4d1c626f4ac0a884e0a9b849378c Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 6 Dec 2006 20:38:11 -0800 Subject: [PATCH] kprobes: enable booster on the preemptible kernel When we are unregistering a kprobe-booster, we can't release its instruction buffer immediately on the preemptive kernel, because some processes might be preempted on the buffer. The freeze_processes() and thaw_processes() functions can clean most of processes up from the buffer. There are still some non-frozen threads who have the PF_NOFREEZE flag. If those threads are sleeping (not preempted) at the known place outside the buffer, we can ensure safety of freeing. However, the processing of this check routine takes a long time. So, this patch introduces the garbage collection mechanism of insn_slot. It also introduces the "dirty" flag to free_insn_slot because of efficiency. The "clean" instruction slots (dirty flag is cleared) are released immediately. But the "dirty" slots which are used by boosted kprobes, are marked as garbages. collect_garbage_slots() will be invoked to release "dirty" slots if there are more than INSNS_PER_PAGE garbage slots or if there are no unused slots. Cc: "Keshavamurthy, Anil S" Cc: Ananth N Mavinakayanahalli Cc: "bibo,mao" Cc: Prasanna S Panchamukhi Cc: Yumiko Sugita Cc: Satoshi Oshima Cc: Hideo Aoki Signed-off-by: Masami Hiramatsu Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 4 ++-- arch/ia64/kernel/kprobes.c | 2 +- arch/powerpc/kernel/kprobes.c | 2 +- arch/s390/kernel/kprobes.c | 2 +- arch/x86_64/kernel/kprobes.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index fc79e1e859c..af1d5334499 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -184,7 +184,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); + free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); mutex_unlock(&kprobe_mutex); } @@ -333,7 +333,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) return 1; ss_probe: -#ifndef CONFIG_PREEMPT +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PM) if (p->ainsn.boostable == 1 && !p->post_handler){ /* Boost up -- we can execute copied instructions directly */ reset_current_kprobe(); diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 51217d63285..4d592ee9300 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -481,7 +481,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); + free_insn_slot(p->ainsn.insn, 0); mutex_unlock(&kprobe_mutex); } /* diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 7b8d12b9026..4657563f881 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -85,7 +85,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); + free_insn_slot(p->ainsn.insn, 0); mutex_unlock(&kprobe_mutex); } diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 67914fe7f31..576368c4f60 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c @@ -200,7 +200,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); + free_insn_slot(p->ainsn.insn, 0); mutex_unlock(&kprobe_mutex); } diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index ac241567e68..209c8c0bec7 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -224,7 +224,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) void __kprobes arch_remove_kprobe(struct kprobe *p) { mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); + free_insn_slot(p->ainsn.insn, 0); mutex_unlock(&kprobe_mutex); } -- cgit v1.2.3 From a38a44c1a93078fc5fadc4ac2df8dea4697069e2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 6 Dec 2006 20:38:16 -0800 Subject: [PATCH] smp_call_function_single() check that local interrupts are enabled smp_call_function_single() can deadlock if the caller disabled local interrupts (the target CPU could be spinning on call_lock). Check for that. Why on earth do these functions use spin_lock_bh()?? Cc: "Randy.Dunlap" Cc: Andi Kleen Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/smp.c | 4 ++++ arch/x86_64/kernel/smp.c | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c index 31e5c6573aa..9827cf927ec 100644 --- a/arch/i386/kernel/smp.c +++ b/arch/i386/kernel/smp.c @@ -699,6 +699,10 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, put_cpu(); return -EBUSY; } + + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); spin_unlock_bh(&call_lock); diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 9f74c883568..32f4d7e2a06 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -379,6 +379,10 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, put_cpu(); return 0; } + + /* Can deadlock when called with interrupts disabled */ + WARN_ON(irqs_disabled()); + spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); spin_unlock_bh(&call_lock); -- cgit v1.2.3 From 02316067852187b8bec781bec07410e91af79627 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 6 Dec 2006 20:38:17 -0800 Subject: [PATCH] hotplug CPU: clean up hotcpu_notifier() use There was lots of #ifdef noise in the kernel due to hotcpu_notifier(fn, prio) not correctly marking 'fn' as used in the !HOTPLUG_CPU case, and thus generating compiler warnings of unused symbols, hence forcing people to add #ifdefs. the compiler can skip truly unused functions just fine: text data bss dec hex filename 1624412 728710 3674856 6027978 5bfaca vmlinux.before 1624412 728710 3674856 6027978 5bfaca vmlinux.after [akpm@osdl.org: topology.c fix] Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpu/mcheck/therm_throt.c | 2 -- arch/i386/kernel/cpuid.c | 2 -- arch/i386/kernel/microcode.c | 2 -- arch/i386/kernel/msr.c | 2 -- arch/ia64/kernel/palinfo.c | 2 -- arch/ia64/kernel/salinfo.c | 2 -- arch/s390/appldata/appldata_base.c | 2 -- arch/x86_64/kernel/mce.c | 2 -- arch/x86_64/kernel/mce_amd.c | 4 ++-- arch/x86_64/kernel/vsyscall.c | 2 -- 10 files changed, 2 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index bad8b442070..065005c3f16 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c @@ -116,7 +116,6 @@ static __cpuinit int thermal_throttle_add_dev(struct sys_device *sys_dev) return sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); } -#ifdef CONFIG_HOTPLUG_CPU static __cpuinit void thermal_throttle_remove_dev(struct sys_device *sys_dev) { return sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); @@ -153,7 +152,6 @@ static struct notifier_block thermal_throttle_cpu_notifier = { .notifier_call = thermal_throttle_cpu_callback, }; -#endif /* CONFIG_HOTPLUG_CPU */ static __init int thermal_throttle_init_device(void) { diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index ab0c327e79d..23b2cc748d4 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -167,7 +167,6 @@ static int cpuid_device_create(int i) return err; } -#ifdef CONFIG_HOTPLUG_CPU static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -187,7 +186,6 @@ static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier = { .notifier_call = cpuid_class_cpu_callback, }; -#endif /* !CONFIG_HOTPLUG_CPU */ static int __init cpuid_init(void) { diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 23f5984d065..972346604f9 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c @@ -703,7 +703,6 @@ static struct sysdev_driver mc_sysdev_driver = { .resume = mc_sysdev_resume, }; -#ifdef CONFIG_HOTPLUG_CPU static __cpuinit int mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { @@ -726,7 +725,6 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) static struct notifier_block mc_cpu_notifier = { .notifier_call = mc_cpu_callback, }; -#endif static int __init microcode_init (void) { diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index a773f776c9e..7763c67ca28 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -250,7 +250,6 @@ static int msr_device_create(int i) return err; } -#ifdef CONFIG_HOTPLUG_CPU static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -271,7 +270,6 @@ static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { .notifier_call = msr_class_cpu_callback, }; -#endif static int __init msr_init(void) { diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 0b546e2b36a..c4c10a0b99d 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -952,7 +952,6 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } -#ifdef CONFIG_HOTPLUG_CPU static int palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -974,7 +973,6 @@ static struct notifier_block palinfo_cpu_notifier = .notifier_call = palinfo_cpu_callback, .priority = 0, }; -#endif static int __init palinfo_init(void) diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index e63b8ca5344..fd607ca51a8 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -575,7 +575,6 @@ static struct file_operations salinfo_data_fops = { .write = salinfo_log_write, }; -#ifdef CONFIG_HOTPLUG_CPU static int __devinit salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { @@ -620,7 +619,6 @@ static struct notifier_block salinfo_cpu_notifier = .notifier_call = salinfo_cpu_callback, .priority = 0, }; -#endif /* CONFIG_HOTPLUG_CPU */ static int __init salinfo_init(void) diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 67d5cf9cba8..b8c23729026 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -561,7 +561,6 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) @@ -582,7 +581,6 @@ appldata_cpu_notify(struct notifier_block *self, static struct notifier_block appldata_nb = { .notifier_call = appldata_cpu_notify, }; -#endif /* * appldata_init() diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index c7587fc3901..bc863c464a1 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c @@ -641,7 +641,6 @@ static __cpuinit int mce_create_device(unsigned int cpu) return err; } -#ifdef CONFIG_HOTPLUG_CPU static void mce_remove_device(unsigned int cpu) { int i; @@ -674,7 +673,6 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) static struct notifier_block mce_cpu_notifier = { .notifier_call = mce_cpu_callback, }; -#endif static __init int mce_init_device(void) { diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index 883fe747f64..fa09debad4b 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c @@ -551,7 +551,6 @@ out: return err; } -#ifdef CONFIG_HOTPLUG_CPU /* * let's be hotplug friendly. * in case of multiple core processors, the first core always takes ownership @@ -594,12 +593,14 @@ static void threshold_remove_bank(unsigned int cpu, int bank) sprintf(name, "threshold_bank%i", bank); +#ifdef CONFIG_SMP /* sibling symlink */ if (shared_bank[bank] && b->blocks->cpu != cpu) { sysfs_remove_link(&per_cpu(device_mce, cpu).kobj, name); per_cpu(threshold_banks, cpu)[bank] = NULL; return; } +#endif /* remove all sibling symlinks before unregistering */ for_each_cpu_mask(i, b->cpus) { @@ -656,7 +657,6 @@ static int threshold_cpu_callback(struct notifier_block *nfb, static struct notifier_block threshold_cpu_notifier = { .notifier_call = threshold_cpu_callback, }; -#endif /* CONFIG_HOTPLUG_CPU */ static __init int threshold_init_device(void) { diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 630036c06c7..3785e495473 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -275,7 +275,6 @@ static void __cpuinit cpu_vsyscall_init(void *arg) vsyscall_set_cpu(raw_smp_processor_id()); } -#ifdef CONFIG_HOTPLUG_CPU static int __cpuinit cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) { @@ -284,7 +283,6 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); return NOTIFY_DONE; } -#endif static void __init map_vsyscall(void) { -- cgit v1.2.3 From db68b189f4b8026b2f532e1b1bbdba5fcb36638c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 6 Dec 2006 20:38:36 -0800 Subject: [PATCH] add rtc-omap driver This creates a new RTC-framework driver for the RTC/calendar module found in various OMAP1 chips. (OMAP2 and OMAP3 use external RTCs, like those in TI's multifunction PM companion chips.) It's been in the Linux-OMAP tree for several months now, and other trees before that, so it's quite stable. The most notable issue is that the OMAP IRQ code doesn't yet support the RTC IRQ as a wakeup event. Once that's fixed, a patch will be needed. Signed-off-by: David Brownell Acked-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-omap1/devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index a611c3b6395..6dcd10ab449 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -55,7 +55,7 @@ static inline void omap_init_irda(void) {} /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC) +#if defined(CONFIG_RTC_DRV_OMAP) || defined(CONFIG_RTC_DRV_OMAP_MODULE) #define OMAP_RTC_BASE 0xfffb4800 -- cgit v1.2.3 From f67637ee4b5d90d41160d755b9a8cca18c394586 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 6 Dec 2006 20:38:54 -0800 Subject: [PATCH] Add struct dev pointer to dma_is_consistent() dma_is_consistent() is ill-designed in that it does not have a struct device pointer argument which makes proper support for systems that consist of a mix of coherent and non-coherent DMA devices hard. Change dma_is_consistent to take a struct device pointer as first argument and fix the sole caller to pass it. Signed-off-by: Ralf Baechle Cc: James Bottomley Cc: "David S. Miller" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-ip27.c | 2 +- arch/mips/mm/dma-ip32.c | 2 +- arch/mips/mm/dma-noncoherent.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c index 7fa5fd16e46..18bc83e577c 100644 --- a/arch/mips/mm/dma-coherent.c +++ b/arch/mips/mm/dma-coherent.c @@ -190,7 +190,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c index 8da19fd22ac..8e9a5a8f5d6 100644 --- a/arch/mips/mm/dma-ip27.c +++ b/arch/mips/mm/dma-ip27.c @@ -197,7 +197,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c index ec54ed0d26f..08720a42100 100644 --- a/arch/mips/mm/dma-ip32.c +++ b/arch/mips/mm/dma-ip32.c @@ -363,7 +363,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index 2eeffe5c2a3..4a3efc63337 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -299,7 +299,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } -- cgit v1.2.3 From d3fa72e4556ec1f04e46a0d561d9e785ecaa173d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 6 Dec 2006 20:38:56 -0800 Subject: [PATCH] Pass struct dev pointer to dma_cache_sync() Pass struct dev pointer to dma_cache_sync() dma_cache_sync() is ill-designed in that it does not have a struct device pointer argument which makes proper support for systems that consist of a mix of coherent and non-coherent DMA devices hard. Change dma_cache_sync to take a struct device pointer as first argument and fix all its callers to pass it. Signed-off-by: Ralf Baechle Cc: James Bottomley Cc: "David S. Miller" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/avr32/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-ip27.c | 2 +- arch/mips/mm/dma-ip32.c | 3 ++- arch/mips/mm/dma-noncoherent.c | 3 ++- 5 files changed, 7 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c index 44ab8a7bdae..b68d669f823 100644 --- a/arch/avr32/mm/dma-coherent.c +++ b/arch/avr32/mm/dma-coherent.c @@ -11,7 +11,7 @@ #include #include -void dma_cache_sync(void *vaddr, size_t size, int direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction) { /* * No need to sync an uncached area diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c index 18bc83e577c..5697c6e250a 100644 --- a/arch/mips/mm/dma-coherent.c +++ b/arch/mips/mm/dma-coherent.c @@ -197,7 +197,7 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c index 8e9a5a8f5d6..f088344db46 100644 --- a/arch/mips/mm/dma-ip27.c +++ b/arch/mips/mm/dma-ip27.c @@ -204,7 +204,7 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c index 08720a42100..b42b6f7456e 100644 --- a/arch/mips/mm/dma-ip32.c +++ b/arch/mips/mm/dma-ip32.c @@ -370,7 +370,8 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) { if (direction == DMA_NONE) return; diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index 4a3efc63337..8cecef0957c 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -306,7 +306,8 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) { if (direction == DMA_NONE) return; -- cgit v1.2.3 From cd6ed52568e161ce924593ebc798050a2d23cca0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 6 Dec 2006 20:40:06 -0800 Subject: [PATCH] arch/i386/kernel/reboot.c should #include Every file should #include the headers containing the prototypes for its global functions. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/reboot.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 84278e0093a..3514b4153f7 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include -- cgit v1.2.3 From a0172a6dd906cf813cd56aeb133a85abf9a36c8e Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Wed, 6 Dec 2006 20:40:33 -0800 Subject: [PATCH] arm26: replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman CC: Ian Molton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm26/kernel/ecard.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm26/kernel/ecard.c b/arch/arm26/kernel/ecard.c index 047d0a408b9..43dd41be71f 100644 --- a/arch/arm26/kernel/ecard.c +++ b/arch/arm26/kernel/ecard.c @@ -620,12 +620,10 @@ ecard_probe(int slot, card_type_t type) struct ex_ecid cid; int i, rc = -ENOMEM; - ec = kmalloc(sizeof(ecard_t), GFP_KERNEL); + ec = kzalloc(sizeof(ecard_t), GFP_KERNEL); if (!ec) goto nomem; - memset(ec, 0, sizeof(ecard_t)); - ec->slot_no = slot; ec->type = type; ec->irq = NO_IRQ; -- cgit v1.2.3 From 85916f8166b59eeac63d2b4f7f1df8de849334b4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 6 Dec 2006 20:40:41 -0800 Subject: [PATCH] Kexec / Kdump: Unify elf note code The elf note saving code is currently duplicated over several architectures. This cleanup patch simply adds code to a common file and then replaces the arch-specific code with calls to the newly added code. The only drawback with this approach is that s390 doesn't fully support kexec-on-panic which for that arch leads to introduction of unused code. Signed-off-by: Magnus Damm Cc: Vivek Goyal Cc: Andi Kleen Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/crash.c | 66 ++----------------------------------------- arch/powerpc/kernel/crash.c | 59 ++------------------------------------ arch/x86_64/kernel/crash.c | 69 ++------------------------------------------- 3 files changed, 6 insertions(+), 188 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/crash.c b/arch/i386/kernel/crash.c index 144b4328896..a5e0e990ea9 100644 --- a/arch/i386/kernel/crash.c +++ b/arch/i386/kernel/crash.c @@ -31,68 +31,6 @@ /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; -static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, - size_t data_len) -{ - struct elf_note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = data_len; - note.n_type = type; - memcpy(buf, ¬e, sizeof(note)); - buf += (sizeof(note) +3)/4; - memcpy(buf, name, note.n_namesz); - buf += (note.n_namesz + 3)/4; - memcpy(buf, data, note.n_descsz); - buf += (note.n_descsz + 3)/4; - - return buf; -} - -static void final_note(u32 *buf) -{ - struct elf_note note; - - note.n_namesz = 0; - note.n_descsz = 0; - note.n_type = 0; - memcpy(buf, ¬e, sizeof(note)); -} - -static void crash_save_this_cpu(struct pt_regs *regs, int cpu) -{ - struct elf_prstatus prstatus; - u32 *buf; - - if ((cpu < 0) || (cpu >= NR_CPUS)) - return; - - /* Using ELF notes here is opportunistic. - * I need a well defined structure format - * for the data I pass, and I need tags - * on the data to indicate what information I have - * squirrelled away. ELF notes happen to provide - * all of that, so there is no need to invent something new. - */ - buf = (u32*)per_cpu_ptr(crash_notes, cpu); - if (!buf) - return; - memset(&prstatus, 0, sizeof(prstatus)); - prstatus.pr_pid = current->pid; - elf_core_copy_regs(&prstatus.pr_reg, regs); - buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, - sizeof(prstatus)); - final_note(buf); -} - -static void crash_save_self(struct pt_regs *regs) -{ - int cpu; - - cpu = safe_smp_processor_id(); - crash_save_this_cpu(regs, cpu); -} - #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static atomic_t waiting_for_crash_ipi; @@ -121,7 +59,7 @@ static int crash_nmi_callback(struct notifier_block *self, crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; } - crash_save_this_cpu(regs, cpu); + crash_save_cpu(regs, cpu); disable_local_APIC(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -195,5 +133,5 @@ void machine_crash_shutdown(struct pt_regs *regs) #if defined(CONFIG_X86_IO_APIC) disable_IO_APIC(); #endif - crash_save_self(regs); + crash_save_cpu(regs, safe_smp_processor_id()); } diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 89b03c8da9d..d3f2080d2ee 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -46,61 +46,6 @@ int crashing_cpu = -1; static cpumask_t cpus_in_crash = CPU_MASK_NONE; cpumask_t cpus_in_sr = CPU_MASK_NONE; -static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, - size_t data_len) -{ - struct elf_note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = data_len; - note.n_type = type; - memcpy(buf, ¬e, sizeof(note)); - buf += (sizeof(note) +3)/4; - memcpy(buf, name, note.n_namesz); - buf += (note.n_namesz + 3)/4; - memcpy(buf, data, note.n_descsz); - buf += (note.n_descsz + 3)/4; - - return buf; -} - -static void final_note(u32 *buf) -{ - struct elf_note note; - - note.n_namesz = 0; - note.n_descsz = 0; - note.n_type = 0; - memcpy(buf, ¬e, sizeof(note)); -} - -static void crash_save_this_cpu(struct pt_regs *regs, int cpu) -{ - struct elf_prstatus prstatus; - u32 *buf; - - if ((cpu < 0) || (cpu >= NR_CPUS)) - return; - - /* Using ELF notes here is opportunistic. - * I need a well defined structure format - * for the data I pass, and I need tags - * on the data to indicate what information I have - * squirrelled away. ELF notes happen to provide - * all of that that no need to invent something new. - */ - buf = (u32*)per_cpu_ptr(crash_notes, cpu); - if (!buf) - return; - - memset(&prstatus, 0, sizeof(prstatus)); - prstatus.pr_pid = current->pid; - elf_core_copy_regs(&prstatus.pr_reg, regs); - buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, - sizeof(prstatus)); - final_note(buf); -} - #ifdef CONFIG_SMP static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); @@ -113,7 +58,7 @@ void crash_ipi_callback(struct pt_regs *regs) hard_irq_disable(); if (!cpu_isset(cpu, cpus_in_crash)) - crash_save_this_cpu(regs, cpu); + crash_save_cpu(regs, cpu); cpu_set(cpu, cpus_in_crash); /* @@ -306,7 +251,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); - crash_save_this_cpu(regs, crashing_cpu); + crash_save_cpu(regs, crashing_cpu); crash_kexec_prepare_cpus(crashing_cpu); cpu_set(crashing_cpu, cpus_in_crash); if (ppc_md.kexec_cpu_down) diff --git a/arch/x86_64/kernel/crash.c b/arch/x86_64/kernel/crash.c index 3525f884af8..95a7a2c1313 100644 --- a/arch/x86_64/kernel/crash.c +++ b/arch/x86_64/kernel/crash.c @@ -28,71 +28,6 @@ /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; -static u32 *append_elf_note(u32 *buf, char *name, unsigned type, - void *data, size_t data_len) -{ - struct elf_note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = data_len; - note.n_type = type; - memcpy(buf, ¬e, sizeof(note)); - buf += (sizeof(note) +3)/4; - memcpy(buf, name, note.n_namesz); - buf += (note.n_namesz + 3)/4; - memcpy(buf, data, note.n_descsz); - buf += (note.n_descsz + 3)/4; - - return buf; -} - -static void final_note(u32 *buf) -{ - struct elf_note note; - - note.n_namesz = 0; - note.n_descsz = 0; - note.n_type = 0; - memcpy(buf, ¬e, sizeof(note)); -} - -static void crash_save_this_cpu(struct pt_regs *regs, int cpu) -{ - struct elf_prstatus prstatus; - u32 *buf; - - if ((cpu < 0) || (cpu >= NR_CPUS)) - return; - - /* Using ELF notes here is opportunistic. - * I need a well defined structure format - * for the data I pass, and I need tags - * on the data to indicate what information I have - * squirrelled away. ELF notes happen to provide - * all of that, no need to invent something new. - */ - - buf = (u32*)per_cpu_ptr(crash_notes, cpu); - - if (!buf) - return; - - memset(&prstatus, 0, sizeof(prstatus)); - prstatus.pr_pid = current->pid; - elf_core_copy_regs(&prstatus.pr_reg, regs); - buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, - sizeof(prstatus)); - final_note(buf); -} - -static void crash_save_self(struct pt_regs *regs) -{ - int cpu; - - cpu = smp_processor_id(); - crash_save_this_cpu(regs, cpu); -} - #ifdef CONFIG_SMP static atomic_t waiting_for_crash_ipi; @@ -117,7 +52,7 @@ static int crash_nmi_callback(struct notifier_block *self, return NOTIFY_STOP; local_irq_disable(); - crash_save_this_cpu(regs, cpu); + crash_save_cpu(regs, cpu); disable_local_APIC(); atomic_dec(&waiting_for_crash_ipi); /* Assume hlt works */ @@ -196,5 +131,5 @@ void machine_crash_shutdown(struct pt_regs *regs) disable_IO_APIC(); - crash_save_self(regs); + crash_save_cpu(regs, smp_processor_id()); } -- cgit v1.2.3 From c324113f20637cbc9b71f8d873409be90bfac167 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 7 Dec 2006 17:19:58 +0000 Subject: [ARM] Update mach-types Signed-off-by: Russell King --- arch/arm/tools/mach-types | 58 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 579c69ae9ff..8bcb838e544 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Mon Oct 16 21:13:36 2006 +# Last update: Thu Dec 7 17:19:20 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -79,7 +79,7 @@ psionw ARCH_PSIONW PSIONW 60 aln SA1100_ALN ALN 61 epxa ARCH_CAMELOT CAMELOT 62 gds2200 SA1100_GDS2200 GDS2200 63 -psion_series7 SA1100_PSION_SERIES7 PSION_SERIES7 64 +netbook SA1100_PSION_SERIES7 PSION_SERIES7 64 xfile SA1100_XFILE XFILE 65 accelent_ep9312 ARCH_ACCELENT_EP9312 ACCELENT_EP9312 66 ic200 ARCH_IC200 IC200 67 @@ -810,9 +810,9 @@ sb3010 MACH_SB3010 SB3010 795 rm9200 MACH_RM9200 RM9200 796 dma03 MACH_DMA03 DMA03 797 road_s101 MACH_ROAD_S101 ROAD_S101 798 -iq_nextgen_a MACH_IQ_NEXTGEN_A IQ_NEXTGEN_A 799 +iq81340sc MACH_IQ81340SC IQ81340SC 799 iq_nextgen_b MACH_IQ_NEXTGEN_B IQ_NEXTGEN_B 800 -iq_nextgen_c MACH_IQ_NEXTGEN_C IQ_NEXTGEN_C 801 +iq81340mc MACH_IQ81340MC IQ81340MC 801 iq_nextgen_d MACH_IQ_NEXTGEN_D IQ_NEXTGEN_D 802 iq_nextgen_e MACH_IQ_NEXTGEN_E IQ_NEXTGEN_E 803 mallow_at91 MACH_MALLOW_AT91 MALLOW_AT91 804 @@ -1165,9 +1165,57 @@ pnx4010 MACH_PNX4010 PNX4010 1151 oxnas MACH_OXNAS OXNAS 1152 fiori MACH_FIORI FIORI 1153 ml1200 MACH_ML1200 ML1200 1154 -cactus MACH_CACTUS CACTUS 1155 +pecos MACH_PECOS PECOS 1155 nb2xxx MACH_NB2XXX NB2XXX 1156 hw6900 MACH_HW6900 HW6900 1157 cdcs_quoll MACH_CDCS_QUOLL CDCS_QUOLL 1158 quicksilver MACH_QUICKSILVER QUICKSILVER 1159 uplat926 MACH_UPLAT926 UPLAT926 1160 +dep2410_dep2410 MACH_DEP2410_THOMAS DEP2410_THOMAS 1161 +dtk2410 MACH_DTK2410 DTK2410 1162 +chili MACH_CHILI CHILI 1163 +demeter MACH_DEMETER DEMETER 1164 +dionysus MACH_DIONYSUS DIONYSUS 1165 +as352x MACH_AS352X AS352X 1166 +service MACH_SERVICE SERVICE 1167 +cs_e9301 MACH_CS_E9301 CS_E9301 1168 +micro9m MACH_MICRO9M MICRO9M 1169 +ia_mospck MACH_IA_MOSPCK IA_MOSPCK 1170 +ql201b MACH_QL201B QL201B 1171 +bbm MACH_BBM BBM 1174 +exxx MACH_EXXX EXXX 1175 +wma11b MACH_WMA11B WMA11B 1176 +pelco_atlas MACH_PELCO_ATLAS PELCO_ATLAS 1177 +g500 MACH_G500 G500 1178 +bug MACH_BUG BUG 1179 +mx33ads MACH_MX33ADS MX33ADS 1180 +chub MACH_CHUB CHUB 1181 +gta01 MACH_GTA01 GTA01 1182 +w90n740 MACH_W90N740 W90N740 1183 +medallion_sa2410 MACH_MEDALLION_SA2410 MEDALLION_SA2410 1184 +ia_cpu_9200_2 MACH_IA_CPU_9200_2 IA_CPU_9200_2 1185 +dimmrm9200 MACH_DIMMRM9200 DIMMRM9200 1186 +pm9261 MACH_PM9261 PM9261 1187 +mx21 MACH_MX21 MX21 1188 +ml7304 MACH_ML7304 ML7304 1189 +ucp250 MACH_UCP250 UCP250 1190 +intboard MACH_INTBOARD INTBOARD 1191 +gulfstream MACH_GULFSTREAM GULFSTREAM 1192 +labquest MACH_LABQUEST LABQUEST 1193 +vcmx313 MACH_VCMX313 VCMX313 1194 +urg200 MACH_URG200 URG200 1195 +cpux255lcdnet MACH_CPUX255LCDNET CPUX255LCDNET 1196 +netdcu9 MACH_NETDCU9 NETDCU9 1197 +netdcu10 MACH_NETDCU10 NETDCU10 1198 +dspg_dga MACH_DSPG_DGA DSPG_DGA 1199 +dspg_dvw MACH_DSPG_DVW DSPG_DVW 1200 +solos MACH_SOLOS SOLOS 1201 +at91sam9263ek MACH_AT91SAM9263EK AT91SAM9263EK 1202 +osstbox MACH_OSSTBOX OSSTBOX 1203 +kbat9261 MACH_KBAT9261 KBAT9261 1204 +ct1100 MACH_CT1100 CT1100 1205 +akcppxa MACH_AKCPPXA AKCPPXA 1206 +zevio_1020 MACH_ZEVIO_1020 ZEVIO_1020 1207 +hitrack MACH_HITRACK HITRACK 1208 +syme1 MACH_SYME1 SYME1 1209 +syhl1 MACH_SYHL1 SYHL1 1210 -- cgit v1.2.3 From 4dbda6a50ae34d853353f15d30a166c87143408f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 1 Dec 2006 21:40:37 +0100 Subject: [ARM] 3968/1: iop13xx: add iop13xx_defconfig Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/configs/iop13xx_defconfig | 1134 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1134 insertions(+) create mode 100644 arch/arm/configs/iop13xx_defconfig (limited to 'arch') diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig new file mode 100644 index 00000000000..f6e46193fd2 --- /dev/null +++ b/arch/arm/configs/iop13xx_defconfig @@ -0,0 +1,1134 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19 +# Fri Dec 1 10:51:01 2006 +# +CONFIG_ARM=y +# CONFIG_GENERIC_TIME is not set +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +CONFIG_POSIX_MQUEUE=y +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +# CONFIG_EMBEDDED is not set +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_BLK_DEV_IO_TRACE is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +CONFIG_DEFAULT_DEADLINE=y +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="deadline" + +# +# System Type +# +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +CONFIG_ARCH_IOP13XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set + +# +# IOP13XX Implementation Options +# + +# +# IOP13XX Platform Support +# +CONFIG_MACH_IQ81340SC=y +CONFIG_MACH_IQ81340MC=y + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSC3=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_IO_36=y + +# +# Processor Features +# +CONFIG_ARM_THUMB=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set + +# +# Bus support +# +CONFIG_PCI=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +CONFIG_HZ=100 +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_RESOURCES_64BIT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=bootp root=nfs console=ttyS0,115200 nfsroot=,tcp,v3,wsize=8192,rsize=8192" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +# CONFIG_MTD_CHAR is not set +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xfa000000 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=2 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=y +CONFIG_SCSI_SAS_ATTRS=y +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID10=y +CONFIG_MD_RAID456=y +# CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_NVRAM is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +# CONFIG_I2C_CHARDEV is not set + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=m +CONFIG_I2C_ALGOPCF=m +CONFIG_I2C_ALGOPCA=m + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# Real Time Clock +# +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_FS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_HEADERS_CHECK is not set +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_PLIST=y -- cgit v1.2.3 From 285f5fa7e9a35e75d9022f9b036ed709721c5cdf Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 7 Dec 2006 02:59:39 +0100 Subject: [ARM] 3995/1: iop13xx: add iop13xx support The iop348 processor integrates an Xscale (XSC3 512KB L2 Cache) core with a Serial Attached SCSI (SAS) controller, multi-ported DDR2 memory controller, 3 Application Direct Memory Access (DMA) controllers, a 133Mhz PCI-X interface, a x8 PCI-Express interface, and other peripherals to form a system-on-a-chip RAID subsystem engine. The iop342 processor replaces the SAS controller with a second Xscale core for dual core embedded applications. The iop341 processor is the single core version of iop342. This patch supports the two Intel customer reference platforms iq81340mc for external storage and iq81340sc for direct attach (HBA) development. The developer's manual is available here: ftp://download.intel.com/design/iio/docs/31503701.pdf Changelog: * removed virtual addresses from resource definitions * cleaned up some unnecessary #include's Signed-off-by: Dan Williams Signed-off-by: Russell King --- arch/arm/Kconfig | 8 + arch/arm/Makefile | 1 + arch/arm/mach-iop13xx/Kconfig | 20 + arch/arm/mach-iop13xx/Makefile | 12 + arch/arm/mach-iop13xx/Makefile.boot | 3 + arch/arm/mach-iop13xx/io.c | 93 +++ arch/arm/mach-iop13xx/iq81340mc.c | 98 +++ arch/arm/mach-iop13xx/iq81340sc.c | 100 ++++ arch/arm/mach-iop13xx/irq.c | 286 +++++++++ arch/arm/mach-iop13xx/pci.c | 1113 +++++++++++++++++++++++++++++++++++ arch/arm/mach-iop13xx/setup.c | 406 +++++++++++++ arch/arm/mach-iop13xx/time.c | 102 ++++ arch/arm/mm/Kconfig | 2 +- 13 files changed, 2243 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-iop13xx/Kconfig create mode 100644 arch/arm/mach-iop13xx/Makefile create mode 100644 arch/arm/mach-iop13xx/Makefile.boot create mode 100644 arch/arm/mach-iop13xx/io.c create mode 100644 arch/arm/mach-iop13xx/iq81340mc.c create mode 100644 arch/arm/mach-iop13xx/iq81340sc.c create mode 100644 arch/arm/mach-iop13xx/irq.c create mode 100644 arch/arm/mach-iop13xx/pci.c create mode 100644 arch/arm/mach-iop13xx/setup.c create mode 100644 arch/arm/mach-iop13xx/time.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ce00c570459..d654c4f87d0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -223,6 +223,12 @@ config ARCH_IOP33X help Support for Intel's IOP33X (XScale) family of processors. +config ARCH_IOP13XX + bool "IOP13xx-based" + select PCI + help + Support for Intel's IOP13XX (XScale) family of processors. + config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU @@ -331,6 +337,8 @@ source "arch/arm/mach-iop32x/Kconfig" source "arch/arm/mach-iop33x/Kconfig" +source "arch/arm/mach-iop13xx/Kconfig" + source "arch/arm/mach-ixp4xx/Kconfig" source "arch/arm/mach-ixp2000/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6f4f8bf3607..5f6f9a58570 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -108,6 +108,7 @@ endif machine-$(CONFIG_ARCH_CLPS711X) := clps711x machine-$(CONFIG_ARCH_IOP32X) := iop32x machine-$(CONFIG_ARCH_IOP33X) := iop33x + machine-$(CONFIG_ARCH_IOP13XX) := iop13xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx diff --git a/arch/arm/mach-iop13xx/Kconfig b/arch/arm/mach-iop13xx/Kconfig new file mode 100644 index 00000000000..40c2d689f2e --- /dev/null +++ b/arch/arm/mach-iop13xx/Kconfig @@ -0,0 +1,20 @@ +if ARCH_IOP13XX + +menu "IOP13XX Implementation Options" + +comment "IOP13XX Platform Support" + +config MACH_IQ81340SC + bool "Enable IQ81340SC Hardware Support" + help + Say Y here if you want to support running on the Intel IQ81340SC + evaluation kit. + +config MACH_IQ81340MC + bool "Enable IQ81340MC Hardware Support" + help + Say Y here if you want to support running on the Intel IQ81340MC + evaluation kit. + +endmenu +endif diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile new file mode 100644 index 00000000000..c3d6c08f2d4 --- /dev/null +++ b/arch/arm/mach-iop13xx/Makefile @@ -0,0 +1,12 @@ +obj-y := +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IOP13XX) += setup.o +obj-$(CONFIG_ARCH_IOP13XX) += irq.o +obj-$(CONFIG_ARCH_IOP13XX) += time.o +obj-$(CONFIG_ARCH_IOP13XX) += pci.o +obj-$(CONFIG_ARCH_IOP13XX) += io.o +obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o +obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o diff --git a/arch/arm/mach-iop13xx/Makefile.boot b/arch/arm/mach-iop13xx/Makefile.boot new file mode 100644 index 00000000000..0b0e19fdfe6 --- /dev/null +++ b/arch/arm/mach-iop13xx/Makefile.boot @@ -0,0 +1,3 @@ + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c new file mode 100644 index 00000000000..fbf9f88e46e --- /dev/null +++ b/arch/arm/mach-iop13xx/io.c @@ -0,0 +1,93 @@ +/* + * iop13xx custom ioremap implementation + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, + unsigned long flags) +{ + void __iomem * retval; + + switch (cookie) { + case IOP13XX_PCIX_LOWER_MEM_RA ... IOP13XX_PCIX_UPPER_MEM_RA: + if (unlikely(!iop13xx_atux_mem_base)) + retval = NULL; + else + retval = (void *)(iop13xx_atux_mem_base + + (cookie - IOP13XX_PCIX_LOWER_MEM_RA)); + break; + case IOP13XX_PCIE_LOWER_MEM_RA ... IOP13XX_PCIE_UPPER_MEM_RA: + if (unlikely(!iop13xx_atue_mem_base)) + retval = NULL; + else + retval = (void *)(iop13xx_atue_mem_base + + (cookie - IOP13XX_PCIE_LOWER_MEM_RA)); + break; + case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA: + retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA + + (cookie - IOP13XX_PBI_LOWER_MEM_RA), + size, flags); + break; + case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA: + retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie); + break; + case IOP13XX_PCIX_LOWER_IO_PA ... IOP13XX_PCIX_UPPER_IO_PA: + retval = (void *) IOP13XX_PCIX_IO_PHYS_TO_VIRT(cookie); + break; + case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA: + retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie); + break; + default: + retval = __ioremap(cookie, size, flags); + } + + return retval; +} +EXPORT_SYMBOL(__iop13xx_ioremap); + +void __iop13xx_iounmap(void __iomem *addr) +{ + extern void __iounmap(volatile void __iomem *addr); + + if (iop13xx_atue_mem_base) + if (addr >= (void __iomem *) iop13xx_atue_mem_base && + addr < (void __iomem *) (iop13xx_atue_mem_base + + iop13xx_atue_mem_size)) + goto skip; + + if (iop13xx_atux_mem_base) + if (addr >= (void __iomem *) iop13xx_atux_mem_base && + addr < (void __iomem *) (iop13xx_atux_mem_base + + iop13xx_atux_mem_size)) + goto skip; + + switch ((u32) addr) { + case IOP13XX_PCIE_LOWER_IO_VA ... IOP13XX_PCIE_UPPER_IO_VA: + case IOP13XX_PCIX_LOWER_IO_VA ... IOP13XX_PCIX_UPPER_IO_VA: + case IOP13XX_PMMR_VIRT_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_VA: + goto skip; + } + __iounmap(addr); + +skip: + return; +} +EXPORT_SYMBOL(__iop13xx_iounmap); diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c new file mode 100644 index 00000000000..ee595786cd2 --- /dev/null +++ b/arch/arm/mach-iop13xx/iq81340mc.c @@ -0,0 +1,98 @@ +/* + * iq81340mc board support + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */ + +static int __init +iq81340mc_pcix_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + switch (idsel) { + case 1: + switch (pin) { + case 1: return ATUX_INTB; + case 2: return ATUX_INTC; + case 3: return ATUX_INTD; + case 4: return ATUX_INTA; + default: return -1; + } + case 2: + switch (pin) { + case 1: return ATUX_INTC; + case 2: return ATUX_INTD; + case 3: return ATUX_INTC; + case 4: return ATUX_INTD; + default: return -1; + } + default: return -1; + } +} + +static struct hw_pci iq81340mc_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 0, + .setup = iop13xx_pci_setup, + .map_irq = iq81340mc_pcix_map_irq, + .scan = iop13xx_scan_bus, + .preinit = iop13xx_pci_init, +}; + +static int __init iq81340mc_pci_init(void) +{ + iop13xx_atu_select(&iq81340mc_pci); + pci_common_init(&iq81340mc_pci); + iop13xx_map_pci_memory(); + + return 0; +} + +static void __init iq81340mc_init(void) +{ + iop13xx_platform_init(); + iq81340mc_pci_init(); +} + +static void __init iq81340mc_timer_init(void) +{ + iop13xx_init_time(400000000); +} + +static struct sys_timer iq81340mc_timer = { + .init = iq81340mc_timer_init, + .offset = iop13xx_gettimeoffset, +}; + +MACHINE_START(IQ81340MC, "Intel IQ81340MC") + /* Maintainer: Dan Williams */ + .phys_io = PHYS_IO, + .io_pg_offst = IO_PG_OFFSET, + .map_io = iop13xx_map_io, + .init_irq = iop13xx_init_irq, + .timer = &iq81340mc_timer, + .boot_params = BOOT_PARAM_OFFSET, + .init_machine = iq81340mc_init, +MACHINE_END diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c new file mode 100644 index 00000000000..6677e14b61b --- /dev/null +++ b/arch/arm/mach-iop13xx/iq81340sc.c @@ -0,0 +1,100 @@ +/* + * iq81340sc board support + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +extern int init_atu; + +static int __init +iq81340sc_atux_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + WARN_ON(idsel < 1 || idsel > 2); + + switch (idsel) { + case 1: + switch (pin) { + case 1: return ATUX_INTB; + case 2: return ATUX_INTC; + case 3: return ATUX_INTD; + case 4: return ATUX_INTA; + default: return -1; + } + case 2: + switch (pin) { + case 1: return ATUX_INTC; + case 2: return ATUX_INTC; + case 3: return ATUX_INTC; + case 4: return ATUX_INTC; + default: return -1; + } + default: return -1; + } +} + +static struct hw_pci iq81340sc_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 0, + .setup = iop13xx_pci_setup, + .scan = iop13xx_scan_bus, + .map_irq = iq81340sc_atux_map_irq, + .preinit = iop13xx_pci_init +}; + +static int __init iq81340sc_pci_init(void) +{ + iop13xx_atu_select(&iq81340sc_pci); + pci_common_init(&iq81340sc_pci); + iop13xx_map_pci_memory(); + + return 0; +} + +static void __init iq81340sc_init(void) +{ + iop13xx_platform_init(); + iq81340sc_pci_init(); +} + +static void __init iq81340sc_timer_init(void) +{ + iop13xx_init_time(400000000); +} + +static struct sys_timer iq81340sc_timer = { + .init = iq81340sc_timer_init, + .offset = iop13xx_gettimeoffset, +}; + +MACHINE_START(IQ81340SC, "Intel IQ81340SC") + /* Maintainer: Dan Williams */ + .phys_io = PHYS_IO, + .io_pg_offst = IO_PG_OFFSET, + .map_io = iop13xx_map_io, + .init_irq = iop13xx_init_irq, + .timer = &iq81340sc_timer, + .boot_params = BOOT_PARAM_OFFSET, + .init_machine = iq81340sc_init, +MACHINE_END diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c new file mode 100644 index 00000000000..c4d9c8c5579 --- /dev/null +++ b/arch/arm/mach-iop13xx/irq.c @@ -0,0 +1,286 @@ +/* + * iop13xx IRQ handling / support functions + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +/* INTCTL0 CP6 R0 Page 4 + */ +static inline u32 read_intctl_0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c0, c4, 0":"=r" (val)); + return val; +} +static inline void write_intctl_0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c4, 0"::"r" (val)); +} + +/* INTCTL1 CP6 R1 Page 4 + */ +static inline u32 read_intctl_1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c1, c4, 0":"=r" (val)); + return val; +} +static inline void write_intctl_1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c1, c4, 0"::"r" (val)); +} + +/* INTCTL2 CP6 R2 Page 4 + */ +static inline u32 read_intctl_2(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c4, 0":"=r" (val)); + return val; +} +static inline void write_intctl_2(u32 val) +{ + asm volatile("mcr p6, 0, %0, c2, c4, 0"::"r" (val)); +} + +/* INTCTL3 CP6 R3 Page 4 + */ +static inline u32 read_intctl_3(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c4, 0":"=r" (val)); + return val; +} +static inline void write_intctl_3(u32 val) +{ + asm volatile("mcr p6, 0, %0, c3, c4, 0"::"r" (val)); +} + +/* INTSTR0 CP6 R0 Page 5 + */ +static inline u32 read_intstr_0(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c0, c5, 0":"=r" (val)); + return val; +} +static inline void write_intstr_0(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c5, 0"::"r" (val)); +} + +/* INTSTR1 CP6 R1 Page 5 + */ +static inline u32 read_intstr_1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c1, c5, 0":"=r" (val)); + return val; +} +static void write_intstr_1(u32 val) +{ + asm volatile("mcr p6, 0, %0, c1, c5, 0"::"r" (val)); +} + +/* INTSTR2 CP6 R2 Page 5 + */ +static inline u32 read_intstr_2(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c5, 0":"=r" (val)); + return val; +} +static void write_intstr_2(u32 val) +{ + asm volatile("mcr p6, 0, %0, c2, c5, 0"::"r" (val)); +} + +/* INTSTR3 CP6 R3 Page 5 + */ +static inline u32 read_intstr_3(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c5, 0":"=r" (val)); + return val; +} +static void write_intstr_3(u32 val) +{ + asm volatile("mcr p6, 0, %0, c3, c5, 0"::"r" (val)); +} + +/* INTBASE CP6 R0 Page 2 + */ +static inline u32 read_intbase(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c0, c2, 0":"=r" (val)); + return val; +} +static void write_intbase(u32 val) +{ + asm volatile("mcr p6, 0, %0, c0, c2, 0"::"r" (val)); +} + +/* INTSIZE CP6 R2 Page 2 + */ +static inline u32 read_intsize(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c2, c2, 0":"=r" (val)); + return val; +} +static void write_intsize(u32 val) +{ + asm volatile("mcr p6, 0, %0, c2, c2, 0"::"r" (val)); +} + +/* 0 = Interrupt Masked and 1 = Interrupt not masked */ +static void +iop13xx_irq_mask0 (unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_0(read_intctl_0() & ~(1 << (irq - 0))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_mask1 (unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_1(read_intctl_1() & ~(1 << (irq - 32))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_mask2 (unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_2(read_intctl_2() & ~(1 << (irq - 64))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_mask3 (unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_3(read_intctl_3() & ~(1 << (irq - 96))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_unmask0(unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_0(read_intctl_0() | (1 << (irq - 0))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_unmask1(unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_1(read_intctl_1() | (1 << (irq - 32))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_unmask2(unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_2(read_intctl_2() | (1 << (irq - 64))); + iop13xx_cp6_restore(cp_flags); +} + +static void +iop13xx_irq_unmask3(unsigned int irq) +{ + u32 cp_flags = iop13xx_cp6_save(); + write_intctl_3(read_intctl_3() | (1 << (irq - 96))); + iop13xx_cp6_restore(cp_flags); +} + +static struct irqchip iop13xx_irqchip0 = { + .ack = iop13xx_irq_mask0, + .mask = iop13xx_irq_mask0, + .unmask = iop13xx_irq_unmask0, +}; + +static struct irqchip iop13xx_irqchip1 = { + .ack = iop13xx_irq_mask1, + .mask = iop13xx_irq_mask1, + .unmask = iop13xx_irq_unmask1, +}; + +static struct irqchip iop13xx_irqchip2 = { + .ack = iop13xx_irq_mask2, + .mask = iop13xx_irq_mask2, + .unmask = iop13xx_irq_unmask2, +}; + +static struct irqchip iop13xx_irqchip3 = { + .ack = iop13xx_irq_mask3, + .mask = iop13xx_irq_mask3, + .unmask = iop13xx_irq_unmask3, +}; + +void __init iop13xx_init_irq(void) +{ + unsigned int i; + + u32 cp_flags = iop13xx_cp6_save(); + + /* disable all interrupts */ + write_intctl_0(0); + write_intctl_1(0); + write_intctl_2(0); + write_intctl_3(0); + + /* treat all as IRQ */ + write_intstr_0(0); + write_intstr_1(0); + write_intstr_2(0); + write_intstr_3(0); + + /* initialize the interrupt vector generator */ + write_intbase(INTBASE); + write_intsize(INTSIZE_4); + + for(i = 0; i < NR_IOP13XX_IRQS; i++) { + if (i < 32) + set_irq_chip(i, &iop13xx_irqchip0); + else if (i < 64) + set_irq_chip(i, &iop13xx_irqchip1); + else if (i < 96) + set_irq_chip(i, &iop13xx_irqchip2); + else + set_irq_chip(i, &iop13xx_irqchip3); + + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + + iop13xx_cp6_restore(cp_flags); +} diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c new file mode 100644 index 00000000000..89ec70ea318 --- /dev/null +++ b/arch/arm/mach-iop13xx/pci.c @@ -0,0 +1,1113 @@ +/* + * iop13xx PCI support + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 + +#define IOP13XX_PCI_DEBUG 0 +#define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x))) + +u32 iop13xx_atux_pmmr_offset; /* This offset can change based on strapping */ +u32 iop13xx_atue_pmmr_offset; /* This offset can change based on strapping */ +static struct pci_bus *pci_bus_atux = 0; +static struct pci_bus *pci_bus_atue = 0; +u32 iop13xx_atue_mem_base; +u32 iop13xx_atux_mem_base; +size_t iop13xx_atue_mem_size; +size_t iop13xx_atux_mem_size; +unsigned long iop13xx_pcibios_min_io = 0; +unsigned long iop13xx_pcibios_min_mem = 0; + +EXPORT_SYMBOL(iop13xx_atue_mem_base); +EXPORT_SYMBOL(iop13xx_atux_mem_base); +EXPORT_SYMBOL(iop13xx_atue_mem_size); +EXPORT_SYMBOL(iop13xx_atux_mem_size); + +int init_atu = 0; /* Flag to select which ATU(s) to initialize / disable */ +static unsigned long atux_trhfa_timeout = 0; /* Trhfa = RST# high to first + access */ + +/* Scan the initialized busses and ioremap the requested memory range + */ +void iop13xx_map_pci_memory(void) +{ + int atu; + struct pci_bus *bus; + struct pci_dev *dev; + resource_size_t end = 0; + + for (atu = 0; atu < 2; atu++) { + bus = atu ? pci_bus_atue : pci_bus_atux; + if (bus) { + list_for_each_entry(dev, &bus->devices, bus_list) { + int i; + int max = 7; + + if (dev->subordinate) + max = DEVICE_COUNT_RESOURCE; + + for (i = 0; i < max; i++) { + struct resource *res = &dev->resource[i]; + if (res->flags & IORESOURCE_MEM) + end = max(res->end, end); + } + } + + switch(atu) { + case 0: + iop13xx_atux_mem_size = + (end - IOP13XX_PCIX_LOWER_MEM_RA) + 1; + + /* 16MB align the request */ + if (iop13xx_atux_mem_size & (SZ_16M - 1)) { + iop13xx_atux_mem_size &= ~(SZ_16M - 1); + iop13xx_atux_mem_size += SZ_16M; + } + + if (end) { + iop13xx_atux_mem_base = + (u32) __ioremap_pfn( + __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA) + , 0, iop13xx_atux_mem_size, 0); + if (!iop13xx_atux_mem_base) { + printk("%s: atux allocation " + "failed\n", __FUNCTION__); + BUG(); + } + } else + iop13xx_atux_mem_size = 0; + PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n", + __FUNCTION__, atu, iop13xx_atux_mem_size, + iop13xx_atux_mem_base); + break; + case 1: + iop13xx_atue_mem_size = + (end - IOP13XX_PCIE_LOWER_MEM_RA) + 1; + + /* 16MB align the request */ + if (iop13xx_atue_mem_size & (SZ_16M - 1)) { + iop13xx_atue_mem_size &= ~(SZ_16M - 1); + iop13xx_atue_mem_size += SZ_16M; + } + + if (end) { + iop13xx_atue_mem_base = + (u32) __ioremap_pfn( + __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA) + , 0, iop13xx_atue_mem_size, 0); + if (!iop13xx_atue_mem_base) { + printk("%s: atue allocation " + "failed\n", __FUNCTION__); + BUG(); + } + } else + iop13xx_atue_mem_size = 0; + PRINTK("%s: atu: %d bus_size: %d mem_base: %x\n", + __FUNCTION__, atu, iop13xx_atue_mem_size, + iop13xx_atue_mem_base); + break; + } + + printk("%s: Initialized (%uM @ resource/virtual: %08lx/%08x)\n", + atu ? "ATUE" : "ATUX", + (atu ? iop13xx_atue_mem_size : iop13xx_atux_mem_size) / + SZ_1M, + atu ? IOP13XX_PCIE_LOWER_MEM_RA : + IOP13XX_PCIX_LOWER_MEM_RA, + atu ? iop13xx_atue_mem_base : + iop13xx_atux_mem_base); + end = 0; + } + + } +} + +static inline int iop13xx_atu_function(int atu) +{ + int func = 0; + /* the function number depends on the value of the + * IOP13XX_INTERFACE_SEL_PCIX reset strap + * see C-Spec section 3.17 + */ + switch(atu) { + case IOP13XX_INIT_ATU_ATUX: + if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) + func = 5; + else + func = 0; + break; + case IOP13XX_INIT_ATU_ATUE: + if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) + func = 0; + else + func = 5; + break; + default: + BUG(); + } + + return func; +} + +/* iop13xx_atux_cfg_address - format a configuration address for atux + * @bus: Target bus to access + * @devfn: Combined device number and function number + * @where: Desired register's address offset + * + * Convert the parameters to a configuration address formatted + * according the PCI-X 2.0 specification + */ +static u32 iop13xx_atux_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | ((where & 0xff) & ~3); + addr |= ((where & 0xf00) >> 8) << 24; /* upper register number */ + + return addr; +} + +/* iop13xx_atue_cfg_address - format a configuration address for atue + * @bus: Target bus to access + * @devfn: Combined device number and function number + * @where: Desired register's address offset + * + * Convert the parameters to an address usable by the ATUE_OCCAR + */ +static u32 iop13xx_atue_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + PRINTK("iop13xx_atue_cfg_address: bus: %d dev: %d func: %d", + bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); + addr = ((u32) bus->number) << IOP13XX_ATUE_OCCAR_BUS_NUM | + ((u32) PCI_SLOT(devfn)) << IOP13XX_ATUE_OCCAR_DEV_NUM | + ((u32) PCI_FUNC(devfn)) << IOP13XX_ATUE_OCCAR_FUNC_NUM | + (where & ~0x3); + + if (sys->busnr != bus->number) + addr |= 1; /* type 1 access */ + + return addr; +} + +/* This routine checks the status of the last configuration cycle. If an error + * was detected it returns >0, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop13xx_atux_pci_status(int clear) +{ + unsigned int status; + int err = 0; + + /* + * Check the status registers. + */ + status = __raw_readw(IOP13XX_ATUX_ATUSR); + if (status & IOP_PCI_STATUS_ERROR) + { + PRINTK("\t\t\tPCI error: ATUSR %#08x", status); + if(clear) + __raw_writew(status & IOP_PCI_STATUS_ERROR, + IOP13XX_ATUX_ATUSR); + err = 1; + } + status = __raw_readl(IOP13XX_ATUX_ATUISR); + if (status & IOP13XX_ATUX_ATUISR_ERROR) + { + PRINTK("\t\t\tPCI error interrupt: ATUISR %#08x", status); + if(clear) + __raw_writel(status & IOP13XX_ATUX_ATUISR_ERROR, + IOP13XX_ATUX_ATUISR); + err = 1; + } + return err; +} + +/* Simply write the address register and read the configuration + * data. Note that the data dependency on %0 encourages an abort + * to be detected before we return. + */ +static inline u32 iop13xx_atux_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "mov %0, %0\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP13XX_ATUX_OCCAR), "r" (IOP13XX_ATUX_OCCDR)); + + return val; +} + +/* The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop13xx_atux_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where); + u32 val = iop13xx_atux_read(addr) >> ((where & 3) * 8); + + if (iop13xx_atux_pci_status(1) || is_atux_occdr_error()) { + __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, + IOP13XX_XBG_BECSR); + val = 0xffffffff; + } + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop13xx_atux_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop13xx_atux_read(addr); + if (!iop13xx_atux_pci_status(1) == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + __raw_writel(val | value << where, IOP13XX_ATUX_OCCDR); + } else { + __raw_writel(addr, IOP13XX_ATUX_OCCAR); + __raw_writel(value, IOP13XX_ATUX_OCCDR); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop13xx_atux_ops = { + .read = iop13xx_atux_read_config, + .write = iop13xx_atux_write_config, +}; + +/* This routine checks the status of the last configuration cycle. If an error + * was detected it returns >0, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop13xx_atue_pci_status(int clear) +{ + unsigned int status; + int err = 0; + + /* + * Check the status registers. + */ + + /* standard pci status register */ + status = __raw_readw(IOP13XX_ATUE_ATUSR); + if (status & IOP_PCI_STATUS_ERROR) { + PRINTK("\t\t\tPCI error: ATUSR %#08x", status); + if(clear) + __raw_writew(status & IOP_PCI_STATUS_ERROR, + IOP13XX_ATUE_ATUSR); + err++; + } + + /* check the normal status bits in the ATUISR */ + status = __raw_readl(IOP13XX_ATUE_ATUISR); + if (status & IOP13XX_ATUE_ATUISR_ERROR) { + PRINTK("\t\t\tPCI error: ATUISR %#08x", status); + if (clear) + __raw_writew(status & IOP13XX_ATUE_ATUISR_ERROR, + IOP13XX_ATUE_ATUISR); + err++; + + /* check the PCI-E status if the ATUISR reports an interface error */ + if (status & IOP13XX_ATUE_STAT_PCI_IFACE_ERR) { + /* get the unmasked errors */ + status = __raw_readl(IOP13XX_ATUE_PIE_STS) & + ~(__raw_readl(IOP13XX_ATUE_PIE_MSK)); + + if (status) { + PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x", + __raw_readl(IOP13XX_ATUE_PIE_STS)); + err++; + } else { + PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x", + __raw_readl(IOP13XX_ATUE_PIE_STS)); + PRINTK("\t\t\tPCI-E error: ATUE_PIE_MSK %#08x", + __raw_readl(IOP13XX_ATUE_PIE_MSK)); + BUG(); + } + + if(clear) + __raw_writel(status, IOP13XX_ATUE_PIE_STS); + } + } + + return err; +} + +static inline int __init +iop13xx_pcie_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + WARN_ON(idsel != 0); + + switch (pin) { + case 1: return ATUE_INTA; + case 2: return ATUE_INTB; + case 3: return ATUE_INTC; + case 4: return ATUE_INTD; + default: return -1; + } +} + +static inline u32 iop13xx_atue_read(unsigned long addr) +{ + u32 val; + + __raw_writel(addr, IOP13XX_ATUE_OCCAR); + val = __raw_readl(IOP13XX_ATUE_OCCDR); + + rmb(); + + return val; +} + +/* The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop13xx_atue_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + u32 val; + unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where); + + /* Hide device numbers > 0 on the local PCI-E bus (Type 0 access) */ + if (!PCI_SLOT(devfn) || (addr & 1)) { + val = iop13xx_atue_read(addr) >> ((where & 3) * 8); + if( iop13xx_atue_pci_status(1) || is_atue_occdr_error() ) { + __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, + IOP13XX_XBG_BECSR); + val = 0xffffffff; + } + + PRINTK("addr=%#0lx, val=%#010x", addr, val); + } else + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop13xx_atue_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop13xx_atue_read(addr); + if (!iop13xx_atue_pci_status(1) == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + __raw_writel(val | value << where, IOP13XX_ATUE_OCCDR); + } else { + __raw_writel(addr, IOP13XX_ATUE_OCCAR); + __raw_writel(value, IOP13XX_ATUE_OCCDR); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop13xx_atue_ops = { + .read = iop13xx_atue_read_config, + .write = iop13xx_atue_write_config, +}; + +/* When a PCI device does not exist during config cycles, the XScale gets a + * bus error instead of returning 0xffffffff. We can't rely on the ATU status + * bits to tell us that it was indeed a configuration cycle that caused this + * error especially in the case when the ATUE link is down. Instead we rely + * on data from the south XSI bridge to validate the abort + */ +int +iop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + PRINTK("Data abort: address = 0x%08lx " + "fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + PRINTK("IOP13XX_XBG_BECSR: %#10x", __raw_readl(IOP13XX_XBG_BECSR)); + PRINTK("IOP13XX_XBG_BERAR: %#10x", __raw_readl(IOP13XX_XBG_BERAR)); + PRINTK("IOP13XX_XBG_BERUAR: %#10x", __raw_readl(IOP13XX_XBG_BERUAR)); + + /* If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + if (is_atue_occdr_error() || is_atux_occdr_error()) + return 0; + else + return 1; +} + +/* Scan an IOP13XX PCI bus. nr selects which ATU we use. + */ +struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *sys) +{ + int which_atu; + struct pci_bus *bus = NULL; + + switch (init_atu) { + case IOP13XX_INIT_ATU_ATUX: + which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX; + break; + case IOP13XX_INIT_ATU_ATUE: + which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE; + break; + case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE): + which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX; + break; + default: + which_atu = 0; + } + + if (!which_atu) { + BUG(); + return NULL; + } + + switch (which_atu) { + case IOP13XX_INIT_ATU_ATUX: + if (time_after_eq(jiffies + msecs_to_jiffies(1000), + atux_trhfa_timeout)) /* ensure not wrap */ + while(time_before(jiffies, atux_trhfa_timeout)) + udelay(100); + + bus = pci_bus_atux = pci_scan_bus(sys->busnr, + &iop13xx_atux_ops, + sys); + break; + case IOP13XX_INIT_ATU_ATUE: + bus = pci_bus_atue = pci_scan_bus(sys->busnr, + &iop13xx_atue_ops, + sys); + break; + } + + return bus; +} + +/* This function is called from iop13xx_pci_init() after assigning valid + * values to iop13xx_atue_pmmr_offset. This is the location for common + * setup of ATUE for all IOP13XX implementations. + */ +void __init iop13xx_atue_setup(void) +{ + int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUE); + u32 reg_val; + + /* BAR 1 (1:1 mapping with Physical RAM) */ + /* Set limit and enable */ + __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1, + IOP13XX_ATUE_IALR1); + __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1); + + /* Set base at the top of the reserved address space */ + __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 | + PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUE_IABAR1); + + /* 1:1 mapping with physical ram + * (leave big endian byte swap disabled) + */ + __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1); + __raw_writel(PHYS_OFFSET, IOP13XX_ATUE_IATVR1); + + /* Outbound window 1 (PCIX/PCIE memory window) */ + /* 32 bit Address Space */ + __raw_writel(0x0, IOP13XX_ATUE_OUMWTVR1); + /* PA[35:32] */ + __raw_writel(IOP13XX_ATUE_OUMBAR_ENABLE | + (IOP13XX_PCIE_MEM_PHYS_OFFSET >> 32), + IOP13XX_ATUE_OUMBAR1); + + /* Setup the I/O Bar + * A[35-16] in 31-12 + */ + __raw_writel(((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000), + IOP13XX_ATUE_OIOBAR); + __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR); + + /* clear startup errors */ + iop13xx_atue_pci_status(1); + + /* OIOBAR function number + */ + reg_val = __raw_readl(IOP13XX_ATUE_OIOBAR); + reg_val &= ~0x7; + reg_val |= func; + __raw_writel(reg_val, IOP13XX_ATUE_OIOBAR); + + /* OUMBAR function numbers + */ + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0); + + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1); + + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2); + + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3); + + /* Enable inbound and outbound cycles + */ + reg_val = __raw_readw(IOP13XX_ATUE_ATUCMD); + reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + __raw_writew(reg_val, IOP13XX_ATUE_ATUCMD); + + reg_val = __raw_readl(IOP13XX_ATUE_ATUCR); + reg_val |= IOP13XX_ATUE_ATUCR_OUT_EN | + IOP13XX_ATUE_ATUCR_IVM; + __raw_writel(reg_val, IOP13XX_ATUE_ATUCR); +} + +void __init iop13xx_atue_disable(void) +{ + u32 reg_val; + + __raw_writew(0x0, IOP13XX_ATUE_ATUCMD); + __raw_writel(IOP13XX_ATUE_ATUCR_IVM, IOP13XX_ATUE_ATUCR); + + /* wait for cycles to quiesce */ + while (__raw_readl(IOP13XX_ATUE_PCSR) & (IOP13XX_ATUE_PCSR_OUT_Q_BUSY | + IOP13XX_ATUE_PCSR_IN_Q_BUSY | + IOP13XX_ATUE_PCSR_LLRB_BUSY)) + cpu_relax(); + + /* BAR 0 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUE_IAUBAR0); + __raw_writel(0x0, IOP13XX_ATUE_IABAR0); + __raw_writel(0x0, IOP13XX_ATUE_IAUTVR0); + __raw_writel(0x0, IOP13XX_ATUE_IATVR0); + __raw_writel(0x0, IOP13XX_ATUE_IALR0); + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0); + reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0); + + /* BAR 1 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1); + __raw_writel(0x0, IOP13XX_ATUE_IABAR1); + __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1); + __raw_writel(0x0, IOP13XX_ATUE_IATVR1); + __raw_writel(0x0, IOP13XX_ATUE_IALR1); + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1); + reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1); + + /* BAR 2 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUE_IAUBAR2); + __raw_writel(0x0, IOP13XX_ATUE_IABAR2); + __raw_writel(0x0, IOP13XX_ATUE_IAUTVR2); + __raw_writel(0x0, IOP13XX_ATUE_IATVR2); + __raw_writel(0x0, IOP13XX_ATUE_IALR2); + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2); + reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2); + + /* BAR 3 ( Disabled ) */ + reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3); + reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3); + + /* Setup the I/O Bar + * A[35-16] in 31-12 + */ + __raw_writel((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000, + IOP13XX_ATUE_OIOBAR); + __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR); +} + +/* This function is called from iop13xx_pci_init() after assigning valid + * values to iop13xx_atux_pmmr_offset. This is the location for common + * setup of ATUX for all IOP13XX implementations. + */ +void __init iop13xx_atux_setup(void) +{ + u32 reg_val; + int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX); + + /* Take PCI-X bus out of reset if bootloader hasn't already. + * According to spec, we should wait for 2^25 PCI clocks to meet + * the PCI timing parameter Trhfa (RST# high to first access). + * This is rarely necessary and often ignored. + */ + reg_val = __raw_readl(IOP13XX_ATUX_PCSR); + if (reg_val & IOP13XX_ATUX_PCSR_P_RSTOUT) { + int msec = (reg_val >> IOP13XX_ATUX_PCSR_FREQ_OFFSET) & 0x7; + msec = 1000 / (8-msec); /* bits 100=133MHz, 111=>33MHz */ + __raw_writel(reg_val & ~IOP13XX_ATUX_PCSR_P_RSTOUT, + IOP13XX_ATUX_PCSR); + atux_trhfa_timeout = jiffies + msecs_to_jiffies(msec); + } + else + atux_trhfa_timeout = jiffies; + + /* BAR 1 (1:1 mapping with Physical RAM) */ + /* Set limit and enable */ + __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1, + IOP13XX_ATUX_IALR1); + __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1); + + /* Set base at the top of the reserved address space */ + __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 | + PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUX_IABAR1); + + /* 1:1 mapping with physical ram + * (leave big endian byte swap disabled) + */ + __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1); + __raw_writel(PHYS_OFFSET, IOP13XX_ATUX_IATVR1); + + /* Outbound window 1 (PCIX/PCIE memory window) */ + /* 32 bit Address Space */ + __raw_writel(0x0, IOP13XX_ATUX_OUMWTVR1); + /* PA[35:32] */ + __raw_writel(IOP13XX_ATUX_OUMBAR_ENABLE | + IOP13XX_PCIX_MEM_PHYS_OFFSET >> 32, + IOP13XX_ATUX_OUMBAR1); + + /* Setup the I/O Bar + * A[35-16] in 31-12 + */ + __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000, + IOP13XX_ATUX_OIOBAR); + __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR); + + /* clear startup errors */ + iop13xx_atux_pci_status(1); + + /* OIOBAR function number + */ + reg_val = __raw_readl(IOP13XX_ATUX_OIOBAR); + reg_val &= ~0x7; + reg_val |= func; + __raw_writel(reg_val, IOP13XX_ATUX_OIOBAR); + + /* OUMBAR function numbers + */ + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0); + + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1); + + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2); + + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3); + reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK << + IOP13XX_ATU_OUMBAR_FUNC_NUM); + reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3); + + /* Enable inbound and outbound cycles + */ + reg_val = __raw_readw(IOP13XX_ATUX_ATUCMD); + reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_PARITY | PCI_COMMAND_SERR; + __raw_writew(reg_val, IOP13XX_ATUX_ATUCMD); + + reg_val = __raw_readl(IOP13XX_ATUX_ATUCR); + reg_val |= IOP13XX_ATUX_ATUCR_OUT_EN; + __raw_writel(reg_val, IOP13XX_ATUX_ATUCR); +} + +void __init iop13xx_atux_disable(void) +{ + u32 reg_val; + + __raw_writew(0x0, IOP13XX_ATUX_ATUCMD); + __raw_writel(0x0, IOP13XX_ATUX_ATUCR); + + /* wait for cycles to quiesce */ + while (__raw_readl(IOP13XX_ATUX_PCSR) & (IOP13XX_ATUX_PCSR_OUT_Q_BUSY | + IOP13XX_ATUX_PCSR_IN_Q_BUSY)) + cpu_relax(); + + /* BAR 0 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUX_IAUBAR0); + __raw_writel(0x0, IOP13XX_ATUX_IABAR0); + __raw_writel(0x0, IOP13XX_ATUX_IAUTVR0); + __raw_writel(0x0, IOP13XX_ATUX_IATVR0); + __raw_writel(0x0, IOP13XX_ATUX_IALR0); + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0); + reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0); + + /* BAR 1 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1); + __raw_writel(0x0, IOP13XX_ATUX_IABAR1); + __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1); + __raw_writel(0x0, IOP13XX_ATUX_IATVR1); + __raw_writel(0x0, IOP13XX_ATUX_IALR1); + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1); + reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1); + + /* BAR 2 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUX_IAUBAR2); + __raw_writel(0x0, IOP13XX_ATUX_IABAR2); + __raw_writel(0x0, IOP13XX_ATUX_IAUTVR2); + __raw_writel(0x0, IOP13XX_ATUX_IATVR2); + __raw_writel(0x0, IOP13XX_ATUX_IALR2); + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2); + reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2); + + /* BAR 3 ( Disabled ) */ + __raw_writel(0x0, IOP13XX_ATUX_IAUBAR3); + __raw_writel(0x0, IOP13XX_ATUX_IABAR3); + __raw_writel(0x0, IOP13XX_ATUX_IAUTVR3); + __raw_writel(0x0, IOP13XX_ATUX_IATVR3); + __raw_writel(0x0, IOP13XX_ATUX_IALR3); + reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3); + reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE; + __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3); + + /* Setup the I/O Bar + * A[35-16] in 31-12 + */ + __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000, + IOP13XX_ATUX_OIOBAR); + __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR); +} + +void __init iop13xx_set_atu_mmr_bases(void) +{ + /* Based on ESSR0, determine the ATU X/E offsets */ + switch(__raw_readl(IOP13XX_ESSR0) & + (IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX)) { + /* both asserted */ + case 0: + iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET; + iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET; + break; + /* IOP13XX_CONTROLLER_ONLY = deasserted + * IOP13XX_INTERFACE_SEL_PCIX = asserted + */ + case IOP13XX_CONTROLLER_ONLY: + iop13xx_atux_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET; + iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET; + break; + /* IOP13XX_CONTROLLER_ONLY = asserted + * IOP13XX_INTERFACE_SEL_PCIX = deasserted + */ + case IOP13XX_INTERFACE_SEL_PCIX: + iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET; + iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET; + break; + /* both deasserted */ + case IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX: + iop13xx_atux_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET; + iop13xx_atue_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET; + break; + default: + BUG(); + } +} + +void __init iop13xx_atu_select(struct hw_pci *plat_pci) +{ + int i; + + /* set system defaults + * note: if "iop13xx_init_atu=" is specified this autodetect + * sequence will be bypassed + */ + if (init_atu == IOP13XX_INIT_ATU_DEFAULT) { + /* check for single/dual interface */ + if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) { + /* ATUE must be present check the device id + * to see if ATUX is present. + */ + init_atu |= IOP13XX_INIT_ATU_ATUE; + switch (__raw_readw(IOP13XX_ATUE_DID) & 0xf0) { + case 0x70: + case 0x80: + case 0xc0: + init_atu |= IOP13XX_INIT_ATU_ATUX; + break; + } + } else { + /* ATUX must be present check the device id + * to see if ATUE is present. + */ + init_atu |= IOP13XX_INIT_ATU_ATUX; + switch (__raw_readw(IOP13XX_ATUX_DID) & 0xf0) { + case 0x70: + case 0x80: + case 0xc0: + init_atu |= IOP13XX_INIT_ATU_ATUE; + break; + } + } + + /* check central resource and root complex capability */ + if (init_atu & IOP13XX_INIT_ATU_ATUX) + if (!(__raw_readl(IOP13XX_ATUX_PCSR) & + IOP13XX_ATUX_PCSR_CENTRAL_RES)) + init_atu &= ~IOP13XX_INIT_ATU_ATUX; + + if (init_atu & IOP13XX_INIT_ATU_ATUE) + if (__raw_readl(IOP13XX_ATUE_PCSR) & + IOP13XX_ATUE_PCSR_END_POINT) + init_atu &= ~IOP13XX_INIT_ATU_ATUE; + } + + for (i = 0; i < 2; i++) { + if((init_atu & (1 << i)) == (1 << i)) + plat_pci->nr_controllers++; + } +} + +void __init iop13xx_pci_init(void) +{ + /* clear pre-existing south bridge errors */ + __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR); + + /* Setup the Min Address for PCI memory... */ + iop13xx_pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA; + + /* if Linux is given control of an ATU + * clear out its prior configuration, + * otherwise do not touch the registers + */ + if (init_atu & IOP13XX_INIT_ATU_ATUE) { + iop13xx_atue_disable(); + iop13xx_atue_setup(); + } + + if (init_atu & IOP13XX_INIT_ATU_ATUX) { + iop13xx_atux_disable(); + iop13xx_atux_setup(); + } + + hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, + "imprecise external abort"); +} + +/* intialize the pci memory space. handle any combination of + * atue and atux enabled/disabled + */ +int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + int which_atu; + u32 pcixsr, pcsr; + + if (nr > 1) + return 0; + + res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + memset(res, 0, sizeof(struct resource) * 2); + + /* 'nr' assumptions: + * ATUX is always 0 + * ATUE is 1 when ATUX is also enabled + * ATUE is 0 when ATUX is disabled + */ + switch(init_atu) { + case IOP13XX_INIT_ATU_ATUX: + which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX; + break; + case IOP13XX_INIT_ATU_ATUE: + which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE; + break; + case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE): + which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX; + break; + default: + which_atu = 0; + } + + if (!which_atu) + return 0; + + switch(which_atu) { + case IOP13XX_INIT_ATU_ATUX: + pcixsr = __raw_readl(IOP13XX_ATUX_PCIXSR); + pcixsr &= ~0xffff; + pcixsr |= sys->busnr << IOP13XX_ATUX_PCIXSR_BUS_NUM | + 0 << IOP13XX_ATUX_PCIXSR_DEV_NUM | + iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX) + << IOP13XX_ATUX_PCIXSR_FUNC_NUM; + __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR); + + res[0].start = IOP13XX_PCIX_LOWER_IO_PA; + res[0].end = IOP13XX_PCIX_UPPER_IO_PA; + res[0].name = "IQ81340 ATUX PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP13XX_PCIX_LOWER_MEM_RA; + res[1].end = IOP13XX_PCIX_UPPER_MEM_RA; + res[1].name = "IQ81340 ATUX PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET; + sys->io_offset = IOP13XX_PCIX_IO_OFFSET; + break; + case IOP13XX_INIT_ATU_ATUE: + /* Note: the function number field in the PCSR is ro */ + pcsr = __raw_readl(IOP13XX_ATUE_PCSR); + pcsr &= ~(0xfff8 << 16); + pcsr |= sys->busnr << IOP13XX_ATUE_PCSR_BUS_NUM | + 0 << IOP13XX_ATUE_PCSR_DEV_NUM; + + __raw_writel(pcsr, IOP13XX_ATUE_PCSR); + + res[0].start = IOP13XX_PCIE_LOWER_IO_PA; + res[0].end = IOP13XX_PCIE_UPPER_IO_PA; + res[0].name = "IQ81340 ATUE PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP13XX_PCIE_LOWER_MEM_RA; + res[1].end = IOP13XX_PCIE_UPPER_MEM_RA; + res[1].name = "IQ81340 ATUE PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET; + sys->io_offset = IOP13XX_PCIE_IO_OFFSET; + sys->map_irq = iop13xx_pcie_map_irq; + break; + default: + return 0; + } + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +u16 iop13xx_dev_id(void) +{ + if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) + return __raw_readw(IOP13XX_ATUE_DID); + else + return __raw_readw(IOP13XX_ATUX_DID); +} + +static int __init iop13xx_init_atu_setup(char *str) +{ + init_atu = IOP13XX_INIT_ATU_NONE; + if (str) { + while (*str != '\0') { + switch (*str) { + case 'x': + case 'X': + init_atu |= IOP13XX_INIT_ATU_ATUX; + init_atu &= ~IOP13XX_INIT_ATU_NONE; + break; + case 'e': + case 'E': + init_atu |= IOP13XX_INIT_ATU_ATUE; + init_atu &= ~IOP13XX_INIT_ATU_NONE; + break; + case ',': + case '=': + break; + default: + PRINTK("\"iop13xx_init_atu\" malformed at " + "character: \'%c\'", *str); + *(str + 1) = '\0'; + init_atu = IOP13XX_INIT_ATU_DEFAULT; + } + str++; + } + } + return 1; +} + +__setup("iop13xx_init_atu", iop13xx_init_atu_setup); diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c new file mode 100644 index 00000000000..3756d2ccb1a --- /dev/null +++ b/arch/arm/mach-iop13xx/setup.c @@ -0,0 +1,406 @@ +/* + * iop13xx platform Initialization + * Copyright (c) 2005-2006, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 +#ifdef CONFIG_MTD_PHYSMAP +#include +#endif +#include +#include +#include + +#define IOP13XX_UART_XTAL 33334000 +#define IOP13XX_SETUP_DEBUG 0 +#define PRINTK(x...) ((void)(IOP13XX_SETUP_DEBUG && printk(x))) + +/* Standard IO mapping for all IOP13XX based systems + */ +static struct map_desc iop13xx_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP13XX_PMMR_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE), + .length = IOP13XX_PMMR_SIZE, + .type = MT_DEVICE, + }, { /* PCIE IO space */ + .virtual = IOP13XX_PCIE_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP13XX_PCIE_LOWER_IO_PA), + .length = IOP13XX_PCIX_IO_WINDOW_SIZE, + .type = MT_DEVICE, + }, { /* PCIX IO space */ + .virtual = IOP13XX_PCIX_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP13XX_PCIX_LOWER_IO_PA), + .length = IOP13XX_PCIX_IO_WINDOW_SIZE, + .type = MT_DEVICE, + }, +}; + +static struct resource iop13xx_uart0_resources[] = { + [0] = { + .start = IOP13XX_UART0_PHYS, + .end = IOP13XX_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP13XX_UART0, + .end = IRQ_IOP13XX_UART0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_uart1_resources[] = { + [0] = { + .start = IOP13XX_UART1_PHYS, + .end = IOP13XX_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP13XX_UART1, + .end = IRQ_IOP13XX_UART1, + .flags = IORESOURCE_IRQ + } +}; + +static struct plat_serial8250_port iop13xx_uart0_data[] = { + { + .membase = (char*)(IOP13XX_UART0_VIRT), + .mapbase = (IOP13XX_UART0_PHYS), + .irq = IRQ_IOP13XX_UART0, + .uartclk = IOP13XX_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct plat_serial8250_port iop13xx_uart1_data[] = { + { + .membase = (char*)(IOP13XX_UART1_VIRT), + .mapbase = (IOP13XX_UART1_PHYS), + .irq = IRQ_IOP13XX_UART1, + .uartclk = IOP13XX_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +/* The ids are fixed up later in iop13xx_platform_init */ +static struct platform_device iop13xx_uart0 = { + .name = "serial8250", + .id = 0, + .dev.platform_data = iop13xx_uart0_data, + .num_resources = 2, + .resource = iop13xx_uart0_resources, +}; + +static struct platform_device iop13xx_uart1 = { + .name = "serial8250", + .id = 0, + .dev.platform_data = iop13xx_uart1_data, + .num_resources = 2, + .resource = iop13xx_uart1_resources +}; + +static struct resource iop13xx_i2c_0_resources[] = { + [0] = { + .start = IOP13XX_I2C0_PHYS, + .end = IOP13XX_I2C0_PHYS + 0x18, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP13XX_I2C_0, + .end = IRQ_IOP13XX_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_i2c_1_resources[] = { + [0] = { + .start = IOP13XX_I2C1_PHYS, + .end = IOP13XX_I2C1_PHYS + 0x18, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP13XX_I2C_1, + .end = IRQ_IOP13XX_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop13xx_i2c_2_resources[] = { + [0] = { + .start = IOP13XX_I2C2_PHYS, + .end = IOP13XX_I2C2_PHYS + 0x18, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP13XX_I2C_2, + .end = IRQ_IOP13XX_I2C_2, + .flags = IORESOURCE_IRQ + } +}; + +/* I2C controllers. The IOP13XX uses the same block as the IOP3xx, so + * we just use the same device name. + */ + +/* The ids are fixed up later in iop13xx_platform_init */ +static struct platform_device iop13xx_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop13xx_i2c_0_resources +}; + +static struct platform_device iop13xx_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop13xx_i2c_1_resources +}; + +static struct platform_device iop13xx_i2c_2_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop13xx_i2c_2_resources +}; + +#ifdef CONFIG_MTD_PHYSMAP +/* PBI Flash Device + */ +static struct physmap_flash_data iq8134x_flash_data = { + .width = 2, +}; + +static struct resource iq8134x_flash_resource = { + .start = IQ81340_FLASHBASE, + .end = 0, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device iq8134x_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { .platform_data = &iq8134x_flash_data, }, + .num_resources = 1, + .resource = &iq8134x_flash_resource, +}; + +static unsigned long iq8134x_probe_flash_size(void) +{ + uint8_t __iomem *flash_addr = ioremap(IQ81340_FLASHBASE, PAGE_SIZE); + int i; + char query[3]; + unsigned long size = 0; + int width = iq8134x_flash_data.width; + + if (flash_addr) { + /* send CFI 'query' command */ + writew(0x98, flash_addr); + + /* check for CFI compliance */ + for (i = 0; i < 3 * width; i += width) + query[i / width] = readb(flash_addr + (0x10 * width) + i); + + /* read the size */ + if (memcmp(query, "QRY", 3) == 0) + size = 1 << readb(flash_addr + (0x27 * width)); + + /* send CFI 'read array' command */ + writew(0xff, flash_addr); + + iounmap(flash_addr); + } + + return size; +} +#endif + +void __init iop13xx_map_io(void) +{ + /* Initialize the Static Page Table maps */ + iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc)); +} + +static int init_uart = 0; +static int init_i2c = 0; + +void __init iop13xx_platform_init(void) +{ + int i; + u32 uart_idx, i2c_idx, plat_idx; + struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES]; + + /* set the bases so we can read the device id */ + iop13xx_set_atu_mmr_bases(); + + memset(iop13xx_devices, 0, sizeof(iop13xx_devices)); + + if (init_uart == IOP13XX_INIT_UART_DEFAULT) { + switch (iop13xx_dev_id()) { + /* enable both uarts on iop341 and iop342 */ + case 0x3380: + case 0x3384: + case 0x3388: + case 0x338c: + case 0x3382: + case 0x3386: + case 0x338a: + case 0x338e: + init_uart |= IOP13XX_INIT_UART_0; + init_uart |= IOP13XX_INIT_UART_1; + break; + /* only enable uart 1 */ + default: + init_uart |= IOP13XX_INIT_UART_1; + } + } + + if (init_i2c == IOP13XX_INIT_I2C_DEFAULT) { + switch (iop13xx_dev_id()) { + /* enable all i2c units on iop341 and iop342 */ + case 0x3380: + case 0x3384: + case 0x3388: + case 0x338c: + case 0x3382: + case 0x3386: + case 0x338a: + case 0x338e: + init_i2c |= IOP13XX_INIT_I2C_0; + init_i2c |= IOP13XX_INIT_I2C_1; + init_i2c |= IOP13XX_INIT_I2C_2; + break; + /* only enable i2c 1 and 2 */ + default: + init_i2c |= IOP13XX_INIT_I2C_1; + init_i2c |= IOP13XX_INIT_I2C_2; + } + } + + plat_idx = 0; + uart_idx = 0; + i2c_idx = 0; + + /* uart 1 (if enabled) is ttyS0 */ + if (init_uart & IOP13XX_INIT_UART_1) { + PRINTK("Adding uart1 to platform device list\n"); + iop13xx_uart1.id = uart_idx++; + iop13xx_devices[plat_idx++] = &iop13xx_uart1; + } + if (init_uart & IOP13XX_INIT_UART_0) { + PRINTK("Adding uart0 to platform device list\n"); + iop13xx_uart0.id = uart_idx++; + iop13xx_devices[plat_idx++] = &iop13xx_uart0; + } + + for(i = 0; i < IQ81340_NUM_I2C; i++) { + if ((init_i2c & (1 << i)) && IOP13XX_SETUP_DEBUG) + printk("Adding i2c%d to platform device list\n", i); + switch(init_i2c & (1 << i)) { + case IOP13XX_INIT_I2C_0: + iop13xx_i2c_0_controller.id = i2c_idx++; + iop13xx_devices[plat_idx++] = + &iop13xx_i2c_0_controller; + break; + case IOP13XX_INIT_I2C_1: + iop13xx_i2c_1_controller.id = i2c_idx++; + iop13xx_devices[plat_idx++] = + &iop13xx_i2c_1_controller; + break; + case IOP13XX_INIT_I2C_2: + iop13xx_i2c_2_controller.id = i2c_idx++; + iop13xx_devices[plat_idx++] = + &iop13xx_i2c_2_controller; + break; + } + } + +#ifdef CONFIG_MTD_PHYSMAP + iq8134x_flash_resource.end = iq8134x_flash_resource.start + + iq8134x_probe_flash_size(); + if (iq8134x_flash_resource.end > iq8134x_flash_resource.start) + iop13xx_devices[plat_idx++] = &iq8134x_flash; + else + printk(KERN_ERR "%s: Failed to probe flash size\n", __FUNCTION__); +#endif + + platform_add_devices(iop13xx_devices, plat_idx); +} + +static int __init iop13xx_init_uart_setup(char *str) +{ + if (str) { + while (*str != '\0') { + switch(*str) { + case '0': + init_uart |= IOP13XX_INIT_UART_0; + break; + case '1': + init_uart |= IOP13XX_INIT_UART_1; + break; + case ',': + case '=': + break; + default: + PRINTK("\"iop13xx_init_uart\" malformed" + " at character: \'%c\'", *str); + *(str + 1) = '\0'; + init_uart = IOP13XX_INIT_UART_DEFAULT; + } + str++; + } + } + return 1; +} + +static int __init iop13xx_init_i2c_setup(char *str) +{ + if (str) { + while (*str != '\0') { + switch(*str) { + case '0': + init_i2c |= IOP13XX_INIT_I2C_0; + break; + case '1': + init_i2c |= IOP13XX_INIT_I2C_1; + break; + case '2': + init_i2c |= IOP13XX_INIT_I2C_2; + break; + case ',': + case '=': + break; + default: + PRINTK("\"iop13xx_init_i2c\" malformed" + " at character: \'%c\'", *str); + *(str + 1) = '\0'; + init_i2c = IOP13XX_INIT_I2C_DEFAULT; + } + str++; + } + } + return 1; +} + +__setup("iop13xx_init_uart", iop13xx_init_uart_setup); +__setup("iop13xx_init_i2c", iop13xx_init_i2c_setup); diff --git a/arch/arm/mach-iop13xx/time.c b/arch/arm/mach-iop13xx/time.c new file mode 100644 index 00000000000..8b21365f653 --- /dev/null +++ b/arch/arm/mach-iop13xx/time.c @@ -0,0 +1,102 @@ +/* + * arch/arm/mach-iop13xx/time.c + * + * Timer code for IOP13xx (copied from IOP32x/IOP33x implementation) + * + * Author: Deepak Saxena + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static unsigned long ticks_per_jiffy; +static unsigned long ticks_per_usec; +static unsigned long next_jiffy_time; + +static inline u32 read_tcr1(void) +{ + u32 val; + asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val)); + return val; +} + +unsigned long iop13xx_gettimeoffset(void) +{ + unsigned long offset; + u32 cp_flags; + + cp_flags = iop13xx_cp6_save(); + offset = next_jiffy_time - read_tcr1(); + iop13xx_cp6_restore(cp_flags); + + return offset / ticks_per_usec; +} + +static irqreturn_t +iop13xx_timer_interrupt(int irq, void *dev_id) +{ + u32 cp_flags = iop13xx_cp6_save(); + + write_seqlock(&xtime_lock); + + asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (1)); + + while ((signed long)(next_jiffy_time - read_tcr1()) + >= ticks_per_jiffy) { + timer_tick(); + next_jiffy_time -= ticks_per_jiffy; + } + + write_sequnlock(&xtime_lock); + + iop13xx_cp6_restore(cp_flags); + + return IRQ_HANDLED; +} + +static struct irqaction iop13xx_timer_irq = { + .name = "IOP13XX Timer Tick", + .handler = iop13xx_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +void __init iop13xx_init_time(unsigned long tick_rate) +{ + u32 timer_ctl; + u32 cp_flags; + + ticks_per_jiffy = (tick_rate + HZ/2) / HZ; + ticks_per_usec = tick_rate / 1000000; + next_jiffy_time = 0xffffffff; + + timer_ctl = IOP13XX_TMR_EN | IOP13XX_TMR_PRIVILEGED | + IOP13XX_TMR_RELOAD | IOP13XX_TMR_RATIO_1_1; + + /* + * We use timer 0 for our timer interrupt, and timer 1 as + * monotonic counter for tracking missed jiffies. + */ + cp_flags = iop13xx_cp6_save(); + asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (ticks_per_jiffy - 1)); + asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (timer_ctl)); + asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (0xffffffff)); + asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (timer_ctl)); + iop13xx_cp6_restore(cp_flags); + + setup_irq(IRQ_IOP13XX_TIMER0, &iop13xx_timer_irq); +} diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index c0bfb8212b7..4c4dae6901f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -333,7 +333,7 @@ config CPU_XSCALE # XScale Core Version 3 config CPU_XSC3 bool - depends on ARCH_IXP23XX + depends on ARCH_IXP23XX || ARCH_IOP13XX default y select CPU_32v5 select CPU_ABRT_EV5T -- cgit v1.2.3 From a79561134f38de12dce14ed72138f38e55ef53fc Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Thu, 7 Dec 2006 09:51:35 -0800 Subject: [IA64] IA64 Kexec/kdump Changes and updates. 1. Remove fake rendz path and related code according to discuss with Khalid Aziz. 2. fc.i offset fix in relocate_kernel.S. 3. iospic shutdown code eoi and mask race fix from Fujitsu. 4. Warm boot hook in machine_kexec to SN SAL code from Jack Steiner. 5. Send slave to SAL slave loop patch from Jay Lan. 6. Kdump on non-recoverable MCA event patch from Jay Lan 7. Use CTL_UNNUMBERED in kdump_on_init sysctl. Signed-off-by: Zou Nan hai Signed-off-by: Tony Luck --- arch/ia64/Kconfig | 23 +++ arch/ia64/kernel/Makefile | 1 + arch/ia64/kernel/crash.c | 245 +++++++++++++++++++++++++++ arch/ia64/kernel/efi.c | 65 +++++++- arch/ia64/kernel/entry.S | 2 +- arch/ia64/kernel/iosapic.c | 21 +++ arch/ia64/kernel/machine_kexec.c | 133 +++++++++++++++ arch/ia64/kernel/mca.c | 5 + arch/ia64/kernel/relocate_kernel.S | 334 +++++++++++++++++++++++++++++++++++++ arch/ia64/kernel/setup.c | 38 +++++ arch/ia64/kernel/smp.c | 28 +++- arch/ia64/sn/kernel/setup.c | 8 + 12 files changed, 898 insertions(+), 5 deletions(-) create mode 100644 arch/ia64/kernel/crash.c create mode 100644 arch/ia64/kernel/machine_kexec.c create mode 100644 arch/ia64/kernel/relocate_kernel.S (limited to 'arch') diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 683b12c6f76..75d839715b2 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -434,6 +434,29 @@ config IA64_ESI source "drivers/sn/Kconfig" +config KEXEC + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU) + help + kexec is a system call that implements the ability to shutdown your + current kernel, and to start another kernel. It is like a reboot + but it is indepedent of the system firmware. And like a reboot + you can start any kernel with it, not just Linux. + + The name comes from the similiarity to the exec system call. + + It is an ongoing process to be certain the hardware in a machine + is properly shutdown, so do not be surprised if this code does not + initially work for you. It may help to enable device hotplugging + support. As of this writing the exact hardware interface is + strongly in flux, so no good recommendation can be made. + +config CRASH_DUMP + bool "kernel crash dumps (EXPERIMENTAL)" + depends on EXPERIMENTAL && IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU) + help + Generate crash dump after being started by kexec. + source "drivers/firmware/Kconfig" source "fs/Kconfig.binfmt" diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index cfa099b04cd..8ae384eb535 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_IA64_CYCLONE) += cyclone.o obj-$(CONFIG_CPU_FREQ) += cpufreq/ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_recovery.o obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_PCI_MSI) += msi_ia64.o diff --git a/arch/ia64/kernel/crash.c b/arch/ia64/kernel/crash.c new file mode 100644 index 00000000000..0aabedf95da --- /dev/null +++ b/arch/ia64/kernel/crash.c @@ -0,0 +1,245 @@ +/* + * arch/ia64/kernel/crash.c + * + * Architecture specific (ia64) functions for kexec based crash dumps. + * + * Created by: Khalid Aziz + * Copyright (C) 2005 Hewlett-Packard Development Company, L.P. + * Copyright (C) 2005 Intel Corp Zou Nan hai + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +int kdump_status[NR_CPUS]; +atomic_t kdump_cpu_freezed; +atomic_t kdump_in_progress; +int kdump_on_init = 1; +ssize_t +copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + vaddr = __va(pfn<n_namesz = strlen(name) + 1; + note->n_descsz = data_len; + note->n_type = type; + buf += (sizeof(*note) + 3)/4; + memcpy(buf, name, note->n_namesz); + buf += (note->n_namesz + 3)/4; + memcpy(buf, data, data_len); + buf += (data_len + 3)/4; + return buf; +} + +static void +final_note(void *buf) +{ + memset(buf, 0, sizeof(struct elf_note)); +} + +extern void ia64_dump_cpu_regs(void *); + +static DEFINE_PER_CPU(struct elf_prstatus, elf_prstatus); + +void +crash_save_this_cpu() +{ + void *buf; + unsigned long cfm, sof, sol; + + int cpu = smp_processor_id(); + struct elf_prstatus *prstatus = &per_cpu(elf_prstatus, cpu); + + elf_greg_t *dst = (elf_greg_t *)&(prstatus->pr_reg); + memset(prstatus, 0, sizeof(*prstatus)); + prstatus->pr_pid = current->pid; + + ia64_dump_cpu_regs(dst); + cfm = dst[43]; + sol = (cfm >> 7) & 0x7f; + sof = cfm & 0x7f; + dst[46] = (unsigned long)ia64_rse_skip_regs((unsigned long *)dst[46], + sof - sol); + + buf = (u64 *) per_cpu_ptr(crash_notes, cpu); + if (!buf) + return; + buf = append_elf_note(buf, "CORE", NT_PRSTATUS, prstatus, + sizeof(*prstatus)); + final_note(buf); +} + +static int +kdump_wait_cpu_freeze(void) +{ + int cpu_num = num_online_cpus() - 1; + int timeout = 1000; + while(timeout-- > 0) { + if (atomic_read(&kdump_cpu_freezed) == cpu_num) + return 0; + udelay(1000); + } + return 1; +} + +void +machine_crash_shutdown(struct pt_regs *pt) +{ + /* This function is only called after the system + * has paniced or is otherwise in a critical state. + * The minimum amount of code to allow a kexec'd kernel + * to run successfully needs to happen here. + * + * In practice this means shooting down the other cpus in + * an SMP system. + */ + kexec_disable_iosapic(); +#ifdef CONFIG_SMP + kdump_smp_send_stop(); + if (kdump_wait_cpu_freeze() && kdump_on_init) { + //not all cpu response to IPI, send INIT to freeze them + kdump_smp_send_init(); + } +#endif +} + +static void +machine_kdump_on_init(void) +{ + local_irq_disable(); + kexec_disable_iosapic(); + machine_kexec(ia64_kimage); +} + +void +kdump_cpu_freeze(struct unw_frame_info *info, void *arg) +{ + int cpuid; + local_irq_disable(); + cpuid = smp_processor_id(); + crash_save_this_cpu(); + current->thread.ksp = (__u64)info->sw - 16; + atomic_inc(&kdump_cpu_freezed); + kdump_status[cpuid] = 1; + mb(); + if (cpuid == 0) { + for (;;) + cpu_relax(); + } else + ia64_jump_to_sal(&sal_boot_rendez_state[cpuid]); +} + +static int +kdump_init_notifier(struct notifier_block *self, unsigned long val, void *data) +{ + struct ia64_mca_notify_die *nd; + struct die_args *args = data; + + if (!kdump_on_init) + return NOTIFY_DONE; + + if (val != DIE_INIT_MONARCH_ENTER && + val != DIE_INIT_SLAVE_ENTER && + val != DIE_MCA_RENDZVOUS_LEAVE && + val != DIE_MCA_MONARCH_LEAVE) + return NOTIFY_DONE; + + nd = (struct ia64_mca_notify_die *)args->err; + /* Reason code 1 means machine check rendezous*/ + if ((val == DIE_INIT_MONARCH_ENTER || DIE_INIT_SLAVE_ENTER) && + nd->sos->rv_rc == 1) + return NOTIFY_DONE; + + switch (val) { + case DIE_INIT_MONARCH_ENTER: + machine_kdump_on_init(); + break; + case DIE_INIT_SLAVE_ENTER: + unw_init_running(kdump_cpu_freeze, NULL); + break; + case DIE_MCA_RENDZVOUS_LEAVE: + if (atomic_read(&kdump_in_progress)) + unw_init_running(kdump_cpu_freeze, NULL); + break; + case DIE_MCA_MONARCH_LEAVE: + /* die_register->signr indicate if MCA is recoverable */ + if (!args->signr) + machine_kdump_on_init(); + break; + } + return NOTIFY_DONE; +} + +#ifdef CONFIG_SYSCTL +static ctl_table kdump_on_init_table[] = { + { + .ctl_name = CTL_UNNUMBERED, + .procname = "kdump_on_init", + .data = &kdump_on_init, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 0 } +}; + +static ctl_table sys_table[] = { + { + .ctl_name = CTL_KERN, + .procname = "kernel", + .mode = 0555, + .child = kdump_on_init_table, + }, + { .ctl_name = 0 } +}; +#endif + +static int +machine_crash_setup(void) +{ + char *from = strstr(saved_command_line, "elfcorehdr="); + static struct notifier_block kdump_init_notifier_nb = { + .notifier_call = kdump_init_notifier, + }; + int ret; + if (from) + elfcorehdr_addr = memparse(from+11, &from); + saved_max_pfn = (unsigned long)-1; + if((ret = register_die_notifier(&kdump_init_notifier_nb)) != 0) + return ret; +#ifdef CONFIG_SYSCTL + register_sysctl_table(sys_table, 0); +#endif + return 0; +} + +__initcall(machine_crash_setup); + diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index bb8770a177b..9b96e7dbaf6 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,7 @@ extern efi_status_t efi_call_phys (void *, ...); struct efi efi; EXPORT_SYMBOL(efi); static efi_runtime_services_t *runtime; -static unsigned long mem_limit = ~0UL, max_addr = ~0UL; +static unsigned long mem_limit = ~0UL, max_addr = ~0UL, min_addr = 0UL; #define efi_call_virt(f, args...) (*(f))(args) @@ -421,6 +422,8 @@ efi_init (void) mem_limit = memparse(cp + 4, &cp); } else if (memcmp(cp, "max_addr=", 9) == 0) { max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp)); + } else if (memcmp(cp, "min_addr=", 9) == 0) { + min_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp)); } else { while (*cp != ' ' && *cp) ++cp; @@ -428,6 +431,8 @@ efi_init (void) ++cp; } } + if (min_addr != 0UL) + printk(KERN_INFO "Ignoring memory below %luMB\n", min_addr >> 20); if (max_addr != ~0UL) printk(KERN_INFO "Ignoring memory above %luMB\n", max_addr >> 20); @@ -894,7 +899,8 @@ find_memmap_space (void) as = max(contig_low, md->phys_addr); ae = min(contig_high, efi_md_end(md)); - /* keep within max_addr= command line arg */ + /* keep within max_addr= and min_addr= command line arg */ + as = max(as, min_addr); ae = min(ae, max_addr); if (ae <= as) continue; @@ -1004,7 +1010,8 @@ efi_memmap_init(unsigned long *s, unsigned long *e) } else ae = efi_md_end(md); - /* keep within max_addr= command line arg */ + /* keep within max_addr= and min_addr= command line arg */ + as = max(as, min_addr); ae = min(ae, max_addr); if (ae <= as) continue; @@ -1116,6 +1123,58 @@ efi_initialize_iomem_resources(struct resource *code_resource, */ insert_resource(res, code_resource); insert_resource(res, data_resource); +#ifdef CONFIG_KEXEC + insert_resource(res, &efi_memmap_res); + insert_resource(res, &boot_param_res); + if (crashk_res.end > crashk_res.start) + insert_resource(res, &crashk_res); +#endif } } } + +#ifdef CONFIG_KEXEC +/* find a block of memory aligned to 64M exclude reserved regions + rsvd_regions are sorted + */ +unsigned long +kdump_find_rsvd_region (unsigned long size, + struct rsvd_region *r, int n) +{ + int i; + u64 start, end; + u64 alignment = 1UL << _PAGE_SIZE_64M; + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; + + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; + + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; + if (!efi_wb(md)) + continue; + start = ALIGN(md->phys_addr, alignment); + end = efi_md_end(md); + for (i = 0; i < n; i++) { + if (__pa(r[i].start) >= start && __pa(r[i].end) < end) { + if (__pa(r[i].start) > start + size) + return start; + start = ALIGN(__pa(r[i].end), alignment); + if (i < n-1 && __pa(r[i+1].start) < start + size) + continue; + else + break; + } + } + if (end > start + size) + return start; + } + + printk(KERN_WARNING "Cannot reserve 0x%lx byte of memory for crashdump\n", + size); + return ~0UL; +} +#endif diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 3390b7c5a63..15234ed3a34 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1575,7 +1575,7 @@ sys_call_table: data8 sys_mq_timedreceive // 1265 data8 sys_mq_notify data8 sys_mq_getsetattr - data8 sys_ni_syscall // reserved for kexec_load + data8 sys_kexec_load data8 sys_ni_syscall // reserved for vserver data8 sys_waitid // 1270 data8 sys_add_key diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 60d64950e3c..0fc5fb7865c 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -288,6 +288,27 @@ nop (unsigned int irq) /* do nothing... */ } + +#ifdef CONFIG_KEXEC +void +kexec_disable_iosapic(void) +{ + struct iosapic_intr_info *info; + struct iosapic_rte_info *rte; + u8 vec = 0; + for (info = iosapic_intr_info; info < + iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) { + list_for_each_entry(rte, &info->rtes, + rte_list) { + iosapic_write(rte->addr, + IOSAPIC_RTE_LOW(rte->rte_index), + IOSAPIC_MASK|vec); + iosapic_eoi(rte->addr, vec); + } + } +} +#endif + static void mask_irq (unsigned int irq) { diff --git a/arch/ia64/kernel/machine_kexec.c b/arch/ia64/kernel/machine_kexec.c new file mode 100644 index 00000000000..468233fa2ce --- /dev/null +++ b/arch/ia64/kernel/machine_kexec.c @@ -0,0 +1,133 @@ +/* + * arch/ia64/kernel/machine_kexec.c + * + * Handle transition of Linux booting another kernel + * Copyright (C) 2005 Hewlett-Packard Development Comapny, L.P. + * Copyright (C) 2005 Khalid Aziz + * Copyright (C) 2006 Intel Corp, Zou Nan hai + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef void (*relocate_new_kernel_t)(unsigned long, unsigned long, + struct ia64_boot_param *, unsigned long); + +struct kimage *ia64_kimage; + +struct resource efi_memmap_res = { + .name = "EFI Memory Map", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + +struct resource boot_param_res = { + .name = "Boot parameter", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + + +/* + * Do what every setup is needed on image and the + * reboot code buffer to allow us to avoid allocations + * later. + */ +int machine_kexec_prepare(struct kimage *image) +{ + void *control_code_buffer; + const unsigned long *func; + + func = (unsigned long *)&relocate_new_kernel; + /* Pre-load control code buffer to minimize work in kexec path */ + control_code_buffer = page_address(image->control_code_page); + memcpy((void *)control_code_buffer, (const void *)func[0], + relocate_new_kernel_size); + flush_icache_range((unsigned long)control_code_buffer, + (unsigned long)control_code_buffer + relocate_new_kernel_size); + ia64_kimage = image; + + return 0; +} + +void machine_kexec_cleanup(struct kimage *image) +{ +} + +void machine_shutdown(void) +{ + int cpu; + + for_each_online_cpu(cpu) { + if (cpu != smp_processor_id()) + cpu_down(cpu); + } + kexec_disable_iosapic(); +} + +/* + * Do not allocate memory (or fail in any way) in machine_kexec(). + * We are past the point of no return, committed to rebooting now. + */ +extern void *efi_get_pal_addr(void); +static void ia64_machine_kexec(struct unw_frame_info *info, void *arg) +{ + struct kimage *image = arg; + relocate_new_kernel_t rnk; + void *pal_addr = efi_get_pal_addr(); + unsigned long code_addr = (unsigned long)page_address(image->control_code_page); + unsigned long vector; + int ii; + + if (image->type == KEXEC_TYPE_CRASH) { + crash_save_this_cpu(); + current->thread.ksp = (__u64)info->sw - 16; + } + + /* Interrupts aren't acceptable while we reboot */ + local_irq_disable(); + + /* Mask CMC and Performance Monitor interrupts */ + ia64_setreg(_IA64_REG_CR_PMV, 1 << 16); + ia64_setreg(_IA64_REG_CR_CMCV, 1 << 16); + + /* Mask ITV and Local Redirect Registers */ + ia64_set_itv(1 << 16); + ia64_set_lrr0(1 << 16); + ia64_set_lrr1(1 << 16); + + /* terminate possible nested in-service interrupts */ + for (ii = 0; ii < 16; ii++) + ia64_eoi(); + + /* unmask TPR and clear any pending interrupts */ + ia64_setreg(_IA64_REG_CR_TPR, 0); + ia64_srlz_d(); + vector = ia64_get_ivr(); + while (vector != IA64_SPURIOUS_INT_VECTOR) { + ia64_eoi(); + vector = ia64_get_ivr(); + } + platform_kernel_launch_event(); + rnk = (relocate_new_kernel_t)&code_addr; + (*rnk)(image->head, image->start, ia64_boot_param, + GRANULEROUNDDOWN((unsigned long) pal_addr)); + BUG(); +} + +void machine_kexec(struct kimage *image) +{ + unw_init_running(ia64_machine_kexec, image); + for(;;); +} diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 6bedd97570c..87c1c4f4287 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c @@ -82,6 +82,7 @@ #include #include #include +#include #include #include @@ -1238,6 +1239,10 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, } else { /* Dump buffered message to console */ ia64_mlogbuf_finish(1); +#ifdef CONFIG_CRASH_DUMP + atomic_set(&kdump_in_progress, 1); + monarch_cpu = -1; +#endif } if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) == NOTIFY_STOP) diff --git a/arch/ia64/kernel/relocate_kernel.S b/arch/ia64/kernel/relocate_kernel.S new file mode 100644 index 00000000000..ae473e3f2a0 --- /dev/null +++ b/arch/ia64/kernel/relocate_kernel.S @@ -0,0 +1,334 @@ +/* + * arch/ia64/kernel/relocate_kernel.S + * + * Relocate kexec'able kernel and start it + * + * Copyright (C) 2005 Hewlett-Packard Development Company, L.P. + * Copyright (C) 2005 Khalid Aziz + * Copyright (C) 2005 Intel Corp, Zou Nan hai + * + * This source code is licensed under the GNU General Public License, + * Version 2. See the file COPYING for more details. + */ +#include +#include +#include +#include +#include + + /* Must be relocatable PIC code callable as a C function + */ +GLOBAL_ENTRY(relocate_new_kernel) + .prologue + alloc r31=ar.pfs,4,0,0,0 + .body +.reloc_entry: +{ + rsm psr.i| psr.ic + mov r2=ip +} + ;; +{ + flushrs // must be first insn in group + srlz.i +} + ;; + dep r2=0,r2,61,3 //to physical address + ;; + //first switch to physical mode + add r3=1f-.reloc_entry, r2 + movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC + mov ar.rsc=0 // put RSE in enforced lazy mode + ;; + add sp=(memory_stack_end - 16 - .reloc_entry),r2 + add r8=(register_stack - .reloc_entry),r2 + ;; + mov r18=ar.rnat + mov ar.bspstore=r8 + ;; + mov cr.ipsr=r16 + mov cr.iip=r3 + mov cr.ifs=r0 + srlz.i + ;; + mov ar.rnat=r18 + rfi + ;; +1: + //physical mode code begin + mov b6=in1 + dep r28=0,in2,61,3 //to physical address + + // purge all TC entries +#define O(member) IA64_CPUINFO_##member##_OFFSET + GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2 + ;; + addl r17=O(PTCE_STRIDE),r2 + addl r2=O(PTCE_BASE),r2 + ;; + ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base + ld4 r19=[r2],4 // r19=ptce_count[0] + ld4 r21=[r17],4 // r21=ptce_stride[0] + ;; + ld4 r20=[r2] // r20=ptce_count[1] + ld4 r22=[r17] // r22=ptce_stride[1] + mov r24=r0 + ;; + adds r20=-1,r20 + ;; +#undef O +2: + cmp.ltu p6,p7=r24,r19 +(p7) br.cond.dpnt.few 4f + mov ar.lc=r20 +3: + ptc.e r18 + ;; + add r18=r22,r18 + br.cloop.sptk.few 3b + ;; + add r18=r21,r18 + add r24=1,r24 + ;; + br.sptk.few 2b +4: + srlz.i + ;; + //purge TR entry for kernel text and data + movl r16=KERNEL_START + mov r18=KERNEL_TR_PAGE_SHIFT<<2 + ;; + ptr.i r16, r18 + ptr.d r16, r18 + ;; + srlz.i + ;; + + // purge TR entry for percpu data + movl r16=PERCPU_ADDR + mov r18=PERCPU_PAGE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.d + ;; + + // purge TR entry for pal code + mov r16=in3 + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.i r16,r18 + ;; + srlz.i + ;; + + // purge TR entry for stack + mov r16=IA64_KR(CURRENT_STACK) + ;; + shl r16=r16,IA64_GRANULE_SHIFT + movl r19=PAGE_OFFSET + ;; + add r16=r19,r16 + mov r18=IA64_GRANULE_SHIFT<<2 + ;; + ptr.d r16,r18 + ;; + srlz.i + ;; + + //copy segments + movl r16=PAGE_MASK + mov r30=in0 // in0 is page_list + br.sptk.few .dest_page + ;; +.loop: + ld8 r30=[in0], 8;; +.dest_page: + tbit.z p0, p6=r30, 0;; // 0x1 dest page +(p6) and r17=r30, r16 +(p6) br.cond.sptk.few .loop;; + + tbit.z p0, p6=r30, 1;; // 0x2 indirect page +(p6) and in0=r30, r16 +(p6) br.cond.sptk.few .loop;; + + tbit.z p0, p6=r30, 2;; // 0x4 end flag +(p6) br.cond.sptk.few .end_loop;; + + tbit.z p6, p0=r30, 3;; // 0x8 source page +(p6) br.cond.sptk.few .loop + + and r18=r30, r16 + + // simple copy page, may optimize later + movl r14=PAGE_SIZE/8 - 1;; + mov ar.lc=r14;; +1: + ld8 r14=[r18], 8;; + st8 [r17]=r14;; + fc.i r17 + add r17=8, r17 + br.ctop.sptk.few 1b + br.sptk.few .loop + ;; + +.end_loop: + sync.i // for fc.i + ;; + srlz.i + ;; + srlz.d + ;; + br.call.sptk.many b0=b6;; + +.align 32 +memory_stack: + .fill 8192, 1, 0 +memory_stack_end: +register_stack: + .fill 8192, 1, 0 +register_stack_end: +relocate_new_kernel_end: +END(relocate_new_kernel) + +.global relocate_new_kernel_size +relocate_new_kernel_size: + data8 relocate_new_kernel_end - relocate_new_kernel + +GLOBAL_ENTRY(ia64_dump_cpu_regs) + .prologue + alloc loc0=ar.pfs,1,2,0,0 + .body + mov ar.rsc=0 // put RSE in enforced lazy mode + add loc1=4*8, in0 // save r4 and r5 first + ;; +{ + flushrs // flush dirty regs to backing store + srlz.i +} + st8 [loc1]=r4, 8 + ;; + st8 [loc1]=r5, 8 + ;; + add loc1=32*8, in0 + mov r4=ar.rnat + ;; + st8 [in0]=r0, 8 // r0 + st8 [loc1]=r4, 8 // rnat + mov r5=pr + ;; + st8 [in0]=r1, 8 // r1 + st8 [loc1]=r5, 8 // pr + mov r4=b0 + ;; + st8 [in0]=r2, 8 // r2 + st8 [loc1]=r4, 8 // b0 + mov r5=b1; + ;; + st8 [in0]=r3, 24 // r3 + st8 [loc1]=r5, 8 // b1 + mov r4=b2 + ;; + st8 [in0]=r6, 8 // r6 + st8 [loc1]=r4, 8 // b2 + mov r5=b3 + ;; + st8 [in0]=r7, 8 // r7 + st8 [loc1]=r5, 8 // b3 + mov r4=b4 + ;; + st8 [in0]=r8, 8 // r8 + st8 [loc1]=r4, 8 // b4 + mov r5=b5 + ;; + st8 [in0]=r9, 8 // r9 + st8 [loc1]=r5, 8 // b5 + mov r4=b6 + ;; + st8 [in0]=r10, 8 // r10 + st8 [loc1]=r5, 8 // b6 + mov r5=b7 + ;; + st8 [in0]=r11, 8 // r11 + st8 [loc1]=r5, 8 // b7 + mov r4=b0 + ;; + st8 [in0]=r12, 8 // r12 + st8 [loc1]=r4, 8 // ip + mov r5=loc0 + ;; + st8 [in0]=r13, 8 // r13 + extr.u r5=r5, 0, 38 // ar.pfs.pfm + mov r4=r0 // user mask + ;; + st8 [in0]=r14, 8 // r14 + st8 [loc1]=r5, 8 // cfm + ;; + st8 [in0]=r15, 8 // r15 + st8 [loc1]=r4, 8 // user mask + mov r5=ar.rsc + ;; + st8 [in0]=r16, 8 // r16 + st8 [loc1]=r5, 8 // ar.rsc + mov r4=ar.bsp + ;; + st8 [in0]=r17, 8 // r17 + st8 [loc1]=r4, 8 // ar.bsp + mov r5=ar.bspstore + ;; + st8 [in0]=r18, 8 // r18 + st8 [loc1]=r5, 8 // ar.bspstore + mov r4=ar.rnat + ;; + st8 [in0]=r19, 8 // r19 + st8 [loc1]=r4, 8 // ar.rnat + mov r5=ar.ccv + ;; + st8 [in0]=r20, 8 // r20 + st8 [loc1]=r5, 8 // ar.ccv + mov r4=ar.unat + ;; + st8 [in0]=r21, 8 // r21 + st8 [loc1]=r4, 8 // ar.unat + mov r5 = ar.fpsr + ;; + st8 [in0]=r22, 8 // r22 + st8 [loc1]=r5, 8 // ar.fpsr + mov r4 = ar.unat + ;; + st8 [in0]=r23, 8 // r23 + st8 [loc1]=r4, 8 // unat + mov r5 = ar.fpsr + ;; + st8 [in0]=r24, 8 // r24 + st8 [loc1]=r5, 8 // fpsr + mov r4 = ar.pfs + ;; + st8 [in0]=r25, 8 // r25 + st8 [loc1]=r4, 8 // ar.pfs + mov r5 = ar.lc + ;; + st8 [in0]=r26, 8 // r26 + st8 [loc1]=r5, 8 // ar.lc + mov r4 = ar.ec + ;; + st8 [in0]=r27, 8 // r27 + st8 [loc1]=r4, 8 // ar.ec + mov r5 = ar.csd + ;; + st8 [in0]=r28, 8 // r28 + st8 [loc1]=r5, 8 // ar.csd + mov r4 = ar.ssd + ;; + st8 [in0]=r29, 8 // r29 + st8 [loc1]=r4, 8 // ar.ssd + ;; + st8 [in0]=r30, 8 // r30 + ;; + st8 [in0]=r31, 8 // r31 + mov ar.pfs=loc0 + ;; + br.ret.sptk.many rp +END(ia64_dump_cpu_regs) + + diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d10404a4175..14e1200376a 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -252,6 +254,41 @@ reserve_memory (void) efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); n++; +#ifdef CONFIG_KEXEC + /* crashkernel=size@offset specifies the size to reserve for a crash + * kernel.(offset is ingored for keep compatibility with other archs) + * By reserving this memory we guarantee that linux never set's it + * up as a DMA target.Useful for holding code to do something + * appropriate after a kernel panic. + */ + { + char *from = strstr(saved_command_line, "crashkernel="); + unsigned long base, size; + if (from) { + size = memparse(from + 12, &from); + if (size) { + sort_regions(rsvd_region, n); + base = kdump_find_rsvd_region(size, + rsvd_region, n); + if (base != ~0UL) { + rsvd_region[n].start = + (unsigned long)__va(base); + rsvd_region[n].end = + (unsigned long)__va(base + size); + n++; + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } + } + efi_memmap_res.start = ia64_boot_param->efi_memmap; + efi_memmap_res.end = efi_memmap_res.start + + ia64_boot_param->efi_memmap_size; + boot_param_res.start = __pa(ia64_boot_param); + boot_param_res.end = boot_param_res.start + + sizeof(*ia64_boot_param); + } +#endif /* end of memory marker */ rsvd_region[n].start = ~0UL; rsvd_region[n].end = ~0UL; @@ -263,6 +300,7 @@ reserve_memory (void) sort_regions(rsvd_region, num_rsvd_regions); } + /** * find_initrd - get initrd parameters from the boot parameter structure * diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 6ab95ceaf9d..b1b9aa4364b 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ static volatile struct call_data_struct *call_data; #define IPI_CALL_FUNC 0 #define IPI_CPU_STOP 1 +#define IPI_KDUMP_CPU_STOP 3 /* This needs to be cacheline aligned because it is written to by *other* CPUs. */ static DEFINE_PER_CPU(u64, ipi_operation) ____cacheline_aligned; @@ -155,7 +157,11 @@ handle_IPI (int irq, void *dev_id) case IPI_CPU_STOP: stop_this_cpu(); break; - +#ifdef CONFIG_CRASH_DUMP + case IPI_KDUMP_CPU_STOP: + unw_init_running(kdump_cpu_freeze, NULL); + break; +#endif default: printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); break; @@ -213,6 +219,26 @@ send_IPI_self (int op) send_IPI_single(smp_processor_id(), op); } +#ifdef CONFIG_CRASH_DUMP +void +kdump_smp_send_stop() +{ + send_IPI_allbutself(IPI_KDUMP_CPU_STOP); +} + +void +kdump_smp_send_init() +{ + unsigned int cpu, self_cpu; + self_cpu = smp_processor_id(); + for_each_online_cpu(cpu) { + if (cpu != self_cpu) { + if(kdump_status[cpu] == 0) + platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0); + } + } +} +#endif /* * Called with preeemption disabled. */ diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 1d009f93244..a934ad06942 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -769,5 +769,13 @@ int sn_prom_feature_available(int id) return 0; return test_bit(id, sn_prom_features); } + +void +sn_kernel_launch_event(void) +{ + /* ignore status until we understand possible failure, if any*/ + if (ia64_sn_kernel_launch_event()) + printk(KERN_ERR "KEXEC is not supported in this PROM, Please update the PROM.\n"); +} EXPORT_SYMBOL(sn_prom_feature_available); -- cgit v1.2.3 From d61b49c1aa49efc657aa0cf270cf931444680563 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 26 Oct 2006 12:22:32 -0600 Subject: [IA64] sparse cleanups 0/NULL confusion and some missing UL on constants. Signed-off-by: Matthew Wilcox Signed-off-by: Tony Luck --- arch/ia64/kernel/kprobes.c | 2 +- arch/ia64/kernel/perfmon_montecito.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 51217d63285..898a07d1d6f 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -851,7 +851,7 @@ static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg) return; } } while (unw_unwind(info) >= 0); - lp->bsp = 0; + lp->bsp = NULL; lp->cfm = 0; return; } diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h index cd06ac6a686..7f8da4c7ca6 100644 --- a/arch/ia64/kernel/perfmon_montecito.h +++ b/arch/ia64/kernel/perfmon_montecito.h @@ -45,16 +45,16 @@ static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={ /* pmc29 */ { PFM_REG_NOTIMPL, }, /* pmc30 */ { PFM_REG_NOTIMPL, }, /* pmc31 */ { PFM_REG_NOTIMPL, }, -/* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffff, 0x30f01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffff, 0xf01ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffff, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, +/* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffffUL, 0x30f01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, +/* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, +/* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffffUL, 0xf01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, +/* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, /* pmc36 */ { PFM_REG_CONFIG, 0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, /* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}}, /* pmc38 */ { PFM_REG_CONFIG, 0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, /* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, /* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}}, -/* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefe, 0x1e00018181818, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, +/* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, /* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ }; @@ -185,7 +185,7 @@ pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cn DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded)); if (cnum == 41 && is_loaded - && (tmpval & 0x1e00000000000) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { + && (tmpval & 0x1e00000000000UL) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval)); -- cgit v1.2.3 From c69577711a8fd232e6b309c3e99f9a8f96f63082 Mon Sep 17 00:00:00 2001 From: John Keller Date: Mon, 6 Nov 2006 14:10:50 -0600 Subject: [IA64] SN: Correctly update smp_affinty mask On Altix systems, the /proc/irq/nn/smp_affinity mask is not being setup at device iniitalization, or updated after an interrupt redirection. This patch resolves those issues. Signed-off-by: John Keller Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/irq.c | 18 +++++++++++++++--- arch/ia64/sn/kernel/msi_sn.c | 4 ---- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index 0b49459a878..8c5bee01eaa 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c @@ -117,7 +117,10 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, nasid_t nasid, int slice) { int vector; + int cpuid; +#ifdef CONFIG_SMP int cpuphys; +#endif int64_t bridge; int local_widget, status; nasid_t local_nasid; @@ -146,7 +149,6 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, vector = sn_irq_info->irq_irq; /* Free the old PROM new_irq_info structure */ sn_intr_free(local_nasid, local_widget, new_irq_info); - /* Update kernels new_irq_info with new target info */ unregister_intr_pda(new_irq_info); /* allocate a new PROM new_irq_info struct */ @@ -160,8 +162,10 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, return NULL; } - cpuphys = nasid_slice_to_cpuid(nasid, slice); - new_irq_info->irq_cpuid = cpuphys; + /* Update kernels new_irq_info with new target info */ + cpuid = nasid_slice_to_cpuid(new_irq_info->irq_nasid, + new_irq_info->irq_slice); + new_irq_info->irq_cpuid = cpuid; register_intr_pda(new_irq_info); pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; @@ -180,6 +184,7 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, call_rcu(&sn_irq_info->rcu, sn_irq_info_free); #ifdef CONFIG_SMP + cpuphys = cpu_physical_id(cpuid); set_irq_affinity_info((vector & 0xff), cpuphys, 0); #endif @@ -299,6 +304,9 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) nasid_t nasid = sn_irq_info->irq_nasid; int slice = sn_irq_info->irq_slice; int cpu = nasid_slice_to_cpuid(nasid, slice); +#ifdef CONFIG_SMP + int cpuphys; +#endif pci_dev_get(pci_dev); sn_irq_info->irq_cpuid = cpu; @@ -311,6 +319,10 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) spin_unlock(&sn_irq_info_lock); register_intr_pda(sn_irq_info); +#ifdef CONFIG_SMP + cpuphys = cpu_physical_id(cpu); + set_irq_affinity_info(sn_irq_info->irq_irq, cpuphys, 0); +#endif } void sn_irq_unfixup(struct pci_dev *pci_dev) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 6ffd1f850d4..b3a435fd70f 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -136,10 +136,6 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) */ msg.data = 0x100 + irq; -#ifdef CONFIG_SMP - set_irq_affinity_info(irq, sn_irq_info->irq_cpuid, 0); -#endif - write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); -- cgit v1.2.3 From 895309ff6f22a9d107e007521e44aac4400b365d Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Thu, 7 Dec 2006 11:06:35 -0800 Subject: [IA64] Update processor_info features Add the printing of additional processor features to proc_features. Based on Rev 2.2 of Volume 2 of "Intel Itanium Architecture Software Developer's Manual" (January 2006) fields (pages 2:430-2:432). This patch gets the features back in sync with the spec. Sample output before: -------------------------------------------------------------- cobra:~ # cat /proc/pal/cpu0/processor_info XIP,XPSR,XFS implemented : On NoCtrl XR1-XR3 implemented : On NoCtrl Disable dynamic predicate prediction : NotImpl Disable processor physical number : NotImpl Disable dynamic data cache prefetch : NotImpl Disable dynamic inst cache prefetch : NotImpl Disable dynamic branch prediction : NotImpl Disable BINIT on processor time-out : On Ctrl Disable dynamic power management (DPM) : NotImpl Disable coherency : NotImpl Disable cache : NotImpl Enable CMCI promotion : Off Ctrl Enable MCA to BINIT promotion : Off Ctrl Enable MCA promotion : NotImpl Enable BERR promotion : NotImpl cobra:~ # -------------------------------------------------------------- Sample output after: -------------------------------------------------------------- cobra:~ # cat /proc/pal/cpu0/processor_info Unimplemented instruction address fault : NotImpl INIT, PMI, and LINT pins : NotImpl Simple unimplimented instr addresses : On NoCtrl Variable P-state performance : NotImpl Virtual machine features implemeted : On NoCtrl XIP,XPSR,XFS implemented : On NoCtrl XR1-XR3 implemented : On NoCtrl Disable dynamic predicate prediction : NotImpl Disable processor physical number : NotImpl Disable dynamic data cache prefetch : NotImpl Disable dynamic inst cache prefetch : NotImpl Disable dynamic branch prediction : NotImpl Disable P-states : Off Ctrl Enable MCA on Data Poisoning : Off Ctrl Enable vmsw instruction : On Ctrl Enable extern environmental notification : NotImpl Disable BINIT on processor time-out : On Ctrl Disable dynamic power management (DPM) : NotImpl Disable coherency : NotImpl Disable cache : NotImpl Enable CMCI promotion : Off Ctrl Enable MCA to BINIT promotion : Off Ctrl Enable MCA promotion : NotImpl Enable BERR promotion : NotImpl cobra:~ # -------------------------------------------------------------- Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/kernel/palinfo.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 0b546e2b36a..ca1884ed5a0 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -16,6 +16,7 @@ * 02/05/2001 S.Eranian fixed module support * 10/23/2001 S.Eranian updated pal_perf_mon_info bug fixes * 03/24/2004 Ashok Raj updated to work with CPU Hotplug + * 10/26/2006 Russ Anderson updated processor features to rev 2.2 spec */ #include #include @@ -467,7 +468,11 @@ static const char *proc_features[]={ NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL, - NULL,NULL,NULL,NULL,NULL, + "Unimplemented instruction address fault", + "INIT, PMI, and LINT pins", + "Simple unimplemented instr addresses", + "Variable P-state performance", + "Virtual machine features implemented", "XIP,XPSR,XFS implemented", "XR1-XR3 implemented", "Disable dynamic predicate prediction", @@ -475,7 +480,11 @@ static const char *proc_features[]={ "Disable dynamic data cache prefetch", "Disable dynamic inst cache prefetch", "Disable dynamic branch prediction", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + "Disable P-states", + "Enable MCA on Data Poisoning", + "Enable vmsw instruction", + "Enable extern environmental notification", "Disable BINIT on processor time-out", "Disable dynamic power management (DPM)", "Disable coherency", -- cgit v1.2.3 From 5b4d5681ffaa6e1bf3b085beb701d87c7c7404da Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Mon, 6 Nov 2006 16:45:18 -0600 Subject: [IA64] More Itanium PAL spec updates Additional updates to conform with Rev 2.2 of Volume 2 of "Intel Itanium Architecture Software Developer's Manual" (January 2006). Add pal_bus_features_s bits 52 & 53 (page 2:347) Add pal_vm_info_2_s field max_purges (page 2:2:451) Add PAL_GET_HW_POLICY call (page 2:381) Add PAL_SET_HW_POLICY call (page 2:439) Sample output before: --------------------------------------------------------------------- cobra:~ # cat /proc/pal/cpu0/vm_info Physical Address Space : 50 bits Virtual Address Space : 61 bits Protection Key Registers(PKR) : 16 Implemented bits in PKR.key : 24 Hash Tag ID : 0x2 Size of RR.rid : 24 Supported memory attributes : WB, UC, UCE, WC, NaTPage --------------------------------------------------------------------- Sample output after: --------------------------------------------------------------------- cobra:~ # cat /proc/pal/cpu0/vm_info Physical Address Space : 50 bits Virtual Address Space : 61 bits Protection Key Registers(PKR) : 16 Implemented bits in PKR.key : 24 Hash Tag ID : 0x2 Max Purges : 1 Size of RR.rid : 24 Supported memory attributes : WB, UC, UCE, WC, NaTPage --------------------------------------------------------------------- Signed-off-by: Russ Anderson (rja@sgi.com) Signed-off-by: Tony Luck --- arch/ia64/kernel/palinfo.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index ca1884ed5a0..32f81b38ae4 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -315,13 +315,20 @@ vm_info(char *page) "Protection Key Registers(PKR) : %d\n" "Implemented bits in PKR.key : %d\n" "Hash Tag ID : 0x%x\n" - "Size of RR.rid : %d\n", + "Size of RR.rid : %d\n" + "Max Purges : ", vm_info_1.pal_vm_info_1_s.phys_add_size, vm_info_2.pal_vm_info_2_s.impl_va_msb+1, vm_info_1.pal_vm_info_1_s.max_pkr+1, vm_info_1.pal_vm_info_1_s.key_size, vm_info_1.pal_vm_info_1_s.hash_tag_id, vm_info_2.pal_vm_info_2_s.rid_size); + if (vm_info_2.pal_vm_info_2_s.max_purges == PAL_MAX_PURGES) + p += sprintf(p, "unlimited\n"); + else + p += sprintf(p, "%d\n", + vm_info_2.pal_vm_info_2_s.max_purges ? + vm_info_2.pal_vm_info_2_s.max_purges : 1); } if (ia64_pal_mem_attrib(&attrib) == 0) { -- cgit v1.2.3 From 007d77d0c5eb36555443ff273ce2a27f90da8837 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Fri, 10 Nov 2006 13:17:50 -0800 Subject: [IA64] implement csum_ipv6_magic for ia64. The asm version is 4.4 times faster than the generic C version and 10X smaller in code size. Signed-off-by: Ken Chen Signed-off-by: Tony Luck --- arch/ia64/lib/ip_fast_csum.S | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S index 19674ca2acf..4fb132ee207 100644 --- a/arch/ia64/lib/ip_fast_csum.S +++ b/arch/ia64/lib/ip_fast_csum.S @@ -8,8 +8,8 @@ * in0: address of buffer to checksum (char *) * in1: length of the buffer (int) * - * Copyright (C) 2002 Intel Corp. - * Copyright (C) 2002 Ken Chen + * Copyright (C) 2002, 2006 Intel Corp. + * Copyright (C) 2002, 2006 Ken Chen */ #include @@ -25,6 +25,9 @@ #define in0 r32 #define in1 r33 +#define in2 r34 +#define in3 r35 +#define in4 r36 #define ret0 r8 GLOBAL_ENTRY(ip_fast_csum) @@ -88,3 +91,51 @@ GLOBAL_ENTRY(ip_fast_csum) mov b0=r34 br.ret.sptk.many b0 END(ip_fast_csum) + +GLOBAL_ENTRY(csum_ipv6_magic) + ld4 r20=[in0],4 + ld4 r21=[in1],4 + dep r15=in3,in2,32,16 + ;; + ld4 r22=[in0],4 + ld4 r23=[in1],4 + mux1 r15=r15,@rev + ;; + ld4 r24=[in0],4 + ld4 r25=[in1],4 + shr.u r15=r15,16 + add r16=r20,r21 + add r17=r22,r23 + ;; + ld4 r26=[in0],4 + ld4 r27=[in1],4 + add r18=r24,r25 + add r8=r16,r17 + ;; + add r19=r26,r27 + add r8=r8,r18 + ;; + add r8=r8,r19 + add r15=r15,in4 + ;; + add r8=r8,r15 + ;; + shr.u r10=r8,32 // now fold sum into short + zxt4 r11=r8 + ;; + add r8=r10,r11 + ;; + shr.u r10=r8,16 // yeah, keep it rolling + zxt2 r11=r8 + ;; + add r8=r10,r11 + ;; + shr.u r10=r8,16 // three times lucky + zxt2 r11=r8 + ;; + add r8=r10,r11 + mov r9=0xffff + ;; + andcm r8=r9,r8 + br.ret.sptk.many b0 +END(csum_ipv6_magic) -- cgit v1.2.3 From 6dbfc19b7ea93f94f1efabaae71a921b49d8cae2 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Wed, 8 Nov 2006 16:29:25 -0800 Subject: [IA64] tidy up return value of ip_fast_csum While working on implementing csum_ipv6_magic, I noticed that current version of ip_fast_csum will potentially return bits above "unsigned short" as 1. While no harm is done right now because all call sites will chop off the upper bits when it uses the return value. However, this is still dangerous and buggy. Here is a patch to enforce that the function really returns unsigned short in the native register format. The fix is free as there are plenty open slot to add one more asm instruction. Signed-off-by: Ken Chen Signed-off-by: Tony Luck --- arch/ia64/lib/ip_fast_csum.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S index 4fb132ee207..1f86aeb2c94 100644 --- a/arch/ia64/lib/ip_fast_csum.S +++ b/arch/ia64/lib/ip_fast_csum.S @@ -68,8 +68,9 @@ GLOBAL_ENTRY(ip_fast_csum) zxt2 r20=r20 ;; add r20=ret0,r20 + mov r9=0xffff ;; - andcm ret0=-1,r20 + andcm ret0=r9,r20 .restore sp // reset frame state br.ret.sptk.many b0 ;; -- cgit v1.2.3 From 17e77b1cc31454908aa286bb1db3c611295ce25c Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Fri, 1 Dec 2006 15:28:14 -0800 Subject: [PATCH] Add support for type argument in PAL_GET_PSTATE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PAL_GET_PSTATE accepts a type argument to return different kinds of frequency information. Refer: Intel Itanium®Architecture Software Developer's Manual - Volume 2: System Architecture, Revision 2.2 (http://developer.intel.com/design/itanium/manuals/245318.htm) Add the support for type argument and use Instantaneous frequency in the acpi driver. Also fix a bug, where in return value of PAL_GET_PSTATE was getting compared with 'control' bits instead of 'status' bits. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Tony Luck --- arch/ia64/kernel/cpufreq/acpi-cpufreq.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c index 86faf221a07..088f130197a 100644 --- a/arch/ia64/kernel/cpufreq/acpi-cpufreq.c +++ b/arch/ia64/kernel/cpufreq/acpi-cpufreq.c @@ -68,7 +68,8 @@ processor_get_pstate ( dprintk("processor_get_pstate\n"); - retval = ia64_pal_get_pstate(&pstate_index); + retval = ia64_pal_get_pstate(&pstate_index, + PAL_GET_PSTATE_TYPE_INSTANT); *value = (u32) pstate_index; if (retval) @@ -91,7 +92,7 @@ extract_clock ( dprintk("extract_clock\n"); for (i = 0; i < data->acpi_data.state_count; i++) { - if (value >= data->acpi_data.states[i].control) + if (value == data->acpi_data.states[i].status) return data->acpi_data.states[i].core_frequency; } return data->acpi_data.states[i-1].core_frequency; @@ -117,11 +118,7 @@ processor_get_freq ( goto migrate_end; } - /* - * processor_get_pstate gets the average frequency since the - * last get. So, do two PAL_get_freq()... - */ - ret = processor_get_pstate(&value); + /* processor_get_pstate gets the instantaneous frequency */ ret = processor_get_pstate(&value); if (ret) { -- cgit v1.2.3 From a5f8ee0291e75f92a27111eb01da82be93c9068e Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 7 Dec 2006 13:18:57 -0800 Subject: [IA64] Need export for csum_ipv6_magic Now we have our own highly optimized assembly code version of this routine (Thanks Ken!) we should export it so that it can be used. Signed-off-by: Tony Luck --- arch/ia64/kernel/ia64_ksyms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 879c1817bd1..bd17190bebb 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -14,6 +14,7 @@ EXPORT_SYMBOL(strlen); #include EXPORT_SYMBOL(ip_fast_csum); /* hand-coded assembly */ +EXPORT_SYMBOL(csum_ipv6_magic); #include EXPORT_SYMBOL(__down); -- cgit v1.2.3 From 66888a6e5ffc756b9a4115fc766ee2258eefb928 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Mon, 4 Dec 2006 14:58:35 -0800 Subject: [IA64] resolve name clash by renaming is_available_memory() There is a name clash with ia64 arch code in Andrew's tree. Rename is_avialable_memory() to is_memory_available() to avoid the clash. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/kernel/efi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index 9b96e7dbaf6..0b25a7d4e1e 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c @@ -225,7 +225,7 @@ efi_gettimeofday (struct timespec *ts) } static int -is_available_memory (efi_memory_desc_t *md) +is_memory_available (efi_memory_desc_t *md) { if (!(md->attribute & EFI_MEMORY_WB)) return 0; @@ -892,7 +892,7 @@ find_memmap_space (void) } contig_high = GRANULEROUNDDOWN(contig_high); } - if (!is_available_memory(md) || md->type == EFI_LOADER_DATA) + if (!is_memory_available(md) || md->type == EFI_LOADER_DATA) continue; /* Round ends inward to granule boundaries */ @@ -968,7 +968,7 @@ efi_memmap_init(unsigned long *s, unsigned long *e) } contig_high = GRANULEROUNDDOWN(contig_high); } - if (!is_available_memory(md)) + if (!is_memory_available(md)) continue; /* -- cgit v1.2.3 From 52fd91088bcbaea5ab441d09d39c21eb684e54ea Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Mon, 4 Dec 2006 14:58:35 -0800 Subject: [IA64] replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman Signed-off-by: Andrew Morton Signed-off-by: Tony Luck --- arch/ia64/hp/common/sba_iommu.c | 10 +++------- arch/ia64/hp/sim/simserial.c | 3 +-- arch/ia64/kernel/perfmon.c | 3 +-- arch/ia64/pci/pci.c | 3 +-- 4 files changed, 6 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 14691cda05c..ce49fe3a3b5 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -1672,15 +1672,13 @@ ioc_sac_init(struct ioc *ioc) * SAC (single address cycle) addressable, so allocate a * pseudo-device to enforce that. */ - sac = kmalloc(sizeof(*sac), GFP_KERNEL); + sac = kzalloc(sizeof(*sac), GFP_KERNEL); if (!sac) panic(PFX "Couldn't allocate struct pci_dev"); - memset(sac, 0, sizeof(*sac)); - controller = kmalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc(sizeof(*controller), GFP_KERNEL); if (!controller) panic(PFX "Couldn't allocate struct pci_controller"); - memset(controller, 0, sizeof(*controller)); controller->iommu = ioc; sac->sysdata = controller; @@ -1737,12 +1735,10 @@ ioc_init(u64 hpa, void *handle) struct ioc *ioc; struct ioc_iommu *info; - ioc = kmalloc(sizeof(*ioc), GFP_KERNEL); + ioc = kzalloc(sizeof(*ioc), GFP_KERNEL); if (!ioc) return NULL; - memset(ioc, 0, sizeof(*ioc)); - ioc->next = ioc_list; ioc_list = ioc; diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index b62f0c4d2c7..1f16ebb9a80 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -684,12 +684,11 @@ static int get_async_struct(int line, struct async_struct **ret_info) *ret_info = sstate->info; return 0; } - info = kmalloc(sizeof(struct async_struct), GFP_KERNEL); + info = kzalloc(sizeof(struct async_struct), GFP_KERNEL); if (!info) { sstate->count--; return -ENOMEM; } - memset(info, 0, sizeof(struct async_struct)); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); init_waitqueue_head(&info->delta_msr_wait); diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 3aaede0d698..fa4a1a7eb67 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -853,9 +853,8 @@ pfm_context_alloc(void) * allocate context descriptor * must be able to free with interrupts disabled */ - ctx = kmalloc(sizeof(pfm_context_t), GFP_KERNEL); + ctx = kzalloc(sizeof(pfm_context_t), GFP_KERNEL); if (ctx) { - memset(ctx, 0, sizeof(pfm_context_t)); DPRINT(("alloc ctx @%p\n", ctx)); } return ctx; diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index eb92cef9cd0..474d179966d 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -125,11 +125,10 @@ alloc_pci_controller (int seg) { struct pci_controller *controller; - controller = kmalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc(sizeof(*controller), GFP_KERNEL); if (!controller) return NULL; - memset(controller, 0, sizeof(*controller)); controller->segment = seg; controller->node = -1; return controller; -- cgit v1.2.3 From b2eba6bb44300b46cdd2e5d0b19d5f4bd7d001ac Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Dec 2006 20:28:23 +0100 Subject: [ARM] 3998/1: VR1000: LED platform devices Support for the GPIO attached LEDs on the VR1000 Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-vr1000.c | 50 ++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index a0d7692cdb2..e2eda3937ab 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -41,6 +41,7 @@ #include #include +#include #include "clock.h" #include "devs.h" @@ -313,6 +314,50 @@ static struct platform_device vr1000_dm9k1 = { } }; +/* LEDS */ + +static struct s3c24xx_led_platdata vr1000_led1_pdata = { + .name = "led1", + .gpio = S3C2410_GPB0, + .def_trigger = "", +}; + +static struct s3c24xx_led_platdata vr1000_led2_pdata = { + .name = "led2", + .gpio = S3C2410_GPB1, + .def_trigger = "", +}; + +static struct s3c24xx_led_platdata vr1000_led3_pdata = { + .name = "led3", + .gpio = S3C2410_GPB2, + .def_trigger = "", +}; + +static struct platform_device vr1000_led1 = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &vr1000_led1_pdata, + }, +}; + +static struct platform_device vr1000_led2 = { + .name = "s3c24xx_led", + .id = 2, + .dev = { + .platform_data = &vr1000_led2_pdata, + }, +}; + +static struct platform_device vr1000_led3 = { + .name = "s3c24xx_led", + .id = 1, + .dev = { + .platform_data = &vr1000_led3_pdata, + }, +}; + /* devices for this board */ static struct platform_device *vr1000_devices[] __initdata = { @@ -325,7 +370,10 @@ static struct platform_device *vr1000_devices[] __initdata = { &serial_device, &vr1000_nor, &vr1000_dm9k0, - &vr1000_dm9k1 + &vr1000_dm9k1, + &vr1000_led1, + &vr1000_led2, + &vr1000_led3, }; static struct clk *vr1000_clocks[] = { -- cgit v1.2.3 From bbf6f2809dbadc2bacfd73a052d8b0893dbf1762 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Dec 2006 20:47:58 +0100 Subject: [ARM] 3999/1: RX3715: suspend to RAM support The RX3715 is similar to the H1940 in the way that suspend to RAM works, so we can use most of the extant support for the H1940 with only a few modifictions Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Kconfig | 8 ++++++++ arch/arm/mach-s3c2410/Makefile | 3 ++- arch/arm/mach-s3c2410/mach-rx3715.c | 3 +++ arch/arm/mach-s3c2410/s3c2410-pm.c | 16 ++++++++++++++++ arch/arm/mm/mmu.c | 4 +++- 5 files changed, 32 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 63965c78de8..08b2f300eb7 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -41,9 +41,16 @@ config BAST_PC104_IRQ Say Y here to enable the PC104 IRQ routing on the Simtec BAST (EB2410ITX) +config PM_H1940 + bool + depends on PM + help + Internal node for H1940 and related PM + config ARCH_H1940 bool "IPAQ H1940" select CPU_S3C2410 + select PM_H1940 help Say Y here if you are using the HP IPAQ H1940 @@ -115,6 +122,7 @@ config MACH_VR1000 config MACH_RX3715 bool "HP iPAQ rx3715" select CPU_S3C2440 + select PM_H1940 help Say Y here if you are using the HP iPAQ rx3715. diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 0cd71dfec44..27663e28cc8 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -31,6 +31,7 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o obj-$(CONFIG_PM) += pm.o sleep.o obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o +obj-$(CONFIG_PM_H1940) += pm-h1940.o # S3C2412 support obj-$(CONFIG_CPU_S3C2412) += s3c2412.o @@ -77,7 +78,7 @@ obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o -obj-$(CONFIG_ARCH_H1940) += mach-h1940.o pm-h1940.o +obj-$(CONFIG_ARCH_H1940) += mach-h1940.o obj-$(CONFIG_MACH_N30) += mach-n30.o obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 23d7c052013..ecbcdf79d73 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -42,6 +42,7 @@ #include #include +#include #include #include @@ -224,7 +225,9 @@ static void __init rx3715_init_irq(void) static void __init rx3715_init_machine(void) { + memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); s3c2410_pm_init(); + s3c24xx_fb_set_platdata(&rx3715_lcdcfg); } diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c index 9cd0c104f1c..77c6814c0f0 100644 --- a/arch/arm/mach-s3c2410/s3c2410-pm.c +++ b/arch/arm/mach-s3c2410/s3c2410-pm.c @@ -66,6 +66,22 @@ static void s3c2410_pm_prepare(void) __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); } + /* the RX3715 uses similar code and the same H1940 and the + * same offsets for resume and checksum pointers */ + + if (machine_is_rx3715()) { + void *base = phys_to_virt(H1940_SUSPEND_CHECK); + unsigned long ptr; + unsigned long calc = 0; + + /* generate check for the bootloader to check on resume */ + + for (ptr = 0; ptr < 0x40000; ptr += 0x4) + calc += __raw_readl(base+ptr); + + __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM)); + } + if ( machine_is_aml_m5900() ) s3c2410_gpio_setpin(S3C2410_GPF2, 1); diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index f2d0d6f7897..b7f194af20b 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -619,7 +619,9 @@ void __init reserve_node_zero(pg_data_t *pgdat) if (machine_is_p720t()) res_size = 0x00014000; - if (machine_is_h1940()) { + /* H1940 and RX3715 need to reserve this for suspend */ + + if (machine_is_h1940() || machine_is_rx3715()) { reserve_bootmem_node(pgdat, 0x30003000, 0x1000); reserve_bootmem_node(pgdat, 0x30081000, 0x1000); } -- cgit v1.2.3 From ca7aa4de81178babca16df67a7b72a063a7c6891 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Dec 2006 20:49:01 +0100 Subject: [ARM] 4000/1: Osiris: add third serial port in Add the mapping for the third S3C2440 serial port into the default serial devices for the Osiris. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/mach-osiris.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2410/mach-osiris.c index e193ba69e65..a4ab144e729 100644 --- a/arch/arm/mach-s3c2410/mach-osiris.c +++ b/arch/arm/mach-s3c2410/mach-osiris.c @@ -114,6 +114,15 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { .clocks = osiris_serial_clocks, .clocks_size = ARRAY_SIZE(osiris_serial_clocks), }, + [2] = { + .hwport = 2, + .flags = 0, + .ucon = UCON, + .ulcon = ULCON, + .ufcon = UFCON, + .clocks = osiris_serial_clocks, + .clocks_size = ARRAY_SIZE(osiris_serial_clocks), + } }; /* NAND Flash on Osiris board */ -- cgit v1.2.3 From 7174d852603ced7a161f47c6e3958073706114a9 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 7 Dec 2006 19:09:20 +0100 Subject: [ARM] 3983/2: remove unused argument to __bug() It appears that include/asm-arm/bug.h requires include/linux/stddef.h for the definition of NULL. It seems that stddef.h was always included indirectly in most cases, and that issue was properly fixed a while ago. Then commit 5047f09b56d0bc3c21aec9cb16de60283da645c6 incorrectly reverted change from commit ff10952a547dad934d9ed9afc5cf579ed1ccb53a (bad dwmw2) and the problem recently resurfaced. Because the third argument to __bug() is never used anyway, RMK suggested getting rid of it entirely instead of readding #include which this patch does. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index bede380c07a..042a12982e9 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -631,12 +631,9 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) notify_die("unknown data abort code", regs, &info, instr, 0); } -void __attribute__((noreturn)) __bug(const char *file, int line, void *data) +void __attribute__((noreturn)) __bug(const char *file, int line) { - printk(KERN_CRIT"kernel BUG at %s:%d!", file, line); - if (data) - printk(" - extra data = %p", data); - printk("\n"); + printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line); *(int *)0 = 0; /* Avoid "noreturn function does return" */ -- cgit v1.2.3 From d4f3e084adf5414539ebb01848b851fe0f888084 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 7 Dec 2006 23:59:05 +0100 Subject: [ARM] 4002/1: S3C24XX: leave parent IRQs unmasked Do not bother masking/unmasking the parent IRQ for the mulitplexed EINT irqs, as masking the leaf seems to be fine. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/irq.c | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index e7d2ad96ae6..3c0ed7871c5 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -206,18 +206,6 @@ s3c_irqext_mask(unsigned int irqno) mask = __raw_readl(S3C24XX_EINTMASK); mask |= ( 1UL << irqno); __raw_writel(mask, S3C24XX_EINTMASK); - - if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { - /* check to see if all need masking */ - - if ((mask & (0xf << 4)) == (0xf << 4)) { - /* all masked, mask the parent */ - s3c_irq_mask(IRQ_EINT4t7); - } - } else { - /* todo: the same check as above for the rest of the irq regs...*/ - - } } static void @@ -229,7 +217,6 @@ s3c_irqext_ack(unsigned int irqno) bit = 1UL << (irqno - EXTINT_OFF); - mask = __raw_readl(S3C24XX_EINTMASK); __raw_writel(bit, S3C24XX_EINTPEND); @@ -258,8 +245,6 @@ s3c_irqext_unmask(unsigned int irqno) mask = __raw_readl(S3C24XX_EINTMASK); mask &= ~( 1UL << irqno); __raw_writel(mask, S3C24XX_EINTMASK); - - s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); } int -- cgit v1.2.3 From a081e126e12f78651499ba0f9944a7df1e9b06b6 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Tue, 5 Dec 2006 15:54:14 +1100 Subject: [POWERPC] Fix cell pmu initialisation Make sure that the pmu is not initialised unless we are running on a cell. Also make the init routine static. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/pmu.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c index 99c612025e8..d04ae1671e6 100644 --- a/arch/powerpc/platforms/cell/pmu.c +++ b/arch/powerpc/platforms/cell/pmu.c @@ -382,11 +382,14 @@ static irqreturn_t cbe_pm_irq(int irq, void *dev_id) return IRQ_HANDLED; } -int __init cbe_init_pm_irq(void) +static int __init cbe_init_pm_irq(void) { unsigned int irq; int rc, node; + if (!machine_is(cell)) + return 0; + for_each_node(node) { irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | (node << IIC_IRQ_NODE_SHIFT)); -- cgit v1.2.3 From 0332c2d447a7a20a4d744ba3814a349d0c1c6405 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 5 Dec 2006 17:52:36 +1100 Subject: [POWERPC] Move rtas_stop_self() into platforms/pseries/hotplug-cpu.c As the first step in consolidating the pseries hotplug cpu code, create platforms/pseries/hotplug-cpu.c and move rtas_stop_self() into it. Do the rtas token initialisation in a new initcall, rather than rtas_initialize(). Signed-off-by: Michael Ellerman Acked-by: Linas Vepstas Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/rtas.c | 29 -------------- arch/powerpc/platforms/pseries/Makefile | 2 + arch/powerpc/platforms/pseries/hotplug-cpu.c | 58 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 29 deletions(-) create mode 100644 arch/powerpc/platforms/pseries/hotplug-cpu.c (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 387ed0d9ad6..952f4c2fc1e 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -810,32 +810,6 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) return 0; } -#ifdef CONFIG_HOTPLUG_CPU -/* This version can't take the spinlock, because it never returns */ -static struct rtas_args rtas_stop_self_args = { - /* The token is initialized for real in setup_system() */ - .token = RTAS_UNKNOWN_SERVICE, - .nargs = 0, - .nret = 1, - .rets = &rtas_stop_self_args.args[0], -}; - -void rtas_stop_self(void) -{ - struct rtas_args *rtas_args = &rtas_stop_self_args; - - local_irq_disable(); - - BUG_ON(rtas_args->token == RTAS_UNKNOWN_SERVICE); - - printk("cpu %u (hwid %u) Ready to die...\n", - smp_processor_id(), hard_smp_processor_id()); - enter_rtas(__pa(rtas_args)); - - panic("Alas, I survived.\n"); -} -#endif - /* * Call early during boot, before mem init or bootmem, to retrieve the RTAS * informations from the device-tree and allocate the RMO buffer for userland @@ -880,9 +854,6 @@ void __init rtas_initialize(void) #endif rtas_rmo_buf = lmb_alloc_base(RTAS_RMOBUF_MAX, PAGE_SIZE, rtas_region); -#ifdef CONFIG_HOTPLUG_CPU - rtas_stop_self_args.token = rtas_token("stop-self"); -#endif /* CONFIG_HOTPLUG_CPU */ #ifdef CONFIG_RTAS_ERROR_LOGGING rtas_last_error_token = rtas_token("rtas-last-error"); #endif diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 997243a91be..69590fbf83d 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -10,6 +10,8 @@ obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o +obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o + obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c new file mode 100644 index 00000000000..6e21ebdfcef --- /dev/null +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -0,0 +1,58 @@ +/* + * pseries CPU Hotplug infrastructure. + * + * Split out from arch/powerpc/kernel/rtas.c + * + * Peter Bergner, IBM March 2001. + * Copyright (C) 2001 IBM. + * + * Copyright (C) 2006 Michael Ellerman, IBM Corporation + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xics.h" + +/* This version can't take the spinlock, because it never returns */ +static struct rtas_args rtas_stop_self_args = { + .token = RTAS_UNKNOWN_SERVICE, + .nargs = 0, + .nret = 1, + .rets = &rtas_stop_self_args.args[0], +}; + +void rtas_stop_self(void) +{ + struct rtas_args *args = &rtas_stop_self_args; + + local_irq_disable(); + + BUG_ON(args->token == RTAS_UNKNOWN_SERVICE); + + printk("cpu %u (hwid %u) Ready to die...\n", + smp_processor_id(), hard_smp_processor_id()); + enter_rtas(__pa(args)); + + panic("Alas, I survived.\n"); +} + +static int __init pseries_cpu_hotplug_init(void) +{ + rtas_stop_self_args.token = rtas_token("stop-self"); + + return 0; +} +arch_initcall(pseries_cpu_hotplug_init); -- cgit v1.2.3 From 04da6af960194ecdee4c29cd3f86e766903418ca Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 5 Dec 2006 17:52:37 +1100 Subject: [POWERPC] Move pSeries_mach_cpu_die() into platforms/pseries/hotplug-cpu.c Move pSeries_mach_cpu_die() into platforms/pseries/hotplug-cpu.c, this allows rtas_stop_self() to be static so remove the prototype. Wire up pSeries_mach_cpu_die() in the initcall, rather than statically in setup.c, the initcall will still run prior to the cpu hotplug code being callable, so there should be no change in behaviour. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 18 ++++++++++++++++-- arch/powerpc/platforms/pseries/setup.c | 16 ---------------- 2 files changed, 16 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 6e21ebdfcef..9e9b6b159fa 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -1,7 +1,8 @@ /* * pseries CPU Hotplug infrastructure. * - * Split out from arch/powerpc/kernel/rtas.c + * Split out from arch/powerpc/platforms/pseries/setup.c and + * arch/powerpc/kernel/rtas.c * * Peter Bergner, IBM March 2001. * Copyright (C) 2001 IBM. @@ -34,7 +35,7 @@ static struct rtas_args rtas_stop_self_args = { .rets = &rtas_stop_self_args.args[0], }; -void rtas_stop_self(void) +static void rtas_stop_self(void) { struct rtas_args *args = &rtas_stop_self_args; @@ -49,10 +50,23 @@ void rtas_stop_self(void) panic("Alas, I survived.\n"); } +static void pSeries_mach_cpu_die(void) +{ + local_irq_disable(); + idle_task_exit(); + xics_teardown_cpu(0); + rtas_stop_self(); + /* Should never get here... */ + BUG(); + for(;;); +} + static int __init pseries_cpu_hotplug_init(void) { rtas_stop_self_args.token = rtas_token("stop-self"); + ppc_md.cpu_die = pSeries_mach_cpu_die; + return 0; } arch_initcall(pseries_cpu_hotplug_init); diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 0dc2548ca9b..6090d753c44 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -347,21 +347,6 @@ static int __init pSeries_init_panel(void) } arch_initcall(pSeries_init_panel); -#ifdef CONFIG_HOTPLUG_CPU -static void pSeries_mach_cpu_die(void) -{ - local_irq_disable(); - idle_task_exit(); - xics_teardown_cpu(0); - rtas_stop_self(); - /* Should never get here... */ - BUG(); - for(;;); -} -#else -#define pSeries_mach_cpu_die NULL -#endif - static int pseries_set_dabr(unsigned long dabr) { return plpar_hcall_norets(H_SET_DABR, dabr); @@ -561,7 +546,6 @@ define_machine(pseries) { .power_off = rtas_power_off, .halt = rtas_halt, .panic = rtas_os_term, - .cpu_die = pSeries_mach_cpu_die, .get_boot_time = rtas_get_boot_time, .get_rtc_time = rtas_get_rtc_time, .set_rtc_time = rtas_set_rtc_time, -- cgit v1.2.3 From 413f7c405a342b0b9370ea7a652b9f0270183bf3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 5 Dec 2006 17:52:38 +1100 Subject: [POWERPC] Move the rest of the hotplug cpu code into platforms/pseries/hotplug-cpu.c Move the rest of the hotplug cpu code from platforms/pseries/smp.c into platforms/pseries/hotplug-cpu.c. Wire up the smp_ops callbacks and the notifier in the hotplug cpu initcall, rather than in smp_init_pseries(). No change in behaviour. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 201 ++++++++++++++++++++++++++- arch/powerpc/platforms/pseries/smp.c | 200 -------------------------- 2 files changed, 199 insertions(+), 202 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9e9b6b159fa..12864d75126 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -1,11 +1,14 @@ /* * pseries CPU Hotplug infrastructure. * - * Split out from arch/powerpc/platforms/pseries/setup.c and - * arch/powerpc/kernel/rtas.c + * Split out from arch/powerpc/platforms/pseries/setup.c + * arch/powerpc/kernel/rtas.c, and arch/powerpc/platforms/pseries/smp.c * * Peter Bergner, IBM March 2001. * Copyright (C) 2001 IBM. + * Dave Engebretsen, Peter Bergner, and + * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com + * Plus various changes from other IBM teams... * * Copyright (C) 2006 Michael Ellerman, IBM Corporation * @@ -61,12 +64,206 @@ static void pSeries_mach_cpu_die(void) for(;;); } +/* Get state of physical CPU. + * Return codes: + * 0 - The processor is in the RTAS stopped state + * 1 - stop-self is in progress + * 2 - The processor is not in the RTAS stopped state + * -1 - Hardware Error + * -2 - Hardware Busy, Try again later. + */ +static int query_cpu_stopped(unsigned int pcpu) +{ + int cpu_status; + int status, qcss_tok; + + qcss_tok = rtas_token("query-cpu-stopped-state"); + if (qcss_tok == RTAS_UNKNOWN_SERVICE) + return -1; + status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); + if (status != 0) { + printk(KERN_ERR + "RTAS query-cpu-stopped-state failed: %i\n", status); + return status; + } + + return cpu_status; +} + +static int pSeries_cpu_disable(void) +{ + int cpu = smp_processor_id(); + + cpu_clear(cpu, cpu_online_map); + vdso_data->processorCount--; + + /*fix boot_cpuid here*/ + if (cpu == boot_cpuid) + boot_cpuid = any_online_cpu(cpu_online_map); + + /* FIXME: abstract this to not be platform specific later on */ + xics_migrate_irqs_away(); + return 0; +} + +static void pSeries_cpu_die(unsigned int cpu) +{ + int tries; + int cpu_status; + unsigned int pcpu = get_hard_smp_processor_id(cpu); + + for (tries = 0; tries < 25; tries++) { + cpu_status = query_cpu_stopped(pcpu); + if (cpu_status == 0 || cpu_status == -1) + break; + msleep(200); + } + if (cpu_status != 0) { + printk("Querying DEAD? cpu %i (%i) shows %i\n", + cpu, pcpu, cpu_status); + } + + /* Isolation and deallocation are definatly done by + * drslot_chrp_cpu. If they were not they would be + * done here. Change isolate state to Isolate and + * change allocation-state to Unusable. + */ + paca[cpu].cpu_start = 0; +} + +/* + * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle + * here is that a cpu device node may represent up to two logical cpus + * in the SMT case. We must honor the assumption in other code that + * the logical ids for sibling SMT threads x and y are adjacent, such + * that x^1 == y and y^1 == x. + */ +static int pSeries_add_processor(struct device_node *np) +{ + unsigned int cpu; + cpumask_t candidate_map, tmp = CPU_MASK_NONE; + int err = -ENOSPC, len, nthreads, i; + const u32 *intserv; + + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return 0; + + nthreads = len / sizeof(u32); + for (i = 0; i < nthreads; i++) + cpu_set(i, tmp); + + lock_cpu_hotplug(); + + BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); + + /* Get a bitmap of unoccupied slots. */ + cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); + if (cpus_empty(candidate_map)) { + /* If we get here, it most likely means that NR_CPUS is + * less than the partition's max processors setting. + */ + printk(KERN_ERR "Cannot add cpu %s; this system configuration" + " supports %d logical cpus.\n", np->full_name, + cpus_weight(cpu_possible_map)); + goto out_unlock; + } + + while (!cpus_empty(tmp)) + if (cpus_subset(tmp, candidate_map)) + /* Found a range where we can insert the new cpu(s) */ + break; + else + cpus_shift_left(tmp, tmp, nthreads); + + if (cpus_empty(tmp)) { + printk(KERN_ERR "Unable to find space in cpu_present_map for" + " processor %s with %d thread(s)\n", np->name, + nthreads); + goto out_unlock; + } + + for_each_cpu_mask(cpu, tmp) { + BUG_ON(cpu_isset(cpu, cpu_present_map)); + cpu_set(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, *intserv++); + } + err = 0; +out_unlock: + unlock_cpu_hotplug(); + return err; +} + +/* + * Update the present map for a cpu node which is going away, and set + * the hard id in the paca(s) to -1 to be consistent with boot time + * convention for non-present cpus. + */ +static void pSeries_remove_processor(struct device_node *np) +{ + unsigned int cpu; + int len, nthreads, i; + const u32 *intserv; + + intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); + if (!intserv) + return; + + nthreads = len / sizeof(u32); + + lock_cpu_hotplug(); + for (i = 0; i < nthreads; i++) { + for_each_present_cpu(cpu) { + if (get_hard_smp_processor_id(cpu) != intserv[i]) + continue; + BUG_ON(cpu_online(cpu)); + cpu_clear(cpu, cpu_present_map); + set_hard_smp_processor_id(cpu, -1); + break; + } + if (cpu == NR_CPUS) + printk(KERN_WARNING "Could not find cpu to remove " + "with physical id 0x%x\n", intserv[i]); + } + unlock_cpu_hotplug(); +} + +static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node) +{ + int err = NOTIFY_OK; + + switch (action) { + case PSERIES_RECONFIG_ADD: + if (pSeries_add_processor(node)) + err = NOTIFY_BAD; + break; + case PSERIES_RECONFIG_REMOVE: + pSeries_remove_processor(node); + break; + default: + err = NOTIFY_DONE; + break; + } + return err; +} + +static struct notifier_block pSeries_smp_nb = { + .notifier_call = pSeries_smp_notifier, +}; + static int __init pseries_cpu_hotplug_init(void) { rtas_stop_self_args.token = rtas_token("stop-self"); ppc_md.cpu_die = pSeries_mach_cpu_die; + smp_ops->cpu_disable = pSeries_cpu_disable; + smp_ops->cpu_die = pSeries_cpu_die; + + /* Processors can be added/removed only on LPAR */ + if (firmware_has_feature(FW_FEATURE_LPAR)) + pSeries_reconfig_notifier_register(&pSeries_smp_nb); + return 0; } arch_initcall(pseries_cpu_hotplug_init); diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index c6624b8a0e7..4408518eaeb 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c @@ -64,197 +64,6 @@ static cpumask_t of_spin_map; extern void generic_secondary_smp_init(unsigned long); -#ifdef CONFIG_HOTPLUG_CPU - -/* Get state of physical CPU. - * Return codes: - * 0 - The processor is in the RTAS stopped state - * 1 - stop-self is in progress - * 2 - The processor is not in the RTAS stopped state - * -1 - Hardware Error - * -2 - Hardware Busy, Try again later. - */ -static int query_cpu_stopped(unsigned int pcpu) -{ - int cpu_status; - int status, qcss_tok; - - qcss_tok = rtas_token("query-cpu-stopped-state"); - if (qcss_tok == RTAS_UNKNOWN_SERVICE) - return -1; - status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); - if (status != 0) { - printk(KERN_ERR - "RTAS query-cpu-stopped-state failed: %i\n", status); - return status; - } - - return cpu_status; -} - -static int pSeries_cpu_disable(void) -{ - int cpu = smp_processor_id(); - - cpu_clear(cpu, cpu_online_map); - vdso_data->processorCount--; - - /*fix boot_cpuid here*/ - if (cpu == boot_cpuid) - boot_cpuid = any_online_cpu(cpu_online_map); - - /* FIXME: abstract this to not be platform specific later on */ - xics_migrate_irqs_away(); - return 0; -} - -static void pSeries_cpu_die(unsigned int cpu) -{ - int tries; - int cpu_status; - unsigned int pcpu = get_hard_smp_processor_id(cpu); - - for (tries = 0; tries < 25; tries++) { - cpu_status = query_cpu_stopped(pcpu); - if (cpu_status == 0 || cpu_status == -1) - break; - msleep(200); - } - if (cpu_status != 0) { - printk("Querying DEAD? cpu %i (%i) shows %i\n", - cpu, pcpu, cpu_status); - } - - /* Isolation and deallocation are definatly done by - * drslot_chrp_cpu. If they were not they would be - * done here. Change isolate state to Isolate and - * change allocation-state to Unusable. - */ - paca[cpu].cpu_start = 0; -} - -/* - * Update cpu_present_map and paca(s) for a new cpu node. The wrinkle - * here is that a cpu device node may represent up to two logical cpus - * in the SMT case. We must honor the assumption in other code that - * the logical ids for sibling SMT threads x and y are adjacent, such - * that x^1 == y and y^1 == x. - */ -static int pSeries_add_processor(struct device_node *np) -{ - unsigned int cpu; - cpumask_t candidate_map, tmp = CPU_MASK_NONE; - int err = -ENOSPC, len, nthreads, i; - const u32 *intserv; - - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return 0; - - nthreads = len / sizeof(u32); - for (i = 0; i < nthreads; i++) - cpu_set(i, tmp); - - lock_cpu_hotplug(); - - BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map)); - - /* Get a bitmap of unoccupied slots. */ - cpus_xor(candidate_map, cpu_possible_map, cpu_present_map); - if (cpus_empty(candidate_map)) { - /* If we get here, it most likely means that NR_CPUS is - * less than the partition's max processors setting. - */ - printk(KERN_ERR "Cannot add cpu %s; this system configuration" - " supports %d logical cpus.\n", np->full_name, - cpus_weight(cpu_possible_map)); - goto out_unlock; - } - - while (!cpus_empty(tmp)) - if (cpus_subset(tmp, candidate_map)) - /* Found a range where we can insert the new cpu(s) */ - break; - else - cpus_shift_left(tmp, tmp, nthreads); - - if (cpus_empty(tmp)) { - printk(KERN_ERR "Unable to find space in cpu_present_map for" - " processor %s with %d thread(s)\n", np->name, - nthreads); - goto out_unlock; - } - - for_each_cpu_mask(cpu, tmp) { - BUG_ON(cpu_isset(cpu, cpu_present_map)); - cpu_set(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, *intserv++); - } - err = 0; -out_unlock: - unlock_cpu_hotplug(); - return err; -} - -/* - * Update the present map for a cpu node which is going away, and set - * the hard id in the paca(s) to -1 to be consistent with boot time - * convention for non-present cpus. - */ -static void pSeries_remove_processor(struct device_node *np) -{ - unsigned int cpu; - int len, nthreads, i; - const u32 *intserv; - - intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len); - if (!intserv) - return; - - nthreads = len / sizeof(u32); - - lock_cpu_hotplug(); - for (i = 0; i < nthreads; i++) { - for_each_present_cpu(cpu) { - if (get_hard_smp_processor_id(cpu) != intserv[i]) - continue; - BUG_ON(cpu_online(cpu)); - cpu_clear(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, -1); - break; - } - if (cpu == NR_CPUS) - printk(KERN_WARNING "Could not find cpu to remove " - "with physical id 0x%x\n", intserv[i]); - } - unlock_cpu_hotplug(); -} - -static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node) -{ - int err = NOTIFY_OK; - - switch (action) { - case PSERIES_RECONFIG_ADD: - if (pSeries_add_processor(node)) - err = NOTIFY_BAD; - break; - case PSERIES_RECONFIG_REMOVE: - pSeries_remove_processor(node); - break; - default: - err = NOTIFY_DONE; - break; - } - return err; -} - -static struct notifier_block pSeries_smp_nb = { - .notifier_call = pSeries_smp_notifier, -}; - -#endif /* CONFIG_HOTPLUG_CPU */ - /** * smp_startup_cpu() - start the given cpu * @@ -422,15 +231,6 @@ static void __init smp_init_pseries(void) DBG(" -> smp_init_pSeries()\n"); -#ifdef CONFIG_HOTPLUG_CPU - smp_ops->cpu_disable = pSeries_cpu_disable; - smp_ops->cpu_die = pSeries_cpu_die; - - /* Processors can be added/removed only on LPAR */ - if (firmware_has_feature(FW_FEATURE_LPAR)) - pSeries_reconfig_notifier_register(&pSeries_smp_nb); -#endif - /* Mark threads which are still spinning in hold loops. */ if (cpu_has_feature(CPU_FTR_SMT)) { for_each_present_cpu(i) { -- cgit v1.2.3 From 674fa677c01ad0b90237f5cddc8d68502fea5156 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 5 Dec 2006 17:52:38 +1100 Subject: [POWERPC] Only enable cpu hotplug via RTAS if the required firmware support is found To support cpu hotplug on pseries we require two RTAS tokens. The cpu hotplug machinery should only be wired up if these tokens are found in the device tree. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 12864d75126..e78e8ac9555 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -64,6 +64,8 @@ static void pSeries_mach_cpu_die(void) for(;;); } +static int qcss_tok; /* query-cpu-stopped-state token */ + /* Get state of physical CPU. * Return codes: * 0 - The processor is in the RTAS stopped state @@ -74,12 +76,8 @@ static void pSeries_mach_cpu_die(void) */ static int query_cpu_stopped(unsigned int pcpu) { - int cpu_status; - int status, qcss_tok; + int cpu_status, status; - qcss_tok = rtas_token("query-cpu-stopped-state"); - if (qcss_tok == RTAS_UNKNOWN_SERVICE) - return -1; status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu); if (status != 0) { printk(KERN_ERR @@ -254,9 +252,16 @@ static struct notifier_block pSeries_smp_nb = { static int __init pseries_cpu_hotplug_init(void) { rtas_stop_self_args.token = rtas_token("stop-self"); + qcss_tok = rtas_token("query-cpu-stopped-state"); - ppc_md.cpu_die = pSeries_mach_cpu_die; + if (rtas_stop_self_args.token == RTAS_UNKNOWN_SERVICE || + qcss_tok == RTAS_UNKNOWN_SERVICE) { + printk(KERN_INFO "CPU Hotplug not supported by firmware " + "- disabling.\n"); + return 0; + } + ppc_md.cpu_die = pSeries_mach_cpu_die; smp_ops->cpu_disable = pSeries_cpu_disable; smp_ops->cpu_die = pSeries_cpu_die; -- cgit v1.2.3 From 06ba30b6bfb30c84b70fed681b8c920dbff5d5a4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 5 Dec 2006 17:52:39 +1100 Subject: [POWERPC] Cleanup pass over platforms/pseries/hotplug-cpu.c Purely cosmetic. Change pSeries to pseries inline with other parts of the kernel, and fix an overly long line. Signed-off-by: Michael Ellerman Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index e78e8ac9555..f460b9cbfd4 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -53,7 +53,7 @@ static void rtas_stop_self(void) panic("Alas, I survived.\n"); } -static void pSeries_mach_cpu_die(void) +static void pseries_mach_cpu_die(void) { local_irq_disable(); idle_task_exit(); @@ -88,7 +88,7 @@ static int query_cpu_stopped(unsigned int pcpu) return cpu_status; } -static int pSeries_cpu_disable(void) +static int pseries_cpu_disable(void) { int cpu = smp_processor_id(); @@ -104,7 +104,7 @@ static int pSeries_cpu_disable(void) return 0; } -static void pSeries_cpu_die(unsigned int cpu) +static void pseries_cpu_die(unsigned int cpu) { int tries; int cpu_status; @@ -136,7 +136,7 @@ static void pSeries_cpu_die(unsigned int cpu) * the logical ids for sibling SMT threads x and y are adjacent, such * that x^1 == y and y^1 == x. */ -static int pSeries_add_processor(struct device_node *np) +static int pseries_add_processor(struct device_node *np) { unsigned int cpu; cpumask_t candidate_map, tmp = CPU_MASK_NONE; @@ -197,7 +197,7 @@ out_unlock: * the hard id in the paca(s) to -1 to be consistent with boot time * convention for non-present cpus. */ -static void pSeries_remove_processor(struct device_node *np) +static void pseries_remove_processor(struct device_node *np) { unsigned int cpu; int len, nthreads, i; @@ -226,17 +226,18 @@ static void pSeries_remove_processor(struct device_node *np) unlock_cpu_hotplug(); } -static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, void *node) +static int pseries_smp_notifier(struct notifier_block *nb, + unsigned long action, void *node) { int err = NOTIFY_OK; switch (action) { case PSERIES_RECONFIG_ADD: - if (pSeries_add_processor(node)) + if (pseries_add_processor(node)) err = NOTIFY_BAD; break; case PSERIES_RECONFIG_REMOVE: - pSeries_remove_processor(node); + pseries_remove_processor(node); break; default: err = NOTIFY_DONE; @@ -245,8 +246,8 @@ static int pSeries_smp_notifier(struct notifier_block *nb, unsigned long action, return err; } -static struct notifier_block pSeries_smp_nb = { - .notifier_call = pSeries_smp_notifier, +static struct notifier_block pseries_smp_nb = { + .notifier_call = pseries_smp_notifier, }; static int __init pseries_cpu_hotplug_init(void) @@ -261,13 +262,13 @@ static int __init pseries_cpu_hotplug_init(void) return 0; } - ppc_md.cpu_die = pSeries_mach_cpu_die; - smp_ops->cpu_disable = pSeries_cpu_disable; - smp_ops->cpu_die = pSeries_cpu_die; + ppc_md.cpu_die = pseries_mach_cpu_die; + smp_ops->cpu_disable = pseries_cpu_disable; + smp_ops->cpu_die = pseries_cpu_die; /* Processors can be added/removed only on LPAR */ if (firmware_has_feature(FW_FEATURE_LPAR)) - pSeries_reconfig_notifier_register(&pSeries_smp_nb); + pSeries_reconfig_notifier_register(&pseries_smp_nb); return 0; } -- cgit v1.2.3 From 885ed0fb484cc2d0a539558edf47a2a7c4fdd664 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Tue, 5 Dec 2006 15:30:17 -0800 Subject: [POWERPC] powerpc: fix build error in rom.c Add missing include in rom.c. Fixes this build error when CONFIG_MTD=y: arch/powerpc/sysdev/rom.c:26: error: implicit declaration of function of_platform_device_create Signed-off-by: Geoff Levand Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/rom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c index bf5b3f10e6c..c855a3b298a 100644 --- a/arch/powerpc/sysdev/rom.c +++ b/arch/powerpc/sysdev/rom.c @@ -9,6 +9,7 @@ #include #include +#include static int __init powerpc_flash_init(void) { -- cgit v1.2.3 From d0e70341c05f6c31375530e0ae29b319153004a7 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Wed, 6 Dec 2006 12:32:20 -0600 Subject: [POWERPC] EEH recovery tweaks If one attempts to create a device driver recovery sequence that does not depend on a hard reset of the device, but simply just attempts to resume processing, then one discovers that the recovery sequence implemented on powerpc is not quite right. This patch fixes this up. Signed-off-by: Linas Vepstas Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/eeh.c | 1 + arch/powerpc/platforms/pseries/eeh_driver.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 3c2d63ebf78..da6e5362e7c 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c @@ -337,6 +337,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", pdn->eeh_check_count); dump_stack(); + msleep(5000); /* re-read the slot reset state */ if (read_slot_reset_state(pdn, rets) != 0) diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index c2bc9904f1c..cbd6b0711ab 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -170,14 +170,19 @@ static void eeh_report_reset(struct pci_dev *dev, void *userdata) static void eeh_report_resume(struct pci_dev *dev, void *userdata) { struct pci_driver *driver = dev->driver; + struct device_node *dn = pci_device_to_OF_node(dev); dev->error_state = pci_channel_io_normal; if (!driver) return; - if (!driver->err_handler) - return; - if (!driver->err_handler->resume) + + if ((PCI_DN(dn)->eeh_mode) & EEH_MODE_IRQ_DISABLED) { + PCI_DN(dn)->eeh_mode &= ~EEH_MODE_IRQ_DISABLED; + enable_irq(dev->irq); + } + if (!driver->err_handler || + !driver->err_handler->resume) return; driver->err_handler->resume(dev); @@ -407,6 +412,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event) if (rc) result = PCI_ERS_RESULT_NEED_RESET; + else + result = PCI_ERS_RESULT_RECOVERED; } /* If any device has a hard failure, then shut off everything. */ -- cgit v1.2.3 From 2c1d2f34a03ef0a89ff57da18b52fda9e6f09a10 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Wed, 6 Dec 2006 15:16:24 -0600 Subject: [POWERPC] qe_ic: Do a sync when masking interrupts This patch causes a sync do be done after masking a QE interrupt, to ensure that the masking has completed before interrupts are enabled. This allows the masking of the cascade IRQ to be removed without causing spurious interrupts. The mask_and_ack function is also removed and set to the mask function, as the two are identical. Signed-off-by: Scott Wood Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/qe_lib/qe_ic.c | 40 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 30 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c index 6995f51b948..74e48d94f27 100644 --- a/arch/powerpc/sysdev/qe_lib/qe_ic.c +++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c @@ -223,23 +223,15 @@ static void qe_ic_mask_irq(unsigned int virq) qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, temp & ~qe_ic_info[src].mask); - spin_unlock_irqrestore(&qe_ic_lock, flags); -} - -static void qe_ic_mask_irq_and_ack(unsigned int virq) -{ - struct qe_ic *qe_ic = qe_ic_from_irq(virq); - unsigned int src = virq_to_hw(virq); - unsigned long flags; - u32 temp; - - spin_lock_irqsave(&qe_ic_lock, flags); - - temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg); - qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg, - temp & ~qe_ic_info[src].mask); - - /* There is nothing to do for ack here, ack is handled in ISR */ + /* Flush the above write before enabling interrupts; otherwise, + * spurious interrupts will sometimes happen. To be 100% sure + * that the write has reached the device before interrupts are + * enabled, the mask register would have to be read back; however, + * this is not required for correctness, only to avoid wasting + * time on a large number of spurious interrupts. In testing, + * a sync reduced the observed spurious interrupts to zero. + */ + mb(); spin_unlock_irqrestore(&qe_ic_lock, flags); } @@ -248,7 +240,7 @@ static struct irq_chip qe_ic_irq_chip = { .typename = " QEIC ", .unmask = qe_ic_unmask_irq, .mask = qe_ic_mask_irq, - .mask_ack = qe_ic_mask_irq_and_ack, + .mask_ack = qe_ic_mask_irq, }; static int qe_ic_host_match(struct irq_host *h, struct device_node *node) @@ -331,34 +323,22 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic) return irq_linear_revmap(qe_ic->irqhost, irq); } -/* FIXME: We mask all the QE Low interrupts while handling. We should - * let other interrupt come in, but BAD interrupts are generated */ void fastcall qe_ic_cascade_low(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; - struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic); - chip->mask_ack(irq); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); - chip->unmask(irq); } -/* FIXME: We mask all the QE High interrupts while handling. We should - * let other interrupt come in, but BAD interrupts are generated */ void fastcall qe_ic_cascade_high(unsigned int irq, struct irq_desc *desc) { struct qe_ic *qe_ic = desc->handler_data; - struct irq_chip *chip = irq_desc[irq].chip; - unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic); - chip->mask_ack(irq); if (cascade_irq != NO_IRQ) generic_handle_irq(cascade_irq); - chip->unmask(irq); } void __init qe_ic_init(struct device_node *node, unsigned int flags) -- cgit v1.2.3 From 17877116c6b0fa78501526e7ec03cabe967a3a72 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Wed, 6 Dec 2006 18:50:43 -0600 Subject: [POWERPC] maple: Match "pcie" name for CPC945 Some firmwares have "pcie" for the "name" property of the CPC945 PCI Express host bridge. Check for "pcie" in addition to "pci" so we don't miss it. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/maple/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 3a32deda765..3f6a69f6719 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c @@ -562,7 +562,7 @@ void __init maple_pci_init(void) for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) { if (np->name == NULL) continue; - if (strcmp(np->name, "pci") == 0) { + if (!strcmp(np->name, "pci") || !strcmp(np->name, "pcie")) { if (add_bridge(np) == 0) of_node_get(np); } -- cgit v1.2.3 From 9d9d868ecf93b35c3c5b0ea3d639dc85e423eb02 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Wed, 6 Dec 2006 18:50:44 -0600 Subject: [POWERPC] maple: Select PPC_RTAS Some systems supported by the maple platform have RTAS; make PPC_MAPLE select PPC_RTAS. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 291c95ac4b3..f524b3bf68c 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -470,6 +470,7 @@ config PPC_MAPLE select PPC_UDBG_16550 select PPC_970_NAP select PPC_NATIVE + select PPC_RTAS default n help This option enables support for the Maple 970FX Evaluation Board. -- cgit v1.2.3 From f2d6d2d8bb4e9bb4aef225c149e42cac3ac3d4d0 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Wed, 6 Dec 2006 18:50:45 -0600 Subject: [POWERPC] Add rtas_service_present() helper To test for the existence of an RTAS function, we typically do: foo_token = rtas_token("foo"); if (foo_token == RTAS_UNKNOWN_SERVICE) return; Add a rtas_service_present method, which provides a more conventional boolean interface for testing the existence of an RTAS method. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/rtas.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 952f4c2fc1e..76b5d7ebdcc 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -303,6 +303,12 @@ int rtas_token(const char *service) } EXPORT_SYMBOL(rtas_token); +int rtas_service_present(const char *service) +{ + return rtas_token(service) != RTAS_UNKNOWN_SERVICE; +} +EXPORT_SYMBOL(rtas_service_present); + #ifdef CONFIG_RTAS_ERROR_LOGGING /* * Return the firmware-specified size of the error log buffer -- cgit v1.2.3 From 9e254c45fb0385b411ad93960f3838de80895210 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Wed, 6 Dec 2006 18:50:46 -0600 Subject: [POWERPC] maple: Use RTAS for reboot and halt On maple, use the RTAS "system-reboot" and "power-off" methods if they are available. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/maple/setup.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 094989d50ba..f12d5c69e74 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include "maple.h" @@ -166,6 +167,16 @@ struct smp_ops_t maple_smp_ops = { }; #endif /* CONFIG_SMP */ +static void __init maple_use_rtas_reboot_and_halt_if_present(void) +{ + if (rtas_service_present("system-reboot") && + rtas_service_present("power-off")) { + ppc_md.restart = rtas_restart; + ppc_md.power_off = rtas_power_off; + ppc_md.halt = rtas_halt; + } +} + void __init maple_setup_arch(void) { /* init to some ~sane value until calibrate_delay() runs */ @@ -181,6 +192,7 @@ void __init maple_setup_arch(void) #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif + maple_use_rtas_reboot_and_halt_if_present(); printk(KERN_DEBUG "Using native/NAP idle loop\n"); } -- cgit v1.2.3 From 30d368430e71bbeaa52ae978b10b6f5f6267d912 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 7 Dec 2006 16:49:18 +0100 Subject: [POWERPC] of_platform_make_bus_id(): make `magic' int of_platform_make_bus_id(): Kill a compiler warning which is a real bug on PPC64 by changing `magic' to `int'. Signed-off-by: Geert Uytterhoeven Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/of_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index b3189d0161b..3002ea3a61a 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c @@ -169,7 +169,7 @@ static void of_platform_make_bus_id(struct of_device *dev) char *name = dev->dev.bus_id; const u32 *reg; u64 addr; - long magic; + int magic; /* * If it's a DCR based device, use 'd' for native DCRs -- cgit v1.2.3 From 18414ec0b56783f625edb95a9499bcb0ef12d6b8 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Thu, 7 Dec 2006 11:07:32 -0600 Subject: [POWERPC] Remove QE header files from lite5200.c The MPC 5200 does not have a QUICCEngine (QE), so lite5200.c should not include the QE header files. Signed-off-by: Timur Tabi Acked-by: Grant Likely Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/52xx/lite5200.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c index a375c15b431..eaff71e74fb 100644 --- a/arch/powerpc/platforms/52xx/lite5200.c +++ b/arch/powerpc/platforms/52xx/lite5200.c @@ -40,8 +40,6 @@ #include #include #include -#include -#include #include #include -- cgit v1.2.3 From 22b6e590478ae8757f0411cf16a24c25d8dfea86 Mon Sep 17 00:00:00 2001 From: Christian Krafft Date: Thu, 7 Dec 2006 19:01:16 +0100 Subject: [POWERPC] cbe_thermal: Fix initialization of sysfs attribute_group This patch adds NULL to the initialization of the attribute_groups. The spu_attributes and ppe_attributes arrays are arrays of pointers that need to be terminated with a NULL entry. Signed-off-by: Christian Krafft Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/cbe_thermal.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c index 616a0a3fd0e..70e0d968d30 100644 --- a/arch/powerpc/platforms/cell/cbe_thermal.c +++ b/arch/powerpc/platforms/cell/cbe_thermal.c @@ -115,6 +115,7 @@ static struct sysdev_attribute attr_spu_temperature = { static struct attribute *spu_attributes[] = { &attr_spu_temperature.attr, + NULL, }; static struct attribute_group spu_attribute_group = { @@ -135,6 +136,7 @@ static struct sysdev_attribute attr_ppe_temperature1 = { static struct attribute *ppe_attributes[] = { &attr_ppe_temperature0.attr, &attr_ppe_temperature1.attr, + NULL, }; static struct attribute_group ppe_attribute_group = { -- cgit v1.2.3 From f09b5ce0184da6a83bac7fafda4e624629272b37 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 8 Dec 2006 16:57:49 +1100 Subject: [POWERPC] iSeries: head_64.o needs to depend on lparmap.s This dependency was inadvertantly removed in a previous patch (e73aedba562d1e7777287043afb8e46131ed402e). Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 4fe53d08ab8..d2ded19e406 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -77,6 +77,7 @@ endif ifeq ($(CONFIG_PPC_ISERIES),y) extra-y += lparmap.s +$(obj)/head_64.o: $(obj)/lparmap.s AFLAGS_head_64.o += -I$(obj) endif -- cgit v1.2.3 From 396a1a5832ae28ce2c4150f98827873cbef554f5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 8 Dec 2006 17:14:33 +1100 Subject: [POWERPC] Fix mmap of PCI resource with hack for X The powerpc version of pci_resource_to_user() and associated hooks used by /proc/bus/pci and /sys/bus/pci mmap have been broken for some time on machines that don't have a 1:1 mapping of devices (basically on non-PowerMacs) and have PCI devices above 32 bits. This attempts to fix it as well as possible. The rule is supposed to be that pci_resource_to_user() always converts the resources back into a BAR values since that's what the /proc interface was supposed to deal with. However, for X to work on platforms where PCI MMIO is not mapped 1:1, it became a habit of platforms like powerpc to pass "fixed up" values there since X expects to be able to use values from /proc/bus/pci/devices as offsets to mmap of /dev/mem... So we keep that contraption here, causing also /sys/*/resource to expose fully absolute MMIO addresses instead of BAR values, which is ugly, but should still work as long as those are only used to calculate alignment within a page. X is still broken when built 32 bits on machines where PCI MMIO can be above 32-bit space unfortunately. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/pci_32.c | 45 +++++++++++++++++++++++++++++++------------- arch/powerpc/kernel/pci_64.c | 42 ++++++++++++++++++++++++++++++----------- arch/ppc/kernel/pci.c | 41 +++++++++++++++++++++++++++++++--------- 3 files changed, 95 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 2f54cd81dea..ab5887bff02 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -1544,7 +1544,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); @@ -1556,7 +1556,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE; @@ -1624,9 +1626,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), - (unsigned long long)rp->start, prot); - return __pgprot(prot); } @@ -1695,7 +1694,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1808,22 +1807,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = (void __iomem *)_IO_BASE - hose->io_base_virt - + hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } -void __init -pci_init_resource(struct resource *res, unsigned long start, unsigned long end, - int flags, char *name) +void __init pci_init_resource(struct resource *res, resource_size_t start, + resource_size_t end, int flags, char *name) { res->start = start; res->end = end; diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 6fa9a0a5c8d..a6b7692c726 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -682,7 +682,7 @@ int pci_proc_domain(struct pci_bus *bus) * Returns negative error code on failure, zero on success. */ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_host(dev->bus); @@ -694,7 +694,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = (unsigned long)hose->io_base_virt - pci_io_base; @@ -762,9 +764,6 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk(KERN_DEBUG "PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); - return __pgprot(prot); } @@ -832,7 +831,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1333,20 +1332,41 @@ EXPORT_SYMBOL(pci_read_irq_line); void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = pci_io_base - (unsigned long)hose->io_base_virt + - hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - pci_io_base; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 63808e01cb0..5e723c4c257 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -879,7 +879,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); @@ -891,7 +891,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = hose->io_base_virt - ___IO_BASE; @@ -1030,7 +1032,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1132,21 +1134,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } -void __init -pci_init_resource(struct resource *res, unsigned long start, unsigned long end, - int flags, char *name) +void __init pci_init_resource(struct resource *res, resource_size_t start, + resource_size_t end, int flags, char *name) { res->start = start; res->end = end; -- cgit v1.2.3 From 39043a5b3d0b1b92b20209b6d401fb70c17177b4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 8 Dec 2006 02:23:07 -0600 Subject: [POWERPC] of_device_register: propagate device_create_file return code Removed compiler warning about ignoring the return code of device_create_file in of_device_register. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/of_device.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index 8a06724e029..e921514e655 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c @@ -109,9 +109,7 @@ int of_device_register(struct of_device *ofdev) if (rc) return rc; - device_create_file(&ofdev->dev, &dev_attr_devspec); - - return 0; + return device_create_file(&ofdev->dev, &dev_attr_devspec); } void of_device_unregister(struct of_device *ofdev) -- cgit v1.2.3 From aa42c69c67f82e88f0726258efe7306708e1cf14 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Fri, 8 Dec 2006 02:43:30 -0600 Subject: [POWERPC] Add support for FP emulation for the e300c2 core The e300c2 has no FPU. Its MSR[FP] is grounded to zero. If an attempt is made to execute a floating point instruction (including floating-point load, store, or move instructions), the e300c2 takes a floating-point unavailable interrupt. This patch adds support for FP emulation on the e300c2 by declaring a new CPU_FTR_FP_TAKES_FPUNAVAIL, where FP unavail interrupts are intercepted and redirected to the ProgramCheck exception path for correct emulation handling. (If we run out of CPU_FTR bits we could look to reclaim this bit by adding support to test the cpu_user_features for PPC_FEATURE_HAS_FPU instead) It adds a nop to the exception path for 32-bit processors with a FPU. Signed-off-by: Kim Phillips Signed-off-by: Kumar Gala --- arch/powerpc/Kconfig | 2 +- arch/powerpc/kernel/cputable.c | 2 +- arch/powerpc/kernel/head_32.S | 7 +++++++ arch/powerpc/kernel/traps.c | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 291c95ac4b3..0b2d05da89d 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -706,7 +706,7 @@ config FORCE_MAX_ZONEORDER config MATH_EMULATION bool "Math emulation" - depends on 4xx || 8xx || E200 || E500 + depends on 4xx || 8xx || E200 || PPC_83xx || E500 ---help--- Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 9d1614c3ce6..11bfbaf655b 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -833,7 +833,7 @@ static struct cpu_spec cpu_specs[] = { .pvr_mask = 0x7fff0000, .pvr_value = 0x00840000, .cpu_name = "e300c2", - .cpu_features = CPU_FTRS_E300, + .cpu_features = CPU_FTRS_E300C2, .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, .icache_bsize = 32, .dcache_bsize = 32, diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index d88e182e40b..9417cf5b4b7 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -437,6 +437,13 @@ Alignment: /* Floating-point unavailable */ . = 0x800 FPUnavailable: +BEGIN_FTR_SECTION +/* + * Certain Freescale cores don't have a FPU and treat fp instructions + * as a FP Unavailable exception. Redirect to illegal/emulation handling. + */ + b ProgramCheck +END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) EXCEPTION_PROLOG bne load_up_fpu /* if from user, just load it up */ addi r3,r1,STACK_FRAME_OVERHEAD diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 0d4e203fa7a..fde820e52d0 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -782,6 +782,8 @@ void __kprobes program_check_exception(struct pt_regs *regs) unsigned int reason = get_reason(regs); extern int do_mathemu(struct pt_regs *regs); + /* We can now get here via a FP Unavailable exception if the core + * has no FPU, in that case no reason flags will be set */ #ifdef CONFIG_MATH_EMULATION /* (reason & REASON_ILLEGAL) would be the obvious thing here, * but there seems to be a hardware bug on the 405GP (RevD) -- cgit v1.2.3 From a147c5857c0b591b05d787e59b691c3a4f245f83 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 8 Dec 2006 02:34:38 -0600 Subject: [POWERPC] Fix 440SPe CPU table entry The 440SPe CPU table entry was missing the CPU_FTR_NODSISRALIGN and really should have been CPU_FTRS_44X. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/cputable.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 11bfbaf655b..b742013bb9d 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -1136,8 +1136,7 @@ static struct cpu_spec cpu_specs[] = { .pvr_mask = 0xff000fff, .pvr_value = 0x53000890, .cpu_name = "440SPe Rev. A", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, + .cpu_features = CPU_FTRS_44X, .cpu_user_features = COMMON_USER_BOOKE, .icache_bsize = 32, .dcache_bsize = 32, -- cgit v1.2.3 From c3e2a79c0bd3e12b67ce5f11cab10951ae8b7f37 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 13:46:52 +0100 Subject: [AVR32] Portmux API update Rename portmux_set_func to at32_select_periph, add at32_select_gpio and add flags parameter to specify the initial state of the pins. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 144 +++++++++++++++++------------------- arch/avr32/mach-at32ap/pio.c | 85 +++++++++++++++++++-- 2 files changed, 146 insertions(+), 83 deletions(-) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index 7ff6ad8bab5..ada7930d5a4 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -11,6 +11,7 @@ #include +#include #include #include #include @@ -57,6 +58,9 @@ static struct platform_device _name##_id##_device = { \ .num_resources = ARRAY_SIZE(_name##_id##_resource), \ } +#define select_peripheral(pin, periph, flags) \ + at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, flags) + #define DEV_CLK(_name, devname, bus, _index) \ static struct clk devname##_##_name = { \ .name = #_name, \ @@ -67,18 +71,6 @@ static struct clk devname##_##_name = { \ .index = _index, \ } -enum { - PIOA, - PIOB, - PIOC, - PIOD, -}; - -enum { - FUNC_A, - FUNC_B, -}; - unsigned long at32ap7000_osc_rates[3] = { [0] = 32768, /* FIXME: these are ATSTK1002-specific */ @@ -569,26 +561,26 @@ DEV_CLK(usart, atmel_usart3, pba, 6); static inline void configure_usart0_pins(void) { - portmux_set_func(PIOA, 8, FUNC_B); /* RXD */ - portmux_set_func(PIOA, 9, FUNC_B); /* TXD */ + select_peripheral(PA(8), PERIPH_B, 0); /* RXD */ + select_peripheral(PA(9), PERIPH_B, 0); /* TXD */ } static inline void configure_usart1_pins(void) { - portmux_set_func(PIOA, 17, FUNC_A); /* RXD */ - portmux_set_func(PIOA, 18, FUNC_A); /* TXD */ + select_peripheral(PA(17), PERIPH_A, 0); /* RXD */ + select_peripheral(PA(18), PERIPH_A, 0); /* TXD */ } static inline void configure_usart2_pins(void) { - portmux_set_func(PIOB, 26, FUNC_B); /* RXD */ - portmux_set_func(PIOB, 27, FUNC_B); /* TXD */ + select_peripheral(PB(26), PERIPH_B, 0); /* RXD */ + select_peripheral(PB(27), PERIPH_B, 0); /* TXD */ } static inline void configure_usart3_pins(void) { - portmux_set_func(PIOB, 18, FUNC_B); /* RXD */ - portmux_set_func(PIOB, 17, FUNC_B); /* TXD */ + select_peripheral(PB(18), PERIPH_B, 0); /* RXD */ + select_peripheral(PB(17), PERIPH_B, 0); /* TXD */ } static struct platform_device *at32_usarts[4]; @@ -663,27 +655,27 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) case 0: pdev = &macb0_device; - portmux_set_func(PIOC, 3, FUNC_A); /* TXD0 */ - portmux_set_func(PIOC, 4, FUNC_A); /* TXD1 */ - portmux_set_func(PIOC, 7, FUNC_A); /* TXEN */ - portmux_set_func(PIOC, 8, FUNC_A); /* TXCK */ - portmux_set_func(PIOC, 9, FUNC_A); /* RXD0 */ - portmux_set_func(PIOC, 10, FUNC_A); /* RXD1 */ - portmux_set_func(PIOC, 13, FUNC_A); /* RXER */ - portmux_set_func(PIOC, 15, FUNC_A); /* RXDV */ - portmux_set_func(PIOC, 16, FUNC_A); /* MDC */ - portmux_set_func(PIOC, 17, FUNC_A); /* MDIO */ + select_peripheral(PC(3), PERIPH_A, 0); /* TXD0 */ + select_peripheral(PC(4), PERIPH_A, 0); /* TXD1 */ + select_peripheral(PC(7), PERIPH_A, 0); /* TXEN */ + select_peripheral(PC(8), PERIPH_A, 0); /* TXCK */ + select_peripheral(PC(9), PERIPH_A, 0); /* RXD0 */ + select_peripheral(PC(10), PERIPH_A, 0); /* RXD1 */ + select_peripheral(PC(13), PERIPH_A, 0); /* RXER */ + select_peripheral(PC(15), PERIPH_A, 0); /* RXDV */ + select_peripheral(PC(16), PERIPH_A, 0); /* MDC */ + select_peripheral(PC(17), PERIPH_A, 0); /* MDIO */ if (!data->is_rmii) { - portmux_set_func(PIOC, 0, FUNC_A); /* COL */ - portmux_set_func(PIOC, 1, FUNC_A); /* CRS */ - portmux_set_func(PIOC, 2, FUNC_A); /* TXER */ - portmux_set_func(PIOC, 5, FUNC_A); /* TXD2 */ - portmux_set_func(PIOC, 6, FUNC_A); /* TXD3 */ - portmux_set_func(PIOC, 11, FUNC_A); /* RXD2 */ - portmux_set_func(PIOC, 12, FUNC_A); /* RXD3 */ - portmux_set_func(PIOC, 14, FUNC_A); /* RXCK */ - portmux_set_func(PIOC, 18, FUNC_A); /* SPD */ + select_peripheral(PC(0), PERIPH_A, 0); /* COL */ + select_peripheral(PC(1), PERIPH_A, 0); /* CRS */ + select_peripheral(PC(2), PERIPH_A, 0); /* TXER */ + select_peripheral(PC(5), PERIPH_A, 0); /* TXD2 */ + select_peripheral(PC(6), PERIPH_A, 0); /* TXD3 */ + select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */ + select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */ + select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */ + select_peripheral(PC(18), PERIPH_A, 0); /* SPD */ } break; @@ -714,12 +706,12 @@ struct platform_device *__init at32_add_device_spi(unsigned int id) switch (id) { case 0: pdev = &spi0_device; - portmux_set_func(PIOA, 0, FUNC_A); /* MISO */ - portmux_set_func(PIOA, 1, FUNC_A); /* MOSI */ - portmux_set_func(PIOA, 2, FUNC_A); /* SCK */ - portmux_set_func(PIOA, 3, FUNC_A); /* NPCS0 */ - portmux_set_func(PIOA, 4, FUNC_A); /* NPCS1 */ - portmux_set_func(PIOA, 5, FUNC_A); /* NPCS2 */ + select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ + select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ + select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ + select_peripheral(PA(3), PERIPH_A, 0); /* NPCS0 */ + select_peripheral(PA(4), PERIPH_A, 0); /* NPCS1 */ + select_peripheral(PA(5), PERIPH_A, 0); /* NPCS2 */ break; default: @@ -762,37 +754,37 @@ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data) switch (id) { case 0: pdev = &lcdc0_device; - portmux_set_func(PIOC, 19, FUNC_A); /* CC */ - portmux_set_func(PIOC, 20, FUNC_A); /* HSYNC */ - portmux_set_func(PIOC, 21, FUNC_A); /* PCLK */ - portmux_set_func(PIOC, 22, FUNC_A); /* VSYNC */ - portmux_set_func(PIOC, 23, FUNC_A); /* DVAL */ - portmux_set_func(PIOC, 24, FUNC_A); /* MODE */ - portmux_set_func(PIOC, 25, FUNC_A); /* PWR */ - portmux_set_func(PIOC, 26, FUNC_A); /* DATA0 */ - portmux_set_func(PIOC, 27, FUNC_A); /* DATA1 */ - portmux_set_func(PIOC, 28, FUNC_A); /* DATA2 */ - portmux_set_func(PIOC, 29, FUNC_A); /* DATA3 */ - portmux_set_func(PIOC, 30, FUNC_A); /* DATA4 */ - portmux_set_func(PIOC, 31, FUNC_A); /* DATA5 */ - portmux_set_func(PIOD, 0, FUNC_A); /* DATA6 */ - portmux_set_func(PIOD, 1, FUNC_A); /* DATA7 */ - portmux_set_func(PIOD, 2, FUNC_A); /* DATA8 */ - portmux_set_func(PIOD, 3, FUNC_A); /* DATA9 */ - portmux_set_func(PIOD, 4, FUNC_A); /* DATA10 */ - portmux_set_func(PIOD, 5, FUNC_A); /* DATA11 */ - portmux_set_func(PIOD, 6, FUNC_A); /* DATA12 */ - portmux_set_func(PIOD, 7, FUNC_A); /* DATA13 */ - portmux_set_func(PIOD, 8, FUNC_A); /* DATA14 */ - portmux_set_func(PIOD, 9, FUNC_A); /* DATA15 */ - portmux_set_func(PIOD, 10, FUNC_A); /* DATA16 */ - portmux_set_func(PIOD, 11, FUNC_A); /* DATA17 */ - portmux_set_func(PIOD, 12, FUNC_A); /* DATA18 */ - portmux_set_func(PIOD, 13, FUNC_A); /* DATA19 */ - portmux_set_func(PIOD, 14, FUNC_A); /* DATA20 */ - portmux_set_func(PIOD, 15, FUNC_A); /* DATA21 */ - portmux_set_func(PIOD, 16, FUNC_A); /* DATA22 */ - portmux_set_func(PIOD, 17, FUNC_A); /* DATA23 */ + select_peripheral(PC(19), PERIPH_A, 0); /* CC */ + select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ + select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ + select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ + select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ + select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ + select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ + select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ + select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ + select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ + select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ + select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ + select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ + select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ + select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ + select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ + select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ + select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ + select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ + select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ + select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ + select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ + select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ + select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ + select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ + select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ + select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ + select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ + select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ + select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ + select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ clk_set_parent(&lcdc0_pixclk, &pll0); clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0)); diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index d3aabfca859..f1280ed8ed6 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -25,27 +25,98 @@ struct pio_device { void __iomem *regs; const struct platform_device *pdev; struct clk *clk; - u32 alloc_mask; + u32 pinmux_mask; char name[32]; }; static struct pio_device pio_dev[MAX_NR_PIO_DEVICES]; -void portmux_set_func(unsigned int portmux_id, unsigned int pin_id, - unsigned int function_id) +static struct pio_device *gpio_to_pio(unsigned int gpio) { struct pio_device *pio; - u32 mask = 1 << pin_id; + unsigned int index; - BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES); + index = gpio >> 5; + if (index >= MAX_NR_PIO_DEVICES) + return NULL; + pio = &pio_dev[index]; + if (!pio->regs) + return NULL; - pio = &pio_dev[portmux_id]; + return pio; +} + +/* Pin multiplexing API */ + +void __init at32_select_periph(unsigned int pin, unsigned int periph, + unsigned long flags) +{ + struct pio_device *pio; + unsigned int pin_index = pin & 0x1f; + u32 mask = 1 << pin_index; + + pio = gpio_to_pio(pin); + if (unlikely(!pio)) { + printk("pio: invalid pin %u\n", pin); + goto fail; + } - if (function_id) + if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { + printk("%s: pin %u is busy\n", pio->name, pin_index); + goto fail; + } + + pio_writel(pio, PUER, mask); + if (periph) pio_writel(pio, BSR, mask); else pio_writel(pio, ASR, mask); + pio_writel(pio, PDR, mask); + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); + + return; + +fail: + dump_stack(); +} + +void __init at32_select_gpio(unsigned int pin, unsigned long flags) +{ + struct pio_device *pio; + unsigned int pin_index = pin & 0x1f; + u32 mask = 1 << pin_index; + + pio = gpio_to_pio(pin); + if (unlikely(!pio)) { + printk("pio: invalid pin %u\n", pin); + goto fail; + } + + if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) { + printk("%s: pin %u is busy\n", pio->name, pin_index); + goto fail; + } + + pio_writel(pio, PUER, mask); + if (flags & AT32_GPIOF_HIGH) + pio_writel(pio, SODR, mask); + else + pio_writel(pio, CODR, mask); + if (flags & AT32_GPIOF_OUTPUT) + pio_writel(pio, OER, mask); + else + pio_writel(pio, ODR, mask); + + pio_writel(pio, PER, mask); + if (!(flags & AT32_GPIOF_PULLUP)) + pio_writel(pio, PUDR, mask); + + return; + +fail: + dump_stack(); } static int __init pio_probe(struct platform_device *pdev) -- cgit v1.2.3 From cfcb3a89d04144c064023bdc7d8dc600a88cc5c4 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 30 Oct 2006 09:23:12 +0100 Subject: [AVR32] Add macb1 platform_device Add platform_device definition and pio init code for the second ethernet controller in AT32AP7000. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/at32ap7000.c | 38 +++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/at32ap7000.c b/arch/avr32/mach-at32ap/at32ap7000.c index ada7930d5a4..48f4ef38c70 100644 --- a/arch/avr32/mach-at32ap/at32ap7000.c +++ b/arch/avr32/mach-at32ap/at32ap7000.c @@ -646,6 +646,15 @@ DEFINE_DEV_DATA(macb, 0); DEV_CLK(hclk, macb0, hsb, 8); DEV_CLK(pclk, macb0, pbb, 6); +static struct eth_platform_data macb1_data; +static struct resource macb1_resource[] = { + PBMEM(0xfff01c00), + IRQ(26), +}; +DEFINE_DEV_DATA(macb, 1); +DEV_CLK(hclk, macb1, hsb, 9); +DEV_CLK(pclk, macb1, pbb, 7); + struct platform_device *__init at32_add_device_eth(unsigned int id, struct eth_platform_data *data) { @@ -679,6 +688,33 @@ at32_add_device_eth(unsigned int id, struct eth_platform_data *data) } break; + case 1: + pdev = &macb1_device; + + select_peripheral(PD(13), PERIPH_B, 0); /* TXD0 */ + select_peripheral(PD(14), PERIPH_B, 0); /* TXD1 */ + select_peripheral(PD(11), PERIPH_B, 0); /* TXEN */ + select_peripheral(PD(12), PERIPH_B, 0); /* TXCK */ + select_peripheral(PD(10), PERIPH_B, 0); /* RXD0 */ + select_peripheral(PD(6), PERIPH_B, 0); /* RXD1 */ + select_peripheral(PD(5), PERIPH_B, 0); /* RXER */ + select_peripheral(PD(4), PERIPH_B, 0); /* RXDV */ + select_peripheral(PD(3), PERIPH_B, 0); /* MDC */ + select_peripheral(PD(2), PERIPH_B, 0); /* MDIO */ + + if (!data->is_rmii) { + select_peripheral(PC(19), PERIPH_B, 0); /* COL */ + select_peripheral(PC(23), PERIPH_B, 0); /* CRS */ + select_peripheral(PC(26), PERIPH_B, 0); /* TXER */ + select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */ + select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */ + select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */ + select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */ + select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */ + select_peripheral(PD(15), PERIPH_B, 0); /* SPD */ + } + break; + default: return NULL; } @@ -830,6 +866,8 @@ struct clk *at32_clock_list[] = { &atmel_usart3_usart, &macb0_hclk, &macb0_pclk, + &macb1_hclk, + &macb1_pclk, &spi0_mck, &lcdc0_hclk, &lcdc0_pixclk, -- cgit v1.2.3 From a6f92f3dc8e53185bae50d44b5042b9cddf7f475 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 13:58:27 +0100 Subject: [AVR32] Move ethernet tag parsing to board-specific code By moving the ethernet tag parsing to the board-specific code we avoid the issue of figuring out which device we're supposed to attach the information to. The board specific code knows this because it's where the actual devices are instantiated. Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/atstk1000/atstk1002.c | 31 +++++++++++++++++++++++-------- arch/avr32/kernel/setup.c | 24 ------------------------ 2 files changed, 23 insertions(+), 32 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index cced73c5811..f65865cd9c3 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -8,19 +8,32 @@ * published by the Free Software Foundation. */ #include +#include +#include +#include +#include #include #include -struct eth_platform_data __initdata eth0_data = { - .valid = 1, - .mii_phy_addr = 0x10, - .is_rmii = 0, - .hw_addr = { 0x6a, 0x87, 0x71, 0x14, 0xcd, 0xcb }, -}; - +static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; +static int __init parse_tag_ethernet(struct tag *tag) +{ + int i; + + i = tag->u.ethernet.mac_index; + if (i < ARRAY_SIZE(eth_data)) { + eth_data[i].mii_phy_addr = tag->u.ethernet.mii_phy_addr; + memcpy(ð_data[i].hw_addr, tag->u.ethernet.hw_address, + sizeof(eth_data[i].hw_addr)); + eth_data[i].valid = 1; + } + return 0; +} +__tagtable(ATAG_ETHERNET, parse_tag_ethernet); + void __init setup_board(void) { at32_map_usart(1, 0); /* /dev/ttyS0 */ @@ -38,7 +51,9 @@ static int __init atstk1002_init(void) at32_add_device_usart(1); at32_add_device_usart(2); - at32_add_device_eth(0, ð0_data); + if (eth_data[0].valid) + at32_add_device_eth(0, ð_data[0]); + at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c index ea2d1ffee47..a3421160100 100644 --- a/arch/avr32/kernel/setup.c +++ b/arch/avr32/kernel/setup.c @@ -229,30 +229,6 @@ static int __init parse_tag_rsvd_mem(struct tag *tag) } __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); -static int __init parse_tag_ethernet(struct tag *tag) -{ -#if 0 - const struct platform_device *pdev; - - /* - * We really need a bus type that supports "classes"...this - * will do for now (until we must handle other kinds of - * ethernet controllers) - */ - pdev = platform_get_device("macb", tag->u.ethernet.mac_index); - if (pdev && pdev->dev.platform_data) { - struct eth_platform_data *data = pdev->dev.platform_data; - - data->valid = 1; - data->mii_phy_addr = tag->u.ethernet.mii_phy_addr; - memcpy(data->hw_addr, tag->u.ethernet.hw_address, - sizeof(data->hw_addr)); - } -#endif - return 0; -} -__tagtable(ATAG_ETHERNET, parse_tag_ethernet); - /* * Scan the tag table for this tag, and call its parse function. The * tag table is built by the linker from all the __tagtable -- cgit v1.2.3 From c164b90135d05ac52f70e6652910a4f585f7b999 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 14:08:39 +0100 Subject: [AVR32] Remove mii_phy_addr and eth_addr from eth_platform_data The macb driver will probe for the PHY chip and read the mac address from the MACB registers, so we don't need them in eth_platform_data anymore. Since u-boot doesn't currently initialize the MACB registers with the mac addresses, the tag parsing code is kept but instead of sticking the information into eth_platform_data, it uses it to initialize the MACB registers (in case the boot loader didn't do it.) This code should be unnecessary at some point in the future. Signed-off-by: Haavard Skinnemoen --- arch/avr32/boards/atstk1000/atstk1002.c | 65 +++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c index f65865cd9c3..32b361f31c2 100644 --- a/arch/avr32/boards/atstk1000/atstk1002.c +++ b/arch/avr32/boards/atstk1000/atstk1002.c @@ -7,33 +7,83 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include +#include #include #include +#include #include #include +#include #include #include #include +struct eth_addr { + u8 addr[6]; +}; + +static struct eth_addr __initdata hw_addr[2]; + static struct eth_platform_data __initdata eth_data[2]; extern struct lcdc_platform_data atstk1000_fb0_data; +/* + * The next two functions should go away as the boot loader is + * supposed to initialize the macb address registers with a valid + * ethernet address. But we need to keep it around for a while until + * we can be reasonably sure the boot loader does this. + * + * The phy_id is ignored as the driver will probe for it. + */ static int __init parse_tag_ethernet(struct tag *tag) { int i; i = tag->u.ethernet.mac_index; - if (i < ARRAY_SIZE(eth_data)) { - eth_data[i].mii_phy_addr = tag->u.ethernet.mii_phy_addr; - memcpy(ð_data[i].hw_addr, tag->u.ethernet.hw_address, - sizeof(eth_data[i].hw_addr)); - eth_data[i].valid = 1; - } + if (i < ARRAY_SIZE(hw_addr)) + memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address, + sizeof(hw_addr[i].addr)); + return 0; } __tagtable(ATAG_ETHERNET, parse_tag_ethernet); +static void __init set_hw_addr(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + const u8 *addr; + void __iomem *regs; + struct clk *pclk; + + if (!res) + return; + if (pdev->id >= ARRAY_SIZE(hw_addr)) + return; + + addr = hw_addr[pdev->id].addr; + if (!is_valid_ether_addr(addr)) + return; + + /* + * Since this is board-specific code, we'll cheat and use the + * physical address directly as we happen to know that it's + * the same as the virtual address. + */ + regs = (void __iomem __force *)res->start; + pclk = clk_get(&pdev->dev, "pclk"); + if (!pclk) + return; + + clk_enable(pclk); + __raw_writel((addr[3] << 24) | (addr[2] << 16) + | (addr[1] << 8) | addr[0], regs + 0x98); + __raw_writel((addr[5] << 8) | addr[4], regs + 0x9c); + clk_disable(pclk); + clk_put(pclk); +} + void __init setup_board(void) { at32_map_usart(1, 0); /* /dev/ttyS0 */ @@ -51,8 +101,7 @@ static int __init atstk1002_init(void) at32_add_device_usart(1); at32_add_device_usart(2); - if (eth_data[0].valid) - at32_add_device_eth(0, ð_data[0]); + set_hw_addr(at32_add_device_eth(0, ð_data[0])); at32_add_device_spi(0); at32_add_device_lcdc(0, &atstk1000_fb0_data); -- cgit v1.2.3 From da58e92f1f2939587ac85ae3abfec8b1c743400b Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 11:52:04 +0100 Subject: [AVR32] Remove unused file Remove arch/avr32/mach-at32ap/sm.c, which is not referenced by any Makefile. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/sm.c | 289 -------------------------------------------- 1 file changed, 289 deletions(-) delete mode 100644 arch/avr32/mach-at32ap/sm.c (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/sm.c b/arch/avr32/mach-at32ap/sm.c deleted file mode 100644 index 03306eb0345..00000000000 --- a/arch/avr32/mach-at32ap/sm.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * System Manager driver for AT32AP CPUs - * - * Copyright (C) 2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "sm.h" - -#define SM_EIM_IRQ_RESOURCE 1 -#define SM_PM_IRQ_RESOURCE 2 -#define SM_RTC_IRQ_RESOURCE 3 - -#define to_eim(irqc) container_of(irqc, struct at32_sm, irqc) - -struct at32_sm system_manager; - -int __init at32_sm_init(void) -{ - struct resource *regs; - struct at32_sm *sm = &system_manager; - int ret = -ENXIO; - - regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0); - if (!regs) - goto fail; - - spin_lock_init(&sm->lock); - sm->pdev = &at32_sm_device; - - ret = -ENOMEM; - sm->regs = ioremap(regs->start, regs->end - regs->start + 1); - if (!sm->regs) - goto fail; - - return 0; - -fail: - printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret); - return ret; -} - -/* - * External Interrupt Module (EIM). - * - * EIM gets level- or edge-triggered interrupts of either polarity - * from the outside and converts it to active-high level-triggered - * interrupts that the internal interrupt controller can handle. EIM - * also provides masking/unmasking of interrupts, as well as - * acknowledging of edge-triggered interrupts. - */ - -static irqreturn_t spurious_eim_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - printk(KERN_WARNING "Spurious EIM interrupt %d\n", irq); - disable_irq(irq); - return IRQ_NONE; -} - -static struct irqaction eim_spurious_action = { - .handler = spurious_eim_interrupt, -}; - -static irqreturn_t eim_handle_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - struct irq_controller * irqc = dev_id; - struct at32_sm *sm = to_eim(irqc); - unsigned long pending; - - /* - * No need to disable interrupts globally. The interrupt - * level relevant to this group must be masked all the time, - * so we know that this particular EIM instance will not be - * re-entered. - */ - spin_lock(&sm->lock); - - pending = intc_get_pending(sm->irqc.irq_group); - if (unlikely(!pending)) { - printk(KERN_ERR "EIM (group %u): No interrupts pending!\n", - sm->irqc.irq_group); - goto unlock; - } - - do { - struct irqaction *action; - unsigned int i; - - i = fls(pending) - 1; - pending &= ~(1 << i); - action = sm->action[i]; - - /* Acknowledge the interrupt */ - sm_writel(sm, EIM_ICR, 1 << i); - - spin_unlock(&sm->lock); - - if (action->flags & SA_INTERRUPT) - local_irq_disable(); - action->handler(sm->irqc.first_irq + i, action->dev_id, regs); - local_irq_enable(); - spin_lock(&sm->lock); - if (action->flags & SA_SAMPLE_RANDOM) - add_interrupt_randomness(sm->irqc.first_irq + i); - } while (pending); - -unlock: - spin_unlock(&sm->lock); - return IRQ_HANDLED; -} - -static void eim_mask(struct irq_controller *irqc, unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned int i; - - i = irq - sm->irqc.first_irq; - sm_writel(sm, EIM_IDR, 1 << i); -} - -static void eim_unmask(struct irq_controller *irqc, unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned int i; - - i = irq - sm->irqc.first_irq; - sm_writel(sm, EIM_IER, 1 << i); -} - -static int eim_setup(struct irq_controller *irqc, unsigned int irq, - struct irqaction *action) -{ - struct at32_sm *sm = to_eim(irqc); - sm->action[irq - sm->irqc.first_irq] = action; - /* Acknowledge earlier interrupts */ - sm_writel(sm, EIM_ICR, (1<<(irq - sm->irqc.first_irq))); - eim_unmask(irqc, irq); - return 0; -} - -static void eim_free(struct irq_controller *irqc, unsigned int irq, - void *dev) -{ - struct at32_sm *sm = to_eim(irqc); - eim_mask(irqc, irq); - sm->action[irq - sm->irqc.first_irq] = &eim_spurious_action; -} - -static int eim_set_type(struct irq_controller *irqc, unsigned int irq, - unsigned int type) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned long flags; - u32 value, pattern; - - spin_lock_irqsave(&sm->lock, flags); - - pattern = 1 << (irq - sm->irqc.first_irq); - - value = sm_readl(sm, EIM_MODE); - if (type & IRQ_TYPE_LEVEL) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_MODE, value); - value = sm_readl(sm, EIM_EDGE); - if (type & IRQ_EDGE_RISING) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_EDGE, value); - value = sm_readl(sm, EIM_LEVEL); - if (type & IRQ_LEVEL_HIGH) - value |= pattern; - else - value &= ~pattern; - sm_writel(sm, EIM_LEVEL, value); - - spin_unlock_irqrestore(&sm->lock, flags); - - return 0; -} - -static unsigned int eim_get_type(struct irq_controller *irqc, - unsigned int irq) -{ - struct at32_sm *sm = to_eim(irqc); - unsigned long flags; - unsigned int type = 0; - u32 mode, edge, level, pattern; - - pattern = 1 << (irq - sm->irqc.first_irq); - - spin_lock_irqsave(&sm->lock, flags); - mode = sm_readl(sm, EIM_MODE); - edge = sm_readl(sm, EIM_EDGE); - level = sm_readl(sm, EIM_LEVEL); - spin_unlock_irqrestore(&sm->lock, flags); - - if (mode & pattern) - type |= IRQ_TYPE_LEVEL; - if (edge & pattern) - type |= IRQ_EDGE_RISING; - if (level & pattern) - type |= IRQ_LEVEL_HIGH; - - return type; -} - -static struct irq_controller_class eim_irq_class = { - .typename = "EIM", - .handle = eim_handle_irq, - .setup = eim_setup, - .free = eim_free, - .mask = eim_mask, - .unmask = eim_unmask, - .set_type = eim_set_type, - .get_type = eim_get_type, -}; - -static int __init eim_init(void) -{ - struct at32_sm *sm = &system_manager; - unsigned int i; - u32 pattern; - int ret; - - /* - * The EIM is really the same module as SM, so register - * mapping, etc. has been taken care of already. - */ - - /* - * Find out how many interrupt lines that are actually - * implemented in hardware. - */ - sm_writel(sm, EIM_IDR, ~0UL); - sm_writel(sm, EIM_MODE, ~0UL); - pattern = sm_readl(sm, EIM_MODE); - sm->irqc.nr_irqs = fls(pattern); - - ret = -ENOMEM; - sm->action = kmalloc(sizeof(*sm->action) * sm->irqc.nr_irqs, - GFP_KERNEL); - if (!sm->action) - goto out; - - for (i = 0; i < sm->irqc.nr_irqs; i++) - sm->action[i] = &eim_spurious_action; - - spin_lock_init(&sm->lock); - sm->irqc.irq_group = sm->pdev->resource[SM_EIM_IRQ_RESOURCE].start; - sm->irqc.class = &eim_irq_class; - - ret = intc_register_controller(&sm->irqc); - if (ret < 0) - goto out_free_actions; - - printk("EIM: External Interrupt Module at 0x%p, IRQ group %u\n", - sm->regs, sm->irqc.irq_group); - printk("EIM: Handling %u external IRQs, starting with IRQ%u\n", - sm->irqc.nr_irqs, sm->irqc.first_irq); - - return 0; - -out_free_actions: - kfree(sm->action); -out: - return ret; -} -arch_initcall(eim_init); -- cgit v1.2.3 From 01cb087e747538d6a831c3ab370a1e1fd4538d5c Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 12:00:03 +0100 Subject: [AVR32] Set flow handler for external interrupts Make sure that the flow handler for external interrupts is updated whenever they type is changed. Also make sure that the defaults correspond with how the interrupt controller is configured. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/extint.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c index 4dff1f98890..b59272e81b9 100644 --- a/arch/avr32/mach-at32ap/extint.c +++ b/arch/avr32/mach-at32ap/extint.c @@ -49,12 +49,25 @@ static void eim_unmask_irq(unsigned int irq) static int eim_set_irq_type(unsigned int irq, unsigned int flow_type) { struct at32_sm *sm = get_irq_chip_data(irq); + struct irq_desc *desc; unsigned int i = irq - sm->eim_first_irq; u32 mode, edge, level; unsigned long flags; int ret = 0; - flow_type &= IRQ_TYPE_SENSE_MASK; + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; + + desc = &irq_desc[irq]; + desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); + desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; + + if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { + desc->status |= IRQ_LEVEL; + set_irq_handler(irq, handle_level_irq); + } else { + set_irq_handler(irq, handle_edge_irq); + } spin_lock_irqsave(&sm->lock, flags); @@ -148,10 +161,15 @@ static int __init eim_init(void) pattern = sm_readl(sm, EIM_MODE); nr_irqs = fls(pattern); + /* Trigger on falling edge unless overridden by driver */ + sm_writel(sm, EIM_MODE, 0UL); + sm_writel(sm, EIM_EDGE, 0UL); + sm->eim_chip = &eim_chip; for (i = 0; i < nr_irqs; i++) { - set_irq_chip(sm->eim_first_irq + i, &eim_chip); + set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip, + handle_edge_irq); set_irq_chip_data(sm->eim_first_irq + i, sm); } -- cgit v1.2.3 From c2eb5090ee531a50533ba9e739071c21f98a5a77 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 12:01:36 +0100 Subject: [AVR32] Put the chip in "stop" mode when halting the system Make machine_halt() execute a sleep instruction to put the chip in "stop" mode when the system is halted. This switches off all clocks except the 32 kHz oscillator, which is needed for the RTC to keep ticking. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/process.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'arch') diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 317dc50945f..0b4325946a4 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -38,6 +38,13 @@ void cpu_idle(void) void machine_halt(void) { + /* + * Enter Stop mode. The 32 kHz oscillator will keep running so + * the RTC will keep the time properly and the system will + * boot quickly. + */ + asm volatile("sleep 3\n\t" + "sub pc, -2"); } void machine_power_off(void) -- cgit v1.2.3 From acc9252a36dcefbcdae12f88566300a80d925e11 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Mon, 4 Dec 2006 14:17:39 +0100 Subject: [AVR32] Don't include Include instead of from a few places. Signed-off-by: Haavard Skinnemoen --- arch/avr32/kernel/avr32_ksyms.c | 2 +- arch/avr32/lib/delay.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c index 372e3f8b241..7c4c76114bb 100644 --- a/arch/avr32/kernel/avr32_ksyms.c +++ b/arch/avr32/kernel/avr32_ksyms.c @@ -7,12 +7,12 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include #include #include #include #include -#include /* * GCC functions diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c index 462c8307b68..76a8474607f 100644 --- a/arch/avr32/lib/delay.c +++ b/arch/avr32/lib/delay.c @@ -14,7 +14,6 @@ #include #include -#include #include #include -- cgit v1.2.3 From 695621183ee10eb22352bb919f50e160fa37aaa1 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 11:04:19 +0100 Subject: [AVR32] Implement intc_get_pending() intc_get_pending() returns a bitmask with pending interrupts in a interrupt controller group (irq). This is used by the upcoming oprofile implementation for avr32 and may also be useful for chained interrupt controller drivers. Signed-off-by: Haavard Skinnemoen --- arch/avr32/mach-at32ap/intc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/avr32/mach-at32ap/intc.c b/arch/avr32/mach-at32ap/intc.c index eb87a18ad7b..dd5c009cf22 100644 --- a/arch/avr32/mach-at32ap/intc.c +++ b/arch/avr32/mach-at32ap/intc.c @@ -136,3 +136,7 @@ fail: panic("Interrupt controller initialization failed!\n"); } +unsigned long intc_get_pending(int group) +{ + return intc_readl(&intc0, INTREQ0 + 4 * group); +} -- cgit v1.2.3 From 3fc0eb47aa96b1d9230ff85b722c45c3b9e83d14 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 12:55:03 +0100 Subject: [AVR32] Add missing #include to delay.c __const_udelay() needs HZ, which is defined in . Signed-off-by: Haavard Skinnemoen --- arch/avr32/lib/delay.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c index 76a8474607f..b3bc0b56e2c 100644 --- a/arch/avr32/lib/delay.c +++ b/arch/avr32/lib/delay.c @@ -12,6 +12,7 @@ #include #include +#include #include #include -- cgit v1.2.3 From 22155914b66b348b7113a0b3baf96a72bd3f643d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 8 Dec 2006 15:53:49 +0100 Subject: [S390] uaccess_pt: add missing down_read() and convert to is_init(). Doesn't seem to be a good idea to duplicate code :) Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_pt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 8741bdc0929..633249c3ba9 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -8,8 +8,8 @@ */ #include -#include #include +#include #include static inline int __handle_fault(struct mm_struct *mm, unsigned long address, @@ -60,8 +60,9 @@ out: out_of_memory: up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { yield(); + down_read(&mm->mmap_sem); goto survive; } printk("VM: killing process %s\n", current->comm); -- cgit v1.2.3 From 34249d0f9243fce773c2fa352934ba108320e234 Mon Sep 17 00:00:00 2001 From: Ursula Braun Date: Fri, 8 Dec 2006 15:54:18 +0100 Subject: [S390] runtime switch for qdio performance statistics Remove CONFIG_QETH_PERF_STATS and use a sysfs attribute instead. We want to have the ability to turn the statistics on/off at runtime. Signed-off-by: Ursula Braun Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 8 -------- arch/s390/defconfig | 1 - 2 files changed, 9 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 583d9ff0a57..a08e9100e7e 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -258,14 +258,6 @@ config QDIO If unsure, say Y. -config QDIO_PERF_STATS - bool "Performance statistics in /proc" - depends on QDIO - help - Say Y here to get performance statistics in /proc/qdio_perf - - If unsure, say N. - config QDIO_DEBUG bool "Extended debugging information" depends on QDIO diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 7cd51e73e27..a6ec919ba83 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -134,7 +134,6 @@ CONFIG_RESOURCES_64BIT=y # CONFIG_MACHCHK_WARNING=y CONFIG_QDIO=y -# CONFIG_QDIO_PERF_STATS is not set # CONFIG_QDIO_DEBUG is not set # -- cgit v1.2.3 From f4eb07c17df2e6cf9bd58bfcd9cc9e05e9489d07 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 8 Dec 2006 15:56:07 +0100 Subject: [S390] Virtual memmap for s390. Virtual memmap support for s390. Inspired by the ia64 implementation. Unlike ia64 we need a mechanism which allows us to dynamically attach shared memory regions. These memory regions are accessed via the dcss device driver. dcss implements the 'direct_access' operation, which requires struct pages for every single shared page. Therefore this implementation provides an interface to attach/detach shared memory: int add_shared_memory(unsigned long start, unsigned long size); int remove_shared_memory(unsigned long start, unsigned long size); The purpose of the add_shared_memory function is to add the given memory range to the 1:1 mapping and to make sure that the corresponding range in the vmemmap is backed with physical pages. It also initialises the new struct pages. remove_shared_memory in turn only invalidates the page table entries in the 1:1 mapping. The page tables and the memory used for struct pages in the vmemmap are currently not freed. They will be reused when the next segment will be attached. Given that the maximum size of a shared memory region is 2GB and in addition all regions must reside below 2GB this is not too much of a restriction, but there is room for improvement. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 + arch/s390/kernel/setup.c | 2 +- arch/s390/mm/Makefile | 2 +- arch/s390/mm/extmem.c | 106 ++++--------- arch/s390/mm/init.c | 163 +++++--------------- arch/s390/mm/vmem.c | 381 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 453 insertions(+), 204 deletions(-) create mode 100644 arch/s390/mm/vmem.c (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a08e9100e7e..f12ca8fba71 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -235,6 +235,9 @@ config WARN_STACK_SIZE source "mm/Kconfig" +config HOLES_IN_ZONE + def_bool y + comment "I/O subsystem configuration" config MACHCHK_WARNING diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b928fecdc74..b8a1ce21514 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -64,7 +64,7 @@ unsigned int console_devno = -1; unsigned int console_irq = -1; unsigned long machine_flags = 0; -struct mem_chunk memory_chunk[MEMORY_CHUNKS]; +struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index aa9a42b6e62..8e09db1edbb 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile @@ -2,6 +2,6 @@ # Makefile for the linux s390-specific parts of the memory manager. # -obj-y := init.o fault.o ioremap.o extmem.o mmap.o +obj-y := init.o fault.o ioremap.o extmem.o mmap.o vmem.o obj-$(CONFIG_CMM) += cmm.o diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 9e9bc48463a..775bf19e742 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -237,65 +238,6 @@ query_segment_type (struct dcss_segment *seg) return rc; } -/* - * check if the given segment collides with guest storage. - * returns 1 if this is the case, 0 if no collision was found - */ -static int -segment_overlaps_storage(struct dcss_segment *seg) -{ - int i; - - for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - if (memory_chunk[i].type != CHUNK_READ_WRITE) - continue; - if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) - continue; - if (((memory_chunk[i].addr + memory_chunk[i].size - 1) >> 20) - < (seg->start_addr >> 20)) - continue; - return 1; - } - return 0; -} - -/* - * check if segment collides with other segments that are currently loaded - * returns 1 if this is the case, 0 if no collision was found - */ -static int -segment_overlaps_others (struct dcss_segment *seg) -{ - struct list_head *l; - struct dcss_segment *tmp; - - BUG_ON(!mutex_is_locked(&dcss_lock)); - list_for_each(l, &dcss_list) { - tmp = list_entry(l, struct dcss_segment, list); - if ((tmp->start_addr >> 20) > (seg->end >> 20)) - continue; - if ((tmp->end >> 20) < (seg->start_addr >> 20)) - continue; - if (seg == tmp) - continue; - return 1; - } - return 0; -} - -/* - * check if segment exceeds the kernel mapping range (detected or set via mem=) - * returns 1 if this is the case, 0 if segment fits into the range - */ -static inline int -segment_exceeds_range (struct dcss_segment *seg) -{ - int seg_last_pfn = (seg->end) >> PAGE_SHIFT; - if (seg_last_pfn > max_pfn) - return 1; - return 0; -} - /* * get info about a segment * possible return values: @@ -341,24 +283,26 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long rc = query_segment_type (seg); if (rc < 0) goto out_free; - if (segment_exceeds_range(seg)) { - PRINT_WARN ("segment_load: not loading segment %s - exceeds" - " kernel mapping range\n",name); - rc = -ERANGE; + + rc = add_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); + + switch (rc) { + case 0: + break; + case -ENOSPC: + PRINT_WARN("segment_load: not loading segment %s - overlaps " + "storage/segment\n", name); goto out_free; - } - if (segment_overlaps_storage(seg)) { - PRINT_WARN ("segment_load: not loading segment %s - overlaps" - " storage\n",name); - rc = -ENOSPC; + case -ERANGE: + PRINT_WARN("segment_load: not loading segment %s - exceeds " + "kernel mapping range\n", name); goto out_free; - } - if (segment_overlaps_others(seg)) { - PRINT_WARN ("segment_load: not loading segment %s - overlaps" - " other segments\n",name); - rc = -EBUSY; + default: + PRINT_WARN("segment_load: not loading segment %s (rc: %d)\n", + name, rc); goto out_free; } + if (do_nonshared) dcss_command = DCSS_LOADNSR; else @@ -372,7 +316,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long rc = dcss_diag_translate_rc (seg->end); dcss_diag(DCSS_PURGESEG, seg->dcss_name, &seg->start_addr, &seg->end); - goto out_free; + goto out_shared; } seg->do_nonshared = do_nonshared; atomic_set(&seg->ref_count, 1); @@ -391,6 +335,8 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long (void*)seg->start_addr, (void*)seg->end, segtype_string[seg->vm_segtype]); goto out; + out_shared: + remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); out_free: kfree(seg); out: @@ -530,12 +476,12 @@ segment_unload(char *name) "please report to linux390@de.ibm.com\n",name); goto out_unlock; } - if (atomic_dec_return(&seg->ref_count) == 0) { - list_del(&seg->list); - dcss_diag(DCSS_PURGESEG, seg->dcss_name, - &dummy, &dummy); - kfree(seg); - } + if (atomic_dec_return(&seg->ref_count) != 0) + goto out_unlock; + remove_shared_memory(seg->start_addr, seg->end - seg->start_addr + 1); + list_del(&seg->list); + dcss_diag(DCSS_PURGESEG, seg->dcss_name, &dummy, &dummy); + kfree(seg); out_unlock: mutex_unlock(&dcss_lock); } diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index e1881c31b1c..5ea12a573ca 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -69,6 +69,8 @@ void show_mem(void) printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; while (i-- > 0) { + if (!pfn_valid(i)) + continue; page = pfn_to_page(i); total++; if (PageReserved(page)) @@ -84,67 +86,53 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +static void __init setup_ro_region(void) +{ + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + pte_t new_pte; + unsigned long address, end; + + address = ((unsigned long)&__start_rodata) & PAGE_MASK; + end = PFN_ALIGN((unsigned long)&__end_rodata); + + for (; address < end; address += PAGE_SIZE) { + pgd = pgd_offset_k(address); + pmd = pmd_offset(pgd, address); + pte = pte_offset_kernel(pmd, address); + new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO)); + set_pte(pte, new_pte); + } +} + extern unsigned long __initdata zholes_size[]; +extern void vmem_map_init(void); /* * paging_init() sets up the page tables */ - -#ifndef CONFIG_64BIT void __init paging_init(void) { - pgd_t * pg_dir; - pte_t * pg_table; - pte_t pte; - int i; - unsigned long tmp; - unsigned long pfn = 0; - unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; - static const int ssm_mask = 0x04000000L; - unsigned long ro_start_pfn, ro_end_pfn; + pgd_t *pg_dir; + int i; + unsigned long pgdir_k; + static const int ssm_mask = 0x04000000L; unsigned long zones_size[MAX_NR_ZONES]; + unsigned long dma_pfn, high_pfn; - ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); - ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); - - memset(zones_size, 0, sizeof(zones_size)); - zones_size[ZONE_DMA] = max_low_pfn; - free_area_init_node(0, &contig_page_data, zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, - zholes_size); - - /* unmap whole virtual address space */ + pg_dir = swapper_pg_dir; - pg_dir = swapper_pg_dir; - +#ifdef CONFIG_64BIT + pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE; for (i = 0; i < PTRS_PER_PGD; i++) - pmd_clear((pmd_t *) pg_dir++); - - /* - * map whole physical memory to virtual memory (identity mapping) - */ - - pg_dir = swapper_pg_dir; - - while (pfn < max_low_pfn) { - /* - * pg_table is physical at this point - */ - pg_table = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); - - pmd_populate_kernel(&init_mm, (pmd_t *) pg_dir, pg_table); - pg_dir++; - - for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { - if (pfn >= ro_start_pfn && pfn < ro_end_pfn) - pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); - else - pte = pfn_pte(pfn, PAGE_KERNEL); - if (pfn >= max_low_pfn) - pte_val(pte) = _PAGE_TYPE_EMPTY; - set_pte(pg_table, pte); - pfn++; - } - } + pgd_clear(pg_dir + i); +#else + pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE; + for (i = 0; i < PTRS_PER_PGD; i++) + pmd_clear((pmd_t *)(pg_dir + i)); +#endif + vmem_map_init(); + setup_ro_region(); S390_lowcore.kernel_asce = pgdir_k; @@ -154,31 +142,9 @@ void __init paging_init(void) __ctl_load(pgdir_k, 13, 13); __raw_local_irq_ssm(ssm_mask); - local_flush_tlb(); -} - -#else /* CONFIG_64BIT */ - -void __init paging_init(void) -{ - pgd_t * pg_dir; - pmd_t * pm_dir; - pte_t * pt_dir; - pte_t pte; - int i,j,k; - unsigned long pfn = 0; - unsigned long pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | - _KERN_REGION_TABLE; - static const int ssm_mask = 0x04000000L; - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long dma_pfn, high_pfn; - unsigned long ro_start_pfn, ro_end_pfn; - memset(zones_size, 0, sizeof(zones_size)); dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; high_pfn = max_low_pfn; - ro_start_pfn = PFN_DOWN((unsigned long)&__start_rodata); - ro_end_pfn = PFN_UP((unsigned long)&__end_rodata); if (dma_pfn > high_pfn) zones_size[ZONE_DMA] = high_pfn; @@ -190,56 +156,7 @@ void __init paging_init(void) /* Initialize mem_map[]. */ free_area_init_node(0, &contig_page_data, zones_size, __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); - - /* - * map whole physical memory to virtual memory (identity mapping) - */ - - pg_dir = swapper_pg_dir; - - for (i = 0 ; i < PTRS_PER_PGD ; i++,pg_dir++) { - - if (pfn >= max_low_pfn) { - pgd_clear(pg_dir); - continue; - } - - pm_dir = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE * 4); - pgd_populate(&init_mm, pg_dir, pm_dir); - - for (j = 0 ; j < PTRS_PER_PMD ; j++,pm_dir++) { - if (pfn >= max_low_pfn) { - pmd_clear(pm_dir); - continue; - } - - pt_dir = (pte_t *) alloc_bootmem_pages(PAGE_SIZE); - pmd_populate_kernel(&init_mm, pm_dir, pt_dir); - - for (k = 0 ; k < PTRS_PER_PTE ; k++,pt_dir++) { - if (pfn >= ro_start_pfn && pfn < ro_end_pfn) - pte = pfn_pte(pfn, __pgprot(_PAGE_RO)); - else - pte = pfn_pte(pfn, PAGE_KERNEL); - if (pfn >= max_low_pfn) - pte_val(pte) = _PAGE_TYPE_EMPTY; - set_pte(pt_dir, pte); - pfn++; - } - } - } - - S390_lowcore.kernel_asce = pgdir_k; - - /* enable virtual mapping in kernel mode */ - __ctl_load(pgdir_k, 1, 1); - __ctl_load(pgdir_k, 7, 7); - __ctl_load(pgdir_k, 13, 13); - __raw_local_irq_ssm(ssm_mask); - - local_flush_tlb(); } -#endif /* CONFIG_64BIT */ void __init mem_init(void) { @@ -269,6 +186,8 @@ void __init mem_init(void) printk("Write protected kernel read-only data: %#lx - %#lx\n", (unsigned long)&__start_rodata, PFN_ALIGN((unsigned long)&__end_rodata) - 1); + printk("Virtual memmap size: %ldk\n", + (max_pfn * sizeof(struct page)) >> 10); } void free_initmem(void) diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c new file mode 100644 index 00000000000..7f2944d3ec2 --- /dev/null +++ b/arch/s390/mm/vmem.c @@ -0,0 +1,381 @@ +/* + * arch/s390/mm/vmem.c + * + * Copyright IBM Corp. 2006 + * Author(s): Heiko Carstens + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long vmalloc_end; +EXPORT_SYMBOL(vmalloc_end); + +static struct page *vmem_map; +static DEFINE_MUTEX(vmem_mutex); + +struct memory_segment { + struct list_head list; + unsigned long start; + unsigned long size; +}; + +static LIST_HEAD(mem_segs); + +void memmap_init(unsigned long size, int nid, unsigned long zone, + unsigned long start_pfn) +{ + struct page *start, *end; + struct page *map_start, *map_end; + int i; + + start = pfn_to_page(start_pfn); + end = start + size; + + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { + unsigned long cstart, cend; + + cstart = PFN_DOWN(memory_chunk[i].addr); + cend = cstart + PFN_DOWN(memory_chunk[i].size); + + map_start = mem_map + cstart; + map_end = mem_map + cend; + + if (map_start < start) + map_start = start; + if (map_end > end) + map_end = end; + + map_start -= ((unsigned long) map_start & (PAGE_SIZE - 1)) + / sizeof(struct page); + map_end += ((PFN_ALIGN((unsigned long) map_end) + - (unsigned long) map_end) + / sizeof(struct page)); + + if (map_start < map_end) + memmap_init_zone((unsigned long)(map_end - map_start), + nid, zone, page_to_pfn(map_start)); + } +} + +static inline void *vmem_alloc_pages(unsigned int order) +{ + if (slab_is_available()) + return (void *)__get_free_pages(GFP_KERNEL, order); + return alloc_bootmem_pages((1 << order) * PAGE_SIZE); +} + +static inline pmd_t *vmem_pmd_alloc(void) +{ + pmd_t *pmd; + int i; + + pmd = vmem_alloc_pages(PMD_ALLOC_ORDER); + if (!pmd) + return NULL; + for (i = 0; i < PTRS_PER_PMD; i++) + pmd_clear(pmd + i); + return pmd; +} + +static inline pte_t *vmem_pte_alloc(void) +{ + pte_t *pte; + pte_t empty_pte; + int i; + + pte = vmem_alloc_pages(PTE_ALLOC_ORDER); + if (!pte) + return NULL; + pte_val(empty_pte) = _PAGE_TYPE_EMPTY; + for (i = 0; i < PTRS_PER_PTE; i++) + set_pte(pte + i, empty_pte); + return pte; +} + +/* + * Add a physical memory range to the 1:1 mapping. + */ +static int vmem_add_range(unsigned long start, unsigned long size) +{ + unsigned long address; + pgd_t *pg_dir; + pmd_t *pm_dir; + pte_t *pt_dir; + pte_t pte; + int ret = -ENOMEM; + + for (address = start; address < start + size; address += PAGE_SIZE) { + pg_dir = pgd_offset_k(address); + if (pgd_none(*pg_dir)) { + pm_dir = vmem_pmd_alloc(); + if (!pm_dir) + goto out; + pgd_populate(&init_mm, pg_dir, pm_dir); + } + + pm_dir = pmd_offset(pg_dir, address); + if (pmd_none(*pm_dir)) { + pt_dir = vmem_pte_alloc(); + if (!pt_dir) + goto out; + pmd_populate_kernel(&init_mm, pm_dir, pt_dir); + } + + pt_dir = pte_offset_kernel(pm_dir, address); + pte = pfn_pte(address >> PAGE_SHIFT, PAGE_KERNEL); + set_pte(pt_dir, pte); + } + ret = 0; +out: + flush_tlb_kernel_range(start, start + size); + return ret; +} + +/* + * Remove a physical memory range from the 1:1 mapping. + * Currently only invalidates page table entries. + */ +static void vmem_remove_range(unsigned long start, unsigned long size) +{ + unsigned long address; + pgd_t *pg_dir; + pmd_t *pm_dir; + pte_t *pt_dir; + pte_t pte; + + pte_val(pte) = _PAGE_TYPE_EMPTY; + for (address = start; address < start + size; address += PAGE_SIZE) { + pg_dir = pgd_offset_k(address); + if (pgd_none(*pg_dir)) + continue; + pm_dir = pmd_offset(pg_dir, address); + if (pmd_none(*pm_dir)) + continue; + pt_dir = pte_offset_kernel(pm_dir, address); + set_pte(pt_dir, pte); + } + flush_tlb_kernel_range(start, start + size); +} + +/* + * Add a backed mem_map array to the virtual mem_map array. + */ +static int vmem_add_mem_map(unsigned long start, unsigned long size) +{ + unsigned long address, start_addr, end_addr; + struct page *map_start, *map_end; + pgd_t *pg_dir; + pmd_t *pm_dir; + pte_t *pt_dir; + pte_t pte; + int ret = -ENOMEM; + + map_start = vmem_map + PFN_DOWN(start); + map_end = vmem_map + PFN_DOWN(start + size); + + start_addr = (unsigned long) map_start & PAGE_MASK; + end_addr = PFN_ALIGN((unsigned long) map_end); + + for (address = start_addr; address < end_addr; address += PAGE_SIZE) { + pg_dir = pgd_offset_k(address); + if (pgd_none(*pg_dir)) { + pm_dir = vmem_pmd_alloc(); + if (!pm_dir) + goto out; + pgd_populate(&init_mm, pg_dir, pm_dir); + } + + pm_dir = pmd_offset(pg_dir, address); + if (pmd_none(*pm_dir)) { + pt_dir = vmem_pte_alloc(); + if (!pt_dir) + goto out; + pmd_populate_kernel(&init_mm, pm_dir, pt_dir); + } + + pt_dir = pte_offset_kernel(pm_dir, address); + if (pte_none(*pt_dir)) { + unsigned long new_page; + + new_page =__pa(vmem_alloc_pages(0)); + if (!new_page) + goto out; + pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); + set_pte(pt_dir, pte); + } + } + ret = 0; +out: + flush_tlb_kernel_range(start_addr, end_addr); + return ret; +} + +static int vmem_add_mem(unsigned long start, unsigned long size) +{ + int ret; + + ret = vmem_add_range(start, size); + if (ret) + return ret; + return vmem_add_mem_map(start, size); +} + +/* + * Add memory segment to the segment list if it doesn't overlap with + * an already present segment. + */ +static int insert_memory_segment(struct memory_segment *seg) +{ + struct memory_segment *tmp; + + if (PFN_DOWN(seg->start + seg->size) > max_pfn || + seg->start + seg->size < seg->start) + return -ERANGE; + + list_for_each_entry(tmp, &mem_segs, list) { + if (seg->start >= tmp->start + tmp->size) + continue; + if (seg->start + seg->size <= tmp->start) + continue; + return -ENOSPC; + } + list_add(&seg->list, &mem_segs); + return 0; +} + +/* + * Remove memory segment from the segment list. + */ +static void remove_memory_segment(struct memory_segment *seg) +{ + list_del(&seg->list); +} + +static void __remove_shared_memory(struct memory_segment *seg) +{ + remove_memory_segment(seg); + vmem_remove_range(seg->start, seg->size); +} + +int remove_shared_memory(unsigned long start, unsigned long size) +{ + struct memory_segment *seg; + int ret; + + mutex_lock(&vmem_mutex); + + ret = -ENOENT; + list_for_each_entry(seg, &mem_segs, list) { + if (seg->start == start && seg->size == size) + break; + } + + if (seg->start != start || seg->size != size) + goto out; + + ret = 0; + __remove_shared_memory(seg); + kfree(seg); +out: + mutex_unlock(&vmem_mutex); + return ret; +} + +int add_shared_memory(unsigned long start, unsigned long size) +{ + struct memory_segment *seg; + struct page *page; + unsigned long pfn, num_pfn, end_pfn; + int ret; + + mutex_lock(&vmem_mutex); + ret = -ENOMEM; + seg = kzalloc(sizeof(*seg), GFP_KERNEL); + if (!seg) + goto out; + seg->start = start; + seg->size = size; + + ret = insert_memory_segment(seg); + if (ret) + goto out_free; + + ret = vmem_add_mem(start, size); + if (ret) + goto out_remove; + + pfn = PFN_DOWN(start); + num_pfn = PFN_DOWN(size); + end_pfn = pfn + num_pfn; + + page = pfn_to_page(pfn); + memset(page, 0, num_pfn * sizeof(struct page)); + + for (; pfn < end_pfn; pfn++) { + page = pfn_to_page(pfn); + init_page_count(page); + reset_page_mapcount(page); + SetPageReserved(page); + INIT_LIST_HEAD(&page->lru); + } + goto out; + +out_remove: + __remove_shared_memory(seg); +out_free: + kfree(seg); +out: + mutex_unlock(&vmem_mutex); + return ret; +} + +/* + * map whole physical memory to virtual memory (identity mapping) + */ +void __init vmem_map_init(void) +{ + unsigned long map_size; + int i; + + map_size = ALIGN(max_low_pfn, MAX_ORDER_NR_PAGES) * sizeof(struct page); + vmalloc_end = PFN_ALIGN(VMALLOC_END_INIT) - PFN_ALIGN(map_size); + vmem_map = (struct page *) vmalloc_end; + NODE_DATA(0)->node_mem_map = vmem_map; + + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) + vmem_add_mem(memory_chunk[i].addr, memory_chunk[i].size); +} + +/* + * Convert memory chunk array to a memory segment list so there is a single + * list that contains both r/w memory and shared memory segments. + */ +static int __init vmem_convert_memory_chunk(void) +{ + struct memory_segment *seg; + int i; + + mutex_lock(&vmem_mutex); + for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { + if (!memory_chunk[i].size) + continue; + seg = kzalloc(sizeof(*seg), GFP_KERNEL); + if (!seg) + panic("Out of memory...\n"); + seg->start = memory_chunk[i].addr; + seg->size = memory_chunk[i].size; + insert_memory_segment(seg); + } + mutex_unlock(&vmem_mutex); + return 0; +} + +core_initcall(vmem_convert_memory_chunk); -- cgit v1.2.3 From 39b742f957a287a7514a8a35c9f516cdf30b9ff5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 8 Dec 2006 15:56:10 +0100 Subject: [S390] Use add_active_range() and free_area_init_nodes(). Size zones and holes in an architecture independent manner for s390. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/Kconfig | 3 +++ arch/s390/kernel/setup.c | 53 +++++++++++------------------------------------- arch/s390/mm/init.c | 23 ++++++--------------- 3 files changed, 21 insertions(+), 58 deletions(-) (limited to 'arch') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index f12ca8fba71..04f5a023029 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -233,6 +233,9 @@ config WARN_STACK_SIZE This allows you to specify the maximum frame size a function may have without the compiler complaining about it. +config ARCH_POPULATES_NODE_MAP + def_bool y + source "mm/Kconfig" config HOLES_IN_ZONE diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index b8a1ce21514..49ef206ec88 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -66,7 +66,6 @@ unsigned long machine_flags = 0; struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ -unsigned long __initdata zholes_size[MAX_NR_ZONES]; static unsigned long __initdata memory_end; /* @@ -354,21 +353,6 @@ void machine_power_off(void) */ void (*pm_power_off)(void) = machine_power_off; -static void __init -add_memory_hole(unsigned long start, unsigned long end) -{ - unsigned long dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; - - if (end <= dma_pfn) - zholes_size[ZONE_DMA] += end - start + 1; - else if (start > dma_pfn) - zholes_size[ZONE_NORMAL] += end - start + 1; - else { - zholes_size[ZONE_DMA] += dma_pfn - start + 1; - zholes_size[ZONE_NORMAL] += end - dma_pfn; - } -} - static int __init early_parse_mem(char *p) { memory_end = memparse(p, &p); @@ -521,7 +505,6 @@ setup_memory(void) { unsigned long bootmap_size; unsigned long start_pfn, end_pfn, init_pfn; - unsigned long last_rw_end; int i; /* @@ -577,39 +560,27 @@ setup_memory(void) /* * Register RAM areas with the bootmem allocator. */ - last_rw_end = start_pfn; for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { - unsigned long start_chunk, end_chunk; + unsigned long start_chunk, end_chunk, pfn; if (memory_chunk[i].type != CHUNK_READ_WRITE) continue; - start_chunk = (memory_chunk[i].addr + PAGE_SIZE - 1); - start_chunk >>= PAGE_SHIFT; - end_chunk = (memory_chunk[i].addr + memory_chunk[i].size); - end_chunk >>= PAGE_SHIFT; - if (start_chunk < start_pfn) - start_chunk = start_pfn; - if (end_chunk > end_pfn) - end_chunk = end_pfn; - if (start_chunk < end_chunk) { - /* Initialize storage key for RAM pages */ - for (init_pfn = start_chunk ; init_pfn < end_chunk; - init_pfn++) - page_set_storage_key(init_pfn << PAGE_SHIFT, - PAGE_DEFAULT_KEY); - free_bootmem(start_chunk << PAGE_SHIFT, - (end_chunk - start_chunk) << PAGE_SHIFT); - if (last_rw_end < start_chunk) - add_memory_hole(last_rw_end, start_chunk - 1); - last_rw_end = end_chunk; - } + start_chunk = PFN_DOWN(memory_chunk[i].addr); + end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1; + end_chunk = min(end_chunk, end_pfn); + if (start_chunk >= end_chunk) + continue; + add_active_range(0, start_chunk, end_chunk); + pfn = max(start_chunk, start_pfn); + for (; pfn <= end_chunk; pfn++) + page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY); } psw_set_key(PAGE_DEFAULT_KEY); - if (last_rw_end < end_pfn - 1) - add_memory_hole(last_rw_end, end_pfn - 1); + free_bootmem_with_active_regions(0, max_pfn); + reserve_bootmem(0, PFN_PHYS(start_pfn)); /* * Reserve the bootmem bitmap itself as well. We do this in two diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 5ea12a573ca..aa39591ca13 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -106,8 +106,8 @@ static void __init setup_ro_region(void) } } -extern unsigned long __initdata zholes_size[]; extern void vmem_map_init(void); + /* * paging_init() sets up the page tables */ @@ -117,8 +117,7 @@ void __init paging_init(void) int i; unsigned long pgdir_k; static const int ssm_mask = 0x04000000L; - unsigned long zones_size[MAX_NR_ZONES]; - unsigned long dma_pfn, high_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES]; pg_dir = swapper_pg_dir; @@ -142,20 +141,10 @@ void __init paging_init(void) __ctl_load(pgdir_k, 13, 13); __raw_local_irq_ssm(ssm_mask); - memset(zones_size, 0, sizeof(zones_size)); - dma_pfn = MAX_DMA_ADDRESS >> PAGE_SHIFT; - high_pfn = max_low_pfn; - - if (dma_pfn > high_pfn) - zones_size[ZONE_DMA] = high_pfn; - else { - zones_size[ZONE_DMA] = dma_pfn; - zones_size[ZONE_NORMAL] = high_pfn - dma_pfn; - } - - /* Initialize mem_map[]. */ - free_area_init_node(0, &contig_page_data, zones_size, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; + free_area_init_nodes(max_zone_pfns); } void __init mem_init(void) -- cgit v1.2.3 From 028d9b3cc62cb9dd31f1b5929edb3c23612cfccc Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 8 Dec 2006 15:56:13 +0100 Subject: [S390] Poison init section before freeing it. The data patterns should allow us to easily tell if somebody accesses initdata/code after it was freed. Same code as on various other architectures. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/init.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index aa39591ca13..4bb21be3b00 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -187,6 +188,7 @@ void free_initmem(void) for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); + memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); free_page(addr); totalram_pages++; } -- cgit v1.2.3 From 8b03a632ef673bf1069ac9c96c97ff2830289312 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Fri, 8 Dec 2006 02:35:54 -0800 Subject: [PATCH] m32r: make userspace headers platform-independent The m32r kernel 2.6.18-rc1 or after cause build errors of "unknown isa configuration" for userspace application programs, such as glibc, gdb, etc. This is because the recent kernel do not include linux/config.h not to expose kernel headers for userspace. To fix the above compile errors, this patch fixes two headers ptrace.h and sigcontext.h for m32r and makes them platform-independent. Signed-off-by: Hirokazu Takata Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/kernel/entry.S | 65 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index ac6d840b382..5b01fd2096f 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -23,35 +23,35 @@ * updated in fork.c:copy_thread, signal.c:do_signal, * ptrace.c and ptrace.h * - * M32Rx/M32R2 M32R - * @(sp) - r4 ditto - * @(0x04,sp) - r5 ditto - * @(0x08,sp) - r6 ditto - * @(0x0c,sp) - *pt_regs ditto - * @(0x10,sp) - r0 ditto - * @(0x14,sp) - r1 ditto - * @(0x18,sp) - r2 ditto - * @(0x1c,sp) - r3 ditto - * @(0x20,sp) - r7 ditto - * @(0x24,sp) - r8 ditto - * @(0x28,sp) - r9 ditto - * @(0x2c,sp) - r10 ditto - * @(0x30,sp) - r11 ditto - * @(0x34,sp) - r12 ditto - * @(0x38,sp) - syscall_nr ditto - * @(0x3c,sp) - acc0h @(0x3c,sp) - acch - * @(0x40,sp) - acc0l @(0x40,sp) - accl - * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h - * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l - * @(0x4c,sp) - psw ditto - * @(0x50,sp) - bpc ditto - * @(0x54,sp) - bbpsw ditto - * @(0x58,sp) - bbpc ditto - * @(0x5c,sp) - spu (cr3) ditto - * @(0x60,sp) - fp (r13) ditto - * @(0x64,sp) - lr (r14) ditto - * @(0x68,sp) - spi (cr2) ditto - * @(0x6c,sp) - orig_r0 ditto + * M32R/M32Rx/M32R2 + * @(sp) - r4 + * @(0x04,sp) - r5 + * @(0x08,sp) - r6 + * @(0x0c,sp) - *pt_regs + * @(0x10,sp) - r0 + * @(0x14,sp) - r1 + * @(0x18,sp) - r2 + * @(0x1c,sp) - r3 + * @(0x20,sp) - r7 + * @(0x24,sp) - r8 + * @(0x28,sp) - r9 + * @(0x2c,sp) - r10 + * @(0x30,sp) - r11 + * @(0x34,sp) - r12 + * @(0x38,sp) - syscall_nr + * @(0x3c,sp) - acc0h + * @(0x40,sp) - acc0l + * @(0x44,sp) - acc1h ; ISA_DSP_LEVEL2 only + * @(0x48,sp) - acc1l ; ISA_DSP_LEVEL2 only + * @(0x4c,sp) - psw + * @(0x50,sp) - bpc + * @(0x54,sp) - bbpsw + * @(0x58,sp) - bbpc + * @(0x5c,sp) - spu (cr3) + * @(0x60,sp) - fp (r13) + * @(0x64,sp) - lr (r14) + * @(0x68,sp) - spi (cr2) + * @(0x6c,sp) - orig_r0 */ #include @@ -95,17 +95,10 @@ #define R11(reg) @(0x30,reg) #define R12(reg) @(0x34,reg) #define SYSCALL_NR(reg) @(0x38,reg) -#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2) #define ACC0H(reg) @(0x3C,reg) #define ACC0L(reg) @(0x40,reg) #define ACC1H(reg) @(0x44,reg) #define ACC1L(reg) @(0x48,reg) -#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) -#define ACCH(reg) @(0x3C,reg) -#define ACCL(reg) @(0x40,reg) -#else -#error unknown isa configuration -#endif #define PSW(reg) @(0x4C,reg) #define BPC(reg) @(0x50,reg) #define BBPSW(reg) @(0x54,reg) -- cgit v1.2.3 From 6b8bd3f4b2e9d0fbfd0e7d75ba1cdc79c6876ecc Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Fri, 8 Dec 2006 02:35:56 -0800 Subject: [PATCH] m32r: fix ace_handler to pass full 32-bit address Don't mask the lower 12-bit of the page fault address. In the current m32r kernel implementation, we use an access exception to detect page faults. This patch fixes ace_handler (access exception handler) for m32r. In order to check userspace address in do_page_fault, we have to pass full 32-bit address to do_page_fault. Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/kernel/entry.S | 2 -- arch/m32r/mm/fault.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 5b01fd2096f..a2c472c0549 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S @@ -596,8 +596,6 @@ ENTRY(ace_handler) beqz r1, inst oprand: ld r2, @(low(MDEVA_offset),r2) ; set address - srli r2, #12 - slli r2, #12 srli r1, #1 bra 1f inst: diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c index 8d5f551b575..9b9feb0f161 100644 --- a/arch/m32r/mm/fault.c +++ b/arch/m32r/mm/fault.c @@ -173,7 +173,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, goto good_area; if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; -#if 0 + if (error_code & ACE_USERMODE) { /* * accessing the stack below "spu" is always a bug. @@ -184,7 +184,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, if (address + 4 < regs->spu) goto bad_area; } -#endif + if (expand_stack(vma, address)) goto bad_area; /* -- cgit v1.2.3 From d93f7de8c5dfefb030a5e65d0857176879bf78e9 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Fri, 8 Dec 2006 02:35:57 -0800 Subject: [PATCH] m32r: bootloader support for OPSPUT platform This patch supports "m32r-g00ff" bootloader for an OPSPUT platform. Applying this patch, it is possible to do ATA-boot from an IDE drive or HTTP-boot from network by m32r-g00ff. * arch/m32r/boot/compressed/m32r_sio.c: Fix hangup on OPSPUT at boot. * arch/m32r/kernel/io_opsput.c: IDE support for OPSPUT. * arch/m32r/kernel/setup_opsput.c: ditto. * include/asm-m32r/ide.h: ditto. Signed-off-by: Kazuhiro Inaoka Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/m32r/boot/compressed/m32r_sio.c | 7 +++- arch/m32r/kernel/io_opsput.c | 71 +++++++++++++++++++++++++++++++++++- arch/m32r/kernel/setup_opsput.c | 17 ++++----- 3 files changed, 82 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/m32r/boot/compressed/m32r_sio.c b/arch/m32r/boot/compressed/m32r_sio.c index bce8af5e3bb..ee3c8be12fa 100644 --- a/arch/m32r/boot/compressed/m32r_sio.c +++ b/arch/m32r/boot/compressed/m32r_sio.c @@ -2,6 +2,7 @@ * arch/m32r/boot/compressed/m32r_sio.c * * 2003-02-12: Takeo Takahashi + * 2006-11-30: OPSPUT support by Kazuhiro Inaoka * */ @@ -16,7 +17,7 @@ static int puts(const char *s) return 0; } -#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) +#if defined(CONFIG_PLAT_M32700UT_Alpha) || defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_OPSPUT) #include #include @@ -31,7 +32,11 @@ static int puts(const char *s) #define BOOT_SIO0TXB (volatile unsigned short *)(0x02c00000 + 0x2000c) #else #undef PLD_BASE +#if defined(CONFIG_PLAT_OPSPUT) +#define PLD_BASE 0x1cc00000 +#else #define PLD_BASE 0xa4c00000 +#endif #define BOOT_SIO0STS PLD_ESIO0STS #define BOOT_SIO0TXB PLD_ESIO0TXB #endif diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c index da6c5f5c1f8..3cbb1f717e5 100644 --- a/arch/m32r/kernel/io_opsput.c +++ b/arch/m32r/kernel/io_opsput.c @@ -30,14 +30,34 @@ extern void pcc_iowrite_byte(int, unsigned long, void *, size_t, size_t, int); extern void pcc_iowrite_word(int, unsigned long, void *, size_t, size_t, int); #endif /* CONFIG_PCMCIA && CONFIG_M32R_CFC */ -#define PORT2ADDR(port) _port2addr(port) -#define PORT2ADDR_USB(port) _port2addr_usb(port) +#define PORT2ADDR(port) _port2addr(port) +#define PORT2ADDR_USB(port) _port2addr_usb(port) static inline void *_port2addr(unsigned long port) { return (void *)(port | NONCACHE_OFFSET); } +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) +static inline void *__port2addr_ata(unsigned long port) +{ + static int dummy_reg; + + switch (port) { + case 0x1f0: return (void *)(0x0c002000 | NONCACHE_OFFSET); + case 0x1f1: return (void *)(0x0c012800 | NONCACHE_OFFSET); + case 0x1f2: return (void *)(0x0c012002 | NONCACHE_OFFSET); + case 0x1f3: return (void *)(0x0c012802 | NONCACHE_OFFSET); + case 0x1f4: return (void *)(0x0c012004 | NONCACHE_OFFSET); + case 0x1f5: return (void *)(0x0c012804 | NONCACHE_OFFSET); + case 0x1f6: return (void *)(0x0c012006 | NONCACHE_OFFSET); + case 0x1f7: return (void *)(0x0c012806 | NONCACHE_OFFSET); + case 0x3f6: return (void *)(0x0c01200e | NONCACHE_OFFSET); + default: return (void *)&dummy_reg; + } +} +#endif + /* * OPSPUT-LAN is located in the extended bus space * from 0x10000000 to 0x13ffffff on physical address. @@ -97,6 +117,12 @@ unsigned char _inb(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inb(PORT2ADDR_NE(port)); + +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + return *(volatile unsigned char *)__port2addr_ata(port); + } +#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned char b; @@ -112,6 +138,11 @@ unsigned short _inw(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inw(PORT2ADDR_NE(port)); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + return *(volatile unsigned short *)__port2addr_ata(port); + } +#endif #if defined(CONFIG_USB) else if(port >= 0x340 && port < 0x3a0) return *(volatile unsigned short *)PORT2ADDR_USB(port); @@ -164,6 +195,11 @@ void _outb(unsigned char b, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outb(b, PORT2ADDR_NE(port)); else +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + *(volatile unsigned char *)__port2addr_ata(port) = b; + } else +#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_byte(0, port, &b, sizeof(b), 1, 0); @@ -177,6 +213,11 @@ void _outw(unsigned short w, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outw(w, PORT2ADDR_NE(port)); else +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + *(volatile unsigned short *)__port2addr_ata(port) = w; + } else +#endif #if defined(CONFIG_USB) if(port >= 0x340 && port < 0x3a0) *(volatile unsigned short *)PORT2ADDR_USB(port) = w; @@ -222,6 +263,14 @@ void _insb(unsigned int port, void *addr, unsigned long count) { if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_insb(PORT2ADDR_NE(port), addr, count); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + unsigned char *buf = addr; + unsigned char *portp = __port2addr_ata(port); + while (count--) + *buf++ = *(volatile unsigned char *)portp; + } +#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread_byte(0, port, (void *)addr, sizeof(unsigned char), @@ -253,6 +302,12 @@ void _insw(unsigned int port, void *addr, unsigned long count) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short), count, 1); +#endif +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *buf++ = *(volatile unsigned short *)portp; #endif } else { portp = PORT2ADDR(port); @@ -280,6 +335,12 @@ void _outsb(unsigned int port, const void *addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) _ne_outb(*buf++, portp); +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *(volatile unsigned char *)portp = *buf++; +#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_byte(0, port, (void *)addr, sizeof(unsigned char), @@ -305,6 +366,12 @@ void _outsw(unsigned int port, const void *addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) *(volatile unsigned short *)portp = *buf++; +#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) + } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { + portp = __port2addr_ata(port); + while (count--) + *(volatile unsigned short *)portp = *buf++; +#endif #if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_CFC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite_word(9, port, (void *)addr, sizeof(unsigned short), diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index 61d3b01cbe0..62d6b71de45 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c @@ -218,13 +218,13 @@ static void shutdown_opsput_lanpld_irq(unsigned int irq) static struct hw_interrupt_type opsput_lanpld_irq_type = { - "OPSPUT-PLD-LAN-IRQ", - startup_opsput_lanpld_irq, - shutdown_opsput_lanpld_irq, - enable_opsput_lanpld_irq, - disable_opsput_lanpld_irq, - mask_and_ack_opsput_lanpld, - end_opsput_lanpld_irq + .typename = "OPSPUT-PLD-LAN-IRQ", + .startup = startup_opsput_lanpld_irq, + .shutdown = shutdown_opsput_lanpld_irq, + .enable = enable_opsput_lanpld_irq, + .disable = disable_opsput_lanpld_irq, + .ack = mask_and_ack_opsput_lanpld, + .end = end_opsput_lanpld_irq }; /* @@ -374,7 +374,6 @@ void __init init_IRQ(void) disable_opsput_pld_irq(PLD_IRQ_SIO0_SND); #endif /* CONFIG_SERIAL_M32R_PLDSIO */ -#if defined(CONFIG_M32R_CFC) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; @@ -398,8 +397,6 @@ void __init init_IRQ(void) irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ disable_opsput_pld_irq(PLD_IRQ_CFC_EJECT); -#endif /* CONFIG_M32R_CFC */ - /* * INT0# is used for LAN, DIO -- cgit v1.2.3 From 24ec839c431eb79bb8f6abc00c4e1eb3b8c4d517 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 8 Dec 2006 02:36:04 -0800 Subject: [PATCH] tty: ->signal->tty locking Fix the locking of signal->tty. Use ->sighand->siglock to protect ->signal->tty; this lock is already used by most other members of ->signal/->sighand. And unless we are 'current' or the tasklist_lock is held we need ->siglock to access ->signal anyway. (NOTE: sys_unshare() is broken wrt ->sighand locking rules) Note that tty_mutex is held over tty destruction, so while holding tty_mutex any tty pointer remains valid. Otherwise the lifetime of ttys are governed by their open file handles. This leaves some holes for tty access from signal->tty (or any other non file related tty access). It solves the tty SLAB scribbles we were seeing. (NOTE: the change from group_send_sig_info to __group_send_sig_info needs to be examined by someone familiar with the security framework, I think it is safe given the SEND_SIG_PRIV from other __group_send_sig_info invocations) [schwidefsky@de.ibm.com: 3270 fix] [akpm@osdl.org: various post-viro fixes] Signed-off-by: Peter Zijlstra Acked-by: Alan Cox Cc: Oleg Nesterov Cc: Prarit Bhargava Cc: Chris Wright Cc: Roland McGrath Cc: Stephen Smalley Cc: James Morris Cc: "David S. Miller" Cc: Jeff Dike Cc: Martin Schwidefsky Cc: Jan Kara Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/solaris/misc.c | 4 +--- arch/um/kernel/exec.c | 7 ++++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index 9ed997982f8..e84241d5f7f 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -423,9 +423,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) Solaris setpgrp and setsid? */ ret = sys_setpgid(0, 0); if (ret) return ret; - mutex_lock(&tty_mutex); - current->signal->tty = NULL; - mutex_unlock(&tty_mutex); + proc_clear_tty(current); return process_group(current); } case 2: /* getsid */ diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 0561c43b468..8d56ec6cca7 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -39,12 +39,13 @@ static long execve1(char *file, char __user * __user *argv, char __user *__user *env) { long error; + struct tty_struct *tty; #ifdef CONFIG_TTY_LOG mutex_lock(&tty_mutex); - task_lock(current); /* FIXME: is this needed ? */ - log_exec(argv, current->signal->tty); - task_unlock(current); + tty = get_current_tty(); + if (tty) + log_exec(argv, tty); mutex_unlock(&tty_mutex); #endif error = do_execve(file, argv, env, ¤t->thread.regs); -- cgit v1.2.3 From 91768d6c2bad0d2766a166f13f2f57e197de3458 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 8 Dec 2006 02:36:21 -0800 Subject: [PATCH] Generic BUG for i386 This makes i386 use the generic BUG machinery. There are no functional changes from the old i386 implementation. The main advantage in using the generic BUG machinery for i386 is that the inlined overhead of BUG is just the ud2a instruction; the file+line(+function) information are no longer inlined into the instruction stream. This reduces cache pollution, and makes disassembly work properly. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Hugh Dickens Cc: Michael Ellerman Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 5 +++++ arch/i386/kernel/module.c | 4 +++- arch/i386/kernel/traps.c | 41 +++++++++++------------------------------ arch/i386/kernel/vmlinux.lds.S | 2 ++ 4 files changed, 21 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index ea70359b02d..c2362c7ba74 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -49,6 +49,11 @@ config GENERIC_IOMAP bool default y +config GENERIC_BUG + bool + default y + depends on BUG + config GENERIC_HWEIGHT bool default y diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index d7d9c8b23f7..3db0a5442eb 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -21,6 +21,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -141,10 +142,11 @@ int module_finalize(const Elf_Ehdr *hdr, apply_paravirt(pseg, pseg + para->sh_size); } - return 0; + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); + module_bug_cleanup(mod); } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 68de48e498c..2b30dbf8d11 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef CONFIG_EISA #include @@ -420,43 +421,22 @@ void show_registers(struct pt_regs *regs) printk("\n"); } -static void handle_BUG(struct pt_regs *regs) +int is_valid_bugaddr(unsigned long eip) { - unsigned long eip = regs->eip; unsigned short ud2; if (eip < PAGE_OFFSET) - return; + return 0; if (probe_kernel_address((unsigned short *)eip, ud2)) - return; - if (ud2 != 0x0b0f) - return; - - printk(KERN_EMERG "------------[ cut here ]------------\n"); - -#ifdef CONFIG_DEBUG_BUGVERBOSE - do { - unsigned short line; - char *file; - char c; - - if (probe_kernel_address((unsigned short *)(eip + 2), line)) - break; - if (probe_kernel_address((char **)(eip + 4), file) || - (unsigned long)file < PAGE_OFFSET || - probe_kernel_address(file, c)) - file = ""; + return 0; - printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line); - return; - } while (0); -#endif - printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n"); + return ud2 == 0x0b0f; } -/* This is gone through when something in the kernel - * has done something bad and is about to be terminated. -*/ +/* + * This is gone through when something in the kernel has done something bad and + * is about to be terminated. + */ void die(const char * str, struct pt_regs * regs, long err) { static struct { @@ -488,7 +468,8 @@ void die(const char * str, struct pt_regs * regs, long err) unsigned long esp; unsigned short ss; - handle_BUG(regs); + report_bug(regs->eip); + printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk(KERN_EMERG "PREEMPT "); diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 56e6ad5cb04..16d3c7133ad 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -57,6 +57,8 @@ SECTIONS RODATA + BUG_TABLE + . = ALIGN(4); .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) { __tracedata_start = .; -- cgit v1.2.3 From c31a0bf3e1bc581676618db7492f18798fd0a73f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 8 Dec 2006 02:36:22 -0800 Subject: [PATCH] Generic BUG for x86-64 This makes x86-64 use the generic BUG machinery. The main advantage in using the generic BUG machinery for x86-64 is that the inlined overhead of BUG is just the ud2a instruction; the file+line information are no longer inlined into the instruction stream. This reduces cache pollution. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Hugh Dickens Cc: Michael Ellerman Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/Kconfig | 5 +++++ arch/x86_64/kernel/module.c | 5 ++++- arch/x86_64/kernel/traps.c | 36 ++++++++++++------------------------ arch/x86_64/kernel/vmlinux.lds.S | 2 ++ 4 files changed, 23 insertions(+), 25 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index bfbb9bcae12..3254a616c69 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -96,6 +96,11 @@ config AUDIT_ARCH bool default y +config GENERIC_BUG + bool + default y + depends on BUG + source "init/Kconfig" diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index 9d0958ff547..a888e67f587 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -173,10 +174,12 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } - return 0; + + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); + module_bug_cleanup(mod); } diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index a1641ffdffc..b54ccc07f37 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -524,30 +525,15 @@ bad: printk("\n"); } -void handle_BUG(struct pt_regs *regs) -{ - struct bug_frame f; - long len; - const char *prefix = ""; +int is_valid_bugaddr(unsigned long rip) +{ + unsigned short ud2; - if (user_mode(regs)) - return; - if (__copy_from_user(&f, (const void __user *) regs->rip, - sizeof(struct bug_frame))) - return; - if (f.filename >= 0 || - f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) - return; - len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1; - if (len < 0 || len >= PATH_MAX) - f.filename = (int)(long)"unmapped filename"; - else if (len > 50) { - f.filename += len - 50; - prefix = "..."; - } - printk("----------- [cut here ] --------- [please bite here ] ---------\n"); - printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line); -} + if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2))) + return 0; + + return ud2 == 0x0b0f; +} #ifdef CONFIG_BUG void out_of_line_bug(void) @@ -627,7 +613,9 @@ void die(const char * str, struct pt_regs * regs, long err) { unsigned long flags = oops_begin(); - handle_BUG(regs); + if (!user_mode(regs)) + report_bug(regs->rip); + __die(str, regs, err); oops_end(flags); do_exit(SIGSEGV); diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 6a1f8f491e5..6c417788c54 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -51,6 +51,8 @@ SECTIONS RODATA + BUG_TABLE + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { -- cgit v1.2.3 From e182c965b6ce0dffed0967a1be2173825a2ede2f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 8 Dec 2006 02:36:23 -0800 Subject: [PATCH] UML: add generic BUG support The BUG changes in -mm3 need some arch support. This patch adds the UML support needed. For the most part, it was stolen from the underlying architecture. The exception is the kernel eip < PAGE_OFFSET test, which is wrong for skas mode UMLs. Signed-off-by: Jeff Dike Cc: Jeremy Fitzhardinge Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Kconfig | 5 +++++ arch/um/sys-i386/Makefile | 2 +- arch/um/sys-i386/bug.c | 20 ++++++++++++++++++++ arch/um/sys-x86_64/Makefile | 2 +- arch/um/sys-x86_64/bug.c | 20 ++++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 arch/um/sys-i386/bug.c create mode 100644 arch/um/sys-x86_64/bug.c (limited to 'arch') diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 5ac1f2963ae..d32a80e6668 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -47,6 +47,11 @@ config GENERIC_CALIBRATE_DELAY bool default y +config GENERIC_BUG + bool + default y + depends on BUG + # Used in kernel/irq/manage.c and include/linux/irq.h config IRQ_RELEASE_METHOD bool diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 0e32adf03be..098720be019 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -1,4 +1,4 @@ -obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ +obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ sys_call_table.o tls.o diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c new file mode 100644 index 00000000000..200c8ba2879 --- /dev/null +++ b/arch/um/sys-i386/bug.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL V2 + */ + +#include + +/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because + * that's not relevent in skas mode. + */ + +int is_valid_bugaddr(unsigned long eip) +{ + unsigned short ud2; + + if (probe_kernel_address((unsigned short __user *)eip, ud2)) + return 0; + + return ud2 == 0x0b0f; +} diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index f41768b8e25..4d9e5efa6fb 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile @@ -4,7 +4,7 @@ # Licensed under the GPL # -obj-y = bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ +obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ ksyms.o tls.o diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c new file mode 100644 index 00000000000..200c8ba2879 --- /dev/null +++ b/arch/um/sys-x86_64/bug.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com) + * Licensed under the GPL V2 + */ + +#include + +/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because + * that's not relevent in skas mode. + */ + +int is_valid_bugaddr(unsigned long eip) +{ + unsigned short ud2; + + if (probe_kernel_address((unsigned short __user *)eip, ud2)) + return 0; + + return ud2 == 0x0b0f; +} -- cgit v1.2.3 From a8605aef813f8eb3ef4b80d32cba6a671ef8deb0 Mon Sep 17 00:00:00 2001 From: Judith Lebzelter Date: Fri, 8 Dec 2006 02:36:23 -0800 Subject: [PATCH] use generic BUG for ppc Switch ppc over to using the generic BUG implementation. Signed-off-by: Judith Lebzelter Cc: Jeremy Fitzhardinge Cc: Michael Ellerman Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/Kconfig | 5 ++++ arch/ppc/kernel/traps.c | 64 +++++-------------------------------------------- 2 files changed, 11 insertions(+), 58 deletions(-) (limited to 'arch') diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index edf71a4ecc9..f76a146cff1 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -52,6 +52,11 @@ config ARCH_MAY_HAVE_PC_FDC bool default y +config GENERIC_BUG + bool + default y + depends on BUG + source "init/Kconfig" menu "Processor" diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 2f835b9e95e..810f7aa72e9 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -559,64 +560,9 @@ static void emulate_single_step(struct pt_regs *regs) } } -/* - * Look through the list of trap instructions that are used for BUG(), - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know - * that the exception was caused by a trap instruction of some kind. - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 - * otherwise. - */ -extern struct bug_entry __start___bug_table[], __stop___bug_table[]; - -#ifndef CONFIG_MODULES -#define module_find_bug(x) NULL -#endif - -struct bug_entry *find_bug(unsigned long bugaddr) -{ - struct bug_entry *bug; - - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) - if (bugaddr == bug->bug_addr) - return bug; - return module_find_bug(bugaddr); -} - -int check_bug_trap(struct pt_regs *regs) +int is_valid_bugaddr(unsigned long addr) { - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ -#ifdef CONFIG_XMON - xmon_printf(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); -#endif /* CONFIG_XMON */ - printk(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - dump_stack(); - return 1; - } -#ifdef CONFIG_XMON - xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - xmon(regs); -#endif /* CONFIG_XMON */ - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - - return 0; + return addr >= PAGE_OFFSET; } void program_check_exception(struct pt_regs *regs) @@ -671,7 +617,9 @@ void program_check_exception(struct pt_regs *regs) /* trap exception */ if (debugger_bpt(regs)) return; - if (check_bug_trap(regs)) { + + if (!(regs->msr & MSR_PR) && /* not user-mode */ + report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } -- cgit v1.2.3 From aab4c5a51cd6defc374ba1961c996781656d5283 Mon Sep 17 00:00:00 2001 From: "Josef \"Jeff\" Sipek" Date: Fri, 8 Dec 2006 02:36:42 -0800 Subject: [PATCH] i386: change uses of f_{dentry, vfsmnt} to use f_path Change all the uses of f_{dentry,vfsmnt} to f_path.{dentry,mnt} in the i386 arch code. Signed-off-by: Josef "Jeff" Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/cpuid.c | 4 ++-- arch/i386/kernel/msr.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index db6dd20c358..51130b39cd2 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c @@ -116,7 +116,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, char __user *tmp = buf; u32 data[4]; u32 reg = *ppos; - int cpu = iminor(file->f_dentry->d_inode); + int cpu = iminor(file->f_path.dentry->d_inode); if (count % 16) return -EINVAL; /* Invalid chunk size */ @@ -134,7 +134,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, static int cpuid_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_dentry->d_inode); + unsigned int cpu = iminor(file->f_path.dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (cpu >= NR_CPUS || !cpu_online(cpu)) diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 1d1a56cae34..4a472a17d1c 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c @@ -172,7 +172,7 @@ static ssize_t msr_read(struct file *file, char __user * buf, u32 __user *tmp = (u32 __user *) buf; u32 data[2]; u32 reg = *ppos; - int cpu = iminor(file->f_dentry->d_inode); + int cpu = iminor(file->f_path.dentry->d_inode); int err; if (count % 8) @@ -196,7 +196,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, const u32 __user *tmp = (const u32 __user *)buf; u32 data[2]; u32 reg = *ppos; - int cpu = iminor(file->f_dentry->d_inode); + int cpu = iminor(file->f_path.dentry->d_inode); int err; if (count % 8) @@ -216,7 +216,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf, static int msr_open(struct inode *inode, struct file *file) { - unsigned int cpu = iminor(file->f_dentry->d_inode); + unsigned int cpu = iminor(file->f_path.dentry->d_inode); struct cpuinfo_x86 *c = &(cpu_data)[cpu]; if (cpu >= NR_CPUS || !cpu_online(cpu)) -- cgit v1.2.3 From c941192aafe053ae445fb22f5d89bd34794c5442 Mon Sep 17 00:00:00 2001 From: "Josef \"Jeff\" Sipek" Date: Fri, 8 Dec 2006 02:36:43 -0800 Subject: [PATCH] x86_64: change uses of f_{dentry, vfsmnt} to use f_path Change all the uses of f_{dentry,vfsmnt} to f_path.{dentry,mnt} in the x86_64 arch code. Signed-off-by: Josef "Jeff" Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/ia32/ia32_aout.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c index 396d3c10001..be87df506f3 100644 --- a/arch/x86_64/ia32/ia32_aout.c +++ b/arch/x86_64/ia32/ia32_aout.c @@ -272,7 +272,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || N_TRSIZE(ex) || N_DRSIZE(ex) || - i_size_read(bprm->file->f_dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { + i_size_read(bprm->file->f_path.dentry->d_inode) < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { return -ENOEXEC; } @@ -357,7 +357,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) { printk(KERN_WARNING "fd_offset is not page aligned. Please convert program: %s\n", - bprm->file->f_dentry->d_name.name); + bprm->file->f_path.dentry->d_name.name); error_time = jiffies; } #endif @@ -440,7 +440,7 @@ static int load_aout_library(struct file *file) int retval; struct exec ex; - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; retval = -ENOEXEC; error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); @@ -471,7 +471,7 @@ static int load_aout_library(struct file *file) { printk(KERN_WARNING "N_TXTOFF is not page aligned. Please convert library: %s\n", - file->f_dentry->d_name.name); + file->f_path.dentry->d_name.name); error_time = jiffies; } #endif -- cgit v1.2.3 From 8ac0352bb20c5a8c051218c689d263b4591d50e1 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:36:51 -0800 Subject: [PATCH] struct path: convert alpha Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/osf_sys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index ad617365199..fb804043b32 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -277,7 +277,7 @@ osf_fstatfs(unsigned long fd, struct osf_statfs __user *buffer, unsigned long bu retval = -EBADF; file = fget(fd); if (file) { - retval = do_osf_statfs(file->f_dentry, buffer, bufsiz); + retval = do_osf_statfs(file->f_path.dentry, buffer, bufsiz); fput(file); } return retval; -- cgit v1.2.3 From d817be9ca8766b521f6195f57281284c5ab0ff4c Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:36:58 -0800 Subject: [PATCH] struct path: convert cris Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/cris/arch-v32/drivers/sync_serial.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/cris/arch-v32/drivers/sync_serial.c b/arch/cris/arch-v32/drivers/sync_serial.c index e067806b220..424eb0eb1cd 100644 --- a/arch/cris/arch-v32/drivers/sync_serial.c +++ b/arch/cris/arch-v32/drivers/sync_serial.c @@ -504,7 +504,7 @@ static int sync_serial_release(struct inode *inode, struct file *file) static unsigned int sync_serial_poll(struct file *file, poll_table *wait) { - int dev = iminor(file->f_dentry->d_inode); + int dev = iminor(file->f_path.dentry->d_inode); unsigned int mask = 0; sync_port* port; DEBUGPOLL( static unsigned int prev_mask = 0; ); @@ -531,7 +531,7 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int return_val = 0; - int dev = iminor(file->f_dentry->d_inode); + int dev = iminor(file->f_path.dentry->d_inode); sync_port* port; reg_sser_rw_tr_cfg tr_cfg; reg_sser_rw_rec_cfg rec_cfg; @@ -789,7 +789,7 @@ static int sync_serial_ioctl(struct inode *inode, struct file *file, static ssize_t sync_serial_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { - int dev = iminor(file->f_dentry->d_inode); + int dev = iminor(file->f_path.dentry->d_inode); DECLARE_WAITQUEUE(wait, current); sync_port *port; unsigned long c, c1; @@ -919,7 +919,7 @@ static ssize_t sync_serial_write(struct file * file, const char * buf, static ssize_t sync_serial_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int dev = iminor(file->f_dentry->d_inode); + int dev = iminor(file->f_path.dentry->d_inode); int avail; sync_port *port; unsigned char* start; -- cgit v1.2.3 From 1f70ceccb8e9159118c1ac65a245b16406d9e721 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:01 -0800 Subject: [PATCH] struct path: convert frv Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/mm/elf-fdpic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/frv/mm/elf-fdpic.c b/arch/frv/mm/elf-fdpic.c index f5a653033fe..9477ccce070 100644 --- a/arch/frv/mm/elf-fdpic.c +++ b/arch/frv/mm/elf-fdpic.c @@ -110,14 +110,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi #if 0 printk("[area] l=%lx (ENOMEM) f='%s'\n", - len, filp ? filp->f_dentry->d_name.name : ""); + len, filp ? filp->f_path.dentry->d_name.name : ""); #endif return -ENOMEM; success: #if 0 printk("[area] l=%lx ad=%lx f='%s'\n", - len, addr, filp ? filp->f_dentry->d_name.name : ""); + len, addr, filp ? filp->f_path.dentry->d_name.name : ""); #endif return addr; } /* end arch_get_unmapped_area() */ -- cgit v1.2.3 From b66ffad90429a2ed84c6e8954d205539f6cc86a9 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:09 -0800 Subject: [PATCH] struct path: convert ia64 Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ia64/ia32/sys_ia32.c | 4 ++-- arch/ia64/kernel/perfmon.c | 10 +++++----- arch/ia64/kernel/salinfo.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index a4a6e1463af..957681c39ad 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c @@ -235,7 +235,7 @@ mmap_subpage (struct file *file, unsigned long start, unsigned long end, int pro if (!(flags & MAP_ANONYMOUS)) { /* read the file contents */ - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; if (!inode->i_fop || !file->f_op->read || ((*file->f_op->read)(file, (char __user *) start, end - start, &off) < 0)) { @@ -837,7 +837,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro if (!is_congruent) { /* read the file contents */ - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; if (!inode->i_fop || !file->f_op->read || ((*file->f_op->read)(file, (char __user *) pstart, pend - pstart, &poff) < 0)) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index dbb28164b19..aa94f60fa8e 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -2188,13 +2188,13 @@ pfm_alloc_fd(struct file **cfile) /* * allocate a new dcache entry */ - file->f_dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); - if (!file->f_dentry) goto out; + file->f_path.dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this); + if (!file->f_path.dentry) goto out; - file->f_dentry->d_op = &pfmfs_dentry_operations; + file->f_path.dentry->d_op = &pfmfs_dentry_operations; - d_add(file->f_dentry, inode); - file->f_vfsmnt = mntget(pfmfs_mnt); + d_add(file->f_path.dentry, inode); + file->f_path.mnt = mntget(pfmfs_mnt); file->f_mapping = inode->i_mapping; file->f_op = &pfm_file_ops; diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index fd607ca51a8..e375a2f0f2c 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c @@ -302,7 +302,7 @@ salinfo_event_open(struct inode *inode, struct file *file) static ssize_t salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; @@ -464,7 +464,7 @@ retry: static ssize_t salinfo_log_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; u8 *buf; @@ -525,7 +525,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) static ssize_t salinfo_log_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) { - struct inode *inode = file->f_dentry->d_inode; + struct inode *inode = file->f_path.dentry->d_inode; struct proc_dir_entry *entry = PDE(inode); struct salinfo_data *data = entry->data; char cmd[32]; -- cgit v1.2.3 From 1b04fe9a8ef10774174897b15d753b9de85fe9e9 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:20 -0800 Subject: [PATCH] struct path: convert mips Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/rtlx.c | 6 +++--- arch/mips/kernel/sysirix.c | 10 +++++----- arch/mips/kernel/vpe.c | 2 +- arch/mips/lasat/sysctl.c | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 8c8c8324f77..5a99e3e0c96 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -415,7 +415,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) int minor; unsigned int mask = 0; - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); poll_wait(file, &channel_wqs[minor].rt_queue, wait); poll_wait(file, &channel_wqs[minor].lx_queue, wait); @@ -437,7 +437,7 @@ static unsigned int file_poll(struct file *file, poll_table * wait) static ssize_t file_read(struct file *file, char __user * buffer, size_t count, loff_t * ppos) { - int minor = iminor(file->f_dentry->d_inode); + int minor = iminor(file->f_path.dentry->d_inode); /* data available? */ if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { @@ -454,7 +454,7 @@ static ssize_t file_write(struct file *file, const char __user * buffer, struct rtlx_channel *rt; DECLARE_WAITQUEUE(wait, current); - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); rt = &rtlx->channel[minor]; /* any space left... */ diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 93c74fefff7..6c2406a93f2 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -732,7 +732,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs __user *buf) goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; @@ -1041,7 +1041,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot, unsigned long old_pos; long max_size = offset + len; - if (max_size > file->f_dentry->d_inode->i_size) { + if (max_size > file->f_path.dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1406,7 +1406,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; @@ -1526,7 +1526,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs) unsigned long old_pos; long max_size = off2 + len; - if (max_size > file->f_dentry->d_inode->i_size) { + if (max_size > file->f_path.dentry->d_inode->i_size) { old_pos = sys_lseek (fd, max_size - 1, 0); sys_write (fd, (void __user *) "", 1); sys_lseek (fd, old_pos, 0); @@ -1658,7 +1658,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs __user *buf) error = -EBADF; goto out; } - error = vfs_statfs(file->f_dentry, &kbuf); + error = vfs_statfs(file->f_path.dentry, &kbuf); if (error) goto out_f; diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 51ddd216689..666bef484dc 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -1179,7 +1179,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, size_t ret = count; struct vpe *v; - minor = iminor(file->f_dentry->d_inode); + minor = iminor(file->f_path.dentry->d_inode); if ((v = get_vpe(minor)) == NULL) return -ENODEV; diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index 6dd7ae1b7c2..da35d455549 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c @@ -286,11 +286,11 @@ int proc_lasat_eeprom_value(ctl_table *table, int write, struct file *filp, mutex_unlock(&lasat_info_mutex); return r; } - if (filp && filp->f_dentry) + if (filp && filp->f_path.dentry) { - if (!strcmp(filp->f_dentry->d_name.name, "prid")) + if (!strcmp(filp->f_path.dentry->d_name.name, "prid")) lasat_board_info.li_eeprom_info.prid = lasat_board_info.li_prid; - if (!strcmp(filp->f_dentry->d_name.name, "debugaccess")) + if (!strcmp(filp->f_path.dentry->d_name.name, "debugaccess")) lasat_board_info.li_eeprom_info.debugaccess = lasat_board_info.li_debugaccess; } lasat_write_eeprom_info(); -- cgit v1.2.3 From 0c5a5566892de5b240c89b9f72eb1c2e861206a0 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:28 -0800 Subject: [PATCH] struct path: convert parisc Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/hpux/sys_hpux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index 2e2dc4f2c85..d88309209f5 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c @@ -237,7 +237,7 @@ asmlinkage long hpux_fstatfs(unsigned int fd, struct hpux_statfs __user * buf) file = fget(fd); if (!file) goto out; - error = vfs_statfs_hpux(file->f_dentry, &tmp); + error = vfs_statfs_hpux(file->f_path.dentry, &tmp); if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) error = -EFAULT; fput(file); -- cgit v1.2.3 From b4d1ab58c016f4dffef4ff1eb392fa84e3c35024 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:30 -0800 Subject: [PATCH] struct path: convert powerpc Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kernel/proc_ppc64.c | 6 +++--- arch/powerpc/kernel/rtas_flash.c | 16 ++++++++-------- arch/powerpc/platforms/cell/spufs/inode.c | 4 ++-- arch/powerpc/platforms/cell/spufs/syscalls.c | 2 +- arch/powerpc/platforms/iseries/mf.c | 2 +- arch/powerpc/platforms/pseries/hvCall_inst.c | 2 +- arch/powerpc/platforms/pseries/scanlog.c | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c index f598cb51953..dd7001cacf7 100644 --- a/arch/powerpc/kernel/proc_ppc64.c +++ b/arch/powerpc/kernel/proc_ppc64.c @@ -83,7 +83,7 @@ __initcall(proc_ppc64_init); static loff_t page_map_seek( struct file *file, loff_t off, int whence) { loff_t new; - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); switch(whence) { case 0: @@ -106,13 +106,13 @@ static loff_t page_map_seek( struct file *file, loff_t off, int whence) static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size); } static int page_map_mmap( struct file *file, struct vm_area_struct *vma ) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); if ((vma->vm_end - vma->vm_start) > dp->size) return -EINVAL; diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 7d0f13fecc0..0c4fcd34bfe 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -193,7 +193,7 @@ static void free_flash_list(struct flash_block_list *f) static int rtas_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_update_flash_t *uf; uf = (struct rtas_update_flash_t *) dp->data; @@ -255,7 +255,7 @@ static void get_flash_status_msg(int status, char *buf) static ssize_t rtas_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_update_flash_t *uf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -299,7 +299,7 @@ void rtas_block_ctor(void *ptr, struct kmem_cache *cache, unsigned long flags) static ssize_t rtas_flash_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_update_flash_t *uf; char *p; int next_free; @@ -391,7 +391,7 @@ static void manage_flash(struct rtas_manage_flash_t *args_buf) static ssize_t manage_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_manage_flash_t *args_buf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -421,7 +421,7 @@ static ssize_t manage_flash_read(struct file *file, char __user *buf, static ssize_t manage_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_manage_flash_t *args_buf; const char reject_str[] = "0"; const char commit_str[] = "1"; @@ -492,7 +492,7 @@ static int get_validate_flash_msg(struct rtas_validate_flash_t *args_buf, static ssize_t validate_flash_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_validate_flash_t *args_buf; char msg[RTAS_MSG_MAXLEN]; int msglen; @@ -520,7 +520,7 @@ static ssize_t validate_flash_read(struct file *file, char __user *buf, static ssize_t validate_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_validate_flash_t *args_buf; int rc; @@ -569,7 +569,7 @@ done: static int validate_flash_release(struct inode *inode, struct file *file) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); struct rtas_validate_flash_t *args_buf; args_buf = (struct rtas_validate_flash_t *) dp->data; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index e3af9112c02..738b9244382 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -205,7 +205,7 @@ static int spufs_dir_close(struct inode *inode, struct file *file) struct dentry *dir; int ret; - dir = file->f_dentry; + dir = file->f_path.dentry; parent = dir->d_parent->d_inode; ctx = SPUFS_I(dir->d_inode)->i_ctx; @@ -363,7 +363,7 @@ static int spufs_gang_close(struct inode *inode, struct file *file) struct dentry *dir; int ret; - dir = file->f_dentry; + dir = file->f_path.dentry; parent = dir->d_parent->d_inode; ret = spufs_rmgang(parent, dir); diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c index a6d1ae4dc2a..8e37bdf4dfd 100644 --- a/arch/powerpc/platforms/cell/spufs/syscalls.c +++ b/arch/powerpc/platforms/cell/spufs/syscalls.c @@ -46,7 +46,7 @@ static long do_spu_run(struct file *filp, if (filp->f_op != &spufs_context_fops) goto out; - i = SPUFS_I(filp->f_dentry->d_inode); + i = SPUFS_I(filp->f_path.dentry->d_inode); ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); if (put_user(npc, unpc)) diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index b5737d68d6c..cff15ae24f6 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -1178,7 +1178,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - struct proc_dir_entry *dp = PDE(file->f_dentry->d_inode); + struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode); ssize_t rc; dma_addr_t dma_addr; char *page; diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index 446e17d162a..80181c4c49e 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -85,7 +85,7 @@ static int hcall_inst_seq_open(struct inode *inode, struct file *file) rc = seq_open(file, &hcall_inst_seq_ops); seq = file->private_data; - seq->private = file->f_dentry->d_inode->i_private; + seq->private = file->f_path.dentry->d_inode->i_private; return rc; } diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 77a5bb1d9c3..45368a57d7d 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c @@ -47,7 +47,7 @@ static struct proc_dir_entry *proc_ppc64_scan_log_dump; /* The proc file */ static ssize_t scanlog_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct inode * inode = file->f_dentry->d_inode; + struct inode * inode = file->f_path.dentry->d_inode; struct proc_dir_entry *dp; unsigned int *data; int status; -- cgit v1.2.3 From c2c8bbadbf6532e48025c9065231244f0c477c29 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:31 -0800 Subject: [PATCH] struct path: convert ppc Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/8xx_io/cs4218_tdm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/ppc/8xx_io/cs4218_tdm.c b/arch/ppc/8xx_io/cs4218_tdm.c index 959d31c26cb..c71ef3c2e7b 100644 --- a/arch/ppc/8xx_io/cs4218_tdm.c +++ b/arch/ppc/8xx_io/cs4218_tdm.c @@ -2165,7 +2165,7 @@ static int sq_release(struct inode *inode, struct file *file) int rc = 0; if (sq.busy) - rc = sq_fsync(file, file->f_dentry); + rc = sq_fsync(file, file->f_path.dentry); sound.soft = sound.dsp; sound.hard = sound.dsp; sound_silence(); @@ -2218,25 +2218,25 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, return 0; case SNDCTL_DSP_POST: case SNDCTL_DSP_SYNC: - return sq_fsync(file, file->f_dentry); + return sq_fsync(file, file->f_path.dentry); /* ++TeSche: before changing any of these it's * probably wise to wait until sound playing has * settled down. */ case SNDCTL_DSP_SPEED: - sq_fsync(file, file->f_dentry); + sq_fsync(file, file->f_path.dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_speed(data)); case SNDCTL_DSP_STEREO: - sq_fsync(file, file->f_dentry); + sq_fsync(file, file->f_path.dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_stereo(data)); case SOUND_PCM_WRITE_CHANNELS: - sq_fsync(file, file->f_dentry); + sq_fsync(file, file->f_path.dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_stereo(data-1)+1); case SNDCTL_DSP_SETFMT: - sq_fsync(file, file->f_dentry); + sq_fsync(file, file->f_path.dentry); IOCTL_IN(arg, data); return IOCTL_OUT(arg, sound_set_format(data)); case SNDCTL_DSP_GETFMTS: -- cgit v1.2.3 From d20343e7406a114a561030e683fafc4fdbc9c6bd Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:35 -0800 Subject: [PATCH] struct path: convert s390 Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/hypfs/inode.c | 4 ++-- arch/s390/kernel/debug.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index cd702ae45d6..b6716c4b993 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -109,7 +109,7 @@ static void hypfs_drop_inode(struct inode *inode) static int hypfs_open(struct inode *inode, struct file *filp) { - char *data = filp->f_dentry->d_inode->i_private; + char *data = filp->f_path.dentry->d_inode->i_private; struct hypfs_sb_info *fs_info; if (filp->f_mode & FMODE_WRITE) { @@ -174,7 +174,7 @@ static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, struct hypfs_sb_info *fs_info; size_t count = iov_length(iov, nr_segs); - sb = iocb->ki_filp->f_dentry->d_inode->i_sb; + sb = iocb->ki_filp->f_path.dentry->d_inode->i_sb; fs_info = sb->s_fs_info; /* * Currently we only allow one update per second for two reasons: diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 43f3d0c7e13..ef5266fbce6 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -603,13 +603,13 @@ debug_open(struct inode *inode, struct file *file) debug_info_t *debug_info, *debug_info_snapshot; down(&debug_lock); - debug_info = file->f_dentry->d_inode->i_private; + debug_info = file->f_path.dentry->d_inode->i_private; /* find debug view */ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (!debug_info->views[i]) continue; else if (debug_info->debugfs_entries[i] == - file->f_dentry) { + file->f_path.dentry) { goto found; /* found view ! */ } } -- cgit v1.2.3 From c943c4b49c75f3cae89e5d993ce1ae859395caa2 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:38 -0800 Subject: [PATCH] struct path: convert sh Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/oprofile/op_model_sh7750.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/oprofile/op_model_sh7750.c b/arch/sh/oprofile/op_model_sh7750.c index c265185b22a..60402eec4b4 100644 --- a/arch/sh/oprofile/op_model_sh7750.c +++ b/arch/sh/oprofile/op_model_sh7750.c @@ -142,7 +142,7 @@ static u64 sh7750_read_counter(int counter) */ static inline int to_counter(struct file *file) { - const unsigned char *name = file->f_dentry->d_parent->d_name.name; + const unsigned char *name = file->f_path.dentry->d_parent->d_name.name; return (int)simple_strtol(name, NULL, 10); } -- cgit v1.2.3 From 45e079810a27d4a072347d90d405948f95cee812 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:41 -0800 Subject: [PATCH] struct path: convert sparc Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/kernel/sys_sunos.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 6f3ac548ee6..0bf8c165fc9 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c @@ -94,8 +94,8 @@ asmlinkage unsigned long sunos_mmap(unsigned long addr, unsigned long len, * SunOS is so stupid some times... hmph! */ if (file) { - if (imajor(file->f_dentry->d_inode) == MEM_MAJOR && - iminor(file->f_dentry->d_inode) == 5) { + if (imajor(file->f_path.dentry->d_inode) == MEM_MAJOR && + iminor(file->f_path.dentry->d_inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); file = NULL; @@ -655,7 +655,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) if (!file) goto out; - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; socket = SOCKET_I(inode); local.sin_family = AF_INET; -- cgit v1.2.3 From 1250ca4c8f48de482ec7c476cb024fe93ad1fbb3 Mon Sep 17 00:00:00 2001 From: Josef Sipek Date: Fri, 8 Dec 2006 02:37:41 -0800 Subject: [PATCH] struct path: convert sparc64 Signed-off-by: Josef Sipek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc64/kernel/binfmt_aout32.c | 4 ++-- arch/sparc64/kernel/sys_sunos32.c | 4 ++-- arch/sparc64/solaris/fs.c | 4 ++-- arch/sparc64/solaris/ioctl.c | 6 +++--- arch/sparc64/solaris/misc.c | 2 +- arch/sparc64/solaris/socksys.c | 14 +++++++------- arch/sparc64/solaris/timod.c | 10 +++++----- 7 files changed, 22 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c index d7caa60a007..f205fc7cbcd 100644 --- a/arch/sparc64/kernel/binfmt_aout32.c +++ b/arch/sparc64/kernel/binfmt_aout32.c @@ -209,7 +209,7 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs) if ((N_MAGIC(ex) != ZMAGIC && N_MAGIC(ex) != OMAGIC && N_MAGIC(ex) != QMAGIC && N_MAGIC(ex) != NMAGIC) || N_TRSIZE(ex) || N_DRSIZE(ex) || - bprm->file->f_dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { + bprm->file->f_path.dentry->d_inode->i_size < ex.a_text+ex.a_data+N_SYMSIZE(ex)+N_TXTOFF(ex)) { return -ENOEXEC; } @@ -349,7 +349,7 @@ static int load_aout32_library(struct file *file) int retval; struct exec ex; - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; retval = -ENOEXEC; error = kernel_read(file, 0, (char *) &ex, sizeof(ex)); diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 7da72d3b322..4446f66590f 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -83,7 +83,7 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of file = fget(fd); if (!file) goto out; - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { flags |= MAP_ANONYMOUS; fput(file); @@ -615,7 +615,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) if (!file) return 0; - inode = file->f_dentry->d_inode; + inode = file->f_path.dentry->d_inode; socket = SOCKET_I(inode); local.sin_family = AF_INET; diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 12a940cc791..61be597bf43 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c @@ -449,7 +449,7 @@ asmlinkage int solaris_fstatvfs(unsigned int fd, u32 buf) error = -EBADF; file = fget(fd); if (file) { - error = report_statvfs(file->f_vfsmnt, file->f_dentry->d_inode, buf); + error = report_statvfs(file->f_path.mnt, file->f_path.dentry->d_inode, buf); fput(file); } @@ -481,7 +481,7 @@ asmlinkage int solaris_fstatvfs64(unsigned int fd, u32 buf) file = fget(fd); if (file) { lock_kernel(); - error = report_statvfs64(file->f_vfsmnt, file->f_dentry->d_inode, buf); + error = report_statvfs64(file->f_path.mnt, file->f_path.dentry->d_inode, buf); unlock_kernel(); fput(file); } diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c index be0a054e3ed..330743c5b3d 100644 --- a/arch/sparc64/solaris/ioctl.c +++ b/arch/sparc64/solaris/ioctl.c @@ -299,8 +299,8 @@ static inline int solaris_sockmod(unsigned int fd, unsigned int cmd, u32 arg) rcu_read_lock(); fdt = files_fdtable(current->files); if (! fdt->fd[fd] || - ! fdt->fd[fd]->f_dentry || - ! (ino = fdt->fd[fd]->f_dentry->d_inode) || + ! fdt->fd[fd]->f_path.dentry || + ! (ino = fdt->fd[fd]->f_path.dentry->d_inode) || ! S_ISSOCK(ino->i_mode)) { rcu_read_unlock(); return TBADF; @@ -480,7 +480,7 @@ static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd struct sol_socket_struct *sock; struct module_info *mi; - ino = filp->f_dentry->d_inode; + ino = filp->f_path.dentry->d_inode; if (!S_ISSOCK(ino->i_mode)) return -EBADF; sock = filp->private_data; diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c index e84241d5f7f..bca16e8c95c 100644 --- a/arch/sparc64/solaris/misc.c +++ b/arch/sparc64/solaris/misc.c @@ -77,7 +77,7 @@ static u32 do_solaris_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u64 o if (!file) goto out; else { - struct inode * inode = file->f_dentry->d_inode; + struct inode * inode = file->f_path.dentry->d_inode; if(imajor(inode) == MEM_MAJOR && iminor(inode) == 5) { flags |= MAP_ANONYMOUS; diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c index 7c90e41fd3b..89a4757f192 100644 --- a/arch/sparc64/solaris/socksys.c +++ b/arch/sparc64/solaris/socksys.c @@ -96,13 +96,13 @@ static int socksys_open(struct inode * inode, struct file * filp) * No shit. WTF is it supposed to do, anyway? * * Try instead: - * d_delete(filp->f_dentry), then d_instantiate with sock inode + * d_delete(filp->f_path.dentry), then d_instantiate with sock inode */ - dentry = filp->f_dentry; - filp->f_dentry = dget(fcheck(fd)->f_dentry); - filp->f_dentry->d_inode->i_rdev = inode->i_rdev; - filp->f_dentry->d_inode->i_flock = inode->i_flock; - SOCKET_I(filp->f_dentry->d_inode)->file = filp; + dentry = filp->f_path.dentry; + filp->f_path.dentry = dget(fcheck(fd)->f_path.dentry); + filp->f_path.dentry->d_inode->i_rdev = inode->i_rdev; + filp->f_path.dentry->d_inode->i_flock = inode->i_flock; + SOCKET_I(filp->f_path.dentry->d_inode)->file = filp; filp->f_op = &socksys_file_ops; sock = (struct sol_socket_struct*) mykmalloc(sizeof(struct sol_socket_struct), GFP_KERNEL); @@ -148,7 +148,7 @@ static unsigned int socksys_poll(struct file * filp, poll_table * wait) struct inode *ino; unsigned int mask = 0; - ino=filp->f_dentry->d_inode; + ino=filp->f_path.dentry->d_inode; if (ino && S_ISSOCK(ino->i_mode)) { struct sol_socket_struct *sock; sock = (struct sol_socket_struct*)filp->private_data; diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index b84e5456b02..a9d32ceabf2 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c @@ -147,7 +147,7 @@ static void timod_wake_socket(unsigned int fd) SOLD("wakeing socket"); fdt = files_fdtable(current->files); - sock = SOCKET_I(fdt->fd[fd]->f_dentry->d_inode); + sock = SOCKET_I(fdt->fd[fd]->f_path.dentry->d_inode); wake_up_interruptible(&sock->wait); read_lock(&sock->sk->sk_callback_lock); if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags)) @@ -361,7 +361,7 @@ int timod_putmsg(unsigned int fd, char __user *ctl_buf, int ctl_len, fdt = files_fdtable(current->files); filp = fdt->fd[fd]; - ino = filp->f_dentry->d_inode; + ino = filp->f_path.dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLD("entry"); if (get_user(ret, (int __user *)A(ctl_buf))) @@ -644,7 +644,7 @@ int timod_getmsg(unsigned int fd, char __user *ctl_buf, int ctl_maxlen, s32 __us SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p)); fdt = files_fdtable(current->files); filp = fdt->fd[fd]; - ino = filp->f_dentry->d_inode; + ino = filp->f_path.dentry->d_inode; sock = (struct sol_socket_struct *)filp->private_data; SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL)); if ( ctl_maxlen > 0 && !sock->pfirst && SOCKET_I(ino)->type == SOCK_STREAM @@ -865,7 +865,7 @@ asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) filp = fdt->fd[fd]; if(!filp) goto out; - ino = filp->f_dentry->d_inode; + ino = filp->f_path.dentry->d_inode; if (!ino || !S_ISSOCK(ino->i_mode)) goto out; @@ -933,7 +933,7 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) filp = fdt->fd[fd]; if(!filp) goto out; - ino = filp->f_dentry->d_inode; + ino = filp->f_path.dentry->d_inode; if (!ino) goto out; if (!S_ISSOCK(ino->i_mode) && -- cgit v1.2.3 From f0d1b0b30d250a07627ad8b9fbbb5c7cc08422e8 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Dec 2006 02:37:49 -0800 Subject: [PATCH] LOG2: Implement a general integer log2 facility in the kernel This facility provides three entry points: ilog2() Log base 2 of unsigned long ilog2_u32() Log base 2 of u32 ilog2_u64() Log base 2 of u64 These facilities can either be used inside functions on dynamic data: int do_something(long q) { ...; y = ilog2(x) ...; } Or can be used to statically initialise global variables with constant values: unsigned n = ilog2(27); When performing static initialisation, the compiler will report "error: initializer element is not constant" if asked to take a log of zero or of something not reducible to a constant. They treat negative numbers as unsigned. When not dealing with a constant, they fall back to using fls() which permits them to use arch-specific log calculation instructions - such as BSR on x86/x86_64 or SCAN on FRV - if available. [akpm@osdl.org: MMC fix] Signed-off-by: David Howells Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Herbert Xu Cc: David Howells Cc: Wojtek Kaniewski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/Kconfig | 8 ++++++++ arch/arm/Kconfig | 8 ++++++++ arch/arm26/Kconfig | 8 ++++++++ arch/avr32/Kconfig | 8 ++++++++ arch/cris/Kconfig | 8 ++++++++ arch/frv/Kconfig | 8 ++++++++ arch/h8300/Kconfig | 8 ++++++++ arch/i386/Kconfig.cpu | 8 ++++++++ arch/ia64/Kconfig | 8 ++++++++ arch/m32r/Kconfig | 8 ++++++++ arch/m68k/Kconfig | 8 ++++++++ arch/m68knommu/Kconfig | 8 ++++++++ arch/mips/Kconfig | 8 ++++++++ arch/parisc/Kconfig | 8 ++++++++ arch/powerpc/Kconfig | 8 ++++++++ arch/ppc/Kconfig | 8 ++++++++ arch/s390/Kconfig | 8 ++++++++ arch/sh/Kconfig | 8 ++++++++ arch/sh64/Kconfig | 8 ++++++++ arch/sparc/Kconfig | 8 ++++++++ arch/sparc64/Kconfig | 8 ++++++++ arch/v850/Kconfig | 8 ++++++++ arch/x86_64/Kconfig | 8 ++++++++ arch/xtensa/Kconfig | 8 ++++++++ 24 files changed, 192 insertions(+) (limited to 'arch') diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 7e55ea66c6d..84caf50725b 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -25,6 +25,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8c05d4321ae..aa1d400d721 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -74,6 +74,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/arm26/Kconfig b/arch/arm26/Kconfig index c14fe918bc4..74eba8b5a8c 100644 --- a/arch/arm26/Kconfig +++ b/arch/arm26/Kconfig @@ -41,6 +41,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig index 5f1694eea84..bb059a4e1df 100644 --- a/arch/avr32/Kconfig +++ b/arch/avr32/Kconfig @@ -45,6 +45,14 @@ config GENERIC_TIME config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_BUST_SPINLOCK bool diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig index 6a1238a29d6..3474309e049 100644 --- a/arch/cris/Kconfig +++ b/arch/cris/Kconfig @@ -16,6 +16,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig index cf1c446e003..7561d7b72e7 100644 --- a/arch/frv/Kconfig +++ b/arch/frv/Kconfig @@ -41,6 +41,14 @@ config TIME_LOW_RES bool default y +config ARCH_HAS_ILOG2_U32 + bool + default y + +config ARCH_HAS_ILOG2_U64 + bool + default y + mainmenu "Fujitsu FR-V Kernel Configuration" source "init/Kconfig" diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig index cabf0bfffc5..34a84bc4baf 100644 --- a/arch/h8300/Kconfig +++ b/arch/h8300/Kconfig @@ -29,6 +29,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default n +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/i386/Kconfig.cpu b/arch/i386/Kconfig.cpu index 821fd269ca5..2aecfba4ac4 100644 --- a/arch/i386/Kconfig.cpu +++ b/arch/i386/Kconfig.cpu @@ -248,6 +248,14 @@ config RWSEM_XCHGADD_ALGORITHM depends on !M386 default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_CALIBRATE_DELAY bool default y diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 75d839715b2..fcacfe291b9 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -34,6 +34,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 41fd490af3b..f383dab973f 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -214,6 +214,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default n +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 7bc14461a6a..70a577c89c7 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig @@ -17,6 +17,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig index aa70dde5422..25993c2a8fb 100644 --- a/arch/m68knommu/Kconfig +++ b/arch/m68knommu/Kconfig @@ -25,6 +25,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default n +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index d8af858fe3f..57af8d8cf46 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -819,6 +819,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index d2101237442..0f9ff618c6d 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -25,6 +25,14 @@ config RWSEM_GENERIC_SPINLOCK config RWSEM_XCHGADD_ALGORITHM bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_FIND_NEXT_BIT bool default y diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 291c95ac4b3..97c7a212cdd 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -41,6 +41,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index f76a146cff1..692b5ba5320 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -19,6 +19,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default y + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 583d9ff0a57..45e47bfb68a 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -22,6 +22,14 @@ config RWSEM_XCHGADD_ALGORITHM bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config GENERIC_HWEIGHT bool default y diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index d83d64af31f..8e24c40662e 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -59,6 +59,14 @@ config LOCKDEP_SUPPORT bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + source "init/Kconfig" menu "System type" diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig index 58c678e0666..7bc0744b7ab 100644 --- a/arch/sh64/Kconfig +++ b/arch/sh64/Kconfig @@ -39,6 +39,14 @@ config RWSEM_XCHGADD_ALGORITHM config GENERIC_ISA_DMA bool +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + source init/Kconfig menu "System type" diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 92a7c8a636d..d0dec1ea2ee 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -166,6 +166,14 @@ config ARCH_MAY_HAVE_PC_FDC bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config SUN_PM bool default y diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index b627f8dbcaa..d391d11f245 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -34,6 +34,14 @@ config ARCH_MAY_HAVE_PC_FDC bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + config AUDIT_ARCH bool default y diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig index 37ec644603a..bcf825875d1 100644 --- a/arch/v850/Kconfig +++ b/arch/v850/Kconfig @@ -38,6 +38,14 @@ config TIME_LOW_RES bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + # Turn off some random 386 crap that can affect device config config ISA bool diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 3254a616c69..3ac581d1720 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -101,6 +101,14 @@ config GENERIC_BUG default y depends on BUG +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + source "init/Kconfig" diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index c1e69a1f92a..9eccfbd1b53 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -34,6 +34,14 @@ config GENERIC_HARDIRQS bool default y +config ARCH_HAS_ILOG2_U32 + bool + default n + +config ARCH_HAS_ILOG2_U64 + bool + default n + source "init/Kconfig" menu "Processor type and features" -- cgit v1.2.3 From ef55d53caa055aedee13e77da82740987dd64f2d Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 8 Dec 2006 02:37:53 -0800 Subject: [PATCH] LOG2: Provide ilog2() fallbacks for powerpc Provide ilog2() fallbacks for powerpc for 32-bit numbers and 64-bit numbers on ppc64. Signed-off-by: David Howells Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 97c7a212cdd..56c3c4065eb 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -43,11 +43,11 @@ config RWSEM_XCHGADD_ALGORITHM config ARCH_HAS_ILOG2_U32 bool - default n + default y config ARCH_HAS_ILOG2_U64 bool - default n + default y if 64BIT config GENERIC_HWEIGHT bool -- cgit v1.2.3 From 937949d9edbf4049bd41af6c9f92c26280584564 Mon Sep 17 00:00:00 2001 From: Cedric Le Goater Date: Fri, 8 Dec 2006 02:37:54 -0800 Subject: [PATCH] add process_session() helper routine Replace occurences of task->signal->session by a new process_session() helper routine. It will be useful for pid namespaces to abstract the session pid number. Signed-off-by: Cedric Le Goater Cc: Kirill Korotaev Cc: Eric W. Biederman Cc: Herbert Poetzl Cc: Sukadev Bhattiprolu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/kernel/irixelf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 1bbefbf4337..37cad5de515 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1145,7 +1145,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current); - psinfo.pr_sid = prstatus.pr_sid = current->signal->session; + psinfo.pr_sid = prstatus.pr_sid = process_session(current); if (current->pid == current->tgid) { /* * This is the record for the group leader. Add in the -- cgit v1.2.3 From 8e087929df884dbb13e383d49d192bdd6928ecbf Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 02:38:04 -0800 Subject: [PATCH] Generic ioremap_page_range: mips conversion Convert MIPS to use generic ioremap_page_range() [yoichi_yuasa@tripeaks.co.jp: build fix] Signed-off-by: Haavard Skinnemoen Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/mm/ioremap.c | 96 +++++--------------------------------------------- 1 file changed, 8 insertions(+), 88 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index cea7d0ea36e..fc2c96f0a1f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -6,98 +6,13 @@ * (C) Copyright 1995 1996 Linus Torvalds * (C) Copyright 2001, 2002 Ralf Baechle */ +#include #include #include #include #include -#include -#include -#include - -static inline void remap_area_pte(pte_t * pte, unsigned long address, - phys_t size, phys_t phys_addr, unsigned long flags) -{ - phys_t end; - unsigned long pfn; - pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE - | __WRITEABLE | flags); - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - pfn = phys_addr >> PAGE_SHIFT; - do { - if (!pte_none(*pte)) { - printk("remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, pfn_pte(pfn, pgprot)); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, - phys_t size, phys_t phys_addr, unsigned long flags) -{ - phys_t end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); - do { - pte_t * pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -static int remap_area_pages(unsigned long address, phys_t phys_addr, - phys_t size, unsigned long flags) -{ - int error; - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset(&init_mm, address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pud_t *pud; - pmd_t *pmd; - - error = -ENOMEM; - pud = pud_alloc(&init_mm, dir, address); - if (!pud) - break; - pmd = pmd_alloc(&init_mm, pud, address); - if (!pmd) - break; - if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - break; - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - flush_tlb_all(); - return error; -} +#include /* * Generic mapping function (not visible outside): @@ -121,6 +36,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) unsigned long offset; phys_t last_addr; void * addr; + pgprot_t pgprot; phys_addr = fixup_bigphys_addr(phys_addr, size); @@ -152,6 +68,9 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) return NULL; } + pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE + | __WRITEABLE | flags); + /* * Mappings have to be page-aligned */ @@ -166,7 +85,8 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) if (!area) return NULL; addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { vunmap(addr); return NULL; } -- cgit v1.2.3 From e34067fdd2bf7a6e62808b9bbc49d2b2a1357216 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 02:38:05 -0800 Subject: [PATCH] Generic ioremap_page_range: parisc conversion Convert parisc to use generic ioremap_page_range() Signed-off-by: Haavard Skinnemoen Acked-by: Kyle McMartin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/parisc/mm/ioremap.c | 111 +++-------------------------------------------- 1 file changed, 7 insertions(+), 104 deletions(-) (limited to 'arch') diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index 47a1d2ac941..44b42c7f639 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c @@ -9,110 +9,8 @@ #include #include #include -#include +#include #include -#include -#include - -static inline void -remap_area_pte(pte_t *pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end, pfn; - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | - _PAGE_ACCESSED | flags); - - address &= ~PMD_MASK; - - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - - BUG_ON(address >= end); - - pfn = phys_addr >> PAGE_SHIFT; - do { - BUG_ON(!pte_none(*pte)); - - set_pte(pte, pfn_pte(pfn, pgprot)); - - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int -remap_area_pmd(pmd_t *pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - - BUG_ON(address >= end); - - phys_addr -= address; - do { - pte_t *pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; - - remap_area_pte(pte, address, end - address, - address + phys_addr, flags); - - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - - return 0; -} - -static int -remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - pgd_t *dir; - int error = 0; - unsigned long end = address + size; - - BUG_ON(address >= end); - - phys_addr -= address; - dir = pgd_offset_k(address); - - flush_cache_all(); - - do { - pud_t *pud; - pmd_t *pmd; - - error = -ENOMEM; - pud = pud_alloc(&init_mm, dir, address); - if (!pud) - break; - - pmd = pmd_alloc(&init_mm, pud, address); - if (!pmd) - break; - - if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - break; - - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - - flush_tlb_all(); - - return error; -} /* * Generic mapping function (not visible outside): @@ -131,6 +29,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void *addr; struct vm_struct *area; unsigned long offset, last_addr; + pgprot_t pgprot; #ifdef CONFIG_EISA unsigned long end = phys_addr + size - 1; @@ -164,6 +63,9 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } } + pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | + _PAGE_ACCESSED | flags); + /* * Mappings have to be page-aligned */ @@ -179,7 +81,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { vfree(addr); return NULL; } -- cgit v1.2.3 From a151ca62d7c28d67a8ca0e950452b5208d1d572d Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 02:38:06 -0800 Subject: [PATCH] Generic ioremap_page_range: s390 conversion Convert S390 to use generic ioremap_page_range() Signed-off-by: Haavard Skinnemoen Cc: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/s390/mm/ioremap.c | 84 ++------------------------------------------------ 1 file changed, 3 insertions(+), 81 deletions(-) (limited to 'arch') diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c index 0f6e9ecbefe..3d2100a4e20 100644 --- a/arch/s390/mm/ioremap.c +++ b/arch/s390/mm/ioremap.c @@ -15,87 +15,8 @@ #include #include -#include +#include #include -#include -#include - -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - unsigned long pfn; - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - pfn = phys_addr >> PAGE_SHIFT; - do { - if (!pte_none(*pte)) { - printk("remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, pfn_pte(pfn, __pgprot(flags))); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); - do { - pte_t * pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -static int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - int error; - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset(&init_mm, address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pmd_t *pmd; - pmd = pmd_alloc(&init_mm, dir, address); - error = -ENOMEM; - if (!pmd) - break; - if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - break; - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - flush_tlb_all(); - return 0; -} /* * Generic mapping function (not visible outside): @@ -122,7 +43,8 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag if (!area) return NULL; addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, __pgprot(flags))) { vfree(addr); return NULL; } -- cgit v1.2.3 From 5b3e1a85c2145813898ac50530c70e6d03a6aa19 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 02:38:07 -0800 Subject: [PATCH] Generic ioremap_page_range: sh conversion Convert SH to use generic ioremap_page_range() Signed-off-by: Haavard Skinnemoen Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/mm/ioremap.c | 90 +++------------------------------------------------- 1 file changed, 4 insertions(+), 86 deletions(-) (limited to 'arch') diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index 11d54c14982..90b494a0cf4 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c @@ -16,97 +16,13 @@ #include #include #include -#include +#include #include #include #include #include #include -static inline void remap_area_pte(pte_t * pte, unsigned long address, - unsigned long size, unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - unsigned long pfn; - pgprot_t pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - pfn = phys_addr >> PAGE_SHIFT; - do { - if (!pte_none(*pte)) { - printk("remap_area_pte: page already exists\n"); - BUG(); - } - set_pte(pte, pfn_pte(pfn, pgprot)); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, - unsigned long size, unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - phys_addr -= address; - if (address >= end) - BUG(); - do { - pte_t * pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - int error; - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset_k(address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pud_t *pud; - pmd_t *pmd; - - error = -ENOMEM; - - pud = pud_alloc(&init_mm, dir, address); - if (!pud) - break; - pmd = pmd_alloc(&init_mm, pud, address); - if (!pmd) - break; - if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) - break; - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - flush_tlb_all(); - return error; -} - /* * Remap an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access high addresses @@ -121,6 +37,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, { struct vm_struct * area; unsigned long offset, last_addr, addr, orig_addr; + pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -190,8 +107,9 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, } #endif + pgprot = __pgprot(pgprot_val(PAGE_KERNEL_NOCACHE) | flags); if (likely(size)) - if (remap_area_pages(addr, phys_addr, size, flags)) { + if (ioremap_page_range(addr, addr + size, phys_addr, pgprot)) { vunmap((void *)orig_addr); return NULL; } -- cgit v1.2.3 From 10731b88a2725e0f1b21394433c8e53fde6a3634 Mon Sep 17 00:00:00 2001 From: Haavard Skinnemoen Date: Fri, 8 Dec 2006 02:38:08 -0800 Subject: [PATCH] Generic ioremap_page_range: sh64 conversion Convert SH64 to use generic ioremap_page_range() Signed-off-by: Haavard Skinnemoen Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh64/mm/ioremap.c | 100 ++++--------------------------------------------- 1 file changed, 8 insertions(+), 92 deletions(-) (limited to 'arch') diff --git a/arch/sh64/mm/ioremap.c b/arch/sh64/mm/ioremap.c index 80c56754f51..ff26c02511a 100644 --- a/arch/sh64/mm/ioremap.c +++ b/arch/sh64/mm/ioremap.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,96 +28,6 @@ static void shmedia_mapioaddr(unsigned long, unsigned long); static unsigned long shmedia_ioremap(struct resource *, u32, int); -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - unsigned long pfn; - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_READ | - _PAGE_WRITE | _PAGE_DIRTY | - _PAGE_ACCESSED | _PAGE_SHARED | flags); - - address &= ~PMD_MASK; - end = address + size; - if (end > PMD_SIZE) - end = PMD_SIZE; - if (address >= end) - BUG(); - - pfn = phys_addr >> PAGE_SHIFT; - - pr_debug(" %s: pte %p address %lx size %lx phys_addr %lx\n", - __FUNCTION__,pte,address,size,phys_addr); - - do { - if (!pte_none(*pte)) { - printk("remap_area_pte: page already exists\n"); - BUG(); - } - - set_pte(pte, pfn_pte(pfn, pgprot)); - address += PAGE_SIZE; - pfn++; - pte++; - } while (address && (address < end)); -} - -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, - unsigned long phys_addr, unsigned long flags) -{ - unsigned long end; - - address &= ~PGDIR_MASK; - end = address + size; - - if (end > PGDIR_SIZE) - end = PGDIR_SIZE; - - phys_addr -= address; - - if (address >= end) - BUG(); - - do { - pte_t * pte = pte_alloc_kernel(pmd, address); - if (!pte) - return -ENOMEM; - remap_area_pte(pte, address, end - address, address + phys_addr, flags); - address = (address + PMD_SIZE) & PMD_MASK; - pmd++; - } while (address && (address < end)); - return 0; -} - -static int remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - int error; - pgd_t * dir; - unsigned long end = address + size; - - phys_addr -= address; - dir = pgd_offset_k(address); - flush_cache_all(); - if (address >= end) - BUG(); - do { - pmd_t *pmd = pmd_alloc(&init_mm, dir, address); - error = -ENOMEM; - if (!pmd) - break; - if (remap_area_pmd(pmd, address, end - address, - phys_addr + address, flags)) { - break; - } - error = 0; - address = (address + PGDIR_SIZE) & PGDIR_MASK; - dir++; - } while (address && (address < end)); - flush_tlb_all(); - return 0; -} - /* * Generic mapping function (not visible outside): */ @@ -136,12 +46,17 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag void * addr; struct vm_struct * area; unsigned long offset, last_addr; + pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; if (!size || last_addr < phys_addr) return NULL; + pgprot = __pgprot(_PAGE_PRESENT | _PAGE_READ | + _PAGE_WRITE | _PAGE_DIRTY | + _PAGE_ACCESSED | _PAGE_SHARED | flags); + /* * Mappings have to be page-aligned */ @@ -158,7 +73,8 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag return NULL; area->phys_addr = phys_addr; addr = area->addr; - if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { vunmap(addr); return NULL; } -- cgit v1.2.3 From 606d099cdd1080bbb50ea50dc52d98252f8f10a1 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 8 Dec 2006 02:38:45 -0800 Subject: [PATCH] tty: switch to ktermios This is the grungy swap all the occurrences in the right places patch that goes with the updates. At this point we have the same functionality as before (except that sgttyb() returns speeds not zero) and are ready to begin turning new stuff on providing nobody reports lots of bugs If you are a tty driver author converting an out of tree driver the only impact should be termios->ktermios name changes for the speed/property setting functions from your upper layers. If you are implementing your own TCGETS function before then your driver was broken already and its about to get a whole lot more painful for you so please fix it 8) Also fill in c_ispeed/ospeed on init for most devices, although the current code will do this for you anyway but I'd like eventually to lose that extra paranoia [akpm@osdl.org: bluetooth fix] [mp3@de.ibm.com: sclp fix] [mp3@de.ibm.com: warning fix for tty3270] [hugh@veritas.com: fix tty_ioctl powerpc build] [jdike@addtoit.com: uml: fix ->set_termios declaration] Signed-off-by: Alan Cox Signed-off-by: Martin Peschke Acked-by: Peter Oberparleiter Cc: Cornelia Huck Signed-off-by: Hugh Dickins Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/drivers/line.c | 2 +- arch/um/include/line.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index aa3090d05a8..83301e1ef67 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -246,7 +246,7 @@ out_up: return ret; } -void line_set_termios(struct tty_struct *tty, struct termios * old) +void line_set_termios(struct tty_struct *tty, struct ktermios * old) { /* nothing */ } diff --git a/arch/um/include/line.h b/arch/um/include/line.h index 214ee76c40d..5f232ae89fb 100644 --- a/arch/um/include/line.h +++ b/arch/um/include/line.h @@ -76,7 +76,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines, extern int line_write(struct tty_struct *tty, const unsigned char *buf, int len); extern void line_put_char(struct tty_struct *tty, unsigned char ch); -extern void line_set_termios(struct tty_struct *tty, struct termios * old); +extern void line_set_termios(struct tty_struct *tty, struct ktermios * old); extern int line_chars_in_buffer(struct tty_struct *tty); extern void line_flush_buffer(struct tty_struct *tty); extern void line_flush_chars(struct tty_struct *tty); -- cgit v1.2.3 From b5bd1cec8999624fa2b32833ba9707eb4966df17 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 8 Dec 2006 02:40:46 -0800 Subject: [PATCH] visws: sgivwfb as module needs exports With CONFIG_FB_SGIVW=m: WARNING: "sgivwfb_mem_size" [drivers/video/sgivwfb.ko] undefined! WARNING: "sgivwfb_mem_phys" [drivers/video/sgivwfb.ko] undefined! (or don't allow FB_SGIVW=m in Kconfig) Signed-off-by: Randy Dunlap Acked-by: James Simmons Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/mach-visws/setup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/i386/mach-visws/setup.c b/arch/i386/mach-visws/setup.c index 885c7cbfd47..233ee20907b 100644 --- a/arch/i386/mach-visws/setup.c +++ b/arch/i386/mach-visws/setup.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -142,6 +143,8 @@ void __init time_init_hook(void) unsigned long sgivwfb_mem_phys; unsigned long sgivwfb_mem_size; +EXPORT_SYMBOL(sgivwfb_mem_phys); +EXPORT_SYMBOL(sgivwfb_mem_size); long long mem_size __initdata = 0; -- cgit v1.2.3 From 3b1bdf4e08d6a8d4fae5a30224ed2c55bf1e43fc Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 8 Dec 2006 02:41:13 -0800 Subject: [PATCH] CPU hotplug broken with 2GB VMSPLIT In VMSPLIT mode, kernel PGD might have more entries than user space. Acked-by: Jens Axboe Signed-off-by: Shaohua Li Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/smpboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 4bf0e3c83b8..1e00b03163b 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -1118,7 +1118,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) /* init low mem mapping */ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, - KERNEL_PGD_PTRS); + min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); flush_tlb_all(); schedule_work(&info.task); wait_for_completion(&done); -- cgit v1.2.3 From 4c198557c6b45956a6f54b958fb97a15b02a6a3b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 8 Dec 2006 17:46:58 +1100 Subject: [POWERPC] Add DSCR SPR to sysfs POWER6 adds a new SPR, the data stream control register (DSCR). It can be used to adjust how agressive the prefetch mechanisms are. Its possible we may want to context switch this, but for now just export it to userspace via sysfs so we can adjust it. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/sysfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 63ed265b7f0..22daba56c86 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -181,6 +181,7 @@ SYSFS_PMCSETUP(pmc6, SPRN_PMC6); SYSFS_PMCSETUP(pmc7, SPRN_PMC7); SYSFS_PMCSETUP(pmc8, SPRN_PMC8); SYSFS_PMCSETUP(purr, SPRN_PURR); +SYSFS_PMCSETUP(dscr, SPRN_DSCR); static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); static SYSDEV_ATTR(mmcr1, 0600, show_mmcr1, store_mmcr1); @@ -194,6 +195,7 @@ static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); static SYSDEV_ATTR(purr, 0600, show_purr, NULL); +static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); static void register_cpu_online(unsigned int cpu) { @@ -231,6 +233,9 @@ static void register_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_create_file(s, &attr_purr); + + if (cpu_has_feature(CPU_FTR_DSCR)) + sysdev_create_file(s, &attr_dscr); } #ifdef CONFIG_HOTPLUG_CPU @@ -272,6 +277,9 @@ static void unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_remove_file(s, &attr_purr); + + if (cpu_has_feature(CPU_FTR_DSCR)) + sysdev_remove_file(s, &attr_dscr); } #endif /* CONFIG_HOTPLUG_CPU */ -- cgit v1.2.3 From f050982a9b7c4edc414f0d5543c3cb24504223c6 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 8 Dec 2006 17:51:13 +1100 Subject: [POWERPC] Add SPURR SPR to sysfs Now we have a SPURR cpu feature bit, we can export it to userspace in sysfs. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/sysfs.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 22daba56c86..400ab2b946e 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -181,6 +181,7 @@ SYSFS_PMCSETUP(pmc6, SPRN_PMC6); SYSFS_PMCSETUP(pmc7, SPRN_PMC7); SYSFS_PMCSETUP(pmc8, SPRN_PMC8); SYSFS_PMCSETUP(purr, SPRN_PURR); +SYSFS_PMCSETUP(spurr, SPRN_SPURR); SYSFS_PMCSETUP(dscr, SPRN_DSCR); static SYSDEV_ATTR(mmcr0, 0600, show_mmcr0, store_mmcr0); @@ -195,6 +196,7 @@ static SYSDEV_ATTR(pmc6, 0600, show_pmc6, store_pmc6); static SYSDEV_ATTR(pmc7, 0600, show_pmc7, store_pmc7); static SYSDEV_ATTR(pmc8, 0600, show_pmc8, store_pmc8); static SYSDEV_ATTR(purr, 0600, show_purr, NULL); +static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL); static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr); static void register_cpu_online(unsigned int cpu) @@ -234,6 +236,9 @@ static void register_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_create_file(s, &attr_purr); + if (cpu_has_feature(CPU_FTR_SPURR)) + sysdev_create_file(s, &attr_spurr); + if (cpu_has_feature(CPU_FTR_DSCR)) sysdev_create_file(s, &attr_dscr); } @@ -278,6 +283,9 @@ static void unregister_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_PURR)) sysdev_remove_file(s, &attr_purr); + if (cpu_has_feature(CPU_FTR_SPURR)) + sysdev_remove_file(s, &attr_spurr); + if (cpu_has_feature(CPU_FTR_DSCR)) sysdev_remove_file(s, &attr_dscr); } -- cgit v1.2.3 From 5773bbcdec54b7258cb9e2aa6f3459b4cbfd9dc5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 8 Dec 2006 18:08:37 +1100 Subject: [POWERPC] micro optimise pSeries_probe We find the OF root the line before, we may as well use it. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 6090d753c44..3e2f7467057 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -433,8 +433,8 @@ static int __init pSeries_probe_hypertas(unsigned long node, static int __init pSeries_probe(void) { unsigned long root = of_get_flat_dt_root(); - char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), - "device_type", NULL); + char *dtype = of_get_flat_dt_prop(root, "device_type", NULL); + if (dtype == NULL) return 0; if (strcmp(dtype, "chrp")) -- cgit v1.2.3 From a223535425eb28082a0925b0ce2f02f962936cf4 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 8 Dec 2006 18:22:09 +1100 Subject: [POWERPC] dont allow pSeries_probe to succeed without initialising MMU pSeries_probe can decide that we are a pseries but then fail to initialise the MMU. If an rtas node doesnt exist, we continually fall out of pSeries_probe_hypertas early and never get to the MMU init code. While pseries without RTAS is an illegal combination, the way we currently fail is a pain to track down, and can happen if your flattened device tree code has issues (like mine did :). With the following patch we init the MMU, come up and print some warnings about RTAS not existing, instead of looping on 0x400 exceptions. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/pseries/setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 3e2f7467057..042ecae107a 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -422,11 +422,6 @@ static int __init pSeries_probe_hypertas(unsigned long node, if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) powerpc_firmware_features |= FW_FEATURE_LPAR; - if (firmware_has_feature(FW_FEATURE_LPAR)) - hpte_init_lpar(); - else - hpte_init_native(); - return 1; } @@ -452,6 +447,11 @@ static int __init pSeries_probe(void) /* Now try to figure out if we are running on LPAR */ of_scan_flat_dt(pSeries_probe_hypertas, NULL); + if (firmware_has_feature(FW_FEATURE_LPAR)) + hpte_init_lpar(); + else + hpte_init_native(); + DBG("Machine is%s LPAR !\n", (powerpc_firmware_features & FW_FEATURE_LPAR) ? "" : " not"); -- cgit v1.2.3 From 14b36af46a1d3652aff6734ea24816995dff8123 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 5 Dec 2006 17:05:44 +0100 Subject: [MIPS] Rename SNI_RM200_PCI to just SNI_RM preparing for more RM machines Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 14 +++++++------- arch/mips/Makefile | 10 +++++----- arch/mips/configs/atlas_defconfig | 2 +- arch/mips/configs/bigsur_defconfig | 2 +- arch/mips/configs/capcella_defconfig | 2 +- arch/mips/configs/cobalt_defconfig | 2 +- arch/mips/configs/db1000_defconfig | 2 +- arch/mips/configs/db1100_defconfig | 2 +- arch/mips/configs/db1200_defconfig | 2 +- arch/mips/configs/db1500_defconfig | 2 +- arch/mips/configs/db1550_defconfig | 2 +- arch/mips/configs/ddb5477_defconfig | 2 +- arch/mips/configs/decstation_defconfig | 2 +- arch/mips/configs/e55_defconfig | 2 +- arch/mips/configs/emma2rh_defconfig | 2 +- arch/mips/configs/ev64120_defconfig | 2 +- arch/mips/configs/excite_defconfig | 2 +- arch/mips/configs/ip22_defconfig | 2 +- arch/mips/configs/ip27_defconfig | 2 +- arch/mips/configs/ip32_defconfig | 2 +- arch/mips/configs/jaguar-atx_defconfig | 2 +- arch/mips/configs/jazz_defconfig | 2 +- arch/mips/configs/jmr3927_defconfig | 2 +- arch/mips/configs/lasat200_defconfig | 2 +- arch/mips/configs/malta_defconfig | 2 +- arch/mips/configs/mipssim_defconfig | 2 +- arch/mips/configs/mpc30x_defconfig | 2 +- arch/mips/configs/ocelot_3_defconfig | 2 +- arch/mips/configs/ocelot_c_defconfig | 2 +- arch/mips/configs/ocelot_defconfig | 2 +- arch/mips/configs/ocelot_g_defconfig | 2 +- arch/mips/configs/pb1100_defconfig | 2 +- arch/mips/configs/pb1500_defconfig | 2 +- arch/mips/configs/pb1550_defconfig | 2 +- arch/mips/configs/pnx8550-jbs_defconfig | 2 +- arch/mips/configs/pnx8550-v2pci_defconfig | 2 +- arch/mips/configs/qemu_defconfig | 2 +- arch/mips/configs/rbhma4500_defconfig | 2 +- arch/mips/configs/rm200_defconfig | 2 +- arch/mips/configs/sb1250-swarm_defconfig | 2 +- arch/mips/configs/sead_defconfig | 2 +- arch/mips/configs/tb0226_defconfig | 2 +- arch/mips/configs/tb0229_defconfig | 2 +- arch/mips/configs/tb0287_defconfig | 2 +- arch/mips/configs/workpad_defconfig | 2 +- arch/mips/configs/wrppmc_defconfig | 2 +- arch/mips/configs/yosemite_defconfig | 2 +- arch/mips/defconfig | 2 +- arch/mips/pci/Makefile | 2 +- 49 files changed, 59 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 57af8d8cf46..7078bf4b6bc 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -701,8 +701,8 @@ config SIBYTE_CRHONE select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN -config SNI_RM200_PCI - bool "SNI RM200 PCI" +config SNI_RM + bool "SNI RM200/300/400" select ARC if CPU_LITTLE_ENDIAN select ARC32 if CPU_LITTLE_ENDIAN select ARCH_MAY_HAVE_PC_FDC @@ -725,8 +725,8 @@ config SNI_RM200_PCI select SYS_SUPPORTS_HIGHMEM select SYS_SUPPORTS_LITTLE_ENDIAN help - The SNI RM200 PCI was a MIPS-based platform manufactured by Siemens - Nixdorf Informationssysteme (SNI), parent company of Pyramid + The SNI RM200/300/400 are MIPS-based machines manufactured by + Siemens Nixdorf Informationssysteme (SNI), parent company of Pyramid Technology and now in turn merged with Fujitsu. Say Y here to support this machine type. @@ -1070,16 +1070,16 @@ config HAVE_STD_PC_SERIAL_PORT config ARC_CONSOLE bool "ARC console support" - depends on SGI_IP22 || SNI_RM200_PCI + depends on SGI_IP22 || SNI_RM config ARC_MEMORY bool - depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP32 + depends on MACH_JAZZ || SNI_RM || SGI_IP32 default y config ARC_PROMLIB bool - depends on MACH_JAZZ || SNI_RM200_PCI || SGI_IP22 || SGI_IP32 + depends on MACH_JAZZ || SNI_RM || SGI_IP22 || SGI_IP32 default y config ARC64 diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 641aa30b363..8eb6fc1f555 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -569,11 +569,11 @@ libs-$(CONFIG_SIBYTE_BIGSUR) += arch/mips/sibyte/swarm/ load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000 # -# SNI RM200 PCI +# SNI RM # -core-$(CONFIG_SNI_RM200_PCI) += arch/mips/sni/ -cflags-$(CONFIG_SNI_RM200_PCI) += -Iinclude/asm-mips/mach-rm200 -load-$(CONFIG_SNI_RM200_PCI) += 0xffffffff80600000 +core-$(CONFIG_SNI_RM) += arch/mips/sni/ +cflags-$(CONFIG_SNI_RM) += -Iinclude/asm-mips/mach-rm +load-$(CONFIG_SNI_RM) += 0xffffffff80600000 # # Toshiba JMR-TX3927 board @@ -695,7 +695,7 @@ ifdef CONFIG_QEMU all: vmlinux.bin endif -ifdef CONFIG_SNI_RM200_PCI +ifdef CONFIG_SNI_RM all: vmlinux.ecoff endif diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 35931bedc3d..ac189168752 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_ATLAS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index ba3bf733d27..9554257c6f3 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -57,7 +57,7 @@ CONFIG_SIBYTE_BIGSUR=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index e5358121d2d..49590d44371 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index adf1e8c98c6..0607fc23908 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_COBALT=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 4fd29ffdfb8..1a57b337548 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_DB1000=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index 025b960ba99..0055ec41f20 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_DB1100=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index 80c9dd98f89..c41823b81be 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_DB1200=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index 6caa90b0e17..7d6d9218788 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_DB1500=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index c6cae86c6ab..c681c91763a 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_DB1550=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index 72f24001c99..dd4bb008021 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -59,7 +59,7 @@ CONFIG_DDB5477=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index fe1387eb83c..8a31ce4be12 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_DECSTATION=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 6133c28beb8..6fa4f914f6e 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index a484b7d396f..4c9d0405a5d 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -59,7 +59,7 @@ CONFIG_MARKEINS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig index 21bfcdebf8f..d5b49735683 100644 --- a/arch/mips/configs/ev64120_defconfig +++ b/arch/mips/configs/ev64120_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_EV64120=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 1a5b06cfb4d..697140c6562 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -60,7 +60,7 @@ CONFIG_BASLER_EXCITE=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index 21d53e0c9ee..f9812d1e457 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -59,7 +59,7 @@ CONFIG_SGI_IP22=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index e3e94c7e5ee..96090f28373 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -59,7 +59,7 @@ CONFIG_SGI_IP27=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index b4ab2bea972..61e069a0f1a 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -59,7 +59,7 @@ CONFIG_SGI_IP32=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig index 9d4d17ace12..88966666f4c 100644 --- a/arch/mips/configs/jaguar-atx_defconfig +++ b/arch/mips/configs/jaguar-atx_defconfig @@ -59,7 +59,7 @@ CONFIG_MOMENCO_JAGUAR_ATX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 382083ebea0..835764d834f 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -57,7 +57,7 @@ CONFIG_MACH_JAZZ=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index d03746667a9..50fd9557e64 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set CONFIG_TOSHIBA_JMR3927=y # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index 1db8249b4c0..05f539f84f5 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -59,7 +59,7 @@ CONFIG_LASAT=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 101e80347dc..1f9300f37f5 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -57,7 +57,7 @@ CONFIG_MIPS_MALTA=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index a3cbd23bf21..03efcfd0503 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_SIM=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 6570b47426c..e4221aafbc4 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index 440d65f93a9..32b1afdd1c2 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -59,7 +59,7 @@ CONFIG_MOMENCO_OCELOT_3=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index c2c7ae77da3..ebe75c1c71a 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -59,7 +59,7 @@ CONFIG_MOMENCO_OCELOT_C=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 67efe270e0c..5a9603c1290 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -59,7 +59,7 @@ CONFIG_MOMENCO_OCELOT=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig index a10f34de5f7..46a942c253c 100644 --- a/arch/mips/configs/ocelot_g_defconfig +++ b/arch/mips/configs/ocelot_g_defconfig @@ -59,7 +59,7 @@ CONFIG_MOMENCO_OCELOT_G=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 9e672f63a0a..7d3c688181d 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_PB1100=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index d0c0f4af1bf..a77805af081 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_PB1500=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index 3db7427d1b5..8318d74d6ad 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_PB1550=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 280a8001eac..fcb8fea3052 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -57,7 +57,7 @@ CONFIG_PNX8550_JBS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig index 64b9fbf44a6..5bc3248e50e 100644 --- a/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/arch/mips/configs/pnx8550-v2pci_defconfig @@ -57,7 +57,7 @@ CONFIG_PNX8550_V2PCI=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index 9b0dab822bd..aa61f0f030a 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -59,7 +59,7 @@ CONFIG_QEMU=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index dd029603602..f9e8f41d17f 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set CONFIG_TOSHIBA_RBTX4938=y diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index d8a498d64d6..496aa67b9f8 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -CONFIG_SNI_RM200_PCI=y +CONFIG_SNI_RM=y # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 805a4fe450f..e33c17200b3 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -59,7 +59,7 @@ CONFIG_SIBYTE_SWARM=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index 6fcb656d8d8..83fb932f9d4 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -59,7 +59,7 @@ CONFIG_MIPS_SEAD=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index dc312f19ada..e9d4eae45bf 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig index 85615d99b01..c19597fb0c3 100644 --- a/arch/mips/configs/tb0229_defconfig +++ b/arch/mips/configs/tb0229_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index f7e8194809a..97d94f96990 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -57,7 +57,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index 863f6a7cadf..553734a47b6 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -59,7 +59,7 @@ CONFIG_MACH_VR41XX=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index c10267d61cc..d3dfb702bb7 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -59,7 +59,7 @@ CONFIG_WR_PPMC=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index 4d3c1329f3c..b9f74d6745e 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -59,7 +59,7 @@ CONFIG_PMC_YOSEMITE=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 21d53e0c9ee..f9812d1e457 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -59,7 +59,7 @@ CONFIG_SGI_IP22=y # CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_CRHINE is not set # CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SNI_RM200_PCI is not set +# CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 70cb55b89df..82b20c28bef 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o -obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o +obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o -- cgit v1.2.3 From 52ffe760ea9ec407292d093c3f06c1cda5187228 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 8 Dec 2006 01:04:31 +0900 Subject: [MIPS] Make csum_partial more readable Use standard o32 register name instead of T0, T1, etc, like memcpy.S. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib/csum_partial.S | 144 ++++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 70 deletions(-) (limited to 'arch') diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 15611d9df7a..3bffdbb1c1f 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -12,19 +12,23 @@ #include #ifdef CONFIG_64BIT -#define T0 ta0 -#define T1 ta1 -#define T2 ta2 -#define T3 ta3 -#define T4 t0 -#define T7 t3 -#else -#define T0 t0 -#define T1 t1 -#define T2 t2 -#define T3 t3 -#define T4 t4 -#define T7 t7 +/* + * As we are sharing code base with the mips32 tree (which use the o32 ABI + * register definitions). We need to redefine the register definitions from + * the n64 ABI register naming to the o32 ABI register naming. + */ +#undef t0 +#undef t1 +#undef t2 +#undef t3 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 #endif #define ADDC(sum,reg) \ @@ -64,37 +68,37 @@ /* unknown src alignment and < 8 bytes to go */ small_csumcpy: - move a1, T2 + move a1, t2 - andi T0, a1, 4 - beqz T0, 1f - andi T0, a1, 2 + andi t0, a1, 4 + beqz t0, 1f + andi t0, a1, 2 /* Still a full word to go */ - ulw T1, (src) + ulw t1, (src) PTR_ADDIU src, 4 - ADDC(sum, T1) + ADDC(sum, t1) -1: move T1, zero - beqz T0, 1f - andi T0, a1, 1 +1: move t1, zero + beqz t0, 1f + andi t0, a1, 1 /* Still a halfword to go */ - ulhu T1, (src) + ulhu t1, (src) PTR_ADDIU src, 2 -1: beqz T0, 1f - sll T1, T1, 16 +1: beqz t0, 1f + sll t1, t1, 16 - lbu T2, (src) + lbu t2, (src) nop #ifdef __MIPSEB__ - sll T2, T2, 8 + sll t2, t2, 8 #endif - or T1, T2 + or t1, t2 -1: ADDC(sum, T1) +1: ADDC(sum, t1) /* fold checksum */ sll v1, sum, 16 @@ -104,7 +108,7 @@ small_csumcpy: addu sum, v1 /* odd buffer alignment? */ - beqz T7, 1f + beqz t7, 1f nop sll v1, sum, 8 srl sum, sum, 8 @@ -122,25 +126,25 @@ small_csumcpy: .align 5 LEAF(csum_partial) move sum, zero - move T7, zero + move t7, zero sltiu t8, a1, 0x8 bnez t8, small_csumcpy /* < 8 bytes to copy */ - move T2, a1 + move t2, a1 beqz a1, out - andi T7, src, 0x1 /* odd buffer? */ + andi t7, src, 0x1 /* odd buffer? */ hword_align: - beqz T7, word_align + beqz t7, word_align andi t8, src, 0x2 - lbu T0, (src) + lbu t0, (src) LONG_SUBU a1, a1, 0x1 #ifdef __MIPSEL__ - sll T0, T0, 8 + sll t0, t0, 8 #endif - ADDC(sum, T0) + ADDC(sum, t0) PTR_ADDU src, src, 0x1 andi t8, src, 0x2 @@ -148,9 +152,9 @@ word_align: beqz t8, dword_align sltiu t8, a1, 56 - lhu T0, (src) + lhu t0, (src) LONG_SUBU a1, a1, 0x2 - ADDC(sum, T0) + ADDC(sum, t0) sltiu t8, a1, 56 PTR_ADDU src, src, 0x2 @@ -162,9 +166,9 @@ dword_align: beqz t8, qword_align andi t8, src, 0x8 - lw T0, 0x00(src) + lw t0, 0x00(src) LONG_SUBU a1, a1, 0x4 - ADDC(sum, T0) + ADDC(sum, t0) PTR_ADDU src, src, 0x4 andi t8, src, 0x8 @@ -172,11 +176,11 @@ qword_align: beqz t8, oword_align andi t8, src, 0x10 - lw T0, 0x00(src) - lw T1, 0x04(src) + lw t0, 0x00(src) + lw t1, 0x04(src) LONG_SUBU a1, a1, 0x8 - ADDC(sum, T0) - ADDC(sum, T1) + ADDC(sum, t0) + ADDC(sum, t1) PTR_ADDU src, src, 0x8 andi t8, src, 0x10 @@ -184,46 +188,46 @@ oword_align: beqz t8, begin_movement LONG_SRL t8, a1, 0x7 - lw T3, 0x08(src) - lw T4, 0x0c(src) - lw T0, 0x00(src) - lw T1, 0x04(src) - ADDC(sum, T3) - ADDC(sum, T4) - ADDC(sum, T0) - ADDC(sum, T1) + lw t3, 0x08(src) + lw t4, 0x0c(src) + lw t0, 0x00(src) + lw t1, 0x04(src) + ADDC(sum, t3) + ADDC(sum, t4) + ADDC(sum, t0) + ADDC(sum, t1) LONG_SUBU a1, a1, 0x10 PTR_ADDU src, src, 0x10 LONG_SRL t8, a1, 0x7 begin_movement: beqz t8, 1f - andi T2, a1, 0x40 + andi t2, a1, 0x40 move_128bytes: - CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) - CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4) - CSUM_BIGCHUNK(src, 0x40, sum, T0, T1, T3, T4) - CSUM_BIGCHUNK(src, 0x60, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) + CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) + CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4) + CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4) LONG_SUBU t8, t8, 0x01 bnez t8, move_128bytes PTR_ADDU src, src, 0x80 1: - beqz T2, 1f - andi T2, a1, 0x20 + beqz t2, 1f + andi t2, a1, 0x20 move_64bytes: - CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) - CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) + CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4) PTR_ADDU src, src, 0x40 1: - beqz T2, do_end_words + beqz t2, do_end_words andi t8, a1, 0x1c move_32bytes: - CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4) + CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4) andi t8, a1, 0x1c PTR_ADDU src, src, 0x20 @@ -232,22 +236,22 @@ do_end_words: LONG_SRL t8, t8, 0x2 end_words: - lw T0, (src) + lw t0, (src) LONG_SUBU t8, t8, 0x1 - ADDC(sum, T0) + ADDC(sum, t0) bnez t8, end_words PTR_ADDU src, src, 0x4 maybe_end_cruft: - andi T2, a1, 0x3 + andi t2, a1, 0x3 small_memcpy: - j small_csumcpy; move a1, T2 /* XXX ??? */ + j small_csumcpy; move a1, t2 /* XXX ??? */ beqz t2, out - move a1, T2 + move a1, t2 end_bytes: - lb T0, (src) + lb t0, (src) LONG_SUBU a1, a1, 0x1 bnez a2, end_bytes PTR_ADDU src, src, 0x1 -- cgit v1.2.3 From 773ff78838ca3c07245e45c06235e0baaa5f710a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 8 Dec 2006 01:04:45 +0900 Subject: [MIPS] Optimize flow of csum_partial Delete dead codes at end of the function and move small_csumcopy there. This makes some labels (maybe_end_cruft, small_memcpy, end_bytes, out) needless and eliminates some branches. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib/csum_partial.S | 129 ++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 75 deletions(-) (limited to 'arch') diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 3bffdbb1c1f..b04475d76f3 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -65,64 +65,6 @@ .text .set noreorder - -/* unknown src alignment and < 8 bytes to go */ -small_csumcpy: - move a1, t2 - - andi t0, a1, 4 - beqz t0, 1f - andi t0, a1, 2 - - /* Still a full word to go */ - ulw t1, (src) - PTR_ADDIU src, 4 - ADDC(sum, t1) - -1: move t1, zero - beqz t0, 1f - andi t0, a1, 1 - - /* Still a halfword to go */ - ulhu t1, (src) - PTR_ADDIU src, 2 - -1: beqz t0, 1f - sll t1, t1, 16 - - lbu t2, (src) - nop - -#ifdef __MIPSEB__ - sll t2, t2, 8 -#endif - or t1, t2 - -1: ADDC(sum, t1) - - /* fold checksum */ - sll v1, sum, 16 - addu sum, v1 - sltu v1, sum, v1 - srl sum, sum, 16 - addu sum, v1 - - /* odd buffer alignment? */ - beqz t7, 1f - nop - sll v1, sum, 8 - srl sum, sum, 8 - or sum, v1 - andi sum, 0xffff -1: - .set reorder - /* Add the passed partial csum. */ - ADDC(sum, a2) - jr ra - .set noreorder - -/* ------------------------------------------------------------------------- */ - .align 5 LEAF(csum_partial) move sum, zero @@ -132,8 +74,7 @@ LEAF(csum_partial) bnez t8, small_csumcpy /* < 8 bytes to copy */ move t2, a1 - beqz a1, out - andi t7, src, 0x1 /* odd buffer? */ + andi t7, src, 0x1 /* odd buffer? */ hword_align: beqz t7, word_align @@ -232,8 +173,9 @@ move_32bytes: PTR_ADDU src, src, 0x20 do_end_words: - beqz t8, maybe_end_cruft - LONG_SRL t8, t8, 0x2 + beqz t8, small_csumcpy + andi t2, a1, 0x3 + LONG_SRL t8, t8, 0x2 end_words: lw t0, (src) @@ -242,21 +184,58 @@ end_words: bnez t8, end_words PTR_ADDU src, src, 0x4 -maybe_end_cruft: - andi t2, a1, 0x3 +/* unknown src alignment and < 8 bytes to go */ +small_csumcpy: + move a1, t2 -small_memcpy: - j small_csumcpy; move a1, t2 /* XXX ??? */ - beqz t2, out - move a1, t2 + andi t0, a1, 4 + beqz t0, 1f + andi t0, a1, 2 -end_bytes: - lb t0, (src) - LONG_SUBU a1, a1, 0x1 - bnez a2, end_bytes - PTR_ADDU src, src, 0x1 + /* Still a full word to go */ + ulw t1, (src) + PTR_ADDIU src, 4 + ADDC(sum, t1) + +1: move t1, zero + beqz t0, 1f + andi t0, a1, 1 + + /* Still a halfword to go */ + ulhu t1, (src) + PTR_ADDIU src, 2 + +1: beqz t0, 1f + sll t1, t1, 16 + + lbu t2, (src) + nop + +#ifdef __MIPSEB__ + sll t2, t2, 8 +#endif + or t1, t2 + +1: ADDC(sum, t1) -out: + /* fold checksum */ + sll v1, sum, 16 + addu sum, v1 + sltu v1, sum, v1 + srl sum, sum, 16 + addu sum, v1 + + /* odd buffer alignment? */ + beqz t7, 1f + nop + sll v1, sum, 8 + srl sum, sum, 8 + or sum, v1 + andi sum, 0xffff +1: + .set reorder + /* Add the passed partial csum. */ + ADDC(sum, a2) jr ra - move v0, sum + .set noreorder END(csum_partial) -- cgit v1.2.3 From ed99e2bc1dc5dc54eb5a019f4975562dbef20103 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 8 Dec 2006 01:04:51 +0900 Subject: [MIPS] Optimize csum_partial for 64bit kernel Make csum_partial 64-bit powered. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/lib/csum_partial.S | 76 +++++++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 22 deletions(-) (limited to 'arch') diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index b04475d76f3..9db357294be 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -29,30 +29,49 @@ #define t5 $13 #define t6 $14 #define t7 $15 + +#define USE_DOUBLE #endif +#ifdef USE_DOUBLE + +#define LOAD ld +#define ADD daddu +#define NBYTES 8 + +#else + +#define LOAD lw +#define ADD addu +#define NBYTES 4 + +#endif /* USE_DOUBLE */ + +#define UNIT(unit) ((unit)*NBYTES) + #define ADDC(sum,reg) \ - addu sum, reg; \ + ADD sum, reg; \ sltu v1, sum, reg; \ - addu sum, v1 + ADD sum, v1 -#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \ - lw _t0, (offset + 0x00)(src); \ - lw _t1, (offset + 0x04)(src); \ - lw _t2, (offset + 0x08)(src); \ - lw _t3, (offset + 0x0c)(src); \ - ADDC(sum, _t0); \ - ADDC(sum, _t1); \ - ADDC(sum, _t2); \ - ADDC(sum, _t3); \ - lw _t0, (offset + 0x10)(src); \ - lw _t1, (offset + 0x14)(src); \ - lw _t2, (offset + 0x18)(src); \ - lw _t3, (offset + 0x1c)(src); \ +#define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) \ + LOAD _t0, (offset + UNIT(0))(src); \ + LOAD _t1, (offset + UNIT(1))(src); \ + LOAD _t2, (offset + UNIT(2))(src); \ + LOAD _t3, (offset + UNIT(3))(src); \ ADDC(sum, _t0); \ ADDC(sum, _t1); \ ADDC(sum, _t2); \ - ADDC(sum, _t3); \ + ADDC(sum, _t3) + +#ifdef USE_DOUBLE +#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \ + CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3) +#else +#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \ + CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3); \ + CSUM_BIGCHUNK1(src, offset + 0x10, sum, _t0, _t1, _t2, _t3) +#endif /* * a0: source address @@ -117,11 +136,17 @@ qword_align: beqz t8, oword_align andi t8, src, 0x10 +#ifdef USE_DOUBLE + ld t0, 0x00(src) + LONG_SUBU a1, a1, 0x8 + ADDC(sum, t0) +#else lw t0, 0x00(src) lw t1, 0x04(src) LONG_SUBU a1, a1, 0x8 ADDC(sum, t0) ADDC(sum, t1) +#endif PTR_ADDU src, src, 0x8 andi t8, src, 0x10 @@ -129,14 +154,14 @@ oword_align: beqz t8, begin_movement LONG_SRL t8, a1, 0x7 - lw t3, 0x08(src) - lw t4, 0x0c(src) - lw t0, 0x00(src) - lw t1, 0x04(src) - ADDC(sum, t3) - ADDC(sum, t4) +#ifdef USE_DOUBLE + ld t0, 0x00(src) + ld t1, 0x08(src) ADDC(sum, t0) ADDC(sum, t1) +#else + CSUM_BIGCHUNK1(src, 0x00, sum, t0, t1, t3, t4) +#endif LONG_SUBU a1, a1, 0x10 PTR_ADDU src, src, 0x10 LONG_SRL t8, a1, 0x7 @@ -219,6 +244,13 @@ small_csumcpy: 1: ADDC(sum, t1) /* fold checksum */ +#ifdef USE_DOUBLE + dsll32 v1, sum, 0 + daddu sum, v1 + sltu v1, sum, v1 + dsra32 sum, sum, 0 + addu sum, v1 +#endif sll v1, sum, 16 addu sum, v1 sltu v1, sum, v1 -- cgit v1.2.3 From 9fd32cfbb602f3e5e898faa61d83c4a7897bd48a Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 8 Dec 2006 01:55:07 +0900 Subject: [MIPS] Add GENERIC_HARDIRQS_NO__DO_IRQ for i8259 users Now that i8259A_chip uses new irq flow handler select GENERIC_HARDIRQS_NO__DO_IRQ on some more platforms. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 6 +++++ .../tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 27 ++-------------------- arch/mips/vr41xx/Kconfig | 5 ---- arch/mips/vr41xx/nec-cmbvr4133/irq.c | 9 +------- 4 files changed, 9 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7078bf4b6bc..e58928a9104 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -165,6 +165,7 @@ config MIPS_COBALT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_LITTLE_ENDIAN + select GENERIC_HARDIRQS_NO__DO_IRQ config MACH_DECSTATION bool "DECstations" @@ -225,6 +226,7 @@ config MACH_JAZZ select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL select SYS_SUPPORTS_100HZ + select GENERIC_HARDIRQS_NO__DO_IRQ help This a family of machines based on the MIPS R4030 chipset which was used by several vendors to build RISC/os and Windows NT workstations. @@ -482,6 +484,7 @@ config MACH_VR41XX select SYS_HAS_CPU_VR41XX select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL + select GENERIC_HARDIRQS_NO__DO_IRQ config PMC_YOSEMITE bool "PMC-Sierra Yosemite eval board" @@ -515,6 +518,7 @@ config QEMU select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_SPARSEMEM_ENABLE + select GENERIC_HARDIRQS_NO__DO_IRQ help Qemu is a software emulator which among other architectures also can simulate a MIPS32 4Kc system. This patch adds support for the @@ -754,6 +758,7 @@ config TOSHIBA_RBTX4927 select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select TOSHIBA_BOARDS + select GENERIC_HARDIRQS_NO__DO_IRQ help This Toshiba board is based on the TX4927 processor. Say Y here to support this machine type @@ -773,6 +778,7 @@ config TOSHIBA_RBTX4938 select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN select TOSHIBA_BOARDS + select GENERIC_HARDIRQS_NO__DO_IRQ help This Toshiba board is based on the TX4938 processor. Say Y here to support this machine type diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index 5a5ea6c0b9f..b54b529a29f 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -158,7 +158,6 @@ JP7 is not bus master -- do NOT use -- only 4 pci bus master's allowed -- SouthB #define TOSHIBA_RBTX4927_IRQ_ISA_ENABLE ( 1 << 23 ) #define TOSHIBA_RBTX4927_IRQ_ISA_DISABLE ( 1 << 24 ) #define TOSHIBA_RBTX4927_IRQ_ISA_MASK ( 1 << 25 ) -#define TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ( 1 << 26 ) #define TOSHIBA_RBTX4927_SETUP_ALL 0xffffffff #endif @@ -175,7 +174,6 @@ static const u32 toshiba_rbtx4927_irq_debug_flag = // | TOSHIBA_RBTX4927_IRQ_ISA_ENABLE // | TOSHIBA_RBTX4927_IRQ_ISA_DISABLE // | TOSHIBA_RBTX4927_IRQ_ISA_MASK -// | TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ ); #endif @@ -226,7 +224,6 @@ static void toshiba_rbtx4927_irq_ioc_disable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_enable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_disable(unsigned int irq); static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq); -static void toshiba_rbtx4927_irq_isa_end(unsigned int irq); #endif #define TOSHIBA_RBTX4927_IOC_NAME "RBTX4927-IOC" @@ -249,7 +246,6 @@ static struct irq_chip toshiba_rbtx4927_irq_isa_type = { .mask = toshiba_rbtx4927_irq_isa_disable, .mask_ack = toshiba_rbtx4927_irq_isa_mask_and_ack, .unmask = toshiba_rbtx4927_irq_isa_enable, - .end = toshiba_rbtx4927_irq_isa_end, }; #endif @@ -402,7 +398,8 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) for (i = TOSHIBA_RBTX4927_IRQ_ISA_BEG; i <= TOSHIBA_RBTX4927_IRQ_ISA_END; i++) - set_irq_chip(i, &toshiba_rbtx4927_irq_isa_type); + set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_isa_type, + handle_level_irq); setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, &toshiba_rbtx4927_irq_isa_master); @@ -470,26 +467,6 @@ static void toshiba_rbtx4927_irq_isa_mask_and_ack(unsigned int irq) #endif -#ifdef CONFIG_TOSHIBA_FPCIB0 -static void toshiba_rbtx4927_irq_isa_end(unsigned int irq) -{ - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_ISA_ENDIRQ, - "irq=%d\n", irq); - - if (irq < TOSHIBA_RBTX4927_IRQ_ISA_BEG - || irq > TOSHIBA_RBTX4927_IRQ_ISA_END) { - TOSHIBA_RBTX4927_IRQ_DPRINTK(TOSHIBA_RBTX4927_IRQ_EROR, - "bad irq=%d\n", irq); - panic("\n"); - } - - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { - toshiba_rbtx4927_irq_isa_enable(irq); - } -} -#endif - - void __init arch_init_irq(void) { extern void tx4927_irq_init(void); diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index c8dfd8092ca..92f41f6f934 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig @@ -6,7 +6,6 @@ config CASIO_E55 select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config IBM_WORKPAD bool "Support for IBM WorkPad z50" @@ -16,7 +15,6 @@ config IBM_WORKPAD select ISA select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config NEC_CMBVR4133 bool "Support for NEC CMB-VR4133" @@ -41,7 +39,6 @@ config TANBAC_TB022X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ help The TANBAC VR4131 multichip module(TB0225) and the TANBAC VR4131DIMM(TB0229) are MIPS-based platforms @@ -74,7 +71,6 @@ config VICTOR_MPC30X select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config ZAO_CAPCELLA bool "Support for ZAO Networks Capcella" @@ -84,7 +80,6 @@ config ZAO_CAPCELLA select IRQ_CPU select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN - select GENERIC_HARDIRQS_NO__DO_IRQ config PCI_VR41XX bool "Add PCI control unit support of NEC VR4100 series" diff --git a/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/arch/mips/vr41xx/nec-cmbvr4133/irq.c index a039bb7251f..128ed8d6f11 100644 --- a/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -45,19 +45,12 @@ static void ack_i8259_irq(unsigned int irq) mask_and_ack_8259A(irq - I8259_IRQ_BASE); } -static void end_i8259_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_8259A_irq(irq - I8259_IRQ_BASE); -} - static struct irq_chip i8259_irq_type = { .typename = "XT-PIC", .ack = ack_i8259_irq, .mask = disable_i8259_irq, .mask_ack = ack_i8259_irq, .unmask = enable_i8259_irq, - .end = end_i8259_irq, }; static int i8259_get_irq_number(int irq) @@ -92,7 +85,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - set_irq_chip(i, &i8259_irq_type); + set_irq_chip_and_handler(i, &i8259_irq_type, handle_level_irq); setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); -- cgit v1.2.3 From c25c79d80e02db1bd993426f979c5f1b42a0f132 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 8 Dec 2006 12:55:42 +0000 Subject: [MIPS] Qemu now has an ELF loader. So nuke kludge for flat binaries. Signed-off-by: Ralf Baechle --- arch/mips/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index a2e095adaa3..9a7811d13db 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S @@ -138,7 +138,7 @@ EXPORT(stext) # used for profiling EXPORT(_stext) -#if defined(CONFIG_QEMU) || defined(CONFIG_MIPS_SIM) +#ifdef CONFIG_MIPS_SIM /* * Give us a fighting chance of running if execution beings at the * kernel load address. This is needed because this platform does -- cgit v1.2.3 From f0647a52974daccbe20990fb6341f07792445fe0 Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Fri, 8 Dec 2006 11:40:35 +0300 Subject: [PATCH] add STB810 support (Philips PNX8550-based) Signed-off-by: Vitaly Wool Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 5 + arch/mips/Makefile | 5 + arch/mips/configs/pnx8550-stb810_defconfig | 1229 ++++++++++++++++++++++++ arch/mips/pci/fixup-pnx8550.c | 4 +- arch/mips/philips/pnx8550/common/prom.c | 20 +- arch/mips/philips/pnx8550/jbs/irqmap.c | 8 +- arch/mips/philips/pnx8550/stb810/Makefile | 4 + arch/mips/philips/pnx8550/stb810/board_setup.c | 49 + arch/mips/philips/pnx8550/stb810/irqmap.c | 23 + arch/mips/philips/pnx8550/stb810/prom_init.c | 49 + 10 files changed, 1376 insertions(+), 20 deletions(-) create mode 100644 arch/mips/configs/pnx8550-stb810_defconfig create mode 100644 arch/mips/philips/pnx8550/stb810/Makefile create mode 100644 arch/mips/philips/pnx8550/stb810/board_setup.c create mode 100644 arch/mips/philips/pnx8550/stb810/irqmap.c create mode 100644 arch/mips/philips/pnx8550/stb810/prom_init.c (limited to 'arch') diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e58928a9104..fd2ff0698a8 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -461,6 +461,11 @@ config PNX8550_JBS select PNX8550 select SYS_SUPPORTS_LITTLE_ENDIAN +config PNX8550_STB810 + bool "Support for Philips PNX8550 based STB810 board" + select PNX8550 + select SYS_SUPPORTS_LITTLE_ENDIAN + config DDB5477 bool "NEC DDB Vrc-5477" select DDB5XXX_COMMON diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 8eb6fc1f555..d1b026a0337 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -463,6 +463,11 @@ libs-$(CONFIG_PNX8550_JBS) += arch/mips/philips/pnx8550/jbs/ #cflags-$(CONFIG_PNX8550_JBS) += -Iinclude/asm-mips/mach-pnx8550 load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000 +# Philips PNX8550 STB810 board +# +libs-$(CONFIG_PNX8550_STB810) += arch/mips/philips/pnx8550/stb810/ +load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000 + # NEC EMMA2RH boards # core-$(CONFIG_EMMA2RH) += arch/mips/emma2rh/common/ diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig new file mode 100644 index 00000000000..f38a2c12303 --- /dev/null +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -0,0 +1,1229 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19 +# Thu Dec 7 16:35:12 2006 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +CONFIG_PNX8550_STB810=y +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +# CONFIG_KEXEC is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_TIME=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +# CONFIG_CPU_BIG_ENDIAN is not set +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_PNX8550=y +CONFIG_SOC_PNX8550=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +CONFIG_CPU_MIPS32_R1=y +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPSR1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_VPE_LOADER is not set +# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_256 is not set +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=250 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set +# CONFIG_UTS_NS is not set +# CONFIG_AUDIT is not set +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_RT_MUTEXES=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set +# CONFIG_PCI_DEBUG is not set +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_TRAD_SIGNALS=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +CONFIG_IDE=y +CONFIG_IDE_MAX_HWIFS=4 +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_IDE_SATA is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +CONFIG_BLK_DEV_IDESCSI=y +# CONFIG_IDE_TASK_IOCTL is not set + +# +# IDE chipset support/bugfixes +# +CONFIG_IDE_GENERIC=y +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_IDEPCI_SHARE_IRQ=y +CONFIG_BLK_DEV_OFFBOARD=y +CONFIG_BLK_DEV_GENERIC=y +# CONFIG_BLK_DEV_OPTI621 is not set +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_IDEDMA_FORCED is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_AMD74XX is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_TRIFLEX is not set +# CONFIG_BLK_DEV_CY82C693 is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_HPT34X is not set +CONFIG_BLK_DEV_HPT366=y +# CONFIG_BLK_DEV_JMICRON is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_NS87415 is not set +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PDC202XX_NEW is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SIIMAGE is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_IDE_ARM is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_IVB is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +CONFIG_SCSI_ISCSI_ATTRS=m +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set + +# +# SCSI low-level drivers +# +CONFIG_ISCSI_TCP=m +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_SCSI_ARCMSR is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +CONFIG_NATSEMI=y +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_QLA3XXX is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set +# CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_PNX8XXX is not set +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +CONFIG_HW_RANDOM=y +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set + +# +# Graphics support +# +CONFIG_FIRMWARE_EDID=y +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +# CONFIG_USB_DEVICEFS is not set +# CONFIG_USB_BANDWIDTH is not set +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_EHCI_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_ISD200=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_ATI_REMOTE2 is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set +# CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_PROC_SYSCTL=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_SCHEDSTATS is not set +CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SLAB_LEAK is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set +CONFIG_FORCED_INLINING=y +CONFIG_HEADERS_CHECK=y +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="console=ttyS1,38400n8 kgdb=ttyS0 root=/dev/nfs ip=bootp" +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_KGDB is not set +# CONFIG_RUNTIME_DEBUG is not set +# CONFIG_MIPS_UNCACHED is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_MANAGER=m +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_PLIST=y diff --git a/arch/mips/pci/fixup-pnx8550.c b/arch/mips/pci/fixup-pnx8550.c index 4256b3b30b7..50546dab668 100644 --- a/arch/mips/pci/fixup-pnx8550.c +++ b/arch/mips/pci/fixup-pnx8550.c @@ -33,7 +33,7 @@ #define DBG(x...) #endif -extern char irq_tab_jbs[][5]; +extern char pnx8550_irq_tab[][5]; void __init pcibios_fixup_resources(struct pci_dev *dev) { @@ -47,7 +47,7 @@ void __init pcibios_fixup(void) int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { - return irq_tab_jbs[slot][pin]; + return pnx8550_irq_tab[slot][pin]; } /* Do platform specific device initialization at pci_enable_device() time */ diff --git a/arch/mips/philips/pnx8550/common/prom.c b/arch/mips/philips/pnx8550/common/prom.c index f8952c1359c..eb6ec11fef0 100644 --- a/arch/mips/philips/pnx8550/common/prom.c +++ b/arch/mips/philips/pnx8550/common/prom.c @@ -35,23 +35,15 @@ char * prom_getcmdline(void) return &(arcs_cmdline[0]); } -void prom_init_cmdline(void) +void __init prom_init_cmdline(void) { - char *cp; - int actr; - - actr = 1; /* Always ignore argv[0] */ + int i; - cp = &(arcs_cmdline[0]); - while(actr < prom_argc) { - strcpy(cp, prom_argv[actr]); - cp += strlen(prom_argv[actr]); - *cp++ = ' '; - actr++; + arcs_cmdline[0] = '\0'; + for (i = 0; i < prom_argc; i++) { + strcat(arcs_cmdline, prom_argv[i]); + strcat(arcs_cmdline, " "); } - if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ - --cp; - *cp = '\0'; } char *prom_getenv(char *envname) diff --git a/arch/mips/philips/pnx8550/jbs/irqmap.c b/arch/mips/philips/pnx8550/jbs/irqmap.c index f78e0423dc9..98c3429e6e5 100644 --- a/arch/mips/philips/pnx8550/jbs/irqmap.c +++ b/arch/mips/philips/pnx8550/jbs/irqmap.c @@ -28,9 +28,9 @@ #include #include -char irq_tab_jbs[][5] __initdata = { - [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, - [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, - [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, +char pnx8550_irq_tab[][5] __initdata = { + [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [17] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, }; diff --git a/arch/mips/philips/pnx8550/stb810/Makefile b/arch/mips/philips/pnx8550/stb810/Makefile new file mode 100644 index 00000000000..f14b592af39 --- /dev/null +++ b/arch/mips/philips/pnx8550/stb810/Makefile @@ -0,0 +1,4 @@ + +# Makefile for the Philips STB810 Board. + +lib-y := prom_init.o board_setup.o irqmap.o diff --git a/arch/mips/philips/pnx8550/stb810/board_setup.c b/arch/mips/philips/pnx8550/stb810/board_setup.c new file mode 100644 index 00000000000..345d71e53cf --- /dev/null +++ b/arch/mips/philips/pnx8550/stb810/board_setup.c @@ -0,0 +1,49 @@ +/* + * STB810 specific board startup routines. + * + * Based on the arch/mips/philips/pnx8550/jbs/board_setup.c + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2005 MontaVista Software Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +void __init board_setup(void) +{ + unsigned long config0, configpr; + + config0 = read_c0_config(); + + /* clear all three cache coherency fields */ + config0 &= ~(0x7 | (7<<25) | (7<<28)); + config0 |= (CONF_CM_DEFAULT | (CONF_CM_DEFAULT<<25) | + (CONF_CM_DEFAULT<<28)); + write_c0_config(config0); + + configpr = read_c0_config7(); + configpr |= (1<<19); /* enable tlb */ + write_c0_config7(configpr); +} diff --git a/arch/mips/philips/pnx8550/stb810/irqmap.c b/arch/mips/philips/pnx8550/stb810/irqmap.c new file mode 100644 index 00000000000..5ee11e19975 --- /dev/null +++ b/arch/mips/philips/pnx8550/stb810/irqmap.c @@ -0,0 +1,23 @@ +/* + * Philips STB810 board irqmap. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2005 MontaVista Software Inc. + * + * 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. + */ + +#include +#include + +char pnx8550_irq_tab[][5] __initdata = { + [8] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [9] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, + [10] = { -1, PNX8550_INT_PCI_INTA, 0xff, 0xff, 0xff}, +}; + diff --git a/arch/mips/philips/pnx8550/stb810/prom_init.c b/arch/mips/philips/pnx8550/stb810/prom_init.c new file mode 100644 index 00000000000..ea5b4e0fb47 --- /dev/null +++ b/arch/mips/philips/pnx8550/stb810/prom_init.c @@ -0,0 +1,49 @@ +/* + * STB810 specific prom routines + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * Copyright 2005 MontaVista Software Inc. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int prom_argc; +char **prom_argv, **prom_envp; +extern void __init prom_init_cmdline(void); +extern char *prom_getenv(char *envname); + +const char *get_system_type(void) +{ + return "Philips PNX8550/STB810"; +} + +void __init prom_init(void) +{ + unsigned long memsize; + + prom_argc = (int) fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + prom_init_cmdline(); + + mips_machgroup = MACH_GROUP_PHILIPS; + mips_machtype = MACH_PHILIPS_STB810; + + memsize = 0x08000000; /* Trimedia uses memory above */ + add_memory_region(0, memsize, BOOT_MEM_RAM); +} -- cgit v1.2.3 From a3a79bd7c75f0055df16540c7e9dbe270060ebe8 Mon Sep 17 00:00:00 2001 From: Sam Creasey Date: Sat, 9 Dec 2006 10:34:38 +0100 Subject: [PATCH] Sun3: General updates General compile fixes for 2.6.16 for sun3, and some updates to make the new bootloader work correctly. Tested on 3/50, 3/60, 3/80. Signed-off-by: Sam Creasey Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/kernel/sun3-head.S | 10 ---------- arch/m68k/kernel/vmlinux-sun3.lds | 2 +- arch/m68k/mm/sun3mmu.c | 7 +++++-- 3 files changed, 6 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/m68k/kernel/sun3-head.S b/arch/m68k/kernel/sun3-head.S index bffd69a4a1a..4b5f050204e 100644 --- a/arch/m68k/kernel/sun3-head.S +++ b/arch/m68k/kernel/sun3-head.S @@ -67,16 +67,6 @@ ENTRY(_start) 1: lea init_task,%curptr | get initial thread... lea init_thread_union+THREAD_SIZE,%sp | ...and its stack. -/* copy bootinfo records from the loader to _end */ - lea _end, %a1 - lea BI_START, %a0 - /* number of longs to copy */ - movel %a0@, %d0 -1: addl #4, %a0 - movel %a0@, %a1@ - addl #4, %a1 - dbf %d0, 1b - /* Point MSP at an invalid page to trap if it's used. --m */ movl #(PAGESIZE),%d0 movc %d0,%msp diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index 2550b4ae273..8c7eccbfc98 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -8,7 +8,7 @@ ENTRY(_start) jiffies = jiffies_64 + 4; SECTIONS { - . = 0xE004000; + . = 0xE002000; _text = .; /* Text and read-only data */ .text : { *(.head) diff --git a/arch/m68k/mm/sun3mmu.c b/arch/m68k/mm/sun3mmu.c index ac6640ade0b..6a6513aa1ce 100644 --- a/arch/m68k/mm/sun3mmu.c +++ b/arch/m68k/mm/sun3mmu.c @@ -49,7 +49,6 @@ void __init paging_init(void) unsigned long zones_size[MAX_NR_ZONES] = { 0, }; unsigned long size; - #ifdef TEST_VERIFY_AREA wp_works_ok = 0; #endif @@ -94,7 +93,11 @@ void __init paging_init(void) /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ zones_size[ZONE_DMA] = ((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT; - free_area_init(zones_size); + /* I really wish I knew why the following change made things better... -- Sam */ +/* free_area_init(zones_size); */ + free_area_init_node(0, NODE_DATA(0), zones_size, + (__pa(PAGE_OFFSET) >> PAGE_SHIFT) + 1, NULL); + } -- cgit v1.2.3 From 3f922221bbeb1a61146126cdec3c7ccf81539463 Mon Sep 17 00:00:00 2001 From: Michael Schmitz Date: Sat, 9 Dec 2006 10:46:30 +0100 Subject: [PATCH] m68k/Atari: 2.6.18 Atari IDE interrupt needs SA_SHIRQ Atari IDE: The interrupt needs SA_SHIRQ now to get registered. Signed-off-by: Michael Schmitz Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/atari/stdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c index d64b5804e98..d01deb46ebb 100644 --- a/arch/m68k/atari/stdma.c +++ b/arch/m68k/atari/stdma.c @@ -174,7 +174,7 @@ int stdma_islocked(void) void __init stdma_init(void) { stdma_isr = NULL; - request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW, + request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | SA_SHIRQ, "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int); } -- cgit v1.2.3 From bf8af91bcd8aadad4933a51c1219ea35e1ae0d77 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 9 Dec 2006 10:50:15 +0100 Subject: [PATCH] m68k: EXPORT_SYMBOL(cache_{clear,push}) bogus comment Remove bogus comments about unexporting cache_{push,clear}(), as inline dma_cache_maintenance() (used by at least bionet and pamsnet) calls them. Signed-off-by: Geert Uytterhoeven Signed-off-by: Linus Torvalds --- arch/m68k/mm/memory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 0f88812822b..13c0b4ad01e 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -299,7 +299,7 @@ void cache_clear (unsigned long paddr, int len) mach_l2_flush(0); #endif } -EXPORT_SYMBOL(cache_clear); /* probably can be unexported */ +EXPORT_SYMBOL(cache_clear); /* @@ -352,7 +352,7 @@ void cache_push (unsigned long paddr, int len) mach_l2_flush(1); #endif } -EXPORT_SYMBOL(cache_push); /* probably can be unexported */ +EXPORT_SYMBOL(cache_push); #ifndef CONFIG_SINGLE_MEMORY_CHUNK int mm_end_of_chunk (unsigned long addr, int len) -- cgit v1.2.3 From 9f25441fe6a4d8fc080a1f814078ac5d67adeea4 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 9 Dec 2006 21:33:35 +0100 Subject: [PATCH] x86-64: Update defconfig Signed-off-by: Andi Kleen --- arch/x86_64/defconfig | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 96f226cfb33..1a1c6a1a299 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-git7 -# Wed Dec 6 23:50:47 2006 +# Linux kernel version: 2.6.19-git14 +# Sat Dec 9 21:23:09 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -22,6 +22,9 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_DMI=y CONFIG_AUDIT_ARCH=y +CONFIG_GENERIC_BUG=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -170,6 +173,7 @@ CONFIG_SECCOMP=y # CONFIG_CC_STACKPROTECTOR is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_REORDER is not set @@ -514,6 +518,7 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set @@ -534,6 +539,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -587,6 +593,7 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers @@ -1106,10 +1113,7 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_ES1371 is not set CONFIG_SOUND_ICH=y # CONFIG_SOUND_TRIDENT is not set @@ -1118,6 +1122,11 @@ CONFIG_SOUND_ICH=y # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set +# +# HID Devices +# +CONFIG_HID=y + # # USB support # @@ -1182,8 +1191,7 @@ CONFIG_USB_STORAGE=y # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HID_POWERBOOK is not set # CONFIG_HID_FF is not set # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set @@ -1474,6 +1482,11 @@ CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + # # Instrumentation Support # @@ -1504,6 +1517,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set +CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set CONFIG_DEBUG_FS=y # CONFIG_DEBUG_VM is not set @@ -1534,6 +1548,7 @@ CONFIG_DEBUG_STACKOVERFLOW=y # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y -- cgit v1.2.3 From e0f27981f2d5fd93b2795e8348327b081c512f83 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 9 Dec 2006 21:33:35 +0100 Subject: [PATCH] i386: Update defconfig Signed-off-by: Andi Kleen --- arch/i386/defconfig | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 65891f11ace..3265208e589 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-git7 -# Wed Dec 6 23:50:49 2006 +# Linux kernel version: 2.6.19-git14 +# Sat Dec 9 21:23:14 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -12,6 +12,7 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_BUG=y CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y @@ -141,6 +142,8 @@ CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_RWSEM_XCHGADD_ALGORITHM=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y @@ -203,6 +206,7 @@ CONFIG_MTRR=y CONFIG_SECCOMP=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=250 # CONFIG_KEXEC is not set @@ -563,6 +567,7 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set @@ -583,6 +588,7 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_MULTI_LUN is not set # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -642,6 +648,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers @@ -1082,10 +1089,7 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set # CONFIG_SOUND_ES1371 is not set CONFIG_SOUND_ICH=y # CONFIG_SOUND_TRIDENT is not set @@ -1094,6 +1098,11 @@ CONFIG_SOUND_ICH=y # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set +# +# HID Devices +# +CONFIG_HID=y + # # USB support # @@ -1158,8 +1167,7 @@ CONFIG_USB_STORAGE=y # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HID_POWERBOOK is not set # CONFIG_HID_FF is not set # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set @@ -1443,6 +1451,11 @@ CONFIG_NLS_ISO8859_15=y # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=y +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + # # Instrumentation Support # @@ -1509,6 +1522,7 @@ CONFIG_DOUBLEFAULT=y # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y -- cgit v1.2.3 From 16d279d277aedd640d9dba5ddeb172b5e6bc7d75 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 9 Dec 2006 21:33:35 +0100 Subject: [PATCH] x86: Fix verify_quirk_intel_irqbalance() Fix verify_quirk_intel_irqbalance(). genapic checks should really happen only on affected versions of the E7520/E7320/E7525 based platforms. AK: This should akpm's Coyote SDV Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen --- arch/i386/kernel/quirks.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index a01320a7b63..34874c398b4 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -10,13 +10,38 @@ #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) { + u8 config, rev; + u32 word; + + /* BIOS may enable hardware IRQ balancing for + * E7520/E7320/E7525(revision ID 0x9 and below) + * based platforms. + * For those platforms, make sure that the genapic is set to 'flat' + */ + pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); + if (rev > 0x9) + return; + + /* enable access to config space*/ + pci_read_config_byte(dev, 0xf4, &config); + pci_write_config_byte(dev, 0xf4, config|0x2); + + /* read xTPR register */ + raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); + + if (!(word & (1 << 13))) { #ifdef CONFIG_X86_64 - if (genapic != &apic_flat) - panic("APIC mode must be flat on this system\n"); + if (genapic != &apic_flat) + panic("APIC mode must be flat on this system\n"); #elif defined(CONFIG_X86_GENERICARCH) - if (genapic != &apic_default) - panic("APIC mode must be default(flat) on this system. Use apic=default\n"); + if (genapic != &apic_default) + panic("APIC mode must be default(flat) on this system. Use apic=default\n"); #endif + } + + /* put back the original value for config space*/ + if (!(config & 0x2)) + pci_write_config_byte(dev, 0xf4, config); } void __init quirk_intel_irqbalance(void) -- cgit v1.2.3 From 92715e282be7c7488f892703c8d39b08976a833b Mon Sep 17 00:00:00 2001 From: Ravikiran G Thirumalai Date: Sat, 9 Dec 2006 21:33:35 +0100 Subject: [PATCH] x86: Fix boot hang due to nmi watchdog init code 2.6.19 stopped booting (or booted based on build/config) on our x86_64 systems due to a bug introduced in 2.6.19. check_nmi_watchdog schedules an IPI on all cpus to busy wait on a flag, but fails to set the busywait flag if NMI functionality is disabled. This causes the secondary cpus to spin in an endless loop, causing the kernel bootup to hang. Depending upon the build, the busywait flag got overwritten (stack variable) and caused the kernel to bootup on certain builds. Following patch fixes the bug by setting the busywait flag before returning from check_nmi_watchdog. I guess using a stack variable is not good here as the calling function could potentially return while the busy wait loop is still spinning on the flag. AK: I redid the patch significantly to be cleaner Signed-off-by: Ravikiran Thirumalai Signed-off-by: Shai Fultheim Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 8 ++++---- arch/x86_64/kernel/nmi.c | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index f5bc7e1be80..a5e34d65596 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -195,6 +195,8 @@ static __cpuinit inline int nmi_known_cpu(void) return 0; } +static int endflag __initdata = 0; + #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when * the CPU is idle. To make sure the NMI watchdog really ticks on all @@ -202,7 +204,6 @@ static __cpuinit inline int nmi_known_cpu(void) */ static __init void nmi_cpu_busy(void *data) { - volatile int *endflag = data; local_irq_enable_in_hardirq(); /* Intentionally don't use cpu_relax here. This is to make sure that the performance counter really ticks, @@ -210,14 +211,13 @@ static __init void nmi_cpu_busy(void *data) pause instruction. On a real HT machine this is fine because all other CPUs are busy with "useless" delay loops and don't care if they get somewhat less cycles. */ - while (*endflag == 0) - barrier(); + while (endflag == 0) + mb(); } #endif static int __init check_nmi_watchdog(void) { - volatile int endflag = 0; unsigned int *prev_nmi_count; int cpu; diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 27e95e7922c..186aebbae32 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -193,6 +193,8 @@ void nmi_watchdog_default(void) nmi_watchdog = NMI_IO_APIC; } +static int endflag __initdata = 0; + #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when * the CPU is idle. To make sure the NMI watchdog really ticks on all @@ -200,7 +202,6 @@ void nmi_watchdog_default(void) */ static __init void nmi_cpu_busy(void *data) { - volatile int *endflag = data; local_irq_enable_in_hardirq(); /* Intentionally don't use cpu_relax here. This is to make sure that the performance counter really ticks, @@ -208,14 +209,13 @@ static __init void nmi_cpu_busy(void *data) pause instruction. On a real HT machine this is fine because all other CPUs are busy with "useless" delay loops and don't care if they get somewhat less cycles. */ - while (*endflag == 0) - barrier(); + while (endflag == 0) + mb(); } #endif int __init check_nmi_watchdog (void) { - volatile int endflag = 0; int *counts; int cpu; @@ -256,6 +256,7 @@ int __init check_nmi_watchdog (void) if (!atomic_read(&nmi_active)) { kfree(counts); atomic_set(&nmi_active, -1); + endflag = 1; return -1; } endflag = 1; -- cgit v1.2.3 From 1bac3b383a93a4a920ffc57441eb133c78567fbd Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 9 Dec 2006 21:33:36 +0100 Subject: [PATCH] x86: Work around gcc 4.2 over aggressive optimizer The new PDA code uses a dummy _proxy_pda variable to describe memory references to the PDA. It is never referenced in inline assembly, but exists as input/output arguments. gcc 4.2 in some cases can CSE references to this which causes unresolved symbols. Define it to zero to avoid this. Signed-off-by: Andi Kleen --- arch/i386/kernel/vmlinux.lds.S | 1 + arch/x86_64/kernel/vmlinux.lds.S | 1 + 2 files changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 16d3c7133ad..a53c8b1854b 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -26,6 +26,7 @@ OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") OUTPUT_ARCH(i386) ENTRY(phys_startup_32) jiffies = jiffies_64; +_proxy_pda = 0; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 6c417788c54..514be5dd230 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -13,6 +13,7 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) jiffies_64 = jiffies; +_proxy_pda = 0; PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(7); /* RWE */ -- cgit v1.2.3 From 7e74437cf60cc84a655e301f1ee48027b3bcf96e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 9 Dec 2006 21:33:36 +0100 Subject: [PATCH] i386: export smp_num_siblings for oprofile oprofile uses smp_num_siblings without testing for CONFIG_X86_HT. I looked at modifying oprofile, but this way is cleaner & simpler and I didn't see a good reason not to just export it when CONFIG_SMP. WARNING: "smp_num_siblings" [arch/i386/oprofile/oprofile.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: Andi Kleen --- arch/i386/kernel/smpboot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 1e00b03163b..b0f84e5778a 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -69,7 +69,7 @@ static int __devinitdata smp_b_stepping; /* Number of siblings per CPU package */ int smp_num_siblings = 1; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP EXPORT_SYMBOL(smp_num_siblings); #endif -- cgit v1.2.3 From 306a22c2a20edf3a440bfb4cf2b94c19dfd81a53 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 9 Dec 2006 21:33:36 +0100 Subject: [PATCH] i386: Fix io_apic.c warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gcc 4.2 warns linux/arch/i386/kernel/io_apic.c: In function ‘create_irq’: linux/arch/i386/kernel/io_apic.c:2488: warning: ‘vector’ may be used uninitialized in this function The warning is false, but somewhat legitimate so work around it. Signed-off-by: Andi Kleen --- arch/i386/kernel/io_apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index e21dcde0790..2424cc9c7b3 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2485,7 +2485,7 @@ device_initcall(ioapic_init_sysfs); int create_irq(void) { /* Allocate an unused irq */ - int irq, new, vector; + int irq, new, vector = 0; unsigned long flags; irq = -ENOSPC; -- cgit v1.2.3 From f0f32fccbffaaba8596d5c671153aa37aea9d4f0 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 9 Dec 2006 21:33:36 +0100 Subject: [PATCH] x86-64: no paravirt for X86_VOYAGER or X86_VISWS Since Voyager and Visual WS already define ARCH_SETUP, it looks like PARAVIRT shouldn't be offered for them. In file included from arch/i386/kernel/setup.c:63: include/asm-i386/mach-visws/setup_arch.h:8:1: warning: "ARCH_SETUP" redefin= ed In file included from include/asm/msr.h:5, from include/asm/processor.h:17, from include/asm/thread_info.h:16, from include/linux/thread_info.h:21, from include/linux/preempt.h:9, from include/linux/spinlock.h:49, from include/linux/capability.h:45, from include/linux/sched.h:46, from arch/i386/kernel/setup.c:26: include/asm/paravirt.h:163:1: warning: this is the location of the previous= definition In file included from arch/i386/kernel/setup.c:63: include/asm-i386/mach-visws/setup_arch.h:8:1: warning: "ARCH_SETUP" redefin= ed In file included from include/asm/msr.h:5, from include/asm/processor.h:17, from include/asm/thread_info.h:16, from include/linux/thread_info.h:21, from include/linux/preempt.h:9, from include/linux/spinlock.h:49, from include/linux/capability.h:45, from include/linux/sched.h:46, from arch/i386/kernel/setup.c:26: include/asm/paravirt.h:163:1: warning: this is the location of the previous= definition Signed-off-by: Randy Dunlap --- arch/i386/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index c2362c7ba74..0d67a0a1151 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -190,6 +190,7 @@ endchoice config PARAVIRT bool "Paravirtualization support (EXPERIMENTAL)" depends on EXPERIMENTAL + depends on !(X86_VISWS || X86_VOYAGER) help Paravirtualization is a way of running multiple instances of Linux on the same machine, under a hypervisor. This option -- cgit v1.2.3 From 10e267234cc0133bc9ed26bc34eb09de90c248c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 16 Nov 2006 13:38:57 -0800 Subject: [SPARC64]: Add irqtrace/stacktrace/lockdep support. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 8 ++++++++ arch/sparc64/Kconfig.debug | 4 ++++ arch/sparc64/kernel/Makefile | 1 + arch/sparc64/kernel/entry.S | 27 +++++++++++++++++++++++++- arch/sparc64/kernel/head.S | 8 ++++++++ arch/sparc64/kernel/rtrap.S | 23 ++++++++++++++++------ arch/sparc64/kernel/stacktrace.c | 41 ++++++++++++++++++++++++++++++++++++++++ arch/sparc64/kernel/sun4v_ivec.S | 20 ++++++++++++++++---- arch/sparc64/mm/ultra.S | 8 ++++++++ 9 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 arch/sparc64/kernel/stacktrace.c (limited to 'arch') diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index d391d11f245..d41f66ac7ff 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -26,6 +26,14 @@ config MMU bool default y +config STACKTRACE_SUPPORT + bool + default y + +config LOCKDEP_SUPPORT + bool + default y + config TIME_INTERPOLATION bool default y diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index afe0a7720a2..1f130f3b6c2 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -1,5 +1,9 @@ menu "Kernel hacking" +config TRACE_IRQFLAGS_SUPPORT + bool + default y + source "lib/Kconfig.debug" config DEBUG_STACK_USAGE diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index e1eabebaed3..eff0c01d357 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -14,6 +14,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ visemul.o prom.o of_device.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 6f28bec0a9b..c15a3edcb82 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -597,7 +597,12 @@ __spitfire_cee_trap_continue: 1: ba,pt %xcc, etrap_irq rd %pc, %g7 -2: mov %l4, %o1 +2: +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif + mov %l4, %o1 mov %l5, %o2 call spitfire_access_error add %sp, PTREGS_OFF, %o0 @@ -824,6 +829,10 @@ do_cheetah_plus_data_parity: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov 0x0, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 @@ -855,6 +864,10 @@ do_cheetah_plus_insn_parity: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov 0x1, %o0 call cheetah_plus_parity_error add %sp, PTREGS_OFF, %o1 @@ -1183,6 +1196,10 @@ c_fast_ecc: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_fecc_handler @@ -1211,6 +1228,10 @@ c_cee: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_cee_handler @@ -1239,6 +1260,10 @@ c_deferred: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif mov %l4, %o1 mov %l5, %o2 call cheetah_deferred_handler diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index c8e9dc9d68a..03ffaf895a2 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S @@ -489,6 +489,14 @@ tlb_fixup_done: call __bzero sub %o1, %o0, %o1 +#ifdef CONFIG_LOCKDEP + /* We have this call this super early, as even prom_init can grab + * spinlocks and thus call into the lockdep code. + */ + call lockdep_init + nop +#endif + mov %l6, %o1 ! OpenPROM stack call prom_init mov %l7, %o0 ! OpenPROM cif handler diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index 3522cd66f3b..079d18a11d2 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -165,14 +165,26 @@ rtrap: __handle_softirq_continue: rtrap_xcall: sethi %hi(0xf << 20), %l4 - andcc %l1, TSTATE_PRIV, %l3 and %l1, %l4, %l4 + andn %l1, %l4, %l1 + srl %l4, 20, %l4 +#ifdef CONFIG_TRACE_IRQFLAGS + brnz,pn %l4, rtrap_no_irq_enable + nop + call trace_hardirqs_on + nop + wrpr %l4, %pil +rtrap_no_irq_enable: +#endif + andcc %l1, TSTATE_PRIV, %l3 bne,pn %icc, to_kernel - andn %l1, %l4, %l1 + nop /* We must hold IRQs off and atomically test schedule+signal * state, then hold them off all the way back to userspace. - * If we are returning to kernel, none of this matters. + * If we are returning to kernel, none of this matters. Note + * that we are disabling interrupts via PSTATE_IE, not using + * %pil. * * If we do not do this, there is a window where we would do * the tests, later the signal/resched event arrives but we do @@ -256,7 +268,6 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 wr %o3, %g0, %y - srl %l4, 20, %l4 wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl wrpr %l1, %g0, %tstate @@ -374,8 +385,8 @@ to_kernel: ldx [%g6 + TI_FLAGS], %l5 andcc %l5, _TIF_NEED_RESCHED, %g0 be,pt %xcc, kern_fpucheck - srl %l4, 20, %l5 - cmp %l5, 0 + nop + cmp %l4, 0 bne,pn %xcc, kern_fpucheck sethi %hi(PREEMPT_ACTIVE), %l6 stw %l6, [%g6 + TI_PRE_COUNT] diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 00000000000..c4d15f2762b --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + unsigned long ksp, fp, thread_base; + struct thread_info *tp; + + if (!task) + task = current; + tp = task_thread_info(task); + if (task == current) { + flushw_all(); + __asm__ __volatile__( + "mov %%fp, %0" + : "=r" (ksp) + ); + } else + ksp = tp->ksp; + + fp = ksp + STACK_BIAS; + thread_base = (unsigned long) tp; + do { + struct reg_window *rw; + + /* Bogus frame pointer? */ + if (fp < (thread_base + sizeof(struct thread_info)) || + fp >= (thread_base + THREAD_SIZE)) + break; + + rw = (struct reg_window *) fp; + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = rw->ins[7]; + + fp = rw->ins[6] + STACK_BIAS; + } while (trace->nr_entries < trace->max_entries); +} diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index 49703c3c576..405855dd886 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S @@ -190,7 +190,10 @@ sun4v_res_mondo: mov %g1, %g4 ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif /* Log the event. */ add %sp, PTREGS_OFF, %o0 call sun4v_resum_error @@ -216,7 +219,10 @@ sun4v_res_mondo_queue_full: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call sun4v_resum_overflow add %sp, PTREGS_OFF, %o0 @@ -295,7 +301,10 @@ sun4v_nonres_mondo: mov %g1, %g4 ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif /* Log the event. */ add %sp, PTREGS_OFF, %o0 call sun4v_nonresum_error @@ -321,7 +330,10 @@ sun4v_nonres_mondo_queue_full: wrpr %g0, 15, %pil ba,pt %xcc, etrap_irq rd %pc, %g7 - +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call sun4v_nonresum_overflow add %sp, PTREGS_OFF, %o0 diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index d70b60a3bbc..737c26923c0 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -477,6 +477,10 @@ xcall_sync_tick: sethi %hi(109f), %g7 b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call smp_synchronize_tick_client nop clr %l6 @@ -508,6 +512,10 @@ xcall_report_regs: sethi %hi(109f), %g7 b,pt %xcc, etrap_irq 109: or %g7, %lo(109b), %g7 +#ifdef CONFIG_TRACE_IRQFLAGS + call trace_hardirqs_off + nop +#endif call __show_regs add %sp, PTREGS_OFF, %o0 clr %l6 -- cgit v1.2.3 From 042cf50cfd0bc3e1769d8287465eb522e8a08ba6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 16 Nov 2006 13:40:11 -0800 Subject: [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 2f4612fa81f..18a1861db66 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,12 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc2 -# Tue Oct 17 19:29:20 2006 +# Linux kernel version: 2.6.19-rc6 +# Thu Nov 16 13:39:41 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y CONFIG_64BIT=y CONFIG_MMU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_TIME_INTERPOLATION=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_AUDIT_ARCH=y @@ -48,7 +50,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set CONFIG_UID16=y -# CONFIG_SYSCTL_SYSCALL is not set +CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -145,7 +147,6 @@ CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m CONFIG_SPARC32_COMPAT=y @@ -219,7 +220,6 @@ CONFIG_INET6_XFRM_MODE_BEET=m # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set CONFIG_IPV6_SIT=m CONFIG_IPV6_TUNNEL=m -# CONFIG_IPV6_SUBTREES is not set # CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -1119,6 +1119,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set # CONFIG_USB_MON is not set @@ -1373,6 +1374,7 @@ CONFIG_KPROBES=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y @@ -1387,6 +1389,8 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1420,7 +1424,7 @@ CONFIG_CRYPTO=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=y -- cgit v1.2.3 From 6e7726e16fb5e8f1169dbfcb75e321ac871af827 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 19 Nov 2006 14:38:25 -0800 Subject: [SPARC64]: Call do_mathemu on illegal instruction traps too. To add this logic, put the VIS instruction check at the vis_emul() call site instead of inside of vis_emul(). Signed-off-by: David S. Miller --- arch/sparc64/kernel/traps.c | 18 +++++++++++++++--- arch/sparc64/kernel/visemul.c | 6 ------ 2 files changed, 15 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index fe1796c939c..ec7a60142be 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -2261,8 +2261,12 @@ void die_if_kernel(char *str, struct pt_regs *regs) do_exit(SIGSEGV); } +#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) +#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) + extern int handle_popc(u32 insn, struct pt_regs *regs); extern int handle_ldf_stq(u32 insn, struct pt_regs *regs); +extern int vis_emul(struct pt_regs *, unsigned int); void do_illegal_instruction(struct pt_regs *regs) { @@ -2287,10 +2291,18 @@ void do_illegal_instruction(struct pt_regs *regs) if (handle_ldf_stq(insn, regs)) return; } else if (tlb_type == hypervisor) { - extern int vis_emul(struct pt_regs *, unsigned int); + if ((insn & VIS_OPCODE_MASK) == VIS_OPCODE_VAL) { + if (!vis_emul(regs, insn)) + return; + } else { + struct fpustate *f = FPUSTATE; - if (!vis_emul(regs, insn)) - return; + /* XXX maybe verify XFSR bits like + * XXX do_fpother() does? + */ + if (do_mathemu(regs, f)) + return; + } } } info.si_signo = SIGILL; diff --git a/arch/sparc64/kernel/visemul.c b/arch/sparc64/kernel/visemul.c index 84fedaa38aa..c3fd64706b5 100644 --- a/arch/sparc64/kernel/visemul.c +++ b/arch/sparc64/kernel/visemul.c @@ -128,9 +128,6 @@ /* 001001100 - Permute bytes as specified by GSR.MASK */ #define BSHUFFLE_OPF 0x04c -#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19)) -#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19)) - #define VIS_OPF_SHIFT 5 #define VIS_OPF_MASK (0x1ff << VIS_OPF_SHIFT) @@ -810,9 +807,6 @@ int vis_emul(struct pt_regs *regs, unsigned int insn) if (get_user(insn, (u32 __user *) pc)) return -EFAULT; - if ((insn & VIS_OPCODE_MASK) != VIS_OPCODE_VAL) - return -EINVAL; - opf = (insn & VIS_OPF_MASK) >> VIS_OPF_SHIFT; switch (opf) { default: -- cgit v1.2.3 From c449c38b5df1fad556ea210deb6cff3b27323e49 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Nov 2006 20:18:05 -0800 Subject: [SPARC64]: Unaligned accesses to userspace are hard errors. Userspace is forbidden from making unaligned loads and stores. So if we get an unaligned trap due to a {get,put}_user(), signal a fault and run the exception handler. Signed-off-by: David S. Miller --- arch/sparc64/kernel/unaligned.c | 44 +++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index a9b765271b8..bc18d480dd1 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c @@ -243,7 +243,7 @@ static inline int ok_for_kernel(unsigned int insn) return !floating_point_load_or_store_p(insn); } -static void kernel_mna_trap_fault(void) +static void kernel_mna_trap_fault(int fixup_tstate_asi) { struct pt_regs *regs = current_thread_info()->kern_una_regs; unsigned int insn = current_thread_info()->kern_una_insn; @@ -274,18 +274,15 @@ static void kernel_mna_trap_fault(void) regs->tpc = entry->fixup; regs->tnpc = regs->tpc + 4; - regs->tstate &= ~TSTATE_ASI; - regs->tstate |= (ASI_AIUS << 24UL); + if (fixup_tstate_asi) { + regs->tstate &= ~TSTATE_ASI; + regs->tstate |= (ASI_AIUS << 24UL); + } } -asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) +static void log_unaligned(struct pt_regs *regs) { static unsigned long count, last_time; - enum direction dir = decode_direction(insn); - int size = decode_access_size(insn); - - current_thread_info()->kern_una_regs = regs; - current_thread_info()->kern_una_insn = insn; if (jiffies - last_time > 5 * HZ) count = 0; @@ -295,6 +292,28 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) printk("Kernel unaligned access at TPC[%lx] ", regs->tpc); print_symbol("%s\n", regs->tpc); } +} + +asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) +{ + enum direction dir = decode_direction(insn); + int size = decode_access_size(insn); + int orig_asi, asi; + + current_thread_info()->kern_una_regs = regs; + current_thread_info()->kern_una_insn = insn; + + orig_asi = asi = decode_asi(insn, regs); + + /* If this is a {get,put}_user() on an unaligned userspace pointer, + * just signal a fault and do not log the event. + */ + if (asi == ASI_AIUS) { + kernel_mna_trap_fault(0); + return; + } + + log_unaligned(regs); if (!ok_for_kernel(insn) || dir == both) { printk("Unsupported unaligned load/store trap for kernel " @@ -302,10 +321,10 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) unaligned_panic("Kernel does fpu/atomic " "unaligned load/store.", regs); - kernel_mna_trap_fault(); + kernel_mna_trap_fault(0); } else { unsigned long addr, *reg_addr; - int orig_asi, asi, err; + int err; addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); @@ -315,7 +334,6 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); #endif - orig_asi = asi = decode_asi(insn, regs); switch (asi) { case ASI_NL: case ASI_AIUPL: @@ -365,7 +383,7 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) /* Not reached... */ } if (unlikely(err)) - kernel_mna_trap_fault(); + kernel_mna_trap_fault(1); else advance(regs); } -- cgit v1.2.3 From a2c1e064c45f5126625121f58afa423e13c55efc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 29 Nov 2006 21:16:21 -0800 Subject: [SPARC64]: Run ctrl-alt-del action for sun4v powerdown request. Signed-off-by: David S. Miller --- arch/sparc64/kernel/traps.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index ec7a60142be..ad67784292d 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -10,7 +10,7 @@ */ #include -#include /* for jiffies */ +#include #include #include #include @@ -1873,6 +1873,16 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) put_cpu(); + if (ent->err_type == SUN4V_ERR_TYPE_WARNING_RES) { + /* If err_type is 0x4, it's a powerdown request. Do + * not do the usual resumable error log because that + * makes it look like some abnormal error. + */ + printk(KERN_INFO "Power down request...\n"); + kill_cad_pid(SIGINT, 1); + return; + } + sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); -- cgit v1.2.3 From c80892d150a872b18cedfbf789211bfbebfc67ce Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Thu, 30 Nov 2006 17:07:04 -0800 Subject: [SPARC]: Replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 6 ++---- arch/sparc/kernel/of_device.c | 3 +-- arch/sparc/kernel/sun4d_irq.c | 3 +-- arch/sparc/mm/io-unit.c | 3 +-- 4 files changed, 5 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 54d51b40460..cbbc98846b0 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -317,9 +317,8 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) if ((va = __get_free_pages(GFP_KERNEL|__GFP_COMP, order)) == 0) goto err_nopages; - if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) + if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) goto err_nomem; - memset((char*)res, 0, sizeof(struct resource)); if (allocate_resource(&_sparc_dvma, res, len_total, _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { @@ -589,12 +588,11 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba) return NULL; } - if ((res = kmalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { + if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { free_pages(va, order); printk("pci_alloc_consistent: no core\n"); return NULL; } - memset((char*)res, 0, sizeof(struct resource)); if (allocate_resource(&_sparc_dvma, res, len_total, _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 46200c43ffb..dab6169e31c 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -793,10 +793,9 @@ struct of_device* of_platform_device_create(struct device_node *np, { struct of_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->dev.parent = parent; dev->dev.bus = bus; diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index d4f9da8170c..b8bd53ab29c 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -545,8 +545,7 @@ void __init sun4d_init_sbi_irq(void) nsbi = 0; for_each_sbus(sbus) nsbi++; - sbus_actions = (struct sbus_action *)kmalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); - memset (sbus_actions, 0, (nsbi * 8 * 4 * sizeof(struct sbus_action))); + sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); for_each_sbus(sbus) { #ifdef CONFIG_SMP extern unsigned char boot_cpu_id; diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 2bb1309003d..00706202296 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -41,9 +41,8 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) struct linux_prom_registers iommu_promregs[PROMREG_MAX]; struct resource r; - iounit = kmalloc(sizeof(struct iounit_struct), GFP_ATOMIC); + iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); - memset(iounit, 0, sizeof(*iounit)); iounit->limit[0] = IOUNIT_BMAP1_START; iounit->limit[1] = IOUNIT_BMAP2_START; iounit->limit[2] = IOUNIT_BMAPM_START; -- cgit v1.2.3 From d4accd60d23f3c8a576fd08b727f88096f42d445 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 30 Nov 2006 17:11:26 -0800 Subject: [SPARC]: Check kzalloc() return value in SUN4D irq/iommu init. Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4d_irq.c | 4 ++++ arch/sparc/mm/io-unit.c | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index b8bd53ab29c..cf1b8baa57e 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -546,6 +546,10 @@ void __init sun4d_init_sbi_irq(void) for_each_sbus(sbus) nsbi++; sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); + if (!sbus_actions) { + prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n"); + prom_halt(); + } for_each_sbus(sbus) { #ifdef CONFIG_SMP extern unsigned char boot_cpu_id; diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 00706202296..4ccda77d08d 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -22,6 +22,7 @@ #include #include #include +#include /* #define IOUNIT_DEBUG */ #ifdef IOUNIT_DEBUG @@ -42,6 +43,10 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) struct resource r; iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); + if (!iounit) { + prom_printf("SUN4D: Cannot alloc iounit, halting.\n"); + prom_halt(); + } iounit->limit[0] = IOUNIT_BMAP1_START; iounit->limit[1] = IOUNIT_BMAP2_START; -- cgit v1.2.3 From 982c2064d9a8b51404088d132489a25e2db807fd Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Thu, 30 Nov 2006 17:13:09 -0800 Subject: [SPARC64]: Replace kmalloc+memset with kzalloc Replace kmalloc+memset with kzalloc Signed-off-by: Yan Burman Signed-off-by: David S. Miller --- arch/sparc64/kernel/chmc.c | 3 +-- arch/sparc64/kernel/isa.c | 12 +++--------- arch/sparc64/kernel/of_device.c | 3 +-- arch/sparc64/kernel/pci_sun4v.c | 16 +++++----------- 4 files changed, 10 insertions(+), 24 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c index 259f37e516f..9699abeb990 100644 --- a/arch/sparc64/kernel/chmc.c +++ b/arch/sparc64/kernel/chmc.c @@ -341,7 +341,7 @@ static void fetch_decode_regs(struct mctrl_info *mp) static int init_one_mctrl(struct device_node *dp) { - struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); + struct mctrl_info *mp = kzalloc(sizeof(*mp), GFP_KERNEL); int portid = of_getintprop_default(dp, "portid", -1); struct linux_prom64_registers *regs; void *pval; @@ -349,7 +349,6 @@ static int init_one_mctrl(struct device_node *dp) if (!mp) return -1; - memset(mp, 0, sizeof(*mp)); if (portid == -1) goto fail; diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c index f028e68b23f..ad1c4f55420 100644 --- a/arch/sparc64/kernel/isa.c +++ b/arch/sparc64/kernel/isa.c @@ -72,14 +72,12 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) struct linux_prom_registers *regs; struct sparc_isa_device *isa_dev; - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { fatal_err("cannot allocate child isa_dev"); prom_halt(); } - memset(isa_dev, 0, sizeof(*isa_dev)); - /* Link it in to parent. */ isa_dev->next = parent_isa_dev->child; parent_isa_dev->child = isa_dev; @@ -104,14 +102,12 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) struct linux_prom_registers *regs; struct sparc_isa_device *isa_dev; - isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); + isa_dev = kzalloc(sizeof(*isa_dev), GFP_KERNEL); if (!isa_dev) { printk(KERN_DEBUG "ISA: cannot allocate isa_dev"); return; } - memset(isa_dev, 0, sizeof(*isa_dev)); - isa_dev->ofdev.node = dp; isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev; isa_dev->ofdev.dev.bus = &isa_bus_type; @@ -180,14 +176,12 @@ void __init isa_init(void) pbm = pdev_cookie->pbm; dp = pdev_cookie->prom_node; - isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); + isa_br = kzalloc(sizeof(*isa_br), GFP_KERNEL); if (!isa_br) { printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge"); return; } - memset(isa_br, 0, sizeof(*isa_br)); - isa_br->ofdev.node = dp; isa_br->ofdev.dev.parent = &pdev->dev; isa_br->ofdev.dev.bus = &isa_bus_type; diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 8cc14fc6b6f..cec0eceae55 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -1007,10 +1007,9 @@ struct of_device* of_platform_device_create(struct device_node *np, { struct of_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; - memset(dev, 0, sizeof(*dev)); dev->dev.parent = parent; dev->dev.bus = bus; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 03ad4c06758..6b04794b7a9 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -798,7 +798,7 @@ static struct pci_ops pci_sun4v_ops = { static void pbm_scan_bus(struct pci_controller_info *p, struct pci_pbm_info *pbm) { - struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL); + struct pcidev_cookie *cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); if (!cookie) { prom_printf("%s: Critical allocation failure.\n", pbm->name); @@ -806,7 +806,6 @@ static void pbm_scan_bus(struct pci_controller_info *p, } /* All we care about is the PBM. */ - memset(cookie, 0, sizeof(*cookie)); cookie->pbm = pbm; pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno, p->pci_ops, pbm); @@ -1048,12 +1047,11 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) /* Allocate and initialize the free area map. */ sz = num_tsb_entries / 8; sz = (sz + 7UL) & ~7UL; - iommu->arena.map = kmalloc(sz, GFP_KERNEL); + iommu->arena.map = kzalloc(sz, GFP_KERNEL); if (!iommu->arena.map) { prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); prom_halt(); } - memset(iommu->arena.map, 0, sz); iommu->arena.limit = num_tsb_entries; sz = probe_existing_entries(pbm, iommu); @@ -1164,24 +1162,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) per_cpu(pci_iommu_batch, i).pglist = (u64 *) page; } - p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); + p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); if (!p) goto fatal_memory_error; - memset(p, 0, sizeof(*p)); - - iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; - memset(iommu, 0, sizeof(*iommu)); p->pbm_A.iommu = iommu; - iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct pci_iommu), GFP_ATOMIC); if (!iommu) goto fatal_memory_error; - memset(iommu, 0, sizeof(*iommu)); p->pbm_B.iommu = iommu; p->next = pci_controller_root; -- cgit v1.2.3 From 35bca36cf7b20a73a89f87aab34b1b4dfff6bf08 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 1 Dec 2006 20:18:40 -0800 Subject: [SPARC{32,64}]: Propagate ptrace_traceme() return value. ptrace_traceme() consolidation made ret = ptrace_traceme(); dead write. Signed-off-by: Alexey Dobriyan Signed-off-by: David S. Miller --- arch/sparc/kernel/ptrace.c | 5 ++++- arch/sparc64/kernel/ptrace.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c index 1baf13ed5c3..003f8eed32f 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c @@ -289,7 +289,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); - pt_succ_return(regs, 0); + if (ret < 0) + pt_error_return(regs, -ret); + else + pt_succ_return(regs, 0); goto out; } diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c index d31975e6d6f..81111a12f0a 100644 --- a/arch/sparc64/kernel/ptrace.c +++ b/arch/sparc64/kernel/ptrace.c @@ -202,7 +202,10 @@ asmlinkage void do_ptrace(struct pt_regs *regs) #endif if (request == PTRACE_TRACEME) { ret = ptrace_traceme(); - pt_succ_return(regs, 0); + if (ret < 0) + pt_error_return(regs, -ret); + else + pt_succ_return(regs, 0); goto out; } -- cgit v1.2.3 From 2f149228bb30ea08bfde740178f832d5c9081005 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 9 Dec 2006 15:41:53 -0800 Subject: [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 18a1861db66..0f0d38f6197 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc6 -# Thu Nov 16 13:39:41 2006 +# Linux kernel version: 2.6.19 +# Sat Dec 9 15:41:30 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -11,16 +11,19 @@ CONFIG_STACKTRACE_SUPPORT=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_TIME_INTERPOLATION=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_AUDIT_ARCH=y CONFIG_SPARC64_PAGE_SIZE_8KB=y # CONFIG_SPARC64_PAGE_SIZE_64KB is not set # CONFIG_SPARC64_PAGE_SIZE_512KB is not set # CONFIG_SPARC64_PAGE_SIZE_4MB is not set CONFIG_SECCOMP=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -44,6 +47,7 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -147,6 +151,7 @@ CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y +# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m CONFIG_SPARC32_COMPAT=y @@ -204,6 +209,7 @@ CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -238,6 +244,8 @@ CONFIG_IP_DCCP_CCID2=m # CONFIG_IP_DCCP_CCID2_DEBUG is not set CONFIG_IP_DCCP_CCID3=m CONFIG_IP_DCCP_TFRC_LIB=m +# CONFIG_IP_DCCP_CCID3_DEBUG is not set +CONFIG_IP_DCCP_CCID3_RTO=100 # # DCCP Kernel Hacking @@ -405,6 +413,7 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_RAID_ATTRS=m CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y @@ -425,6 +434,7 @@ CONFIG_CHR_DEV_SG=m CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -468,6 +478,7 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SUNESP is not set +# CONFIG_SCSI_SRP is not set # # Serial ATA (prod) and Parallel ATA (experimental) drivers @@ -598,6 +609,7 @@ CONFIG_BNX2=m # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -724,10 +736,6 @@ CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set @@ -1038,6 +1046,11 @@ CONFIG_SND_SUN_CS4231=m # # CONFIG_SOUND_PRIME is not set +# +# HID Devices +# +CONFIG_HID=y + # # USB support # @@ -1053,6 +1066,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1089,8 +1103,7 @@ CONFIG_USB_UHCI_HCD=m # USB Input Devices # CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set +# CONFIG_USB_HID_POWERBOOK is not set # CONFIG_HID_FF is not set CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set @@ -1364,6 +1377,11 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_UTF8 is not set +# +# Distributed Lock Manager +# +# CONFIG_DLM is not set + # # Instrumentation Support # @@ -1426,6 +1444,7 @@ CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=y CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MD5=y @@ -1434,8 +1453,10 @@ CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_GF128MUL=m CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m @@ -1460,6 +1481,7 @@ CONFIG_CRYPTO_TEST=m # # Library routines # +CONFIG_BITREVERSE=y CONFIG_CRC_CCITT=m CONFIG_CRC16=m CONFIG_CRC32=y -- cgit v1.2.3 From f0882589666440d573f657cb3a1d5f66f3caa157 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 10 Dec 2006 02:42:03 -0800 Subject: [SPARC64]: Fix several kprobes bugs. - relbranch_fixup(), for non-branches, would end up setting regs->tnpc incorrectly, in fact it would set it equal to regs->tpc which would cause that instruction to execute twice Also, if this is not a PC-relative branch, we should just leave regs->tnpc as-is. This covers cases like 'jmpl' which branch to absolute values. - To be absolutely %100 safe, we need to flush the instruction cache for all assignments to kprobe->ainsn.insn[], including cases like add_aggr_kprobe() - prev_kprobe's status field needs to be 'unsigned long' to match the type of the value it is saving - jprobes were totally broken: = jprobe_return() can run in the stack frame of the jprobe handler, or in an even deeper stack frame, thus we'll be in the wrong register window than the one from the original probe state. So unwind using 'restore' instructions, if necessary, right before we do the jprobe_return() breakpoint trap. = There is no reason to save/restore the register window saved at %sp at jprobe trigger time. Those registers cannot be modified by the jprobe handler. Also, this code was saving and restoring "sizeof (struct sparc_stackf)" bytes. Depending upon the caller, this could clobber unrelated stack frame pieces if there is only a basic 128-byte register window stored on the stack, without the argument save area. So just saving and restoring struct pt_regs is sufficient. = Kill the "jprobe_saved_esp", totally unused. Also, delete "jprobe_saved_regs_location", with the stack frame unwind now done explicitly by jprobe_return(), this check is superfluous. Signed-off-by: David S. Miller --- arch/sparc64/kernel/kprobes.c | 91 ++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 48 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 8e75ed762fd..ae221f0d4a6 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -45,7 +45,11 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); int __kprobes arch_prepare_kprobe(struct kprobe *p) { p->ainsn.insn[0] = *p->addr; + flushi(&p->ainsn.insn[0]); + p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2; + flushi(&p->ainsn.insn[1]); + p->opcode = *p->addr; return 0; } @@ -185,16 +189,19 @@ no_kprobe: /* If INSN is a relative control transfer instruction, * return the corrected branch destination value. * - * The original INSN location was REAL_PC, it actually - * executed at PC and produced destination address NPC. + * regs->tpc and regs->tnpc still hold the values of the + * program counters at the time of trap due to the execution + * of the BREAKPOINT_INSTRUCTION_2 at p->ainsn.insn[1] + * */ -static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, - unsigned long pc, - unsigned long npc) +static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p, + struct pt_regs *regs) { + unsigned long real_pc = (unsigned long) p->addr; + /* Branch not taken, no mods necessary. */ - if (npc == pc + 0x4UL) - return real_pc + 0x4UL; + if (regs->tnpc == regs->tpc + 0x4UL) + return real_pc + 0x8UL; /* The three cases are call, branch w/prediction, * and traditional branch. @@ -202,14 +209,21 @@ static unsigned long __kprobes relbranch_fixup(u32 insn, unsigned long real_pc, if ((insn & 0xc0000000) == 0x40000000 || (insn & 0xc1c00000) == 0x00400000 || (insn & 0xc1c00000) == 0x00800000) { + unsigned long ainsn_addr; + + ainsn_addr = (unsigned long) &p->ainsn.insn[0]; + /* The instruction did all the work for us * already, just apply the offset to the correct * instruction location. */ - return (real_pc + (npc - pc)); + return (real_pc + (regs->tnpc - ainsn_addr)); } - return real_pc + 0x4UL; + /* It is jmpl or some other absolute PC modification instruction, + * leave NPC as-is. + */ + return regs->tnpc; } /* If INSN is an instruction which writes it's PC location @@ -220,12 +234,12 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, { unsigned long *slot = NULL; - /* Simplest cast is call, which always uses %o7 */ + /* Simplest case is 'call', which always uses %o7 */ if ((insn & 0xc0000000) == 0x40000000) { slot = ®s->u_regs[UREG_I7]; } - /* Jmpl encodes the register inside of the opcode */ + /* 'jmpl' encodes the register inside of the opcode */ if ((insn & 0xc1f80000) == 0x81c00000) { unsigned long rd = ((insn >> 25) & 0x1f); @@ -247,11 +261,11 @@ static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn, /* * Called after single-stepping. p->addr is the address of the - * instruction whose first byte has been replaced by the breakpoint + * instruction which has been replaced by the breakpoint * instruction. To avoid the SMP problems that can occur when we * temporarily put back the original opcode to single-step, we * single-stepped a copy of the instruction. The address of this - * copy is p->ainsn.insn. + * copy is &p->ainsn.insn[0]. * * This function prepares to return from the post-single-step * breakpoint trap. @@ -261,11 +275,11 @@ static void __kprobes resume_execution(struct kprobe *p, { u32 insn = p->ainsn.insn[0]; + regs->tnpc = relbranch_fixup(insn, p, regs); + + /* This assignment must occur after relbranch_fixup() */ regs->tpc = kcb->kprobe_orig_tnpc; - regs->tnpc = relbranch_fixup(insn, - (unsigned long) p->addr, - (unsigned long) &p->ainsn.insn[0], - regs->tnpc); + retpc_fixup(regs, insn, (unsigned long) p->addr); regs->tstate = ((regs->tstate & ~TSTATE_PIL) | @@ -430,17 +444,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) struct jprobe *jp = container_of(p, struct jprobe, kp); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - kcb->jprobe_saved_regs_location = regs; memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs)); - /* Save a whole stack frame, this gets arguments - * pushed onto the stack after using up all the - * arg registers. - */ - memcpy(&(kcb->jprobe_saved_stack), - (char *) (regs->u_regs[UREG_FP] + STACK_BIAS), - sizeof(kcb->jprobe_saved_stack)); - regs->tpc = (unsigned long) jp->entry; regs->tnpc = ((unsigned long) jp->entry) + 0x4UL; regs->tstate |= TSTATE_PIL; @@ -450,10 +455,19 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) void __kprobes jprobe_return(void) { - __asm__ __volatile__( - ".globl jprobe_return_trap_instruction\n" + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + register unsigned long orig_fp asm("g1"); + + orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP]; + __asm__ __volatile__("\n" +"1: cmp %%sp, %0\n\t" + "blu,a,pt %%xcc, 1b\n\t" + " restore\n\t" + ".globl jprobe_return_trap_instruction\n" "jprobe_return_trap_instruction:\n\t" - "ta 0x70"); + "ta 0x70" + : /* no outputs */ + : "r" (orig_fp)); } extern void jprobe_return_trap_instruction(void); @@ -466,26 +480,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); if (addr == (u32 *) jprobe_return_trap_instruction) { - if (kcb->jprobe_saved_regs_location != regs) { - printk("JPROBE: Current regs (%p) does not match " - "saved regs (%p).\n", - regs, kcb->jprobe_saved_regs_location); - printk("JPROBE: Saved registers\n"); - __show_regs(kcb->jprobe_saved_regs_location); - printk("JPROBE: Current registers\n"); - __show_regs(regs); - BUG(); - } - /* Restore old register state. Do pt_regs - * first so that UREG_FP is the original one for - * the stack frame restore. - */ memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs)); - - memcpy((char *) (regs->u_regs[UREG_FP] + STACK_BIAS), - &(kcb->jprobe_saved_stack), - sizeof(kcb->jprobe_saved_stack)); - preempt_enable_no_resched(); return 1; } -- cgit v1.2.3 From fd43fe19b830d6cd0eba08a6c6a5f71a6bd9c1b0 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Sun, 10 Dec 2006 02:18:47 -0800 Subject: [PATCH] xtensa: fix irq and misc fixes Update the architecture specific interrupt handling code for Xtensa to support the new API. Use generic BUG macros in bug.h, and some minor fixes. Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/kernel/irq.c | 107 +++++++++++++++++++-------------------- arch/xtensa/kernel/time.c | 8 +-- arch/xtensa/kernel/vmlinux.lds.S | 1 + 3 files changed, 57 insertions(+), 59 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index 1cf744ee095..c9ea73b7031 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c @@ -4,7 +4,7 @@ * Xtensa built-in interrupt controller and some generic functions copied * from i386. * - * Copyright (C) 2002 - 2005 Tensilica, Inc. + * Copyright (C) 2002 - 2006 Tensilica, Inc. * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar * * @@ -22,11 +22,6 @@ #include #include -static void enable_xtensa_irq(unsigned int irq); -static void disable_xtensa_irq(unsigned int irq); -static void mask_and_ack_xtensa(unsigned int irq); -static void end_xtensa_irq(unsigned int irq); - static unsigned int cached_irq_mask; atomic_t irq_err_count; @@ -46,8 +41,16 @@ void ack_bad_irq(unsigned int irq) * handlers). */ -unsigned int do_IRQ(int irq, struct pt_regs *regs) +asmlinkage void do_IRQ(int irq, struct pt_regs *regs) { + struct pt_regs *old_regs = set_irq_regs(regs); + struct irq_desc *desc = irq_desc + irq; + + if (irq >= NR_IRQS) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + } + irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW @@ -63,12 +66,10 @@ unsigned int do_IRQ(int irq, struct pt_regs *regs) sp - sizeof(struct thread_info)); } #endif - - __do_IRQ(irq, regs); + desc->handle_irq(irq, desc); irq_exit(); - - return 1; + set_irq_regs(old_regs); } /* @@ -118,72 +119,68 @@ skip: } return 0; } -/* shutdown is same as "disable" */ -#define shutdown_xtensa_irq disable_xtensa_irq -static unsigned int startup_xtensa_irq(unsigned int irq) -{ - enable_xtensa_irq(irq); - return 0; /* never anything pending */ -} - -static struct hw_interrupt_type xtensa_irq_type = { - "Xtensa-IRQ", - startup_xtensa_irq, - shutdown_xtensa_irq, - enable_xtensa_irq, - disable_xtensa_irq, - mask_and_ack_xtensa, - end_xtensa_irq -}; - -static inline void mask_irq(unsigned int irq) +static void xtensa_irq_mask(unsigned int irq) { cached_irq_mask &= ~(1 << irq); set_sr (cached_irq_mask, INTENABLE); } -static inline void unmask_irq(unsigned int irq) +static void xtensa_irq_unmask(unsigned int irq) { cached_irq_mask |= 1 << irq; set_sr (cached_irq_mask, INTENABLE); } -static void disable_xtensa_irq(unsigned int irq) +static void xtensa_irq_ack(unsigned int irq) { - unsigned long flags; - local_save_flags(flags); - mask_irq(irq); - local_irq_restore(flags); + set_sr(1 << irq, INTCLEAR); } -static void enable_xtensa_irq(unsigned int irq) +static int xtensa_irq_retrigger(unsigned int irq) { - unsigned long flags; - local_save_flags(flags); - unmask_irq(irq); - local_irq_restore(flags); -} - -static void mask_and_ack_xtensa(unsigned int irq) -{ - disable_xtensa_irq(irq); + set_sr (1 << irq, INTSET); + return 1; } -static void end_xtensa_irq(unsigned int irq) -{ - enable_xtensa_irq(irq); -} +static struct irq_chip xtensa_irq_chip = { + .name = "xtensa", + .mask = xtensa_irq_mask, + .unmask = xtensa_irq_unmask, + .ack = xtensa_irq_ack, + .retrigger = xtensa_irq_retrigger, +}; void __init init_IRQ(void) { - int i; + int index; - for (i=0; i < XTENSA_NR_IRQS; i++) - irq_desc[i].chip = &xtensa_irq_type; + for (index = 0; index < XTENSA_NR_IRQS; index++) { + int mask = 1 << index; - cached_irq_mask = 0; + if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_simple_irq); - platform_init_irq(); + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); + + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); + + else if (mask & XCHAL_INTTYPE_MASK_TIMER) + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); + + else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ + /* XCHAL_INTTYPE_MASK_NMI */ + + set_irq_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); + } + + cached_irq_mask = 0; } diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 37347e36998..a350431363a 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -47,7 +47,7 @@ unsigned long long sched_clock(void) return (unsigned long long)jiffies * (1000000000 / HZ); } -static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static irqreturn_t timer_interrupt(int irq, void *dev_id); static struct irqaction timer_irqaction = { .handler = timer_interrupt, .flags = IRQF_DISABLED, @@ -150,7 +150,7 @@ EXPORT_SYMBOL(do_gettimeofday); * The timer interrupt is called HZ times per second. */ -irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long next; @@ -160,9 +160,9 @@ irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) again: while ((signed long)(get_ccount() - next) > 0) { - profile_tick(CPU_PROFILING, regs); + profile_tick(CPU_PROFILING); #ifndef CONFIG_SMP - update_process_times(user_mode(regs)); + update_process_times(user_mode(get_irq_regs())); #endif write_seqlock(&xtime_lock); diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index cfe75f52872..e01131fec69 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -17,6 +17,7 @@ #include #define _NOCLANGUAGE +#undef __ASSEMBLER__ #include #include OUTPUT_ARCH(xtensa) -- cgit v1.2.3 From 173d6681380aa1d60dfc35ed7178bd7811ba2784 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Sun, 10 Dec 2006 02:18:48 -0800 Subject: [PATCH] xtensa: remove extra header files The Xtensa port contained many header files that were never needed. This rather lengthy patch removes all those files. Unfortunately, there were many dependencies that needed to be updated, so this patch touches quite a few source files. Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/Kconfig | 21 +- arch/xtensa/Makefile | 25 +- arch/xtensa/boot/boot-elf/bootstrap.S | 3 - arch/xtensa/boot/boot-redboot/bootstrap.S | 37 ++- arch/xtensa/configs/iss_defconfig | 6 +- arch/xtensa/kernel/align.S | 42 ++- arch/xtensa/kernel/coprocessor.S | 2 +- arch/xtensa/kernel/entry.S | 28 +- arch/xtensa/kernel/head.S | 53 ++-- arch/xtensa/kernel/pci-dma.c | 44 ++- arch/xtensa/kernel/process.c | 37 +-- arch/xtensa/kernel/ptrace.c | 2 +- arch/xtensa/kernel/setup.c | 41 +-- arch/xtensa/kernel/signal.c | 16 +- arch/xtensa/kernel/syscalls.c | 4 +- arch/xtensa/kernel/traps.c | 56 ++-- arch/xtensa/kernel/vectors.S | 12 +- arch/xtensa/kernel/vmlinux.lds.S | 27 +- arch/xtensa/lib/checksum.S | 3 +- arch/xtensa/lib/memcopy.S | 2 +- arch/xtensa/lib/memset.S | 2 +- arch/xtensa/lib/strncpy_user.S | 2 +- arch/xtensa/lib/strnlen_user.S | 2 +- arch/xtensa/lib/usercopy.S | 2 +- arch/xtensa/mm/fault.c | 10 +- arch/xtensa/mm/init.c | 6 +- arch/xtensa/mm/misc.S | 265 ++++-------------- arch/xtensa/mm/tlb.c | 445 ++---------------------------- arch/xtensa/platform-iss/console.c | 8 +- arch/xtensa/platform-iss/network.c | 2 +- 30 files changed, 290 insertions(+), 915 deletions(-) (limited to 'arch') diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 9eccfbd1b53..2e74cb0b780 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -48,25 +48,10 @@ menu "Processor type and features" choice prompt "Xtensa Processor Configuration" - default XTENSA_CPU_LINUX_BE + default XTENSA_VARIANT_FSF -config XTENSA_CPU_LINUX_BE - bool "linux_be" - ---help--- - The linux_be processor configuration is the baseline Xtensa - configurations included in this kernel and also used by - binutils, gcc, and gdb. It contains no TIE, no coprocessors, - and the following configuration options: - - Code Density Option 2 Misc Special Registers - NSA/NSAU Instructions 128-bit Data Bus Width - Processor ID 8K, 2-way I and D Caches - Zero-Overhead Loops 2 Inst Address Break Registers - Big Endian 2 Data Address Break Registers - 64 General-Purpose Registers JTAG Interface and Trace Port - 17 Interrupts MMU w/ TLBs and Autorefill - 3 Interrupt Levels 8 Autorefill Ways (I/D TLBs) - 3 Timers Unaligned Exceptions +config XTENSA_VARIANT_FSF + bool "fsf" endchoice config MMU diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 3a3a4c66ef8..95f836db38f 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -11,13 +11,13 @@ # this architecture # Core configuration. -# (Use CPU= to use another default compiler.) +# (Use VAR= to use another default compiler.) -cpu-$(CONFIG_XTENSA_CPU_LINUX_BE) := linux_be -cpu-$(CONFIG_XTENSA_CPU_LINUX_CUSTOM) := linux_custom +variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf +variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom -CPU = $(cpu-y) -export CPU +VARIANT = $(variant-y) +export VARIANT # Platform configuration @@ -27,8 +27,6 @@ platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss PLATFORM = $(platform-y) export PLATFORM -CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/) -CPPFLAGS += -Iinclude/asm CFLAGS += -pipe -mlongcalls KBUILD_DEFCONFIG := iss_defconfig @@ -41,12 +39,12 @@ core-$(CONFIG_EMBEDDED_RAMDISK) += arch/xtensa/boot/ramdisk/ # Test for cross compiling -ifneq ($(CPU),) +ifneq ($(VARIANT),) COMPILE_ARCH = $(shell uname -m) ifneq ($(COMPILE_ARCH), xtensa) ifndef CROSS_COMPILE - CROSS_COMPILE = xtensa_$(CPU)- + CROSS_COMPILE = xtensa_$(VARIANT)- endif endif endif @@ -68,14 +66,13 @@ archinc := include/asm-xtensa archprepare: $(archinc)/.platform -# Update machine cpu and platform symlinks if something which affects +# Update processor variant and platform symlinks if something which affects # them changed. $(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' + @echo ' SYMLINK $(archinc)/variant -> $(archinc)/variant-$(VARIANT)' $(Q)mkdir -p $(archinc) - $(Q)mkdir -p $(archinc)/xtensa - $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config + $(Q)ln -fsn $(srctree)/$(archinc)/variant-$(VARIANT) $(archinc)/variant @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)' $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform @touch $@ @@ -89,7 +86,7 @@ zImage zImage.initrd: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ CLEAN_FILES += arch/xtensa/vmlinux.lds \ - $(archinc)/platform $(archinc)/xtensa/config \ + $(archinc)/platform $(archinc)/variant \ $(archinc)/.platform define archhelp diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S index f857fc760aa..464298bc348 100644 --- a/arch/xtensa/boot/boot-elf/bootstrap.S +++ b/arch/xtensa/boot/boot-elf/bootstrap.S @@ -1,7 +1,4 @@ -#include -#include - #include diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S index ee636b0da81..84848123e2a 100644 --- a/arch/xtensa/boot/boot-redboot/bootstrap.S +++ b/arch/xtensa/boot/boot-redboot/bootstrap.S @@ -1,9 +1,7 @@ - -#define _ASMLANGUAGE -#include -#include -#include - +#include +#include +#include +#include /* * RB-Data: RedBoot data/bss * P: Boot-Parameters @@ -77,8 +75,14 @@ _start: /* Note: The assembler cannot relax "addi a0, a0, ..." to an l32r, so we load to a4 first. */ - addi a4, a0, __start - __start_a0 - mov a0, a4 + # addi a4, a0, __start - __start_a0 + # mov a0, a4 + + movi a4, __start + movi a5, __start_a0 + add a4, a0, a4 + sub a0, a4, a5 + movi a4, __start movi a5, __reloc_end @@ -106,9 +110,13 @@ _start: /* We have to flush and invalidate the caches here before we jump. */ #if XCHAL_DCACHE_IS_WRITEBACK - dcache_writeback_all a5, a6 + + ___flush_dcache_all a5 a6 + #endif - icache_invalidate_all a5, a6 + + ___invalidate_icache_all a5 a6 + isync movi a11, _reloc jx a11 @@ -209,9 +217,14 @@ _reloc: /* jump to the kernel */ 2: #if XCHAL_DCACHE_IS_WRITEBACK - dcache_writeback_all a5, a6 + + ___flush_dcache_all a5 a6 + #endif - icache_invalidate_all a5, a6 + + ___invalidate_icache_all a5 a6 + + isync movi a5, __start movi a3, boot_initrd_start diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index 802621dd486..f19854035e6 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig @@ -53,11 +53,7 @@ CONFIG_CC_ALIGN_JUMPS=0 # # Processor type and features # -CONFIG_XTENSA_ARCH_LINUX_BE=y -# CONFIG_XTENSA_ARCH_LINUX_LE is not set -# CONFIG_XTENSA_ARCH_LINUX_TEST is not set -# CONFIG_XTENSA_ARCH_S5 is not set -# CONFIG_XTENSA_CUSTOM is not set +CONFIG_XTENSA_VARIANT_FSF=y CONFIG_MMU=y # CONFIG_XTENSA_UNALIGNED_USER is not set # CONFIG_PREEMPT is not set diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index a4956578a24..33d6e9d2e83 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -16,14 +16,9 @@ */ #include -#include -#include #include #include -#include #include -#include -#include #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION @@ -216,7 +211,7 @@ ENTRY(fast_unaligned) extui a5, a4, INSN_OP0, 4 # get insn.op0 nibble -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY _beqi a5, OP0_L32I_N, .Lload # L32I.N, jump addi a6, a5, -OP0_S32I_N _beqz a6, .Lstore # S32I.N, do a store @@ -251,7 +246,7 @@ ENTRY(fast_unaligned) #endif __src_b a3, a5, a6 # a3 has the data word -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY addi a7, a7, 2 # increment PC (assume 16-bit insn) extui a5, a4, INSN_OP0, 4 @@ -279,14 +274,14 @@ ENTRY(fast_unaligned) 1: -#if XCHAL_HAVE_LOOP - rsr a3, LEND # check if we reached LEND - bne a7, a3, 1f - rsr a3, LCOUNT # and LCOUNT != 0 - beqz a3, 1f - addi a3, a3, -1 # decrement LCOUNT and set +#if XCHAL_HAVE_LOOPS + rsr a5, LEND # check if we reached LEND + bne a7, a5, 1f + rsr a5, LCOUNT # and LCOUNT != 0 + beqz a5, 1f + addi a5, a5, -1 # decrement LCOUNT and set rsr a7, LBEG # set PC to LBEGIN - wsr a3, LCOUNT + wsr a5, LCOUNT #endif 1: wsr a7, EPC_1 # skip load instruction @@ -336,7 +331,7 @@ ENTRY(fast_unaligned) movi a6, 0 # mask: ffffffff:00000000 -#if XCHAL_HAVE_NARROW +#if XCHAL_HAVE_DENSITY addi a7, a7, 2 # incr. PC,assume 16-bit instruction extui a5, a4, INSN_OP0, 4 # extract OP0 @@ -359,14 +354,14 @@ ENTRY(fast_unaligned) /* Get memory address */ 1: -#if XCHAL_HAVE_LOOP - rsr a3, LEND # check if we reached LEND - bne a7, a3, 1f - rsr a3, LCOUNT # and LCOUNT != 0 - beqz a3, 1f - addi a3, a3, -1 # decrement LCOUNT and set +#if XCHAL_HAVE_LOOPS + rsr a4, LEND # check if we reached LEND + bne a7, a4, 1f + rsr a4, LCOUNT # and LCOUNT != 0 + beqz a4, 1f + addi a4, a4, -1 # decrement LCOUNT and set rsr a7, LBEG # set PC to LBEGIN - wsr a3, LCOUNT + wsr a4, LCOUNT #endif 1: wsr a7, EPC_1 # skip store instruction @@ -416,6 +411,7 @@ ENTRY(fast_unaligned) /* Restore working register */ + l32i a8, a2, PT_AREG8 l32i a7, a2, PT_AREG7 l32i a6, a2, PT_AREG6 l32i a5, a2, PT_AREG5 @@ -446,7 +442,7 @@ ENTRY(fast_unaligned) mov a1, a2 rsr a0, PS - bbsi.l a2, PS_UM_SHIFT, 1f # jump if user mode + bbsi.l a2, PS_UM_BIT, 1f # jump if user mode movi a0, _kernel_exception jx a0 diff --git a/arch/xtensa/kernel/coprocessor.S b/arch/xtensa/kernel/coprocessor.S index cf5a93fb6a2..01bcb9fcfcb 100644 --- a/arch/xtensa/kernel/coprocessor.S +++ b/arch/xtensa/kernel/coprocessor.S @@ -90,7 +90,6 @@ ENTRY(enable_coprocessor) rsync retw -#endif ENTRY(save_coprocessor_extra) entry sp, 16 @@ -197,4 +196,5 @@ _xtensa_reginfo_tables: XCHAL_CP7_SA_CONTENTS_LIBDB .word 0xFC000000 /* invalid register number,marks end of table*/ _xtensa_reginfo_table_end: +#endif diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 89e409e9e0d..c0b56b17927 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -24,7 +24,7 @@ #include #include #include -#include +#include /* Unimplemented features. */ @@ -364,7 +364,7 @@ common_exception: movi a2, 1 extui a3, a3, 0, 1 # a3 = PS.INTLEVEL[0] moveqz a3, a2, a0 # a3 = 1 iff interrupt exception - movi a2, PS_WOE_MASK + movi a2, 1 << PS_WOE_BIT or a3, a3, a2 rsr a0, EXCCAUSE xsr a3, PS @@ -399,7 +399,7 @@ common_exception_return: /* Jump if we are returning from kernel exceptions. */ 1: l32i a3, a1, PT_PS - _bbsi.l a3, PS_UM_SHIFT, 2f + _bbsi.l a3, PS_UM_BIT, 2f j kernel_exception_exit /* Specific to a user exception exit: @@ -422,7 +422,7 @@ common_exception_return: * (Hint: There is only one user exception frame on stack) */ - movi a3, PS_WOE_MASK + movi a3, 1 << PS_WOE_BIT _bbsi.l a4, TIF_NEED_RESCHED, 3f _bbci.l a4, TIF_SIGPENDING, 4f @@ -694,7 +694,7 @@ common_exception_exit: ENTRY(debug_exception) rsr a0, EPS + XCHAL_DEBUGLEVEL - bbsi.l a0, PS_EXCM_SHIFT, 1f # exception mode + bbsi.l a0, PS_EXCM_BIT, 1f # exception mode /* Set EPC_1 and EXCCAUSE */ @@ -707,7 +707,7 @@ ENTRY(debug_exception) /* Restore PS to the value before the debug exc but with PS.EXCM set.*/ - movi a2, 1 << PS_EXCM_SHIFT + movi a2, 1 << PS_EXCM_BIT or a2, a0, a2 movi a0, debug_exception # restore a3, debug jump vector wsr a2, PS @@ -715,7 +715,7 @@ ENTRY(debug_exception) /* Switch to kernel/user stack, restore jump vector, and save a0 */ - bbsi.l a2, PS_UM_SHIFT, 2f # jump if user mode + bbsi.l a2, PS_UM_BIT, 2f # jump if user mode addi a2, a1, -16-PT_SIZE # assume kernel stack s32i a0, a2, PT_AREG0 @@ -778,7 +778,7 @@ ENTRY(unrecoverable_exception) wsr a1, WINDOWBASE rsync - movi a1, PS_WOE_MASK | 1 + movi a1, (1 << PS_WOE_BIT) | 1 wsr a1, PS rsync @@ -1491,7 +1491,7 @@ ENTRY(_spill_registers) */ rsr a0, PS - _bbci.l a0, PS_UM_SHIFT, 1f + _bbci.l a0, PS_UM_BIT, 1f /* User space: Setup a dummy frame and kill application. * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. @@ -1510,7 +1510,7 @@ ENTRY(_spill_registers) l32i a1, a3, EXC_TABLE_KSTK wsr a3, EXCSAVE_1 - movi a4, PS_WOE_MASK | 1 + movi a4, (1 << PS_WOE_BIT) | 1 wsr a4, PS rsync @@ -1612,7 +1612,7 @@ ENTRY(fast_second_level_miss) rsr a1, PTEVADDR srli a1, a1, PAGE_SHIFT slli a1, a1, PAGE_SHIFT # ptevaddr & PAGE_MASK - addi a1, a1, DTLB_WAY_PGTABLE # ... + way_number + addi a1, a1, DTLB_WAY_PGD # ... + way_number wdtlb a0, a1 dsync @@ -1654,7 +1654,7 @@ ENTRY(fast_second_level_miss) mov a1, a2 rsr a2, PS - bbsi.l a2, PS_UM_SHIFT, 1f + bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception @@ -1753,7 +1753,7 @@ ENTRY(fast_store_prohibited) mov a1, a2 rsr a2, PS - bbsi.l a2, PS_UM_SHIFT, 1f + bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception @@ -1924,7 +1924,7 @@ ENTRY(_switch_to) /* Disable ints while we manipulate the stack pointer; spill regs. */ - movi a5, PS_EXCM_MASK | LOCKLEVEL + movi a5, (1 << PS_EXCM_BIT) | LOCKLEVEL xsr a5, PS rsr a3, EXCSAVE_1 rsync diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index c07cb252299..ea89910efa4 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -15,9 +15,9 @@ * Kevin Chea */ -#include #include #include +#include /* * This module contains the entry code for kernel images. It performs the @@ -32,13 +32,6 @@ * */ - .macro iterate from, to , cmd - .ifeq ((\to - \from) & ~0xfff) - \cmd \from - iterate "(\from+1)", \to, \cmd - .endif - .endm - /* * _start * @@ -64,7 +57,7 @@ _startup: /* Disable interrupts and exceptions. */ - movi a0, XCHAL_PS_EXCM_MASK + movi a0, LOCKLEVEL wsr a0, PS /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */ @@ -91,11 +84,11 @@ _startup: movi a1, 15 wsr a0, ICOUNTLEVEL - .macro reset_dbreak num - wsr a0, DBREAKC + \num - .endm - - iterate 0, XCHAL_NUM_IBREAK-1, reset_dbreak + .set _index, 0 + .rept XCHAL_NUM_DBREAK - 1 + wsr a0, DBREAKC + _index + .set _index, _index + 1 + .endr #endif /* Clear CCOUNT (not really necessary, but nice) */ @@ -110,10 +103,11 @@ _startup: /* Disable all timers. */ - .macro reset_timer num - wsr a0, CCOMPARE_0 + \num - .endm - iterate 0, XCHAL_NUM_TIMERS-1, reset_timer + .set _index, 0 + .rept XCHAL_NUM_TIMERS - 1 + wsr a0, CCOMPARE + _index + .set _index, _index + 1 + .endr /* Interrupt initialization. */ @@ -139,12 +133,21 @@ _startup: rsync /* Initialize the caches. - * Does not include flushing writeback d-cache. - * a6, a7 are just working registers (clobbered). + * a2, a3 are just working registers (clobbered). */ - icache_reset a2, a3 - dcache_reset a2, a3 +#if XCHAL_DCACHE_LINE_LOCKABLE + ___unlock_dcache_all a2 a3 +#endif + +#if XCHAL_ICACHE_LINE_LOCKABLE + ___unlock_icache_all a2 a3 +#endif + + ___invalidate_dcache_all a2 a3 + ___invalidate_icache_all a2 a3 + + isync /* Unpack data sections * @@ -181,9 +184,9 @@ _startup: movi a2, _bss_start # start of BSS movi a3, _bss_end # end of BSS -1: addi a2, a2, 4 + __loopt a2, a3, a4, 2 s32i a0, a2, 0 - blt a2, a3, 1b + __endla a2, a4, 4 #if XCHAL_DCACHE_IS_WRITEBACK @@ -191,7 +194,7 @@ _startup: * instructions/data are available. */ - dcache_writeback_all a2, a3 + ___flush_dcache_all a2 a3 #endif /* Setup stack and enable window exceptions (keep irqs disabled) */ diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 6648fa9d919..ca76f071666 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -1,5 +1,5 @@ /* - * arch/xtensa/kernel/pci-dma.c + * arch/xtensa/pci-dma.c * * DMA coherent memory allocation. * @@ -29,28 +29,48 @@ */ void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) +dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag) { - void *ret; + unsigned long ret; + unsigned long uncached = 0; /* ignore region speicifiers */ - gfp &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (dev == NULL || (*dev->dma_mask < 0xffffffff)) - gfp |= GFP_DMA; - ret = (void *)__get_free_pages(gfp, get_order(size)); + flag &= ~(__GFP_DMA | __GFP_HIGHMEM); - if (ret != NULL) { - memset(ret, 0, size); - *handle = virt_to_bus(ret); + if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff)) + flag |= GFP_DMA; + ret = (unsigned long)__get_free_pages(flag, get_order(size)); + + if (ret == 0) + return NULL; + + /* We currently don't support coherent memory outside KSEG */ + + if (ret < XCHAL_KSEG_CACHED_VADDR + || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) + BUG(); + + + if (ret != 0) { + memset((void*) ret, 0, size); + uncached = ret+XCHAL_KSEG_BYPASS_VADDR-XCHAL_KSEG_CACHED_VADDR; + *handle = virt_to_bus((void*)ret); + __flush_invalidate_dcache_range(ret, size); } - return (void*) BYPASS_ADDR((unsigned long)ret); + + return (void*)uncached; } void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { - free_pages(CACHED_ADDR((unsigned long)vaddr), get_order(size)); + long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; + + if (addr < 0 || addr >= XCHAL_KSEG_SIZE) + BUG(); + + free_pages(addr, get_order(size)); } diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index a7c4178c2a8..3785f3481d7 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -1,4 +1,3 @@ -// TODO verify coprocessor handling /* * arch/xtensa/kernel/process.c * @@ -43,7 +42,7 @@ #include #include #include -#include +#include extern void ret_from_fork(void); @@ -67,25 +66,6 @@ void (*pm_power_off)(void) = NULL; EXPORT_SYMBOL(pm_power_off); -#if XCHAL_CP_NUM > 0 - -/* - * Coprocessor ownership. - */ - -coprocessor_info_t coprocessor_info[] = { - { 0, XTENSA_CPE_CP0_OFFSET }, - { 0, XTENSA_CPE_CP1_OFFSET }, - { 0, XTENSA_CPE_CP2_OFFSET }, - { 0, XTENSA_CPE_CP3_OFFSET }, - { 0, XTENSA_CPE_CP4_OFFSET }, - { 0, XTENSA_CPE_CP5_OFFSET }, - { 0, XTENSA_CPE_CP6_OFFSET }, - { 0, XTENSA_CPE_CP7_OFFSET }, -}; - -#endif - /* * Powermanagement idle function, if any is provided by the platform. */ @@ -110,12 +90,10 @@ void cpu_idle(void) void exit_thread(void) { - release_coprocessors(current); /* Empty macro if no CPs are defined */ } void flush_thread(void) { - release_coprocessors(current); /* Empty macro if no CPs are defined */ } /* @@ -275,7 +253,7 @@ void do_copy_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, */ elfregs->pc = regs->pc; - elfregs->ps = (regs->ps & ~XCHAL_PS_EXCM_MASK); + elfregs->ps = (regs->ps & ~(1 << PS_EXCM_BIT)); elfregs->exccause = regs->exccause; elfregs->excvaddr = regs->excvaddr; elfregs->windowbase = regs->windowbase; @@ -325,7 +303,7 @@ void do_restore_regs (xtensa_gregset_t *elfregs, struct pt_regs *regs, */ regs->pc = elfregs->pc; - regs->ps = (elfregs->ps | XCHAL_PS_EXCM_MASK); + regs->ps = (elfregs->ps | (1 << PS_EXCM_BIT)); regs->exccause = elfregs->exccause; regs->excvaddr = elfregs->excvaddr; regs->windowbase = elfregs->windowbase; @@ -459,16 +437,7 @@ int do_restore_fpregs (elf_fpregset_t *fpregs, struct pt_regs *regs, int dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r) { -/* see asm/coprocessor.h for this magic number 16 */ -#if XTENSA_CP_EXTRA_SIZE > 16 - do_save_fpregs (r, regs, task); - - /* For now, bit 16 means some extra state may be present: */ -// FIXME!! need to track to return more accurate mask - return 0x10000 | XCHAL_CP_MASK; -#else return 0; /* no coprocessors active on this processor */ -#endif } /* diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9aea23cc0dc..604c3c3c675 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -96,7 +96,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* Note: PS.EXCM is not set while user task is running; * its being set in regs is for exception handling * convenience. */ - tmp = (regs->ps & ~XCHAL_PS_EXCM_MASK); + tmp = (regs->ps & ~(1 << PS_EXCM_BIT)); break; case REG_WB: tmp = regs->windowbase; diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index c99ab72b41b..b6374c09de2 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -42,8 +42,6 @@ #include #include -#include - #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; #endif @@ -336,7 +334,7 @@ c_show(struct seq_file *f, void *slot) /* high-level stuff */ seq_printf(f,"processor\t: 0\n" "vendor_id\t: Tensilica\n" - "model\t\t: Xtensa " XCHAL_HW_RELEASE_NAME "\n" + "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n" "core ID\t\t: " XCHAL_CORE_ID "\n" "build ID\t: 0x%x\n" "byte order\t: %s\n" @@ -420,25 +418,6 @@ c_show(struct seq_file *f, void *slot) XCHAL_NUM_TIMERS, XCHAL_DEBUGLEVEL); - /* Coprocessors */ -#if XCHAL_HAVE_CP - seq_printf(f, "coprocessors\t: %d\n", XCHAL_CP_NUM); -#else - seq_printf(f, "coprocessors\t: none\n"); -#endif - - /* {I,D}{RAM,ROM} and XLMI */ - seq_printf(f,"inst ROMs\t: %d\n" - "inst RAMs\t: %d\n" - "data ROMs\t: %d\n" - "data RAMs\t: %d\n" - "XLMI ports\t: %d\n", - XCHAL_NUM_IROM, - XCHAL_NUM_IRAM, - XCHAL_NUM_DROM, - XCHAL_NUM_DRAM, - XCHAL_NUM_XLMI); - /* Cache */ seq_printf(f,"icache line size: %d\n" "icache ways\t: %d\n" @@ -466,24 +445,6 @@ c_show(struct seq_file *f, void *slot) XCHAL_DCACHE_WAYS, XCHAL_DCACHE_SIZE); - /* MMU */ - seq_printf(f,"ASID bits\t: %d\n" - "ASID invalid\t: %d\n" - "ASID kernel\t: %d\n" - "rings\t\t: %d\n" - "itlb ways\t: %d\n" - "itlb AR ways\t: %d\n" - "dtlb ways\t: %d\n" - "dtlb AR ways\t: %d\n", - XCHAL_MMU_ASID_BITS, - XCHAL_MMU_ASID_INVALID, - XCHAL_MMU_ASID_KERNEL, - XCHAL_MMU_RINGS, - XCHAL_ITLB_WAYS, - XCHAL_ITLB_ARF_WAYS, - XCHAL_DTLB_WAYS, - XCHAL_DTLB_ARF_WAYS); - return 0; } diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index c494f0826fc..6af7f414599 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -12,8 +12,8 @@ * */ -#include -#include +#include +#include #include #include #include @@ -216,8 +216,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) * handler, or the user mode value doesn't matter (e.g. PS.OWB). */ err |= __get_user(ps, &sc->sc_ps); - regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK) - | (ps & XCHAL_PS_CALLINC_MASK); + regs->ps = (regs->ps & ~PS_CALLINC_MASK) + | (ps & PS_CALLINC_MASK); /* Additional corruption checks */ @@ -280,7 +280,7 @@ flush_my_cpstate(struct task_struct *tsk) static int save_cpextra (struct _cpstate *buf) { -#if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0) +#if XCHAL_CP_NUM == 0 return 0; #else @@ -497,8 +497,10 @@ gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) /* Flush generated code out of the data cache */ - if (err == 0) - __flush_invalidate_cache_range((unsigned long)codemem, 6UL); + if (err == 0) { + __invalidate_icache_range((unsigned long)codemem, 6UL); + __flush_invalidate_dcache_range((unsigned long)codemem, 6UL); + } return err; } diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c index f49cb239e60..f9a5a752ca6 100644 --- a/arch/xtensa/kernel/syscalls.c +++ b/arch/xtensa/kernel/syscalls.c @@ -175,8 +175,8 @@ void system_call (struct pt_regs *regs) * interrupts in the first place: */ local_save_flags (ps); - local_irq_restore((ps & ~XCHAL_PS_INTLEVEL_MASK) | - (regs->ps & XCHAL_PS_INTLEVEL_MASK) ); + local_irq_restore((ps & ~PS_INTLEVEL_MASK) | + (regs->ps & PS_INTLEVEL_MASK) ); if (syscallnr > __NR_Linux_syscalls) { regs->areg[2] = -ENOSYS; diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index ce077d6bf3a..693ab268485 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -75,7 +75,7 @@ extern void system_call (struct pt_regs*); #define USER 0x02 #define COPROCESSOR(x) \ -{ XCHAL_EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor } +{ EXCCAUSE_COPROCESSOR ## x ## _DISABLED, USER, fast_coprocessor } typedef struct { int cause; @@ -85,38 +85,38 @@ typedef struct { dispatch_init_table_t __init dispatch_init_table[] = { -{ XCHAL_EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction}, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel }, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user }, -{ XCHAL_EXCCAUSE_SYSTEM_CALL, 0, system_call }, -/* XCHAL_EXCCAUSE_INSTRUCTION_FETCH unhandled */ -/* XCHAL_EXCCAUSE_LOAD_STORE_ERROR unhandled*/ -{ XCHAL_EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, -{ XCHAL_EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, -/* XCHAL_EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ -/* XCHAL_EXCCAUSE_PRIVILEGED unhandled */ +{ EXCCAUSE_ILLEGAL_INSTRUCTION, 0, do_illegal_instruction}, +{ EXCCAUSE_SYSTEM_CALL, KRNL, fast_syscall_kernel }, +{ EXCCAUSE_SYSTEM_CALL, USER, fast_syscall_user }, +{ EXCCAUSE_SYSTEM_CALL, 0, system_call }, +/* EXCCAUSE_INSTRUCTION_FETCH unhandled */ +/* EXCCAUSE_LOAD_STORE_ERROR unhandled*/ +{ EXCCAUSE_LEVEL1_INTERRUPT, 0, do_interrupt }, +{ EXCCAUSE_ALLOCA, USER|KRNL, fast_alloca }, +/* EXCCAUSE_INTEGER_DIVIDE_BY_ZERO unhandled */ +/* EXCCAUSE_PRIVILEGED unhandled */ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION #ifdef CONFIG_UNALIGNED_USER -{ XCHAL_EXCCAUSE_UNALIGNED, USER, fast_unaligned }, +{ EXCCAUSE_UNALIGNED, USER, fast_unaligned }, #else -{ XCHAL_EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, +{ EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, #endif -{ XCHAL_EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, +{ EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, #endif -{ XCHAL_EXCCAUSE_ITLB_MISS, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, -{ XCHAL_EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit }, -{ XCHAL_EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault }, -/* XCHAL_EXCCAUSE_SIZE_RESTRICTION unhandled */ -{ XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss}, -{ XCHAL_EXCCAUSE_DTLB_MISS, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit }, -{ XCHAL_EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault }, -/* XCHAL_EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */ -{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited }, -{ XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, -{ XCHAL_EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_ITLB_MISS, 0, do_page_fault }, +{ EXCCAUSE_ITLB_MISS, USER|KRNL, fast_second_level_miss}, +{ EXCCAUSE_ITLB_MULTIHIT, 0, do_multihit }, +{ EXCCAUSE_ITLB_PRIVILEGE, 0, do_page_fault }, +/* EXCCAUSE_SIZE_RESTRICTION unhandled */ +{ EXCCAUSE_FETCH_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_DTLB_MISS, USER|KRNL, fast_second_level_miss}, +{ EXCCAUSE_DTLB_MISS, 0, do_page_fault }, +{ EXCCAUSE_DTLB_MULTIHIT, 0, do_multihit }, +{ EXCCAUSE_DTLB_PRIVILEGE, 0, do_page_fault }, +/* EXCCAUSE_DTLB_SIZE_RESTRICTION unhandled */ +{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, USER|KRNL, fast_store_prohibited }, +{ EXCCAUSE_STORE_CACHE_ATTRIBUTE, 0, do_page_fault }, +{ EXCCAUSE_LOAD_CACHE_ATTRIBUTE, 0, do_page_fault }, /* XCCHAL_EXCCAUSE_FLOATING_POINT unhandled */ #if (XCHAL_CP_MASK & 1) COPROCESSOR(0), diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 0e74397bfa2..eb2d7bb69ee 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -53,6 +53,8 @@ #include #include +#define WINDOW_VECTORS_SIZE 0x180 + /* * User exception vector. (Exceptions with PS.UM == 1, PS.EXCM == 0) @@ -210,7 +212,7 @@ ENTRY(_DoubleExceptionVector) /* Check for kernel double exception (usually fatal). */ rsr a3, PS - _bbci.l a3, PS_UM_SHIFT, .Lksp + _bbci.l a3, PS_UM_BIT, .Lksp /* Check if we are currently handling a window exception. */ /* Note: We don't need to indicate that we enter a critical section. */ @@ -219,7 +221,7 @@ ENTRY(_DoubleExceptionVector) movi a3, XCHAL_WINDOW_VECTORS_VADDR _bltu a0, a3, .Lfixup - addi a3, a3, XSHAL_WINDOW_VECTORS_SIZE + addi a3, a3, WINDOW_VECTORS_SIZE _bgeu a0, a3, .Lfixup /* Window overflow/underflow exception. Get stack pointer. */ @@ -245,7 +247,7 @@ ENTRY(_DoubleExceptionVector) wsr a2, DEPC # save stack pointer temporarily rsr a0, PS - extui a0, a0, XCHAL_PS_OWB_SHIFT, XCHAL_PS_OWB_BITS + extui a0, a0, PS_OWB_SHIFT, 4 wsr a0, WINDOWBASE rsync @@ -312,8 +314,8 @@ ENTRY(_DoubleExceptionVector) .Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */ rsr a3, EXCCAUSE - beqi a3, XCHAL_EXCCAUSE_ITLB_MISS, 1f - addi a3, a3, -XCHAL_EXCCAUSE_DTLB_MISS + beqi a3, EXCCAUSE_ITLB_MISS, 1f + addi a3, a3, -EXCCAUSE_DTLB_MISS bnez a3, .Lunrecoverable 1: movi a3, fast_second_level_miss_double_kernel jx a3 diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index e01131fec69..a36c104c3a5 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -16,20 +16,17 @@ #include -#define _NOCLANGUAGE -#undef __ASSEMBLER__ -#include -#include +#include OUTPUT_ARCH(xtensa) ENTRY(_start) -#if XCHAL_MEMORY_ORDER == XTHAL_BIGENDIAN +#ifdef __XTENSA_EB__ jiffies = jiffies_64 + 4; #else jiffies = jiffies_64; #endif -#define KERNELOFFSET 0x1000 +#define KERNELOFFSET 0xd0001000 /* Note: In the following macros, it would be nice to specify only the vector name and section kind and construct "sym" and "section" using @@ -76,7 +73,7 @@ jiffies = jiffies_64; SECTIONS { - . = XCHAL_KSEG_CACHED_VADDR + KERNELOFFSET; + . = KERNELOFFSET; /* .text section */ _text = .; @@ -160,7 +157,7 @@ SECTIONS /* Initialization code and data: */ - . = ALIGN(1< #include -#define _ASMLANGUAGE -#include +#include /* * computes a partial checksum, e.g. for TCP/UDP fragments diff --git a/arch/xtensa/lib/memcopy.S b/arch/xtensa/lib/memcopy.S index e8f6d7eb722..ddda8f4bc86 100644 --- a/arch/xtensa/lib/memcopy.S +++ b/arch/xtensa/lib/memcopy.S @@ -9,7 +9,7 @@ * Copyright (C) 2002 - 2005 Tensilica Inc. */ -#include +#include .macro src_b r, w0, w1 #ifdef __XTENSA_EB__ diff --git a/arch/xtensa/lib/memset.S b/arch/xtensa/lib/memset.S index 4de25134bc6..56a17495b2d 100644 --- a/arch/xtensa/lib/memset.S +++ b/arch/xtensa/lib/memset.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include +#include /* * void *memset(void *dst, int c, size_t length) diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index 71d55df4389..a834057bda6 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include +#include #include /* Load or store instructions that may cause exceptions use the EX macro. */ diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index cdff4d670f3..5e9c1e709b2 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S @@ -11,7 +11,7 @@ * Copyright (C) 2002 Tensilica Inc. */ -#include +#include /* Load or store instructions that may cause exceptions use the EX macro. */ diff --git a/arch/xtensa/lib/usercopy.S b/arch/xtensa/lib/usercopy.S index 4641ef510f0..a8ab1d4fe0a 100644 --- a/arch/xtensa/lib/usercopy.S +++ b/arch/xtensa/lib/usercopy.S @@ -53,7 +53,7 @@ * a11/ original length */ -#include +#include #ifdef __XTENSA_EB__ #define ALIGN(R, W0, W1) src R, W0, W1 diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c index dd0dbec2e57..3dc6f2f07bb 100644 --- a/arch/xtensa/mm/fault.c +++ b/arch/xtensa/mm/fault.c @@ -21,7 +21,7 @@ #include #include -unsigned long asid_cache = ASID_FIRST_VERSION; +unsigned long asid_cache = ASID_USER_FIRST; void bad_page_fault(struct pt_regs*, unsigned long, int); /* @@ -58,10 +58,10 @@ void do_page_fault(struct pt_regs *regs) return; } - is_write = (exccause == XCHAL_EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0; - is_exec = (exccause == XCHAL_EXCCAUSE_ITLB_PRIVILEGE || - exccause == XCHAL_EXCCAUSE_ITLB_MISS || - exccause == XCHAL_EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0; + is_write = (exccause == EXCCAUSE_STORE_CACHE_ATTRIBUTE) ? 1 : 0; + is_exec = (exccause == EXCCAUSE_ITLB_PRIVILEGE || + exccause == EXCCAUSE_ITLB_MISS || + exccause == EXCCAUSE_FETCH_CACHE_ATTRIBUTE) ? 1 : 0; #if 0 printk("[%s:%d:%08x:%d:%08x:%s%s]\n", current->comm, current->pid, diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 660ef058c14..e1ec2d1e818 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c @@ -141,8 +141,8 @@ void __init bootmem_init(void) if (min_low_pfn > max_pfn) panic("No memory found!\n"); - max_low_pfn = max_pfn < MAX_LOW_MEMORY >> PAGE_SHIFT ? - max_pfn : MAX_LOW_MEMORY >> PAGE_SHIFT; + max_low_pfn = max_pfn < MAX_MEM_PFN >> PAGE_SHIFT ? + max_pfn : MAX_MEM_PFN >> PAGE_SHIFT; /* Find an area to use for the bootmem bitmap. */ @@ -215,7 +215,7 @@ void __init init_mmu (void) /* Set rasid register to a known value. */ - set_rasid_register (ASID_ALL_RESERVED); + set_rasid_register (ASID_USER_FIRST); /* Set PTEVADDR special register to the start of the page * table, which is in kernel mappable space (ie. not diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index 327c0f17187..ae085332c60 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S @@ -19,9 +19,8 @@ #include #include #include - -#include -#include +#include +#include /* clear_page (page) */ @@ -74,104 +73,66 @@ ENTRY(copy_page) retw - /* - * void __flush_invalidate_cache_all(void) + * void __invalidate_icache_page(ulong start) */ -ENTRY(__flush_invalidate_cache_all) +ENTRY(__invalidate_icache_page) entry sp, 16 - dcache_writeback_inv_all a2, a3 - icache_invalidate_all a2, a3 - retw -/* - * void __invalidate_icache_all(void) - */ + ___invalidate_icache_page a2 a3 + isync -ENTRY(__invalidate_icache_all) - entry sp, 16 - icache_invalidate_all a2, a3 retw /* - * void __flush_invalidate_dcache_all(void) + * void __invalidate_dcache_page(ulong start) */ -ENTRY(__flush_invalidate_dcache_all) +ENTRY(__invalidate_dcache_page) entry sp, 16 - dcache_writeback_inv_all a2, a3 - retw - -/* - * void __flush_invalidate_cache_range(ulong start, ulong size) - */ + ___invalidate_dcache_page a2 a3 + dsync -ENTRY(__flush_invalidate_cache_range) - entry sp, 16 - mov a4, a2 - mov a5, a3 - dcache_writeback_inv_region a4, a5, a6 - icache_invalidate_region a2, a3, a4 retw /* - * void __invalidate_icache_page(ulong start) + * void __flush_invalidate_dcache_page(ulong start) */ -ENTRY(__invalidate_icache_page) +ENTRY(__flush_invalidate_dcache_page) entry sp, 16 - movi a3, PAGE_SIZE - icache_invalidate_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_page(ulong start) - */ + ___flush_invalidate_dcache_page a2 a3 -ENTRY(__invalidate_dcache_page) - entry sp, 16 - movi a3, PAGE_SIZE - dcache_invalidate_region a2, a3, a4 + dsync retw /* - * void __invalidate_icache_range(ulong start, ulong size) + * void __flush_dcache_page(ulong start) */ -ENTRY(__invalidate_icache_range) +ENTRY(__flush_dcache_page) entry sp, 16 - icache_invalidate_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_range(ulong start, ulong size) - */ + ___flush_dcache_page a2 a3 -ENTRY(__invalidate_dcache_range) - entry sp, 16 - dcache_invalidate_region a2, a3, a4 + dsync retw -/* - * void __flush_dcache_page(ulong start) - */ -ENTRY(__flush_dcache_page) - entry sp, 16 - movi a3, PAGE_SIZE - dcache_writeback_region a2, a3, a4 - retw /* - * void __flush_invalidate_dcache_page(ulong start) + * void __invalidate_icache_range(ulong start, ulong size) */ -ENTRY(__flush_invalidate_dcache_page) +ENTRY(__invalidate_icache_range) entry sp, 16 - movi a3, PAGE_SIZE - dcache_writeback_inv_region a2, a3, a4 + + ___invalidate_icache_range a2 a3 a4 + isync + retw /* @@ -180,195 +141,69 @@ ENTRY(__flush_invalidate_dcache_page) ENTRY(__flush_invalidate_dcache_range) entry sp, 16 - dcache_writeback_inv_region a2, a3, a4 - retw -/* - * void __invalidate_dcache_all(void) - */ + ___flush_invalidate_dcache_range a2 a3 a4 + dsync -ENTRY(__invalidate_dcache_all) - entry sp, 16 - dcache_invalidate_all a2, a3 retw /* - * void __flush_invalidate_dcache_page_phys(ulong start) + * void _flush_dcache_range(ulong start, ulong size) */ -ENTRY(__flush_invalidate_dcache_page_phys) +ENTRY(__flush_dcache_range) entry sp, 16 - movi a3, XCHAL_DCACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 + ___flush_dcache_range a2 a3 a4 dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw -2: diwbi a3, 0 - bgeui a3, 2, 1b retw -ENTRY(check_dcache_low0) - entry sp, 16 - - movi a3, XCHAL_DCACHE_SIZE / 4 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw - -2: j 2b - -ENTRY(check_dcache_high0) - entry sp, 16 - - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE / 2 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE - - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b - retw - -2: j 2b +/* + * void _invalidate_dcache_range(ulong start, ulong size) + */ -ENTRY(check_dcache_low1) +ENTRY(__invalidate_dcache_range) entry sp, 16 - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE * 3 / 4 - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 + ___invalidate_dcache_range a2 a3 a4 -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b retw -2: j 2b +/* + * void _invalidate_icache_all(void) + */ -ENTRY(check_dcache_high1) +ENTRY(__invalidate_icache_all) entry sp, 16 - movi a5, XCHAL_DCACHE_SIZE / 4 - movi a3, XCHAL_DCACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_DCACHE_LINESIZE - addi a5, a5, -XCHAL_DCACHE_LINESIZE + ___invalidate_icache_all a2 a3 + isync - ldct a6, a3 - dsync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a5, 2, 1b retw -2: j 2b - - /* - * void __invalidate_icache_page_phys(ulong start) + * void _flush_invalidate_dcache_all(void) */ -ENTRY(__invalidate_icache_page_phys) +ENTRY(__flush_invalidate_dcache_all) entry sp, 16 - movi a3, XCHAL_ICACHE_SIZE - movi a4, PAGE_MASK | 1 - addi a2, a2, 1 - -1: addi a3, a3, -XCHAL_ICACHE_LINESIZE - - lict a6, a3 - isync - and a6, a6, a4 - beq a6, a2, 2f - bgeui a3, 2, 1b - retw + ___flush_invalidate_dcache_all a2 a3 + dsync -2: iii a3, 0 - bgeui a3, 2, 1b retw +/* + * void _invalidate_dcache_all(void) + */ -#if 0 - - movi a3, XCHAL_DCACHE_WAYS - 1 - movi a4, PAGE_SIZE - -1: mov a5, a2 - add a6, a2, a4 - -2: diwbi a5, 0 - diwbi a5, XCHAL_DCACHE_LINESIZE - diwbi a5, XCHAL_DCACHE_LINESIZE * 2 - diwbi a5, XCHAL_DCACHE_LINESIZE * 3 - - addi a5, a5, XCHAL_DCACHE_LINESIZE * 4 - blt a5, a6, 2b - - addi a3, a3, -1 - addi a2, a2, XCHAL_DCACHE_SIZE / XCHAL_DCACHE_WAYS - bgez a3, 1b - - retw - -ENTRY(__invalidate_icache_page_index) +ENTRY(__invalidate_dcache_all) entry sp, 16 - movi a3, XCHAL_ICACHE_WAYS - 1 - movi a4, PAGE_SIZE - -1: mov a5, a2 - add a6, a2, a4 - -2: iii a5, 0 - iii a5, XCHAL_ICACHE_LINESIZE - iii a5, XCHAL_ICACHE_LINESIZE * 2 - iii a5, XCHAL_ICACHE_LINESIZE * 3 - - addi a5, a5, XCHAL_ICACHE_LINESIZE * 4 - blt a5, a6, 2b - - addi a3, a3, -1 - addi a2, a2, XCHAL_ICACHE_SIZE / XCHAL_ICACHE_WAYS - bgez a3, 2b + ___invalidate_dcache_all a2 a3 + dsync retw -#endif - - - - - - diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index 0fefb866687..239461d8ea8 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c @@ -24,12 +24,12 @@ static inline void __flush_itlb_all (void) { - int way, index; + int w, i; - for (way = 0; way < XCHAL_ITLB_ARF_WAYS; way++) { - for (index = 0; index < ITLB_ENTRIES_PER_ARF_WAY; index++) { - int entry = way + (index << PAGE_SHIFT); - invalidate_itlb_entry_no_isync (entry); + for (w = 0; w < ITLB_ARF_WAYS; w++) { + for (i = 0; i < (1 << XCHAL_ITLB_ARF_ENTRIES_LOG2); i++) { + int e = w + (i << PAGE_SHIFT); + invalidate_itlb_entry_no_isync(e); } } asm volatile ("isync\n"); @@ -37,12 +37,12 @@ static inline void __flush_itlb_all (void) static inline void __flush_dtlb_all (void) { - int way, index; + int w, i; - for (way = 0; way < XCHAL_DTLB_ARF_WAYS; way++) { - for (index = 0; index < DTLB_ENTRIES_PER_ARF_WAY; index++) { - int entry = way + (index << PAGE_SHIFT); - invalidate_dtlb_entry_no_isync (entry); + for (w = 0; w < DTLB_ARF_WAYS; w++) { + for (i = 0; i < (1 << XCHAL_DTLB_ARF_ENTRIES_LOG2); i++) { + int e = w + (i << PAGE_SHIFT); + invalidate_dtlb_entry_no_isync(e); } } asm volatile ("isync\n"); @@ -63,21 +63,25 @@ void flush_tlb_all (void) void flush_tlb_mm(struct mm_struct *mm) { -#if 0 - printk("[tlbmm<%lx>]\n", (unsigned long)mm->context); -#endif - if (mm == current->active_mm) { int flags; local_save_flags(flags); - get_new_mmu_context(mm, asid_cache); - set_rasid_register(ASID_INSERT(mm->context)); + __get_new_mmu_context(mm); + __load_mmu_context(mm); local_irq_restore(flags); } else mm->context = 0; } +#define _ITLB_ENTRIES (ITLB_ARF_WAYS << XCHAL_ITLB_ARF_ENTRIES_LOG2) +#define _DTLB_ENTRIES (DTLB_ARF_WAYS << XCHAL_DTLB_ARF_ENTRIES_LOG2) +#if _ITLB_ENTRIES > _DTLB_ENTRIES +# define _TLB_ENTRIES _ITLB_ENTRIES +#else +# define _TLB_ENTRIES _DTLB_ENTRIES +#endif + void flush_tlb_range (struct vm_area_struct *vma, unsigned long start, unsigned long end) { @@ -93,7 +97,7 @@ void flush_tlb_range (struct vm_area_struct *vma, #endif local_save_flags(flags); - if (end-start + (PAGE_SIZE-1) <= SMALLEST_NTLB_ENTRIES << PAGE_SHIFT) { + if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) { int oldpid = get_rasid_register(); set_rasid_register (ASID_INSERT(mm->context)); start &= PAGE_MASK; @@ -111,9 +115,7 @@ void flush_tlb_range (struct vm_area_struct *vma, set_rasid_register(oldpid); } else { - get_new_mmu_context(mm, asid_cache); - if (mm == current->active_mm) - set_rasid_register(ASID_INSERT(mm->context)); + flush_tlb_mm(mm); } local_irq_restore(flags); } @@ -123,10 +125,6 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) struct mm_struct* mm = vma->vm_mm; unsigned long flags; int oldpid; -#if 0 - printk("[tlbpage<%02lx,%08lx>]\n", - (unsigned long)mm->context, page); -#endif if(mm->context == NO_CONTEXT) return; @@ -142,404 +140,5 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) set_rasid_register(oldpid); local_irq_restore(flags); - -#if 0 - flush_tlb_all(); - return; -#endif -} - - -#ifdef DEBUG_TLB - -#define USE_ITLB 0 -#define USE_DTLB 1 - -struct way_config_t { - int indicies; - int indicies_log2; - int pgsz_log2; - int arf; -}; - -static struct way_config_t itlb[XCHAL_ITLB_WAYS] = -{ - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ARF) - }, - { XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES_LOG2), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, PAGESZ_LOG2_MIN), - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ARF) - } -}; - -static struct way_config_t dtlb[XCHAL_DTLB_WAYS] = -{ - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ARF) - }, - { XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES_LOG2), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, PAGESZ_LOG2_MIN), - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ARF) - } -}; - -/* Total number of entries: */ -#define ITLB_TOTAL_ENTRIES \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY0_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY1_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY2_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY3_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY4_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY5_SET, ENTRIES) + \ - XCHAL_ITLB_SET(XCHAL_ITLB_WAY6_SET, ENTRIES) -#define DTLB_TOTAL_ENTRIES \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY0_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY1_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY2_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY3_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY4_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY5_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY6_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY7_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY8_SET, ENTRIES) + \ - XCHAL_DTLB_SET(XCHAL_DTLB_WAY9_SET, ENTRIES) - - -typedef struct { - unsigned va; - unsigned pa; - unsigned char asid; - unsigned char ca; - unsigned char way; - unsigned char index; - unsigned char pgsz_log2; /* 0 .. 32 */ - unsigned char type; /* 0=ITLB 1=DTLB */ -} tlb_dump_entry_t; - -/* Return -1 if a precedes b, +1 if a follows b, 0 if same: */ -int cmp_tlb_dump_info( tlb_dump_entry_t *a, tlb_dump_entry_t *b ) -{ - if (a->asid < b->asid) return -1; - if (a->asid > b->asid) return 1; - if (a->va < b->va) return -1; - if (a->va > b->va) return 1; - if (a->pa < b->pa) return -1; - if (a->pa > b->pa) return 1; - if (a->ca < b->ca) return -1; - if (a->ca > b->ca) return 1; - if (a->way < b->way) return -1; - if (a->way > b->way) return 1; - if (a->index < b->index) return -1; - if (a->index > b->index) return 1; - return 0; -} - -void sort_tlb_dump_info( tlb_dump_entry_t *t, int n ) -{ - int i, j; - /* Simple O(n*n) sort: */ - for (i = 0; i < n-1; i++) - for (j = i+1; j < n; j++) - if (cmp_tlb_dump_info(t+i, t+j) > 0) { - tlb_dump_entry_t tmp = t[i]; - t[i] = t[j]; - t[j] = tmp; - } -} - - -static tlb_dump_entry_t itlb_dump_info[ITLB_TOTAL_ENTRIES]; -static tlb_dump_entry_t dtlb_dump_info[DTLB_TOTAL_ENTRIES]; - - -static inline char *way_type (int type) -{ - return type ? "autorefill" : "non-autorefill"; -} - -void print_entry (struct way_config_t *way_info, - unsigned int way, - unsigned int index, - unsigned int virtual, - unsigned int translation) -{ - char valid_chr; - unsigned int va, pa, asid, ca; - - va = virtual & - ~((1 << (way_info->pgsz_log2 + way_info->indicies_log2)) - 1); - asid = virtual & ((1 << XCHAL_MMU_ASID_BITS) - 1); - pa = translation & ~((1 << way_info->pgsz_log2) - 1); - ca = translation & ((1 << XCHAL_MMU_CA_BITS) - 1); - valid_chr = asid ? 'V' : 'I'; - - /* Compute and incorporate the effect of the index bits on the - * va. It's more useful for kernel debugging, since we always - * want to know the effective va anyway. */ - - va += index << way_info->pgsz_log2; - - printk ("\t[%d,%d] (%c) vpn 0x%.8x ppn 0x%.8x asid 0x%.2x am 0x%x\n", - way, index, valid_chr, va, pa, asid, ca); -} - -void print_itlb_entry (struct way_config_t *way_info, int way, int index) -{ - print_entry (way_info, way, index, - read_itlb_virtual (way + (index << way_info->pgsz_log2)), - read_itlb_translation (way + (index << way_info->pgsz_log2))); -} - -void print_dtlb_entry (struct way_config_t *way_info, int way, int index) -{ - print_entry (way_info, way, index, - read_dtlb_virtual (way + (index << way_info->pgsz_log2)), - read_dtlb_translation (way + (index << way_info->pgsz_log2))); -} - -void dump_itlb (void) -{ - int way, index; - - printk ("\nITLB: ways = %d\n", XCHAL_ITLB_WAYS); - - for (way = 0; way < XCHAL_ITLB_WAYS; way++) { - printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n", - way, itlb[way].indicies, - itlb[way].pgsz_log2, way_type(itlb[way].arf)); - for (index = 0; index < itlb[way].indicies; index++) { - print_itlb_entry(&itlb[way], way, index); - } - } -} - -void dump_dtlb (void) -{ - int way, index; - - printk ("\nDTLB: ways = %d\n", XCHAL_DTLB_WAYS); - - for (way = 0; way < XCHAL_DTLB_WAYS; way++) { - printk ("\nWay: %d, Entries: %d, MinPageSize: %d, Type: %s\n", - way, dtlb[way].indicies, - dtlb[way].pgsz_log2, way_type(dtlb[way].arf)); - for (index = 0; index < dtlb[way].indicies; index++) { - print_dtlb_entry(&dtlb[way], way, index); - } - } -} - -void dump_tlb (tlb_dump_entry_t *tinfo, struct way_config_t *config, - int entries, int ways, int type, int show_invalid) -{ - tlb_dump_entry_t *e = tinfo; - int way, i; - - /* Gather all info: */ - for (way = 0; way < ways; way++) { - struct way_config_t *cfg = config + way; - for (i = 0; i < cfg->indicies; i++) { - unsigned wayindex = way + (i << cfg->pgsz_log2); - unsigned vv = (type ? read_dtlb_virtual (wayindex) - : read_itlb_virtual (wayindex)); - unsigned pp = (type ? read_dtlb_translation (wayindex) - : read_itlb_translation (wayindex)); - - /* Compute and incorporate the effect of the index bits on the - * va. It's more useful for kernel debugging, since we always - * want to know the effective va anyway. */ - - e->va = (vv & ~((1 << (cfg->pgsz_log2 + cfg->indicies_log2)) - 1)); - e->va += (i << cfg->pgsz_log2); - e->pa = (pp & ~((1 << cfg->pgsz_log2) - 1)); - e->asid = (vv & ((1 << XCHAL_MMU_ASID_BITS) - 1)); - e->ca = (pp & ((1 << XCHAL_MMU_CA_BITS) - 1)); - e->way = way; - e->index = i; - e->pgsz_log2 = cfg->pgsz_log2; - e->type = type; - e++; - } - } -#if 1 - /* Sort by ASID and VADDR: */ - sort_tlb_dump_info (tinfo, entries); -#endif - - /* Display all sorted info: */ - printk ("\n%cTLB dump:\n", (type ? 'D' : 'I')); - for (e = tinfo, i = 0; i < entries; i++, e++) { -#if 0 - if (e->asid == 0 && !show_invalid) - continue; -#endif - printk ("%c way=%d i=%d ASID=%02X V=%08X -> P=%08X CA=%X (%d %cB)\n", - (e->type ? 'D' : 'I'), e->way, e->index, - e->asid, e->va, e->pa, e->ca, - (1 << (e->pgsz_log2 % 10)), - " kMG"[e->pgsz_log2 / 10] - ); - } -} - -void dump_tlbs2 (int showinv) -{ - dump_tlb (itlb_dump_info, itlb, ITLB_TOTAL_ENTRIES, XCHAL_ITLB_WAYS, 0, showinv); - dump_tlb (dtlb_dump_info, dtlb, DTLB_TOTAL_ENTRIES, XCHAL_DTLB_WAYS, 1, showinv); -} - -void dump_all_tlbs (void) -{ - dump_tlbs2 (1); -} - -void dump_valid_tlbs (void) -{ - dump_tlbs2 (0); } - -void dump_tlbs (void) -{ - dump_itlb(); - dump_dtlb(); -} - -void dump_cache_tag(int dcache, int idx) -{ - int w, i, s, e; - unsigned long tag, index; - unsigned long num_lines, num_ways, cache_size, line_size; - - num_ways = dcache ? XCHAL_DCACHE_WAYS : XCHAL_ICACHE_WAYS; - cache_size = dcache ? XCHAL_DCACHE_SIZE : XCHAL_ICACHE_SIZE; - line_size = dcache ? XCHAL_DCACHE_LINESIZE : XCHAL_ICACHE_LINESIZE; - - num_lines = cache_size / num_ways; - - s = 0; e = num_lines; - - if (idx >= 0) - e = (s = idx * line_size) + 1; - - for (i = s; i < e; i+= line_size) { - printk("\nline %#08x:", i); - for (w = 0; w < num_ways; w++) { - index = w * num_lines + i; - if (dcache) - __asm__ __volatile__("ldct %0, %1\n\t" - : "=a"(tag) : "a"(index)); - else - __asm__ __volatile__("lict %0, %1\n\t" - : "=a"(tag) : "a"(index)); - - printk(" %#010lx", tag); - } - } - printk ("\n"); -} - -void dump_icache(int index) -{ - unsigned long data, addr; - int w, i; - - const unsigned long num_ways = XCHAL_ICACHE_WAYS; - const unsigned long cache_size = XCHAL_ICACHE_SIZE; - const unsigned long line_size = XCHAL_ICACHE_LINESIZE; - const unsigned long num_lines = cache_size / num_ways / line_size; - - for (w = 0; w < num_ways; w++) { - printk ("\nWay %d", w); - - for (i = 0; i < line_size; i+= 4) { - addr = w * num_lines + index * line_size + i; - __asm__ __volatile__("licw %0, %1\n\t" - : "=a"(data) : "a"(addr)); - printk(" %#010lx", data); - } - } - printk ("\n"); -} - -void dump_cache_tags(void) -{ - printk("Instruction cache\n"); - dump_cache_tag(0, -1); - printk("Data cache\n"); - dump_cache_tag(1, -1); -} - -#endif diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 5c947cae752..2f4f20ffe66 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c @@ -25,11 +25,15 @@ #include #include -#include +#include #include #include +#ifdef SERIAL_INLINE +#define _INLINE_ inline +#endif + #define SERIAL_MAX_NUM_LINES 1 #define SERIAL_TIMER_VALUE (20 * HZ) @@ -191,7 +195,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 15d64414bd6..8ebfc876122 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c @@ -34,7 +34,7 @@ #include #include -#include +#include #define DRIVER_NAME "iss-netdev" #define ETH_MAX_PACKET 1500 -- cgit v1.2.3 From fc4fb2adf944d45a7f3d4d38df991c79ffdb6a43 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Sun, 10 Dec 2006 02:18:52 -0800 Subject: [PATCH] xtensa: fix system call interface This is a long outstanding patch to finally fix the syscall interface. The constants used for the system calls are those we have provided in our libc patches. This patch also fixes the shmbuf and stat structure, and fcntl definitions. Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/kernel/asm-offsets.c | 5 + arch/xtensa/kernel/entry.S | 228 ++++++++++++++++++++----------- arch/xtensa/kernel/process.c | 71 ++++++---- arch/xtensa/kernel/ptrace.c | 26 +++- arch/xtensa/kernel/signal.c | 12 +- arch/xtensa/kernel/syscall.c | 95 +++++++++++++ arch/xtensa/kernel/syscalls.c | 288 --------------------------------------- arch/xtensa/kernel/syscalls.h | 247 --------------------------------- 8 files changed, 317 insertions(+), 655 deletions(-) create mode 100644 arch/xtensa/kernel/syscall.c delete mode 100644 arch/xtensa/kernel/syscalls.c delete mode 100644 arch/xtensa/kernel/syscalls.h (limited to 'arch') diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 7cd1d7f8f60..b256cfbef34 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -87,6 +87,11 @@ int main(void) DEFINE(MM_CONTEXT, offsetof (struct mm_struct, context)); BLANK(); DEFINE(PT_SINGLESTEP_BIT, PT_SINGLESTEP_BIT); + + /* constants */ + DEFINE(_CLONE_VM, CLONE_VM); + DEFINE(_CLONE_UNTRACED, CLONE_UNTRACED); + return 0; } diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index c0b56b17927..9e271ba009b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -1004,13 +1004,10 @@ ENTRY(fast_syscall_kernel) rsr a0, DEPC # get syscall-nr _beqz a0, fast_syscall_spill_registers - - addi a0, a0, -__NR_sysxtensa - _beqz a0, fast_syscall_sysxtensa + _beqi a0, __NR_xtensa, fast_syscall_xtensa j kernel_exception - ENTRY(fast_syscall_user) /* Skip syscall. */ @@ -1024,9 +1021,7 @@ ENTRY(fast_syscall_user) rsr a0, DEPC # get syscall-nr _beqz a0, fast_syscall_spill_registers - - addi a0, a0, -__NR_sysxtensa - _beqz a0, fast_syscall_sysxtensa + _beqi a0, __NR_xtensa, fast_syscall_xtensa j user_exception @@ -1047,18 +1042,19 @@ ENTRY(fast_syscall_unrecoverable) /* * sysxtensa syscall handler * - * int sysxtensa (XTENSA_ATOMIC_SET, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_ADD, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_EXG_ADD, ptr, val, unused); - * int sysxtensa (XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval); - * a2 a6 a3 a4 a5 + * int sysxtensa (SYS_XTENSA_ATOMIC_SET, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_ADD, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_EXG_ADD, ptr, val, unused); + * int sysxtensa (SYS_XTENSA_ATOMIC_CMP_SWP, ptr, oldval, newval); + * a2 a6 a3 a4 a5 * * Entry condition: * - * a0: trashed, original value saved on stack (PT_AREG0) + * a0: a2 (syscall-nr), original value saved on stack (PT_AREG0) * a1: a1 - * a2: new stack pointer, original in DEPC - * a3: dispatch table + * a2: new stack pointer, original in a0 and DEPC + * a3: dispatch table, original in excsave_1 + * a4..a15: unchanged * depc: a2, original value saved on stack (PT_DEPC) * excsave_1: a3 * @@ -1091,59 +1087,62 @@ ENTRY(fast_syscall_unrecoverable) #define CATCH \ 67: -ENTRY(fast_syscall_sysxtensa) - - _beqz a6, 1f - _blti a6, SYSXTENSA_COUNT, 2f +ENTRY(fast_syscall_xtensa) -1: j user_exception - -2: xsr a3, EXCSAVE_1 # restore a3, excsave1 - s32i a7, a2, PT_AREG7 + xsr a3, EXCSAVE_1 # restore a3, excsave1 + s32i a7, a2, PT_AREG7 # we need an additional register movi a7, 4 # sizeof(unsigned int) - access_ok a0, a3, a7, a2, .Leac + access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp - _beqi a6, SYSXTENSA_ATOMIC_SET, .Lset - _beqi a6, SYSXTENSA_ATOMIC_EXG_ADD, .Lexg - _beqi a6, SYSXTENSA_ATOMIC_ADD, .Ladd + addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 + _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill + _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp - /* Fall through for SYSXTENSA_ATOMIC_CMP_SWP */ + /* Fall through for ATOMIC_CMP_SWP. */ .Lswp: /* Atomic compare and swap */ -TRY l32i a7, a3, 0 # read old value - bne a7, a4, 1f # same as old value? jump - s32i a5, a3, 0 # different, modify value - movi a7, 1 # and return 1 - j .Lret - -1: movi a7, 0 # same values: return 0 - j .Lret - -.Ladd: /* Atomic add */ -.Lexg: /* Atomic (exchange) add */ +TRY l32i a0, a3, 0 # read old value + bne a0, a4, 1f # same as old value? jump +TRY s32i a5, a3, 0 # different, modify value + l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, 1 # and return 1 + addi a6, a6, 1 # restore a6 (really necessary?) + rfe -TRY l32i a7, a3, 0 - add a4, a4, a7 - s32i a4, a3, 0 - j .Lret +1: l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, 0 # return 0 (note that we cannot set + addi a6, a6, 1 # restore a6 (really necessary?) + rfe -.Lset: /* Atomic set */ +.Lnswp: /* Atomic set, add, and exg_add. */ -TRY l32i a7, a3, 0 # read old value as return value - s32i a4, a3, 0 # write new value +TRY l32i a7, a3, 0 # orig + add a0, a4, a7 # + arg + moveqz a0, a4, a6 # set +TRY s32i a0, a3, 0 # write new value -.Lret: mov a0, a2 + mov a0, a2 mov a2, a7 - l32i a7, a0, PT_AREG7 - l32i a3, a0, PT_AREG3 - l32i a0, a0, PT_AREG0 + l32i a7, a0, PT_AREG7 # restore a7 + l32i a0, a0, PT_AREG0 # restore a0 + addi a6, a6, 1 # restore a6 (really necessary?) rfe CATCH -.Leac: movi a7, -EFAULT - j .Lret +.Leac: l32i a7, a2, PT_AREG7 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -EFAULT + rfe + +.Lill: l32i a7, a2, PT_AREG0 # restore a7 + l32i a0, a2, PT_AREG0 # restore a0 + movi a2, -EINVAL + rfe + @@ -1906,6 +1905,103 @@ ENTRY(fast_coprocessor) #endif /* XCHAL_EXTRA_SA_SIZE */ +/* + * System Calls. + * + * void system_call (struct pt_regs* regs, int exccause) + * a2 a3 + */ + +ENTRY(system_call) + entry a1, 32 + + /* regs->syscall = regs->areg[2] */ + + l32i a3, a2, PT_AREG2 + mov a6, a2 + movi a4, do_syscall_trace_enter + s32i a3, a2, PT_SYSCALL + callx4 a4 + + /* syscall = sys_call_table[syscall_nr] */ + + movi a4, sys_call_table; + movi a5, __NR_syscall_count + movi a6, -ENOSYS + bgeu a3, a5, 1f + + addx4 a4, a3, a4 + l32i a4, a4, 0 + movi a5, sys_ni_syscall; + beq a4, a5, 1f + + /* Load args: arg0 - arg5 are passed via regs. */ + + l32i a6, a2, PT_AREG6 + l32i a7, a2, PT_AREG3 + l32i a8, a2, PT_AREG4 + l32i a9, a2, PT_AREG5 + l32i a10, a2, PT_AREG8 + l32i a11, a2, PT_AREG9 + + /* Pass one additional argument to the syscall: pt_regs (on stack) */ + s32i a2, a1, 0 + + callx4 a4 + +1: /* regs->areg[2] = return_value */ + + s32i a6, a2, PT_AREG2 + movi a4, do_syscall_trace_leave + mov a6, a2 + callx4 a4 + retw + + +/* + * Create a kernel thread + * + * int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_thread) + entry a1, 16 + + mov a5, a2 # preserve fn over syscall + mov a7, a3 # preserve args over syscall + + movi a3, _CLONE_VM | _CLONE_UNTRACED + movi a2, __NR_clone + or a6, a4, a3 # arg0: flags + mov a3, a1 # arg1: sp + syscall + + beq a3, a1, 1f # branch if parent + mov a6, a7 # args + callx4 a5 # fn(args) + + movi a2, __NR_exit + syscall # return value of fn(args) still in a6 + +1: retw + +/* + * Do a system call from kernel instead of calling sys_execve, so we end up + * with proper pt_regs. + * + * int kernel_execve(const char *fname, char *const argv[], charg *const envp[]) + * a2 a2 a3 a4 + */ + +ENTRY(kernel_execve) + entry a1, 16 + mov a6, a2 # arg0 is in a6 + movi a2, __NR_execve + syscall + + retw + /* * Task switch. * @@ -1964,33 +2060,9 @@ ENTRY(ret_from_fork) movi a4, schedule_tail callx4 a4 - movi a4, do_syscall_trace + movi a4, do_syscall_trace_leave + mov a6, a1 callx4 a4 j common_exception_return - - -/* - * Table of syscalls - */ - -.data -.align 4 -.global sys_call_table -sys_call_table: - -#define SYSCALL(call, narg) .word call -#include "syscalls.h" - -/* - * Number of arguments of each syscall - */ - -.global sys_narg_table -sys_narg_table: - -#undef SYSCALL -#define SYSCALL(call, narg) .byte narg -#include "syscalls.h" - diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 3785f3481d7..795bd5ac6f4 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -160,36 +160,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, } -/* - * Create a kernel thread - */ - -int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - long retval; - __asm__ __volatile__ - ("mov a5, %4\n\t" /* preserve fn in a5 */ - "mov a6, %3\n\t" /* preserve and setup arg in a6 */ - "movi a2, %1\n\t" /* load __NR_clone for syscall*/ - "mov a3, sp\n\t" /* sp check and sys_clone */ - "mov a4, %5\n\t" /* load flags for syscall */ - "syscall\n\t" - "beq a3, sp, 1f\n\t" /* branch if parent */ - "callx4 a5\n\t" /* call fn */ - "movi a2, %2\n\t" /* load __NR_exit for syscall */ - "mov a3, a6\n\t" /* load fn return value */ - "syscall\n" - "1:\n\t" - "mov %0, a2\n\t" /* parent returns zero */ - :"=r" (retval) - :"i" (__NR_clone), "i" (__NR_exit), - "r" (arg), "r" (fn), - "r" (flags | CLONE_VM) - : "a2", "a3", "a4", "a5", "a6" ); - return retval; -} - - /* * These bracket the sleeping functions.. */ @@ -452,3 +422,44 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) { return dump_task_fpu(regs, current, r); } + +asmlinkage +long xtensa_clone(unsigned long clone_flags, unsigned long newsp, + void __user *parent_tid, void *child_tls, + void __user *child_tid, long a5, + struct pt_regs *regs) +{ + if (!newsp) + newsp = regs->areg[1]; + return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); +} + +/* + * * xtensa_execve() executes a new program. + * */ + +asmlinkage +long xtensa_execve(char __user *name, char __user * __user *argv, + char __user * __user *envp, + long a3, long a4, long a5, + struct pt_regs *regs) +{ + long error; + char * filename; + + filename = getname(name); + error = PTR_ERR(filename); + if (IS_ERR(filename)) + goto out; + // FIXME: release coprocessor?? + error = do_execve(filename, argv, envp, regs); + if (error == 0) { + task_lock(current); + current->ptrace &= ~PT_DTRACE; + task_unlock(current); + } + putname(filename); +out: + return error; +} + diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 604c3c3c675..8b6d3d0623b 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -332,12 +332,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) void do_syscall_trace(void) { - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - - if (!(current->ptrace & PT_PTRACED)) - return; - /* * The 0x80 provides a way for the tracing parent to distinguish * between a syscall stop and SIGTRAP delivery @@ -354,3 +348,23 @@ void do_syscall_trace(void) current->exit_code = 0; } } + +void do_syscall_trace_enter(struct pt_regs *regs) +{ + if (test_thread_flag(TIF_SYSCALL_TRACE) + && (current->ptrace & PT_PTRACED)) + do_syscall_trace(); + +#if 0 + if (unlikely(current->audit_context)) + audit_syscall_entry(current, AUDIT_ARCH_XTENSA..); +#endif +} + +void do_syscall_trace_leave(struct pt_regs *regs) +{ + if ((test_thread_flag(TIF_SYSCALL_TRACE)) + && (current->ptrace & PT_PTRACED)) + do_syscall_trace(); +} + diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 6af7f414599..c6d9880a4cd 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c @@ -46,7 +46,7 @@ extern struct task_struct *coproc_owners[]; * Atomically swap in the new signal mask, and wait for a signal. */ -int sys_sigsuspend(struct pt_regs *regs) +int xtensa_sigsuspend(struct pt_regs *regs) { old_sigset_t mask = (old_sigset_t) regs->areg[3]; sigset_t saveset; @@ -68,7 +68,7 @@ int sys_sigsuspend(struct pt_regs *regs) } asmlinkage int -sys_rt_sigsuspend(struct pt_regs *regs) +xtensa_rt_sigsuspend(struct pt_regs *regs) { sigset_t *unewset = (sigset_t *) regs->areg[4]; size_t sigsetsize = (size_t) regs->areg[3]; @@ -96,7 +96,7 @@ sys_rt_sigsuspend(struct pt_regs *regs) } asmlinkage int -sys_sigaction(int sig, const struct old_sigaction *act, +xtensa_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { struct k_sigaction new_ka, old_ka; @@ -128,7 +128,7 @@ sys_sigaction(int sig, const struct old_sigaction *act, } asmlinkage int -sys_sigaltstack(struct pt_regs *regs) +xtensa_sigaltstack(struct pt_regs *regs) { const stack_t *uss = (stack_t *) regs->areg[4]; stack_t *uoss = (stack_t *) regs->areg[3]; @@ -350,7 +350,7 @@ setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate, return err; } -asmlinkage int sys_sigreturn(struct pt_regs *regs) +asmlinkage int xtensa_sigreturn(struct pt_regs *regs) { struct sigframe *frame = (struct sigframe *)regs->areg[1]; sigset_t set; @@ -382,7 +382,7 @@ badframe: return 0; } -asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) { struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1]; sigset_t set; diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c new file mode 100644 index 00000000000..418268f4976 --- /dev/null +++ b/arch/xtensa/kernel/syscall.c @@ -0,0 +1,95 @@ +/* + * arch/xtensa/kernel/syscall.c + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2000 Silicon Graphics, Inc. + * Copyright (C) 1995 - 2000 by Ralf Baechle + * + * Joe Taylor + * Marc Gauthier + * Chris Zankel + * Kevin Chea + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef void (*syscall_t)(void); + +syscall_t sys_call_table[__NR_syscall_count] /* FIXME __cacheline_aligned */= { + [0 ... __NR_syscall_count - 1] = (syscall_t)&sys_ni_syscall, + +#undef __SYSCALL +#define __SYSCALL(nr,symbol,nargs) [ nr ] = (syscall_t)symbol, +#undef _XTENSA_UNISTD_H +#undef __KERNEL_SYSCALLS__ +#include +}; + +/* + * xtensa_pipe() is the normal C calling standard for creating a pipe. It's not + * the way unix traditional does this, though. + */ + +asmlinkage long xtensa_pipe(int __user *userfds) +{ + int fd[2]; + int error; + + error = do_pipe(fd); + if (!error) { + if (copy_to_user(userfds, fd, 2 * sizeof(int))) + error = -EFAULT; + } + return error; +} + + +asmlinkage long xtensa_mmap2(unsigned long addr, unsigned long len, + unsigned long prot, unsigned long flags, + unsigned long fd, unsigned long pgoff) +{ + int error = -EBADF; + struct file * file = NULL; + + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + if (!(flags & MAP_ANONYMOUS)) { + file = fget(fd); + if (!file) + goto out; + } + + down_write(¤t->mm->mmap_sem); + error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); + up_write(¤t->mm->mmap_sem); + + if (file) + fput(file); +out: + return error; +} + +asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg) +{ + unsigned long ret; + long err; + + err = do_shmat(shmid, shmaddr, shmflg, &ret); + if (err) + return err; + return (long)ret; +} + diff --git a/arch/xtensa/kernel/syscalls.c b/arch/xtensa/kernel/syscalls.c deleted file mode 100644 index f9a5a752ca6..00000000000 --- a/arch/xtensa/kernel/syscalls.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * arch/xtensa/kernel/syscalls.c - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001 - 2005 Tensilica Inc. - * Copyright (C) 2000 Silicon Graphics, Inc. - * Copyright (C) 1995 - 2000 by Ralf Baechle - * - * Joe Taylor - * Marc Gauthier - * Chris Zankel - * Kevin Chea - * - */ - -#define DEBUG 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern void do_syscall_trace(void); -typedef int (*syscall_t)(void *a0,...); -extern syscall_t sys_call_table[]; -extern unsigned char sys_narg_table[]; - -/* - * sys_pipe() is the normal C calling standard for creating a pipe. It's not - * the way unix traditional does this, though. - */ - -int sys_pipe(int __user *userfds) -{ - int fd[2]; - int error; - - error = do_pipe(fd); - if (!error) { - if (copy_to_user(userfds, fd, 2 * sizeof(int))) - error = -EFAULT; - } - return error; -} - -/* - * Common code for old and new mmaps. - */ -long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, - unsigned long flags, unsigned long fd, unsigned long pgoff) -{ - int error = -EBADF; - struct file * file = NULL; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) - goto out; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); -out: - return error; -} - -int sys_clone(struct pt_regs *regs) -{ - unsigned long clone_flags; - unsigned long newsp; - int __user *parent_tidptr, *child_tidptr; - clone_flags = regs->areg[4]; - newsp = regs->areg[3]; - parent_tidptr = (int __user *)regs->areg[5]; - child_tidptr = (int __user *)regs->areg[6]; - if (!newsp) - newsp = regs->areg[1]; - return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr); -} - -/* - * sys_execve() executes a new program. - */ - -int sys_execve(struct pt_regs *regs) -{ - int error; - char * filename; - - filename = getname((char *) (long)regs->areg[5]); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, (char **) (long)regs->areg[3], - (char **) (long)regs->areg[4], regs); - putname(filename); - -out: - return error; -} - -int sys_uname(struct old_utsname * name) -{ - if (name && !copy_to_user(name, utsname(), sizeof (*name))) - return 0; - return -EFAULT; -} - -/* - * Build the string table for the builtin "poor man's strace". - */ - -#if DEBUG -#define SYSCALL(fun, narg) #fun, -static char *sfnames[] = { -#include "syscalls.h" -}; -#undef SYS -#endif - -void system_call (struct pt_regs *regs) -{ - syscall_t syscall; - unsigned long parm0, parm1, parm2, parm3, parm4, parm5; - int nargs, res; - unsigned int syscallnr; - int ps; - -#if DEBUG - int i; - unsigned long parms[6]; - char *sysname; -#endif - - regs->syscall = regs->areg[2]; - - do_syscall_trace(); - - /* Have to load after syscall_trace because strace - * sometimes changes regs->syscall. - */ - syscallnr = regs->syscall; - - parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0; - - /* Restore interrupt level to syscall invoker's. - * If this were in assembly, we wouldn't disable - * interrupts in the first place: - */ - local_save_flags (ps); - local_irq_restore((ps & ~PS_INTLEVEL_MASK) | - (regs->ps & PS_INTLEVEL_MASK) ); - - if (syscallnr > __NR_Linux_syscalls) { - regs->areg[2] = -ENOSYS; - return; - } - - syscall = sys_call_table[syscallnr]; - nargs = sys_narg_table[syscallnr]; - - if (syscall == NULL) { - regs->areg[2] = -ENOSYS; - return; - } - - /* There shouldn't be more than six arguments in the table! */ - - if (nargs > 6) - panic("Internal error - too many syscall arguments (%d)!\n", - nargs); - - /* Linux takes system-call arguments in registers. The ABI - * and Xtensa software conventions require the system-call - * number in a2. If an argument exists in a2, we move it to - * the next available register. Note that for improved - * efficiency, we do NOT shift all parameters down one - * register to maintain the original order. - * - * At best case (zero arguments), we just write the syscall - * number to a2. At worst case (1 to 6 arguments), we move - * the argument in a2 to the next available register, then - * write the syscall number to a2. - * - * For clarity, the following truth table enumerates all - * possibilities. - * - * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5 - * --------- -------------- ---------------------------------- - * 0 a2 - * 1 a2 a3 - * 2 a2 a4, a3 - * 3 a2 a5, a3, a4 - * 4 a2 a6, a3, a4, a5 - * 5 a2 a7, a3, a4, a5, a6 - * 6 a2 a8, a3, a4, a5, a6, a7 - */ - if (nargs) { - parm0 = regs->areg[nargs+2]; - parm1 = regs->areg[3]; - parm2 = regs->areg[4]; - parm3 = regs->areg[5]; - parm4 = regs->areg[6]; - parm5 = regs->areg[7]; - } else /* nargs == 0 */ - parm0 = (unsigned long) regs; - -#if DEBUG - parms[0] = parm0; - parms[1] = parm1; - parms[2] = parm2; - parms[3] = parm3; - parms[4] = parm4; - parms[5] = parm5; - - sysname = sfnames[syscallnr]; - if (strncmp(sysname, "sys_", 4) == 0) - sysname = sysname + 4; - - printk("\017SYSCALL:I:%x:%d:%s %s(", regs->pc, current->pid, - current->comm, sysname); - for (i = 0; i < nargs; i++) - printk((i>0) ? ", %#lx" : "%#lx", parms[i]); - printk(")\n"); -#endif - - res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5); - -#if DEBUG - printk("\017SYSCALL:O:%d:%s %s(",current->pid, current->comm, sysname); - for (i = 0; i < nargs; i++) - printk((i>0) ? ", %#lx" : "%#lx", parms[i]); - if (res < 4096) - printk(") = %d\n", res); - else - printk(") = %#x\n", res); -#endif /* DEBUG */ - - regs->areg[2] = res; - do_syscall_trace(); -} - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ( - " mov a5, %2 \n" - " mov a4, %4 \n" - " mov a3, %3 \n" - " movi a2, %1 \n" - " syscall \n" - " mov %0, a2 \n" - : "=a" (__res) - : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp) - : "a2", "a3", "a4", "a5"); - return __res; -} diff --git a/arch/xtensa/kernel/syscalls.h b/arch/xtensa/kernel/syscalls.h deleted file mode 100644 index 216c10a3150..00000000000 --- a/arch/xtensa/kernel/syscalls.h +++ /dev/null @@ -1,247 +0,0 @@ -/* - * arch/xtensa/kernel/syscalls.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle - * Copyright (C) 2001 - 2005 Tensilica Inc. - * - * Changes by Joe Taylor - */ - -/* - * This file is being included twice - once to build a list of all - * syscalls and once to build a table of how many arguments each syscall - * accepts. Syscalls that receive a pointer to the saved registers are - * marked as having zero arguments. - * - * The binary compatibility calls are in a separate list. - * - * Entry '0' used to be system_call. It's removed to disable indirect - * system calls for now so user tasks can't recurse. See mips' - * sys_syscall for a comparable example. - */ - -SYSCALL(0, 0) /* 00 */ -SYSCALL(sys_exit, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_read, 3) -SYSCALL(sys_write, 3) -SYSCALL(sys_open, 3) /* 05 */ -SYSCALL(sys_close, 1) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_creat, 2) -SYSCALL(sys_link, 2) -SYSCALL(sys_unlink, 1) /* 10 */ -SYSCALL(sys_execve, 0) -SYSCALL(sys_chdir, 1) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_mknod, 3) -SYSCALL(sys_chmod, 2) /* 15 */ -SYSCALL(sys_lchown, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_newstat, 2) -SYSCALL(sys_lseek, 3) -SYSCALL(sys_getpid, 0) /* 20 */ -SYSCALL(sys_mount, 5) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_setuid, 1) -SYSCALL(sys_getuid, 0) -SYSCALL(sys_ni_syscall, 1) /* 25 */ -SYSCALL(sys_ptrace, 4) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_newfstat, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_utime, 2) /* 30 */ -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_access, 2) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_ni_syscall, 0) /* 35 */ -SYSCALL(sys_sync, 0) -SYSCALL(sys_kill, 2) -SYSCALL(sys_rename, 2) -SYSCALL(sys_mkdir, 2) -SYSCALL(sys_rmdir, 1) /* 40 */ -SYSCALL(sys_dup, 1) -SYSCALL(sys_pipe, 1) -SYSCALL(sys_times, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_brk, 1) /* 45 */ -SYSCALL(sys_setgid, 1) -SYSCALL(sys_getgid, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_geteuid, 0) -SYSCALL(sys_getegid, 0) /* 50 */ -SYSCALL(sys_acct, 1) -SYSCALL(sys_umount, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ioctl, 3) -SYSCALL(sys_fcntl, 3) /* 55 */ -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_setpgid, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_umask, 1) /* 60 */ -SYSCALL(sys_chroot, 1) -SYSCALL(sys_ustat, 2) -SYSCALL(sys_dup2, 2) -SYSCALL(sys_getppid, 0) -SYSCALL(sys_ni_syscall, 0) /* 65 */ -SYSCALL(sys_setsid, 0) -SYSCALL(sys_sigaction, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_setreuid, 2) /* 70 */ -SYSCALL(sys_setregid, 2) -SYSCALL(sys_sigsuspend, 0) -SYSCALL(sys_ni_syscall, 1) -SYSCALL(sys_sethostname, 2) -SYSCALL(sys_setrlimit, 2) /* 75 */ -SYSCALL(sys_getrlimit, 2) -SYSCALL(sys_getrusage, 2) -SYSCALL(sys_gettimeofday, 2) -SYSCALL(sys_settimeofday, 2) -SYSCALL(sys_getgroups, 2) /* 80 */ -SYSCALL(sys_setgroups, 2) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_symlink, 2) -SYSCALL(sys_newlstat, 2) -SYSCALL(sys_readlink, 3) /* 85 */ -SYSCALL(sys_uselib, 1) -SYSCALL(sys_swapon, 2) -SYSCALL(sys_reboot, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 6) /* 90 */ -SYSCALL(sys_munmap, 2) -SYSCALL(sys_truncate, 2) -SYSCALL(sys_ftruncate, 2) -SYSCALL(sys_fchmod, 2) -SYSCALL(sys_fchown, 3) /* 95 */ -SYSCALL(sys_getpriority, 2) -SYSCALL(sys_setpriority, 3) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_statfs, 2) -SYSCALL(sys_fstatfs, 2) /* 100 */ -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_syslog, 3) -SYSCALL(sys_setitimer, 3) -SYSCALL(sys_getitimer, 2) /* 105 */ -SYSCALL(sys_newstat, 2) -SYSCALL(sys_newlstat, 2) -SYSCALL(sys_newfstat, 2) -SYSCALL(sys_uname, 1) -SYSCALL(sys_ni_syscall, 0) /* 110 */ -SYSCALL(sys_vhangup, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_wait4, 4) -SYSCALL(sys_swapoff, 1) /* 115 */ -SYSCALL(sys_sysinfo, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_fsync, 1) -SYSCALL(sys_sigreturn, 0) -SYSCALL(sys_clone, 0) /* 120 */ -SYSCALL(sys_setdomainname, 2) -SYSCALL(sys_newuname, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_adjtimex, 1) -SYSCALL(sys_mprotect, 3) /* 125 */ -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 2) -SYSCALL(sys_init_module, 2) -SYSCALL(sys_delete_module, 1) -SYSCALL(sys_ni_syscall, 1) /* 130 */ -SYSCALL(sys_quotactl, 0) -SYSCALL(sys_getpgid, 1) -SYSCALL(sys_fchdir, 1) -SYSCALL(sys_bdflush, 2) -SYSCALL(sys_sysfs, 3) /* 135 */ -SYSCALL(sys_personality, 1) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_setfsuid, 1) -SYSCALL(sys_setfsgid, 1) -SYSCALL(sys_llseek, 5) /* 140 */ -SYSCALL(sys_getdents, 3) -SYSCALL(sys_select, 5) -SYSCALL(sys_flock, 2) -SYSCALL(sys_msync, 3) -SYSCALL(sys_readv, 3) /* 145 */ -SYSCALL(sys_writev, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 3) -SYSCALL(sys_ni_syscall, 4) /* handled in fast syscall handler. */ -SYSCALL(sys_ni_syscall, 0) /* 150 */ -SYSCALL(sys_getsid, 1) -SYSCALL(sys_fdatasync, 1) -SYSCALL(sys_sysctl, 1) -SYSCALL(sys_mlock, 2) -SYSCALL(sys_munlock, 2) /* 155 */ -SYSCALL(sys_mlockall, 1) -SYSCALL(sys_munlockall, 0) -SYSCALL(sys_sched_setparam,2) -SYSCALL(sys_sched_getparam,2) -SYSCALL(sys_sched_setscheduler,3) /* 160 */ -SYSCALL(sys_sched_getscheduler,1) -SYSCALL(sys_sched_yield,0) -SYSCALL(sys_sched_get_priority_max,1) -SYSCALL(sys_sched_get_priority_min,1) -SYSCALL(sys_sched_rr_get_interval,2) /* 165 */ -SYSCALL(sys_nanosleep,2) -SYSCALL(sys_mremap,4) -SYSCALL(sys_accept, 3) -SYSCALL(sys_bind, 3) -SYSCALL(sys_connect, 3) /* 170 */ -SYSCALL(sys_getpeername, 3) -SYSCALL(sys_getsockname, 3) -SYSCALL(sys_getsockopt, 5) -SYSCALL(sys_listen, 2) -SYSCALL(sys_recv, 4) /* 175 */ -SYSCALL(sys_recvfrom, 6) -SYSCALL(sys_recvmsg, 3) -SYSCALL(sys_send, 4) -SYSCALL(sys_sendmsg, 3) -SYSCALL(sys_sendto, 6) /* 180 */ -SYSCALL(sys_setsockopt, 5) -SYSCALL(sys_shutdown, 2) -SYSCALL(sys_socket, 3) -SYSCALL(sys_socketpair, 4) -SYSCALL(sys_setresuid, 3) /* 185 */ -SYSCALL(sys_getresuid, 3) -SYSCALL(sys_ni_syscall, 5) -SYSCALL(sys_poll, 3) -SYSCALL(sys_nfsservctl, 3) -SYSCALL(sys_setresgid, 3) /* 190 */ -SYSCALL(sys_getresgid, 3) -SYSCALL(sys_prctl, 5) -SYSCALL(sys_rt_sigreturn, 0) -SYSCALL(sys_rt_sigaction, 4) -SYSCALL(sys_rt_sigprocmask, 4) /* 195 */ -SYSCALL(sys_rt_sigpending, 2) -SYSCALL(sys_rt_sigtimedwait, 4) -SYSCALL(sys_rt_sigqueueinfo, 3) -SYSCALL(sys_rt_sigsuspend, 0) -SYSCALL(sys_pread64, 5) /* 200 */ -SYSCALL(sys_pwrite64, 5) -SYSCALL(sys_chown, 3) -SYSCALL(sys_getcwd, 2) -SYSCALL(sys_capget, 2) -SYSCALL(sys_capset, 2) /* 205 */ -SYSCALL(sys_sigaltstack, 0) -SYSCALL(sys_sendfile, 4) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_ni_syscall, 0) -SYSCALL(sys_mmap, 6) /* 210 */ -SYSCALL(sys_truncate64, 2) -SYSCALL(sys_ftruncate64, 2) -SYSCALL(sys_stat64, 2) -SYSCALL(sys_lstat64, 2) -SYSCALL(sys_fstat64, 2) /* 215 */ -SYSCALL(sys_pivot_root, 2) -SYSCALL(sys_mincore, 3) -SYSCALL(sys_madvise, 3) -SYSCALL(sys_getdents64, 3) -SYSCALL(sys_ni_syscall, 0) /* 220 */ -- cgit v1.2.3 From 1f29bcd739972f71f2fd5d5d265daf3e1208fa5e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sun, 10 Dec 2006 02:19:10 -0800 Subject: [PATCH] sysctl: remove unused "context" param Signed-off-by: Alexey Dobriyan Cc: Andi Kleen Cc: "David S. Miller" Cc: David Howells Cc: Ralf Baechle Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/pm.c | 6 +++--- arch/mips/lasat/sysctl.c | 17 ++++++++--------- arch/x86_64/kernel/vsyscall.c | 3 +-- 3 files changed, 12 insertions(+), 14 deletions(-) (limited to 'arch') diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c index c1d9fc8f1a8..ee677ced7b6 100644 --- a/arch/frv/kernel/pm.c +++ b/arch/frv/kernel/pm.c @@ -223,7 +223,7 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp, static int cmode_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; @@ -326,7 +326,7 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp, static int p0_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; @@ -370,7 +370,7 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp, static int cm_sysctl(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, void **context) + void __user *newval, size_t newlen) { if (oldval && oldlenp) { size_t oldlen; diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index da35d455549..12878359f2c 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c @@ -40,12 +40,12 @@ static DEFINE_MUTEX(lasat_info_mutex); /* Strategy function to write EEPROM after changing string entry */ int sysctl_lasatstring(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); r = sysctl_string(table, name, - nlen, oldval, oldlenp, newval, newlen, context); + nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -119,11 +119,11 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, /* Sysctl for setting the IP addresses */ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -139,14 +139,14 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen, /* Same for RTC */ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); rtctmp = ds1603_read(); if (rtctmp < 0) rtctmp = 0; - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; @@ -251,13 +251,12 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp, static int sysctl_lasat_eeprom_value(ctl_table *table, int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen, - void **context) + void *newval, size_t newlen) { int r; mutex_lock(&lasat_info_mutex); - r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen, context); + r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen); if (r < 0) { mutex_unlock(&lasat_info_mutex); return r; diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 4a673f5397a..2433d6fc68b 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -225,8 +225,7 @@ out: static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen, - void **context) + void __user *newval, size_t newlen) { return -ENOSYS; } -- cgit v1.2.3 From bbea9f69668a3d0cf9feba15a724cd02896f8675 Mon Sep 17 00:00:00 2001 From: Vadim Lobanov Date: Sun, 10 Dec 2006 02:21:12 -0800 Subject: [PATCH] fdtable: Make fdarray and fdsets equal in size Currently, each fdtable supports three dynamically-sized arrays of data: the fdarray and two fdsets. The code allows the number of fds supported by the fdarray (fdtable->max_fds) to differ from the number of fds supported by each of the fdsets (fdtable->max_fdset). In practice, it is wasteful for these two sizes to differ: whenever we hit a limit on the smaller-capacity structure, we will reallocate the entire fdtable and all the dynamic arrays within it, so any delta in the memory used by the larger-capacity structure will never be touched at all. Rather than hogging this excess, we shouldn't even allocate it in the first place, and keep the capacities of the fdarray and the fdsets equal. This patch removes fdtable->max_fdset. As an added bonus, most of the supporting code becomes simpler. Signed-off-by: Vadim Lobanov Cc: Christoph Hellwig Cc: Al Viro Cc: Dipankar Sarma Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/osf_sys.c | 6 +++--- arch/mips/kernel/kspd.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index fb804043b32..be133f1f75a 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c @@ -979,7 +979,7 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, long timeout; int ret = -EINVAL; struct fdtable *fdt; - int max_fdset; + int max_fds; timeout = MAX_SCHEDULE_TIMEOUT; if (tvp) { @@ -1003,9 +1003,9 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, rcu_read_lock(); fdt = files_fdtable(current->files); - max_fdset = fdt->max_fdset; + max_fds = fdt->max_fds; rcu_read_unlock(); - if (n < 0 || n > max_fdset) + if (n < 0 || n > max_fds) goto out_nofds; /* diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 2c82412b9ef..5929f883e46 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -301,7 +301,7 @@ static void sp_cleanup(void) for (;;) { unsigned long set; i = j * __NFDBITS; - if (i >= fdt->max_fdset || i >= fdt->max_fds) + if (i >= fdt->max_fds) break; set = fdt->open_fds->fds_bits[j++]; while (set) { -- cgit v1.2.3 From 41561f28e76a47dc6de0a954da85d0b5c42874eb Mon Sep 17 00:00:00 2001 From: Vitaly Wool Date: Sun, 10 Dec 2006 21:21:29 +0100 Subject: i2c: New Philips PNX bus driver New I2C bus driver for Philips ARM boards (Philips IP3204 I2C IP block). This I2C controller can be found on (at least) PNX010x, PNX52xx and PNX4008 Philips boards. Signed-off-by: Vitaly Wool Signed-off-by: Jean Delvare --- arch/arm/mach-pnx4008/Makefile | 2 +- arch/arm/mach-pnx4008/i2c.c | 167 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-pnx4008/i2c.c (limited to 'arch') diff --git a/arch/arm/mach-pnx4008/Makefile b/arch/arm/mach-pnx4008/Makefile index b457ca0a431..777564c90a1 100644 --- a/arch/arm/mach-pnx4008/Makefile +++ b/arch/arm/mach-pnx4008/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o +obj-y := core.o irq.o time.o clock.o gpio.o serial.o dma.o i2c.o obj-m := obj-n := obj- := diff --git a/arch/arm/mach-pnx4008/i2c.c b/arch/arm/mach-pnx4008/i2c.c new file mode 100644 index 00000000000..6f308827c4f --- /dev/null +++ b/arch/arm/mach-pnx4008/i2c.c @@ -0,0 +1,167 @@ +/* + * I2C initialization for PNX4008. + * + * Author: Vitaly Wool + * + * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int set_clock_run(struct platform_device *pdev) +{ + struct clk *clk; + char name[10]; + int retval = 0; + + snprintf(name, 10, "i2c%d_ck", pdev->id); + clk = clk_get(&pdev->dev, name); + if (!IS_ERR(clk)) { + clk_set_rate(clk, 1); + clk_put(clk); + } else + retval = -ENOENT; + + return retval; +} + +static int set_clock_stop(struct platform_device *pdev) +{ + struct clk *clk; + char name[10]; + int retval = 0; + + snprintf(name, 10, "i2c%d_ck", pdev->id); + clk = clk_get(&pdev->dev, name); + if (!IS_ERR(clk)) { + clk_set_rate(clk, 0); + clk_put(clk); + } else + retval = -ENOENT; + + return retval; +} + +static int i2c_pnx_suspend(struct platform_device *pdev, pm_message_t state) +{ + int retval = 0; +#ifdef CONFIG_PM + retval = set_clock_run(pdev); +#endif + return retval; +} + +static int i2c_pnx_resume(struct platform_device *pdev) +{ + int retval = 0; +#ifdef CONFIG_PM + retval = set_clock_run(pdev); +#endif + return retval; +} + +static u32 calculate_input_freq(struct platform_device *pdev) +{ + return HCLK_MHZ; +} + + +static struct i2c_pnx_algo_data pnx_algo_data0 = { + .base = PNX4008_I2C1_BASE, + .irq = I2C_1_INT, +}; + +static struct i2c_pnx_algo_data pnx_algo_data1 = { + .base = PNX4008_I2C2_BASE, + .irq = I2C_2_INT, +}; + +static struct i2c_pnx_algo_data pnx_algo_data2 = { + .base = (PNX4008_USB_CONFIG_BASE + 0x300), + .irq = USB_I2C_INT, +}; + +static struct i2c_adapter pnx_adapter0 = { + .name = I2C_CHIP_NAME "0", + .algo_data = &pnx_algo_data0, +}; +static struct i2c_adapter pnx_adapter1 = { + .name = I2C_CHIP_NAME "1", + .algo_data = &pnx_algo_data1, +}; + +static struct i2c_adapter pnx_adapter2 = { + .name = "USB-I2C", + .algo_data = &pnx_algo_data2, +}; + +static struct i2c_pnx_data i2c0_data = { + .suspend = i2c_pnx_suspend, + .resume = i2c_pnx_resume, + .calculate_input_freq = calculate_input_freq, + .set_clock_run = set_clock_run, + .set_clock_stop = set_clock_stop, + .adapter = &pnx_adapter0, +}; + +static struct i2c_pnx_data i2c1_data = { + .suspend = i2c_pnx_suspend, + .resume = i2c_pnx_resume, + .calculate_input_freq = calculate_input_freq, + .set_clock_run = set_clock_run, + .set_clock_stop = set_clock_stop, + .adapter = &pnx_adapter1, +}; + +static struct i2c_pnx_data i2c2_data = { + .suspend = i2c_pnx_suspend, + .resume = i2c_pnx_resume, + .calculate_input_freq = calculate_input_freq, + .set_clock_run = set_clock_run, + .set_clock_stop = set_clock_stop, + .adapter = &pnx_adapter2, +}; + +static struct platform_device i2c0_device = { + .name = "pnx-i2c", + .id = 0, + .dev = { + .platform_data = &i2c0_data, + }, +}; + +static struct platform_device i2c1_device = { + .name = "pnx-i2c", + .id = 1, + .dev = { + .platform_data = &i2c1_data, + }, +}; + +static struct platform_device i2c2_device = { + .name = "pnx-i2c", + .id = 2, + .dev = { + .platform_data = &i2c2_data, + }, +}; + +static struct platform_device *devices[] __initdata = { + &i2c0_device, + &i2c1_device, + &i2c2_device, +}; + +void __init pnx4008_register_i2c_devices(void) +{ + platform_add_devices(devices, ARRAY_SIZE(devices)); +} -- cgit v1.2.3 From 6b65cd742823f78a6538491982159098ab5fcae1 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 10 Dec 2006 21:21:32 +0100 Subject: i2c: New ARM Versatile/Realview bus driver Add support for the I2C bus found on the ARM Versatile and Realview platforms. The I2C bus has a RTC and optionally some EEPROMs attached. Signed-off-by: Russell King Signed-off-by: Jean Delvare --- arch/arm/mach-realview/core.c | 13 +++++++++++++ arch/arm/mach-realview/core.h | 1 + arch/arm/mach-realview/realview_eb.c | 1 + arch/arm/mach-versatile/core.c | 14 ++++++++++++++ 4 files changed, 29 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 68c67053f47..84d3fe76e94 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -141,6 +141,19 @@ struct platform_device realview_smc91x_device = { .resource = realview_smc91x_resources, }; +static struct resource realview_i2c_resource = { + .start = REALVIEW_I2C_BASE, + .end = REALVIEW_I2C_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +struct platform_device realview_i2c_device = { + .name = "versatile-i2c", + .id = -1, + .num_resources = 1, + .resource = &realview_i2c_resource, +}; + #define REALVIEW_SYSMCI (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_MCI_OFFSET) static unsigned int realview_mmc_status(struct device *dev) diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 93e86d9f439..2b53420f9c1 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h @@ -108,6 +108,7 @@ static struct amba_device name##_device = { \ extern struct platform_device realview_flash_device; extern struct platform_device realview_smc91x_device; +extern struct platform_device realview_i2c_device; extern struct mmc_platform_data realview_mmc0_plat_data; extern struct mmc_platform_data realview_mmc1_plat_data; extern struct clk realview_clcd_clk; diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 84a959530fb..9741b4d3c9c 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -155,6 +155,7 @@ static void __init realview_eb_init(void) platform_device_register(&realview_flash_device); platform_device_register(&realview_smc91x_device); + platform_device_register(&realview_i2c_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { struct amba_device *d = amba_devs[i]; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 57196947559..bf71507c76f 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -325,6 +325,19 @@ static struct platform_device smc91x_device = { .resource = smc91x_resources, }; +static struct resource versatile_i2c_resource = { + .start = VERSATILE_I2C_BASE, + .end = VERSATILE_I2C_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device versatile_i2c_device = { + .name = "versatile-i2c", + .id = -1, + .num_resources = 1, + .resource = &versatile_i2c_resource, +}; + #define VERSATILE_SYSMCI (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET) unsigned int mmc_status(struct device *dev) @@ -775,6 +788,7 @@ void __init versatile_init(void) clk_register(&versatile_clcd_clk); platform_device_register(&versatile_flash_device); + platform_device_register(&versatile_i2c_device); platform_device_register(&smc91x_device); for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -- cgit v1.2.3 From 86384d544157db23879064cde36061cdcafc6794 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 14:57:28 +0000 Subject: [MIPS] Discard .exit.text at linktime. This fixes fairly unobvious breakage of various drivers. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vmlinux.lds.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 79f0317d84a..2f4508f55fc 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -109,9 +109,6 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT - /* .exit.text is discarded at runtime, not link time, to deal with - references from .rodata */ - .exit.text : { *(.exit.text) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -139,6 +136,7 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { + *(.exit.text) *(.exit.data) *(.exitcall.exit) -- cgit v1.2.3 From ae32ffd65bbcc32795bb9b58ed12941efeb03dff Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 15:05:11 +0000 Subject: [MIPS] Export csum_partial_copy_nocheck. ibmtr.c and typhoon.c use it. Signed-off-by: Ralf Baechle --- arch/mips/lib/csum_partial_copy.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c index 1720f2ceeea..06771040a26 100644 --- a/arch/mips/lib/csum_partial_copy.c +++ b/arch/mips/lib/csum_partial_copy.c @@ -7,6 +7,7 @@ * Copyright (C) 1998, 1999 Ralf Baechle */ #include +#include #include #include #include @@ -29,6 +30,8 @@ __wsum csum_partial_copy_nocheck(const void *src, return sum; } +EXPORT_SYMBOL(csum_partial_copy_nocheck); + /* * Copy from userspace and compute checksum. If we catch an exception * then zero the rest of the buffer. -- cgit v1.2.3 From f8bf35a9145b0831d7d110402662d9cff2d90bd9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 15:09:38 +0000 Subject: [MIPS] Export pm_power_off This is required for ipmi_poweroff.c to work as a module. Signed-off-by: Ralf Baechle --- arch/mips/kernel/reset.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 621037db229..060563a712b 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c @@ -23,6 +23,8 @@ void (*_machine_restart)(char *command); void (*_machine_halt)(void); void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + void machine_restart(char *command) { if (_machine_restart) -- cgit v1.2.3 From 9202f32558601c2c99ddc438eb3218131d00d413 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 10 Dec 2006 18:43:59 +0000 Subject: [MIPS] Export local_flush_data_cache_page for sake of IDE. On a CPU with aliases the IDE core needs to flush caches in the special IDE variants of insw, insl etc. If IDE support is built as a module this will only work if local_flush_data_cache_page happens is exported as a module. As per policy export local_flush_data_cache_page as GPL symbol only. Signed-off-by: Ralf Baechle --- arch/mips/mm/cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index caf807ded51..1f954a238a6 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -32,6 +32,7 @@ void (*local_flush_data_cache_page)(void * addr); void (*flush_data_cache_page)(unsigned long addr); void (*flush_icache_all)(void); +EXPORT_SYMBOL_GPL(local_flush_data_cache_page); EXPORT_SYMBOL(flush_data_cache_page); #ifdef CONFIG_DMA_NONCOHERENT -- cgit v1.2.3 From 0204568a088fecd5478153504f9476ee2c46d5bf Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 29 Nov 2006 22:27:42 +1100 Subject: [POWERPC] Support ibm,dynamic-reconfiguration-memory nodes For PAPR partitions with large amounts of memory, the firmware has an alternative, more compact representation for the information about the memory in the partition and its NUMA associativity information. This adds the code to the kernel to parse this alternative representation. The other part of this patch is telling the firmware that we can handle the alternative representation. There is however a subtlety here, because the firmware will invoke a reboot if the memory representation we request is different from the representation that firmware is currently using. This is because firmware can't change the representation on the fly. Further, some firmware versions used on POWER5+ machines have a bug where this reboot leaves the machine with an altered value of load-base, which will prevent any kernel booting until it is reset to the normal value (0x4000). Because of this bug, we do NOT set fake_elf.rpanote.new_mem_def = 1, and thus we do not request the new representation on POWER5+ and earlier machines. We do request the new representation on POWER6, which uses the ibm,client-architecture-support call. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom.c | 55 ++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/prom_init.c | 2 +- arch/powerpc/mm/numa.c | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index c18dbe77fdc..1fc732a552d 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -804,6 +804,56 @@ static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp) return of_read_ulong(p, s); } +#ifdef CONFIG_PPC_PSERIES +/* + * Interpret the ibm,dynamic-memory property in the + * /ibm,dynamic-reconfiguration-memory node. + * This contains a list of memory blocks along with NUMA affinity + * information. + */ +static int __init early_init_dt_scan_drconf_memory(unsigned long node) +{ + cell_t *dm, *ls; + unsigned long l, n; + unsigned long base, size, lmb_size, flags; + + ls = (cell_t *)of_get_flat_dt_prop(node, "ibm,lmb-size", &l); + if (ls == NULL || l < dt_root_size_cells * sizeof(cell_t)) + return 0; + lmb_size = dt_mem_next_cell(dt_root_size_cells, &ls); + + dm = (cell_t *)of_get_flat_dt_prop(node, "ibm,dynamic-memory", &l); + if (dm == NULL || l < sizeof(cell_t)) + return 0; + + n = *dm++; /* number of entries */ + if (l < (n * (dt_root_addr_cells + 4) + 1) * sizeof(cell_t)) + return 0; + + for (; n != 0; --n) { + base = dt_mem_next_cell(dt_root_addr_cells, &dm); + flags = dm[3]; + /* skip DRC index, pad, assoc. list index, flags */ + dm += 4; + /* skip this block if the reserved bit is set in flags (0x80) + or if the block is not assigned to this partition (0x8) */ + if ((flags & 0x80) || !(flags & 0x8)) + continue; + size = lmb_size; + if (iommu_is_off) { + if (base >= 0x80000000ul) + continue; + if ((base + size) > 0x80000000ul) + size = 0x80000000ul - base; + } + lmb_add(base, size); + } + lmb_dump_all(); + return 0; +} +#else +#define early_init_dt_scan_drconf_memory(node) 0 +#endif /* CONFIG_PPC_PSERIES */ static int __init early_init_dt_scan_memory(unsigned long node, const char *uname, int depth, void *data) @@ -812,6 +862,11 @@ static int __init early_init_dt_scan_memory(unsigned long node, cell_t *reg, *endp; unsigned long l; + /* Look for the ibm,dynamic-reconfiguration-memory node */ + if (depth == 1 && + strcmp(uname, "ibm,dynamic-reconfiguration-memory") == 0) + return early_init_dt_scan_drconf_memory(node); + /* We are scanning "memory" nodes only */ if (type == NULL) { /* diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 46cf32670dd..520ef42f642 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -679,7 +679,7 @@ static unsigned char ibm_architecture_vec[] = { /* option vector 5: PAPR/OF options */ 3 - 2, /* length */ 0, /* don't ignore, don't halt */ - OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES, + OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY, }; /* Old method - ELF header with PT_NOTE sections */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 9da01dc8cfd..262790910ff 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -295,6 +295,63 @@ static unsigned long __init numa_enforce_memory_limit(unsigned long start, return lmb_end_of_DRAM() - start; } +/* + * Extract NUMA information from the ibm,dynamic-reconfiguration-memory + * node. This assumes n_mem_{addr,size}_cells have been set. + */ +static void __init parse_drconf_memory(struct device_node *memory) +{ + const unsigned int *lm, *dm, *aa; + unsigned int ls, ld, la; + unsigned int n, aam, aalen; + unsigned long lmb_size, size; + int nid, default_nid = 0; + unsigned int start, ai, flags; + + lm = get_property(memory, "ibm,lmb-size", &ls); + dm = get_property(memory, "ibm,dynamic-memory", &ld); + aa = get_property(memory, "ibm,associativity-lookup-arrays", &la); + if (!lm || !dm || !aa || + ls < sizeof(unsigned int) || ld < sizeof(unsigned int) || + la < 2 * sizeof(unsigned int)) + return; + + lmb_size = read_n_cells(n_mem_size_cells, &lm); + n = *dm++; /* number of LMBs */ + aam = *aa++; /* number of associativity lists */ + aalen = *aa++; /* length of each associativity list */ + if (ld < (n * (n_mem_addr_cells + 4) + 1) * sizeof(unsigned int) || + la < (aam * aalen + 2) * sizeof(unsigned int)) + return; + + for (; n != 0; --n) { + start = read_n_cells(n_mem_addr_cells, &dm); + ai = dm[2]; + flags = dm[3]; + dm += 4; + /* 0x80 == reserved, 0x8 = assigned to us */ + if ((flags & 0x80) || !(flags & 0x8)) + continue; + nid = default_nid; + /* flags & 0x40 means associativity index is invalid */ + if (min_common_depth > 0 && min_common_depth <= aalen && + (flags & 0x40) == 0 && ai < aam) { + /* this is like of_node_to_nid_single */ + nid = aa[ai * aalen + min_common_depth - 1]; + if (nid == 0xffff || nid >= MAX_NUMNODES) + nid = default_nid; + } + node_set_online(nid); + + size = numa_enforce_memory_limit(start, lmb_size); + if (!size) + continue; + + add_active_range(nid, start >> PAGE_SHIFT, + (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); + } +} + static int __init parse_numa_properties(void) { struct device_node *cpu = NULL; @@ -385,6 +442,14 @@ new_range: goto new_range; } + /* + * Now do the same thing for each LMB listed in the ibm,dynamic-memory + * property in the ibm,dynamic-reconfiguration-memory node. + */ + memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (memory) + parse_drconf_memory(memory); + return 0; } -- cgit v1.2.3 From 74e95d5de9d8eb243cda68b546bdb29f6ef0f01c Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Fri, 8 Dec 2006 18:27:47 -0800 Subject: [POWERPC] ps3: Add vuart support Adds support for the PS3 virtual UART (vuart). The vuart provides a bi-directional byte stream data link between logical partitions. This is needed for the ps3 graphics driver and the ps3 power control support to be able to communicate with the lv1 policy module. Signed-off-by: Geoff Levand Acked-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/powerpc/configs/ps3_defconfig | 1 + arch/powerpc/platforms/ps3/Kconfig | 11 +++++++++++ 2 files changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index f2d888e014a..70ed61337f5 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -157,6 +157,7 @@ CONFIG_SPU_BASE=y CONFIG_PS3_HTAB_SIZE=20 CONFIG_PS3_DYNAMIC_DMA=y CONFIG_PS3_USE_LPAR_ADDR=y +CONFIG_PS3_VUART=y # # Kernel options diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index 451bfcd5502..de52ec4e9e5 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -40,4 +40,15 @@ config PS3_USE_LPAR_ADDR If you have any doubt, choose the default y. +config PS3_VUART + depends on PPC_PS3 + bool "PS3 Virtual UART support" + default y + help + Include support for the PS3 Virtual UART. + + This support is required for several system services + including the System Manager and AV Settings. In + general, all users will say Y. + endmenu -- cgit v1.2.3 From dae4828d66ac6db353dee213c594257929a310cb Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 11 Dec 2006 14:09:07 +1100 Subject: [POWERPC] Fix irq routing on some 32-bit PowerMacs The changes to use pci_read_irq_line() broke interrupt parsing on some 32-bit powermacs (oops). The reason is a bit obscure. The code to parse interrupts happens earlier now, during pcibios_fixup() as the PCI bus is being probed. However, the current implementation pci_device_to_OF_node() for 32-bit powerpc relies, on machines like PowerMac which renumber PCI buses, on a table called pci_OF_bus_map containing a map of bus numbers between the kernel and the firmware which is setup only later. Thus, it fails to match the device node. In addition, some of Apple internal PCI devices lack a proper PCI_INTERRUPT_PIN, thus preventing the fallback mapping code to work. This patch fixes it by making pci_device_to_OF_node() 32-bit implementation use a different algorithm that works without using the pci_OF_bus_map thing (which I intend to deprecate anyway). It's a bit slower but that function isn't called in any hot path hopefully. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_32.c | 98 ++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 45 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index ab5887bff02..8336deafc62 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c @@ -736,25 +736,51 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* return NULL; } -static int -scan_OF_pci_childs_iterator(struct device_node* node, void* data) +static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, + unsigned int devfn) { - const unsigned int *reg; - u8* fdata = (u8*)data; - - reg = get_property(node, "reg", NULL); - if (reg && ((reg[0] >> 8) & 0xff) == fdata[1] - && ((reg[0] >> 16) & 0xff) == fdata[0]) - return 1; - return 0; + struct device_node *np = NULL; + const u32 *reg; + unsigned int psize; + + while ((np = of_get_next_child(parent, np)) != NULL) { + reg = get_property(np, "reg", &psize); + if (reg == NULL || psize < 4) + continue; + if (((reg[0] >> 8) & 0xff) == devfn) + return np; + } + return NULL; } -static struct device_node* -scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) + +static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus) { - u8 filter_data[2] = {bus, dev_fn}; + struct device_node *parent, *np; + + /* Are we a root bus ? */ + if (bus->self == NULL || bus->parent == NULL) { + struct pci_controller *hose = pci_bus_to_hose(bus->number); + if (hose == NULL) + return NULL; + return of_node_get(hose->arch_data); + } + + /* not a root bus, we need to get our parent */ + parent = scan_OF_for_pci_bus(bus->parent); + if (parent == NULL) + return NULL; + + /* now iterate for children for a match */ + np = scan_OF_for_pci_dev(parent, bus->self->devfn); + of_node_put(parent); - return scan_OF_pci_childs(node, scan_OF_pci_childs_iterator, filter_data); + /* sanity check */ + if (strcmp(np->type, "pci") != 0) + printk(KERN_WARNING "pci: wrong type \"%s\" for bridge %s\n", + np->type, np->full_name); + + return np; } /* @@ -763,43 +789,25 @@ scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) struct device_node * pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) { - struct pci_controller *hose; - struct device_node *node; - int busnr; + struct device_node *parent, *np; if (!have_of) return NULL; - - /* Lookup the hose */ - busnr = bus->number; - hose = pci_bus_to_hose(busnr); - if (!hose) - return NULL; - /* Check it has an OF node associated */ - node = (struct device_node *) hose->arch_data; - if (!node) + DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); + parent = scan_OF_for_pci_bus(bus); + if (parent == NULL) return NULL; - - /* Fixup bus number according to what OF think it is. */ -#ifdef CONFIG_PPC_PMAC - /* The G5 need a special case here. Basically, we don't remap all - * busses on it so we don't create the pci-OF-map. However, we do - * remap the AGP bus and so have to deal with it. A future better - * fix has to be done by making the remapping per-host and always - * filling the pci_to_OF map. --BenH + DBG(" parent is %s\n", parent ? parent->full_name : ""); + np = scan_OF_for_pci_dev(parent, devfn); + of_node_put(parent); + DBG(" result is %s\n", np ? np->full_name : ""); + + /* XXX most callers don't release the returned node + * mostly because ppc64 doesn't increase the refcount, + * we need to fix that. */ - if (machine_is(powermac) && busnr >= 0xf0) - busnr -= 0xf0; - else -#endif - if (pci_to_OF_bus_map) - busnr = pci_to_OF_bus_map[busnr]; - if (busnr == 0xff) - return NULL; - - /* Now, lookup childs of the hose */ - return scan_OF_childs_for_device(node->child, busnr, devfn); + return np; } EXPORT_SYMBOL(pci_busdev_to_OF_node); -- cgit v1.2.3 From 39f44be375d07a977ba68f900c87cea97cb05f4a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 11 Dec 2006 15:13:37 +1100 Subject: [POWERPC] Fix SPU coredump code for max_fdset removal Commit bbea9f69668a3d0cf9feba15a724cd02896f8675 removed the max_fdset element of struct fdtable. It appears that checking max_fds is sufficient now. Signed-off-by: Paul Mackerras --- arch/powerpc/platforms/cell/spufs/coredump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index 26945c491f6..725e1956115 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c @@ -147,7 +147,7 @@ static int spufs_arch_notes_size(void) struct fdtable *fdt = files_fdtable(current->files); int size = 0, fd; - for (fd = 0; fd < fdt->max_fdset && fd < fdt->max_fds; fd++) { + for (fd = 0; fd < fdt->max_fds; fd++) { if (FD_ISSET(fd, fdt->open_fds)) { struct file *file = fcheck(fd); -- cgit v1.2.3 From 4383162c8f2fa75d916c4901b0d1ebcac7aeaf74 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 11 Dec 2006 15:08:40 +1100 Subject: [POWERPC] Remove old dcr.S When I renamed dcr.S to dcr_low.S (and added dcr.c) it looks like the old dcr.S file didn't properly get removed. This fixes it. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/sysdev/dcr.S | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 arch/powerpc/sysdev/dcr.S (limited to 'arch') diff --git a/arch/powerpc/sysdev/dcr.S b/arch/powerpc/sysdev/dcr.S deleted file mode 100644 index 2078f39e2f1..00000000000 --- a/arch/powerpc/sysdev/dcr.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * "Indirect" DCR access - * - * Copyright (c) 2004 Eugene Surovegin - * - * 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. - */ - -#include -#include - -#define DCR_ACCESS_PROLOG(table) \ - rlwinm r3,r3,4,18,27; \ - lis r5,table@h; \ - ori r5,r5,table@l; \ - add r3,r3,r5; \ - mtctr r3; \ - bctr - -_GLOBAL(__mfdcr) - DCR_ACCESS_PROLOG(__mfdcr_table) - -_GLOBAL(__mtdcr) - DCR_ACCESS_PROLOG(__mtdcr_table) - -__mfdcr_table: - mfdcr r3,0; blr -__mtdcr_table: - mtdcr 0,r4; blr - -dcr = 1 - .rept 1023 - mfdcr r3,dcr; blr - mtdcr dcr,r4; blr - dcr = dcr + 1 - .endr -- cgit v1.2.3 From 45d8e7aaf47668550fdb6c2d3abbe42f48a76df2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Sun, 10 Dec 2006 23:15:47 -0600 Subject: [POWERPC] Only export __mtdcr/__mfdcr if CONFIG_PPC_DCR is set On 85xx we don't build in dcr support because the core doesn't implement the instructions. This caused problems when building an 85xx kernel. Additionally made it so we only build __mtdcr/__mfdcr if we are CONFIG_PPC_DCR_NATIVE. The 85xx build issue wasPointed out by Dai Haruki. Signed-off-by: Kumar Gala --- arch/powerpc/kernel/ppc_ksyms.c | 2 +- arch/powerpc/sysdev/Makefile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 9179f0739ea..95776b6af4e 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -208,7 +208,7 @@ EXPORT_SYMBOL(mmu_hash_lock); /* For MOL */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); #endif /* CONFIG_PPC_STD_MMU_32 */ -#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) +#ifdef CONFIG_PPC_DCR_NATIVE EXPORT_SYMBOL(__mtdcr); EXPORT_SYMBOL(__mfdcr); #endif diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 6cc34597a62..04d4917eb30 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -5,7 +5,8 @@ endif obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o obj-$(CONFIG_PPC_MPC106) += grackle.o -obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o +obj-$(CONFIG_PPC_DCR) += dcr.o +obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o -- cgit v1.2.3 From 73c9ceab40b1269d6195e556773167c078ac8311 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 8 Dec 2006 03:30:41 -0800 Subject: [POWERPC] Generic BUG for powerpc This makes powerpc use the generic BUG machinery. The biggest reports the function name, since it is redundant with kallsyms, and not needed in general. There is an overall reduction of code, since module_32/64 duplicated several functions. Unfortunately there's no way to tell gcc that BUG won't return, so the BUG macro includes a goto loop. This will generate a real jmp instruction, which is never used. [akpm@osdl.org: build fix] [paulus@samba.org: remove infinite loop in BUG_ON] Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Hugh Dickens Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 5 ++++ arch/powerpc/kernel/module_32.c | 23 +++++------------ arch/powerpc/kernel/module_64.c | 23 +++++------------ arch/powerpc/kernel/traps.c | 54 +++++---------------------------------- arch/powerpc/kernel/vmlinux.lds.S | 6 +---- arch/powerpc/xmon/xmon.c | 10 ++++---- 6 files changed, 29 insertions(+), 92 deletions(-) (limited to 'arch') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index a35212b7346..f81d9f6f19f 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -99,6 +99,11 @@ config AUDIT_ARCH bool default y +config GENERIC_BUG + bool + default y + depends on BUG + config DEFAULT_UIMAGE bool help diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index e2c3c6a85f3..8339fd609de 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "setup.h" @@ -290,23 +291,11 @@ int module_finalize(const Elf_Ehdr *hdr, struct module *me) { const Elf_Shdr *sect; + int err; - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); + err = module_bug_finalize(hdr, sechdrs, me); + if (err) /* never true, currently */ + return err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); @@ -320,7 +309,7 @@ int module_finalize(const Elf_Ehdr *hdr, void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); + module_bug_cleanup(mod); } struct bug_entry *module_find_bug(unsigned long bugaddr) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 8dd1f0aae5d..75c7c4f1928 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -439,23 +440,11 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; + int err; - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - sect = find_section(hdr, sechdrs, "__bug_table"); - if (sect != NULL) { - me->arch.bug_table = (void *) sect->sh_addr; - me->arch.num_bugs = sect->sh_size / sizeof(struct bug_entry); - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); + err = module_bug_finalize(hdr, sechdrs, me); + if (err) + return err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, "__ftr_fixup"); @@ -475,7 +464,7 @@ int module_finalize(const Elf_Ehdr *hdr, void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); + module_bug_cleanup(mod); } struct bug_entry *module_find_bug(unsigned long bugaddr) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index fde820e52d0..535f5066564 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -727,54 +728,9 @@ static int emulate_instruction(struct pt_regs *regs) return -EINVAL; } -/* - * Look through the list of trap instructions that are used for BUG(), - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know - * that the exception was caused by a trap instruction of some kind. - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 - * otherwise. - */ -extern struct bug_entry __start___bug_table[], __stop___bug_table[]; - -#ifndef CONFIG_MODULES -#define module_find_bug(x) NULL -#endif - -struct bug_entry *find_bug(unsigned long bugaddr) +int is_valid_bugaddr(unsigned long addr) { - struct bug_entry *bug; - - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) - if (bugaddr == bug->bug_addr) - return bug; - return module_find_bug(bugaddr); -} - -static int check_bug_trap(struct pt_regs *regs) -{ - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ - printk(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - dump_stack(); - return 1; - } - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - - return 0; + return is_kernel_addr(addr); } void __kprobes program_check_exception(struct pt_regs *regs) @@ -810,7 +766,9 @@ void __kprobes program_check_exception(struct pt_regs *regs) return; if (debugger_bpt(regs)) return; - if (check_bug_trap(regs)) { + + if (!(regs->msr & MSR_PR) && /* not user-mode */ + report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 04b98671a06..04b8e71bf5b 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -62,11 +62,7 @@ SECTIONS __stop___ex_table = .; } - __bug_table : { - __start___bug_table = .; - *(__bug_table) - __stop___bug_table = .; - } + BUG_TABLE /* * Init sections discarded at runtime diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a34ed49e035..77540a2f770 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -1346,7 +1346,7 @@ static void backtrace(struct pt_regs *excp) static void print_bug_trap(struct pt_regs *regs) { - struct bug_entry *bug; + const struct bug_entry *bug; unsigned long addr; if (regs->msr & MSR_PR) @@ -1357,11 +1357,11 @@ static void print_bug_trap(struct pt_regs *regs) bug = find_bug(regs->nip); if (bug == NULL) return; - if (bug->line & BUG_WARNING_TRAP) + if (is_warning_bug(bug)) return; - printf("kernel BUG in %s at %s:%d!\n", - bug->function, bug->file, (unsigned int)bug->line); + printf("kernel BUG at %s:%u!\n", + bug->file, bug->line); } void excprint(struct pt_regs *fp) -- cgit v1.2.3 From e45116b8d71ece9dbe41b114368ff7aebe3ae41a Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 11 Dec 2006 20:14:15 +0100 Subject: [PATCH] Fix typo in 'EXPERIMENTAL' in CC_STACKPROTECTOR on x86_64 Fix typo in 'EXPERIMENTAL' in config CC_STACKPROTECTOR in arch/x86_64/Kconfig. Signed-off-by: Brice Goglin Signed-off-by: Linus Torvalds --- arch/x86_64/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 3ac581d1720..d4275537b25 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -584,7 +584,7 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)" + bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" depends on EXPERIMENTAL help This option turns on the -fstack-protector GCC feature. This -- cgit v1.2.3 From fce3a24e7087ba1f56eea5ec14fec592e677e672 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 7 Dec 2006 13:20:58 +0900 Subject: sh: push-switch fixups for work_struct API damage. INIT_WORK() dropped the data arg, so now we have to stash an extra pointer and backpedal instead. Signed-off-by: Paul Mundt --- arch/sh/drivers/push-switch.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index f2b9157c314..b3d20c0e021 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -14,7 +14,7 @@ #include #define DRV_NAME "push-switch" -#define DRV_VERSION "0.1.0" +#define DRV_VERSION "0.1.1" static ssize_t switch_show(struct device *dev, struct device_attribute *attr, @@ -32,10 +32,10 @@ static void switch_timer(unsigned long data) schedule_work(&psw->work); } -static void switch_work_handler(void *data) +static void switch_work_handler(struct work_struct *work) { - struct platform_device *pdev = data; - struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch *psw = container_of(work, struct push_switch, work); + struct platform_device *pdev = psw->pdev; psw->state = 0; @@ -76,12 +76,15 @@ static int switch_drv_probe(struct platform_device *pdev) } } - INIT_WORK(&psw->work, switch_work_handler, pdev); + INIT_WORK(&psw->work, switch_work_handler); init_timer(&psw->debounce); psw->debounce.function = switch_timer; psw->debounce.data = (unsigned long)psw; + /* Workqueue API brain-damage */ + psw->pdev = pdev; + platform_set_drvdata(pdev, psw); return 0; -- cgit v1.2.3 From cf00e20444fc39fe37691ca32919061bf65527b0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 7 Dec 2006 17:00:32 +0900 Subject: sh: Add uImage and S-rec generation support. Add a couple of new targets, both for uImage and S-rec generation. Signed-off-by: Paul Mundt --- arch/sh/Makefile | 7 +++++-- arch/sh/boot/Makefile | 40 ++++++++++++++++++++++++++++++++++++++-- arch/sh/boot/compressed/Makefile | 6 ------ 3 files changed, 43 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/sh/Makefile b/arch/sh/Makefile index d10bba5e107..c1dbef21263 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -179,7 +179,7 @@ maketools: include/linux/version.h FORCE all: zImage -zImage: vmlinux +zImage uImage uImage.srec vmlinux.srec: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ compressed: zImage @@ -190,5 +190,8 @@ archclean: CLEAN_FILES += include/asm-sh/machtypes.h define archhelp - @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)' + @echo '* zImage - Compressed kernel image' + @echo ' vmlinux.srec - Create an ELF S-record' + @echo ' uImage - Create a bootable image for U-Boot' + @echo ' uImage.srec - Create an S-record for U-Boot' endef diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile index 60797b31089..11dc272c618 100644 --- a/arch/sh/boot/Makefile +++ b/arch/sh/boot/Makefile @@ -8,13 +8,49 @@ # Copyright (C) 1999 Stuart Menefy # -targets := zImage +MKIMAGE := $(srctree)/scripts/mkuboot.sh + +# +# Assign safe dummy values if these variables are not defined, +# in order to suppress error message. +# +CONFIG_PAGE_OFFSET ?= 0x80000000 +CONFIG_MEMORY_START ?= 0x0c000000 +CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 +CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 + +export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ + CONFIG_ZERO_PAGE_OFFSET + +targets := zImage vmlinux.srec uImage uImage.srec subdir- := compressed $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) - @echo 'Kernel: $@ is ready' + @echo ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ +KERNEL_LOAD := $(shell printf "0x%8x" $$[$(CONFIG_PAGE_OFFSET) + \ + $(CONFIG_MEMORY_START) + \ + $(CONFIG_ZERO_PAGE_OFFSET)+0x1000]) + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sh -O linux -T kernel \ + -C gzip -a $(KERNEL_LOAD) -e $(KERNEL_LOAD) \ + -n 'Linux-$(KERNELRELEASE)' -d $< $@ + +$(obj)/uImage: $(obj)/zImage FORCE + $(call if_changed,uimage) + @echo ' Image $@ is ready' + +OBJCOPYFLAGS_vmlinux.srec := -I binary -O srec +$(obj)/vmlinux.srec: $(obj)/compressed/vmlinux + $(call if_changed,objcopy) + +OBJCOPYFLAGS_uImage.srec := -I binary -O srec +$(obj)/uImage.srec: $(obj)/uImage + $(call if_changed,objcopy) + +clean-files += uImage uImage.srec vmlinux.srec diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile index e5f44379007..d9512416f88 100644 --- a/arch/sh/boot/compressed/Makefile +++ b/arch/sh/boot/compressed/Makefile @@ -15,13 +15,7 @@ endif # # IMAGE_OFFSET is the load offset of the compression loader -# Assign dummy values if these 2 variables are not defined, -# in order to suppress error message. # -CONFIG_PAGE_OFFSET ?= 0x80000000 -CONFIG_MEMORY_START ?= 0x0c000000 -CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 - IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET) + \ $(CONFIG_MEMORY_START) + \ $(CONFIG_BOOT_LINK_OFFSET)]) -- cgit v1.2.3 From d79b8741f212a9da38f1648d9242041db074216f Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Thu, 7 Dec 2006 17:09:46 +0900 Subject: sh: SH-2 defconfig updates. This adds a new defconfig for SE7619 and updates SE7206. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/configs/se7206_defconfig | 142 ++++++-- arch/sh/configs/se7619_defconfig | 744 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 847 insertions(+), 39 deletions(-) create mode 100644 arch/sh/configs/se7619_defconfig (limited to 'arch') diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index 36cec0b6e7c..87ab9080fd1 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.19-rc4 -# Sun Nov 5 16:20:10 2006 +# Linux kernel version: 2.6.19 +# Wed Dec 6 14:40:15 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -11,6 +11,8 @@ CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y # CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -34,24 +36,23 @@ CONFIG_LOCALVERSION="" # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y -CONFIG_UID16=y +# CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KALLSYMS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_VM_EVENT_COUNTERS is not set CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 +CONFIG_BASE_SMALL=1 # CONFIG_SLOB is not set # @@ -160,6 +161,7 @@ CONFIG_CPU_SUBTYPE_SH7206=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -172,7 +174,10 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_PAGE_OFFSET=0x00000000 CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x02000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -194,6 +199,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # # CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_CPU_BIG_ENDIAN=y # CONFIG_SH_FPU is not set # CONFIG_SH_FPU_EMU is not set # CONFIG_SH_DSP is not set @@ -203,6 +209,8 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_SH_CMT=y # CONFIG_SH_MTU2 is not set +CONFIG_SH_TIMER_IRQ=140 +# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 CONFIG_SH_CLK_MD=6 @@ -221,6 +229,11 @@ CONFIG_SH_CLK_MD=6 # # CONFIG_HD6446X_SERIES is not set +# +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + # # Kernel features # @@ -279,9 +292,6 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set # CONFIG_UNIX is not set -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set @@ -297,9 +307,9 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_XFRM_MODE_BEET=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y @@ -371,7 +381,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 @@ -422,7 +432,7 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_START=0x20000000 -CONFIG_MTD_PHYSMAP_LEN=0x1000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_MTD_SOLUTIONENGINE is not set # CONFIG_MTD_UCLINUX is not set @@ -468,10 +478,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +# CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -519,7 +526,50 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Network device support # -# CONFIG_NETDEVICES is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC is not set +CONFIG_SMC91X=y + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -536,7 +586,26 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports @@ -564,8 +633,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_UNIX98_PTYS is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 +# CONFIG_LEGACY_PTYS is not set # # IPMI @@ -576,7 +644,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -610,12 +678,8 @@ CONFIG_HW_RANDOM=y # # Hardware Monitoring support # -CONFIG_HWMON=y +# CONFIG_HWMON is not set # CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_HWMON_DEBUG_CHIP is not set # # Multimedia devices @@ -630,7 +694,7 @@ CONFIG_HWMON=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_EDID is not set # CONFIG_FB is not set # @@ -701,8 +765,7 @@ CONFIG_FIRMWARE_EDID=y # # File systems # -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set @@ -755,7 +818,7 @@ CONFIG_RAMFS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -793,8 +856,9 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_MUST_CHECK=y +# CONFIG_ENABLE_MUST_CHECK is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set @@ -819,7 +883,7 @@ CONFIG_LOG_BUF_SHIFT=14 # # Library routines # -CONFIG_CRC_CCITT=y +# CONFIG_CRC_CCITT is not set # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set diff --git a/arch/sh/configs/se7619_defconfig b/arch/sh/configs/se7619_defconfig new file mode 100644 index 00000000000..20ac7f4c53f --- /dev/null +++ b/arch/sh/configs/se7619_defconfig @@ -0,0 +1,744 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.19 +# Wed Dec 6 16:35:36 2006 +# +CONFIG_SUPERH=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_UTS_NS is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SYSCTL=y +CONFIG_EMBEDDED=y +# CONFIG_UID16 is not set +# CONFIG_SYSCTL_SYSCALL is not set +# CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +# CONFIG_BASE_FULL is not set +# CONFIG_FUTEX is not set +# CONFIG_EPOLL is not set +CONFIG_SLAB=y +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_BLOCK=y +# CONFIG_LBD is not set +# CONFIG_LSF is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_7343_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_7710VOIPGW is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_R7780RP is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +# CONFIG_SH_TITAN is not set +# CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +CONFIG_SH_7619_SOLUTION_ENGINE=y +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH2=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set +CONFIG_CPU_SUBTYPE_SH7619=y + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7706 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set +# CONFIG_CPU_SUBTYPE_SH7710 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +# CONFIG_CPU_SUBTYPE_SH7751 is not set +# CONFIG_CPU_SUBTYPE_SH7751R is not set +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set + +# +# SH4AL-DSP Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7343 is not set + +# +# Memory management options +# +CONFIG_PAGE_OFFSET=0x00000000 +CONFIG_MEMORY_START=0x0c000000 +CONFIG_MEMORY_SIZE=0x04000000 +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +CONFIG_SH_WRITETHROUGH=y +# CONFIG_SH_OCRAM is not set + +# +# Processor features +# +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_SH_FPU is not set +# CONFIG_SH_FPU_EMU is not set +# CONFIG_SH_DSP is not set + +# +# Timer support +# +CONFIG_SH_CMT=y +CONFIG_SH_TIMER_IRQ=86 +# CONFIG_NO_IDLE_HZ is not set +CONFIG_SH_PCLK_FREQ=31250000 +CONFIG_SH_CLK_MD=5 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +# CONFIG_SH_DMA is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + +# +# Kernel features +# +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_KEXEC is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x00800000 +# CONFIG_UBC_WAKEUP is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Bus options +# +# CONFIG_PCI is not set + +# +# PCCARD (PCMCIA/CardBus) support +# + +# +# PCI Hotplug Support +# + +# +# Executable file formats +# +CONFIG_BINFMT_FLAT=y +CONFIG_BINFMT_ZFLAT=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set + +# +# Networking +# +# CONFIG_NET is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +# CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_CONCAT=y +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xa0000000 +CONFIG_MTD_PHYSMAP_LEN=0x01000000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_SOLUTIONENGINE is not set +# CONFIG_MTD_UCLINUX is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# Misc devices +# +# CONFIG_TIFM_CORE is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# +# CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# ISDN subsystem +# + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_NR_UARTS=3 +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_UNIX98_PTYS is not set +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# + +# +# Graphics support +# +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# File systems +# +# CONFIG_EXT2_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_EXT4DEV_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y +# CONFIG_INOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +# CONFIG_PRINTK_TIME is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_HEADERS_CHECK is not set +# CONFIG_SH_STANDARD_BIOS is not set +# CONFIG_EARLY_SCIF_CONSOLE is not set +# CONFIG_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y -- cgit v1.2.3 From 417d6b9edb5958c2cc76e8ef701ebe09a3152deb Mon Sep 17 00:00:00 2001 From: Jamie Lenehan Date: Thu, 7 Dec 2006 17:23:07 +0900 Subject: sh: register rtc resources for sh775x. Register the RTC resources for the sh775x subtype so that the new generic RTC support in drivers/rtc/rtc-sh.c will work. Signed-off-by: Jamie Lenehan Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/setup-sh7750.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index bbcb06f18b0..cbac27634c0 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -14,6 +14,36 @@ #include #include +static struct resource rtc_resources[] = { + [0] = { + .start = 0xffc80000, + .end = 0xffc80000 + 0x58 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 20, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, @@ -39,6 +69,7 @@ static struct platform_device sci_device = { }; static struct platform_device *sh7750_devices[] __initdata = { + &rtc_device, &sci_device, }; -- cgit v1.2.3 From b6250e37292b9679b82a3edc28f330a32eed9ae4 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 7 Dec 2006 17:27:18 +0900 Subject: sh: landisk board build fixes. Get the landisk board building again.. Signed-off-by: Paul Mundt --- arch/sh/boards/landisk/irq.c | 4 +- arch/sh/configs/landisk_defconfig | 85 +++++++++++++++++++++++++-------------- 2 files changed, 56 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/landisk/irq.c b/arch/sh/boards/landisk/irq.c index 8f2e1c68b90..3eba6d086d7 100644 --- a/arch/sh/boards/landisk/irq.c +++ b/arch/sh/boards/landisk/irq.c @@ -16,8 +16,8 @@ */ #include #include -#include -#include +#include +#include #include static void enable_landisk_irq(unsigned int irq); diff --git a/arch/sh/configs/landisk_defconfig b/arch/sh/configs/landisk_defconfig index 238c0f10990..e7f8ddb0ada 100644 --- a/arch/sh/configs/landisk_defconfig +++ b/arch/sh/configs/landisk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Tue Oct 3 11:14:13 2006 +# Linux kernel version: 2.6.19 +# Thu Dec 7 17:13:04 2006 # CONFIG_SUPERH=y CONFIG_RWSEM_GENERIC_SPINLOCK=y @@ -10,6 +10,9 @@ CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_CALIBRATE_DELAY=y +# CONFIG_GENERIC_TIME is not set +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -33,6 +36,7 @@ CONFIG_SYSVIPC=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y @@ -114,6 +118,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" CONFIG_SH_LANDISK=y # CONFIG_SH_TITAN is not set # CONFIG_SH_SHMIN is not set +# CONFIG_SH_7206_SOLUTION_ENGINE is not set +# CONFIG_SH_7619_SOLUTION_ENGINE is not set # CONFIG_SH_UNKNOWN is not set # @@ -125,6 +131,12 @@ CONFIG_CPU_SH4=y # SH-2 Processor Support # # CONFIG_CPU_SUBTYPE_SH7604 is not set +# CONFIG_CPU_SUBTYPE_SH7619 is not set + +# +# SH-2A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7206 is not set # # SH-3 Processor Support @@ -160,6 +172,7 @@ CONFIG_CPU_SUBTYPE_SH7751R=y # # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set +# CONFIG_CPU_SUBTYPE_SH7785 is not set # # SH4AL-DSP Processor Support @@ -175,6 +188,9 @@ CONFIG_PAGE_OFFSET=0x80000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 CONFIG_VSYSCALL=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set @@ -196,16 +212,21 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 # Processor features # CONFIG_CPU_LITTLE_ENDIAN=y +# CONFIG_CPU_BIG_ENDIAN is not set CONFIG_SH_FPU=y # CONFIG_SH_DSP is not set # CONFIG_SH_STORE_QUEUES is not set CONFIG_CPU_HAS_INTEVT=y +CONFIG_CPU_HAS_IPR_IRQ=y CONFIG_CPU_HAS_SR_RB=y +CONFIG_CPU_HAS_PTEA=y # # Timer support # CONFIG_SH_TMU=y +CONFIG_SH_TIMER_IRQ=16 +# CONFIG_NO_IDLE_HZ is not set CONFIG_SH_PCLK_FREQ=33333333 # @@ -216,9 +237,7 @@ CONFIG_SH_PCLK_FREQ=33333333 # # DMA support # -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=4 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set +# CONFIG_SH_DMA is not set # # Companion Chips @@ -226,6 +245,11 @@ CONFIG_NR_ONCHIP_DMA_CHANNELS=4 # CONFIG_HD6446X_SERIES is not set CONFIG_HEARTBEAT=y +# +# Additional SuperH Device Drivers +# +# CONFIG_PUSH_SWITCH is not set + # # Kernel features # @@ -340,11 +364,13 @@ CONFIG_IP_PNP=y # CONFIG_INET_TUNNEL is not set CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set # # IP: Virtual Server Configuration @@ -361,24 +387,12 @@ CONFIG_NETFILTER=y # Core Netfilter Configuration # # CONFIG_NETFILTER_NETLINK is not set +# CONFIG_NF_CONNTRACK_ENABLED is not set # CONFIG_NETFILTER_XTABLES is not set # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -# CONFIG_IP_NF_NETBIOS_NS is not set -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -# CONFIG_IP_NF_PPTP is not set -# CONFIG_IP_NF_H323 is not set -# CONFIG_IP_NF_SIP is not set CONFIG_IP_NF_QUEUE=m # @@ -476,6 +490,12 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set +# +# Misc devices +# +# CONFIG_SGI_IOC4 is not set +# CONFIG_TIFM_CORE is not set + # # ATA/ATAPI/MFM/RLL support # @@ -519,6 +539,7 @@ CONFIG_BLK_DEV_AEC62XX=y # CONFIG_BLK_DEV_CS5530 is not set # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set +# CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set @@ -542,6 +563,7 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y +# CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -561,6 +583,7 @@ CONFIG_BLK_DEV_SD=y CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports @@ -602,12 +625,12 @@ CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_DC395x is not set @@ -615,6 +638,7 @@ CONFIG_SCSI_MULTI_LUN=y # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_SRP is not set # # PCMCIA SCSI adapter support @@ -757,6 +781,7 @@ CONFIG_8139CP=y # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set +# CONFIG_NETXEN_NIC is not set # # Token Ring devices @@ -871,10 +896,6 @@ CONFIG_HW_RANDOM=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# # CONFIG_DRM is not set # @@ -889,7 +910,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -905,6 +925,7 @@ CONFIG_HW_RANDOM=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support @@ -916,10 +937,6 @@ CONFIG_HWMON=y # CONFIG_SENSORS_VT1211 is not set # CONFIG_HWMON_DEBUG_CHIP is not set -# -# Misc devices -# - # # Multimedia devices # @@ -1037,6 +1054,7 @@ CONFIG_USB=y CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1106,7 +1124,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set -# CONFIG_USB_TRANCEVIBRATOR is not set # # USB Imaging devices @@ -1121,6 +1138,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_KAWETH is not set CONFIG_USB_PEGASUS=m CONFIG_USB_RTL8150=m +# CONFIG_USB_USBNET_MII is not set # CONFIG_USB_USBNET is not set CONFIG_USB_MON=y @@ -1156,6 +1174,7 @@ CONFIG_USB_SERIAL_FTDI_SIO=m # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_MOS7720 is not set # CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_NAVMAN is not set CONFIG_USB_SERIAL_PL2303=m @@ -1167,6 +1186,7 @@ CONFIG_USB_SERIAL_PL2303=m # CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set +# CONFIG_USB_SERIAL_DEBUG is not set # # USB Miscellaneous drivers @@ -1188,6 +1208,7 @@ CONFIG_USB_EMI26=m CONFIG_USB_SISUSBVGA=m CONFIG_USB_SISUSBVGA_CON=y # CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_TEST is not set # @@ -1254,6 +1275,7 @@ CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set +# CONFIG_EXT4DEV_FS is not set CONFIG_JBD=y # CONFIG_JBD_DEBUG is not set CONFIG_FS_MBCACHE=y @@ -1264,6 +1286,7 @@ CONFIG_REISERFS_FS=y # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y @@ -1414,6 +1437,7 @@ CONFIG_NLS_CODEPAGE_932=y # # Kernel hacking # +CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set @@ -1422,6 +1446,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_DEBUG_FS is not set +# CONFIG_HEADERS_CHECK is not set CONFIG_SH_STANDARD_BIOS=y # CONFIG_EARLY_SCIF_CONSOLE is not set # CONFIG_EARLY_PRINTK is not set @@ -1445,6 +1470,4 @@ CONFIG_SH_STANDARD_BIOS=y # CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m CONFIG_PLIST=y -- cgit v1.2.3 From ff4e2ca7c64cd87ec72fa0d238c1b34493133910 Mon Sep 17 00:00:00 2001 From: Stuart Menefy Date: Thu, 7 Dec 2006 17:48:52 +0900 Subject: sh: gcc4 symbol export fixups. gcc 4 for sh changes the names of some compiler intrinsic functions and adds some additional ones. This patch adds the new ones, and fixes up various module symbol resolution issues. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt --- arch/sh/kernel/sh_ksyms.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c index ceee7914340..e6106239a0f 100644 --- a/arch/sh/kernel/sh_ksyms.c +++ b/arch/sh/kernel/sh_ksyms.c @@ -70,13 +70,26 @@ DECLARE_EXPORT(__sdivsi3); DECLARE_EXPORT(__ashrdi3); DECLARE_EXPORT(__ashldi3); DECLARE_EXPORT(__lshrdi3); -DECLARE_EXPORT(__movstr); DECLARE_EXPORT(__movstrSI16); +#if __GNUC__ == 4 +DECLARE_EXPORT(__movmem); +#else +DECLARE_EXPORT(__movstr); +#endif #ifdef CONFIG_CPU_SH4 +#if __GNUC__ == 4 +DECLARE_EXPORT(__movmem_i4_even); +DECLARE_EXPORT(__movmem_i4_odd); +DECLARE_EXPORT(__movmemSI12_i4); +DECLARE_EXPORT(__sdivsi3_i4i); +DECLARE_EXPORT(__udiv_qrnnd_16); +DECLARE_EXPORT(__udivsi3_i4i); +#else /* GCC 3.x */ DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); DECLARE_EXPORT(__movstrSI12_i4); +#endif /* __GNUC__ == 4 */ #endif #if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) -- cgit v1.2.3 From 780a1568886a2f5df9bf11b72ba0624c80db5b3b Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Thu, 7 Dec 2006 18:01:23 +0900 Subject: sh: IPR IRQ updates for SH7619/SH7206. This updates the SH7619 and SH7206 code for the IPR IRQ changes. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/boards/se/7206/irq.c | 16 ++++++--- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 41 ++++++++++++++++++++++ arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 62 +++++++++++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 8 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/se/7206/irq.c b/arch/sh/boards/se/7206/irq.c index 3fb0c5f5b23..27da88486f7 100644 --- a/arch/sh/boards/se/7206/irq.c +++ b/arch/sh/boards/se/7206/irq.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #define INTSTS0 0x31800000 @@ -18,6 +19,13 @@ #define INTMSK1 0x31800006 #define INTSEL 0x31800008 +#define IRQ0_IRQ 64 +#define IRQ1_IRQ 65 +#define IRQ3_IRQ 67 + +#define INTC_IPR01 0xfffe0818 +#define INTC_ICR1 0xfffe0802 + static void disable_se7206_irq(unsigned int irq) { unsigned short val; @@ -39,7 +47,7 @@ static void disable_se7206_irq(unsigned int irq) case IRQ1_IRQ: msk0 |= 0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: msk0 |= 0x0f00; msk1 |= 0x00ff; break; @@ -70,7 +78,7 @@ static void enable_se7206_irq(unsigned int irq) case IRQ1_IRQ: msk0 &= ~0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: msk0 &= ~0x0f00; msk1 &= ~0x00ff; break; @@ -96,7 +104,7 @@ static void eoi_se7206_irq(unsigned int irq) case IRQ1_IRQ: sts0 &= ~0x000f; break; - case IRQ2_IRQ: + case IRQ3_IRQ: sts0 &= ~0x0f00; sts1 &= ~0x00ff; break; @@ -106,7 +114,7 @@ static void eoi_se7206_irq(unsigned int irq) } static struct irq_chip se7206_irq_chip __read_mostly = { - .name = "SE7206-FPGA-IRQ", + .name = "SE7206-FPGA", .mask = disable_se7206_irq, .unmask = enable_se7206_irq, .mask_ack = disable_se7206_irq, diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 82c2d905152..79283e6c1d8 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -51,3 +51,44 @@ static int __init sh7619_devices_setup(void) ARRAY_SIZE(sh7619_devices)); } __initcall(sh7619_devices_setup); + +#define INTC_IPRC 0xf8080000UL +#define INTC_IPRD 0xf8080002UL + +#define CMI0_IRQ 86 + +#define SCIF0_ERI_IRQ 88 +#define SCIF0_RXI_IRQ 89 +#define SCIF0_BRI_IRQ 90 +#define SCIF0_TXI_IRQ 91 + +#define SCIF1_ERI_IRQ 92 +#define SCIF1_RXI_IRQ 93 +#define SCIF1_BRI_IRQ 94 +#define SCIF1_TXI_IRQ 95 + +#define SCIF2_BRI_IRQ 96 +#define SCIF2_ERI_IRQ 97 +#define SCIF2_RXI_IRQ 98 +#define SCIF2_TXI_IRQ 99 + +static struct ipr_data sh7619_ipr_map[] = { + { CMI0_IRQ, INTC_IPRC, 1, 2 }, + { SCIF0_ERI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_RXI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_BRI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF0_TXI_IRQ, INTC_IPRD, 3, 3 }, + { SCIF1_ERI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_RXI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_BRI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF1_TXI_IRQ, INTC_IPRD, 2, 3 }, + { SCIF2_ERI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_RXI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_BRI_IRQ, INTC_IPRD, 1, 3 }, + { SCIF2_TXI_IRQ, INTC_IPRD, 1, 3 }, +}; + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index cdfeef49e62..4b60fcc7d66 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -17,22 +17,22 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 240, 241, 242, 243}, + .irqs = { 241, 242, 243, 240}, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 244, 245, 246, 247}, + .irqs = { 247, 244, 245, 246}, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 248, 249, 250, 251}, + .irqs = { 249, 250, 251, 248}, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCIF, - .irqs = { 252, 253, 254, 255}, + .irqs = { 253, 254, 255, 252}, }, { .flags = 0, } @@ -56,3 +56,57 @@ static int __init sh7206_devices_setup(void) ARRAY_SIZE(sh7206_devices)); } __initcall(sh7206_devices_setup); + +#define INTC_IPR08 0xfffe0c04UL +#define INTC_IPR09 0xfffe0c06UL +#define INTC_IPR14 0xfffe0c10UL + +#define CMI0_IRQ 140 + +#define MTU1_TGI1A 164 + +#define SCIF0_BRI_IRQ 240 +#define SCIF0_ERI_IRQ 241 +#define SCIF0_RXI_IRQ 242 +#define SCIF0_TXI_IRQ 243 + +#define SCIF1_BRI_IRQ 244 +#define SCIF1_ERI_IRQ 245 +#define SCIF1_RXI_IRQ 246 +#define SCIF1_TXI_IRQ 247 + +#define SCIF2_BRI_IRQ 248 +#define SCIF2_ERI_IRQ 249 +#define SCIF2_RXI_IRQ 250 +#define SCIF2_TXI_IRQ 251 + +#define SCIF3_BRI_IRQ 252 +#define SCIF3_ERI_IRQ 253 +#define SCIF3_RXI_IRQ 254 +#define SCIF3_TXI_IRQ 255 + +static struct ipr_data sh7206_ipr_map[] = { + { CMI0_IRQ, INTC_IPR08, 3, 2 }, + { MTU2_TGI1A, INTC_IPR09, 1, 2 }, + { SCIF0_ERI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_RXI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_BRI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF0_TXI_IRQ, INTC_IPR14, 3, 3 }, + { SCIF1_ERI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_RXI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_BRI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF1_TXI_IRQ, INTC_IPR14, 2, 3 }, + { SCIF2_ERI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_RXI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_BRI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF2_TXI_IRQ, INTC_IPR14, 1, 3 }, + { SCIF3_ERI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_RXI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_BRI_IRQ, INTC_IPR14, 0, 3 }, + { SCIF3_TXI_IRQ, INTC_IPR14, 0, 3 }, +}; + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); +} -- cgit v1.2.3 From 11cbb70ea326e8ec78b2beb2b0c85c9ec71c279b Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Thu, 7 Dec 2006 18:07:27 +0900 Subject: sh: Trivial build fixes for SH-2 support. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 14 +------------- arch/sh/Kconfig.debug | 3 ++- arch/sh/kernel/signal.c | 2 +- arch/sh/kernel/sys_sh.c | 2 +- arch/sh/mm/init.c | 2 ++ 5 files changed, 7 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 8e24c40662e..3aa3b885ab3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -479,7 +479,7 @@ config SH_CLK_MD int "CPU Mode Pin Setting" depends on CPU_SUBTYPE_SH7619 || CPU_SUBTYPE_SH7206 help - MD2 - MD0 Setting. + MD2 - MD0 pin setting. menu "CPU Frequency scaling" @@ -580,18 +580,6 @@ config NR_CPUS source "kernel/Kconfig.preempt" -config CPU_HAS_SR_RB - bool "CPU has SR.RB" - depends on CPU_SH3 || CPU_SH4 - default y - help - This will enable the use of SR.RB register bank usage. Processors - that are lacking this bit must have another method in place for - accomplishing what is taken care of by the banked registers. - - See for further - information on SR.RB and register banking in the kernel in general. - config NODES_SHIFT int default "1" diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 66a25ef4ef1..87902e0298e 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug @@ -31,7 +31,8 @@ config EARLY_SCIF_CONSOLE_PORT hex "SCIF port for early console" depends on EARLY_SCIF_CONSOLE default "0xffe00000" if CPU_SUBTYPE_SH7780 - default "0xfffe9800" if CPU_SUBTYPE_SH72060 + default "0xfffe9800" if CPU_SUBTYPE_SH7206 + default "0xf8420000" if CPU_SUBTYPE_SH7619 default "0xffe80000" if CPU_SH4 config EARLY_PRINTK diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index bb1c480a59c..379c88bf5d9 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -101,7 +101,7 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, */ #define MOVW(n) (0x9300|((n)-2)) /* Move mem word at PC+n to R3 */ -#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#if defined(CONFIG_CPU_SH2) #define TRAP_NOARG 0xc320 /* Syscall w/no args (NR in R3) */ #else #define TRAP_NOARG 0xc310 /* Syscall w/no args (NR in R3) */ diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 5083b6ed4b3..f38874def74 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -324,7 +324,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) register long __sc4 __asm__ ("r4") = (long) filename; register long __sc5 __asm__ ("r5") = (long) argv; register long __sc6 __asm__ ("r6") = (long) envp; - __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0) + __asm__ __volatile__ (SYSCALL_ARG3 : "=z" (__sc0) : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) : "memory"); return __sc0; diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 59f4cc18235..29bd37b1488 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -77,6 +77,7 @@ void show_mem(void) printk("%d pages swap cached\n",cached); } +#ifdef CONFIG_MMU static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) { pgd_t *pgd; @@ -139,6 +140,7 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) set_pte_phys(address, phys, prot); } +#endif /* CONFIG_MMU */ /* References to section boundaries */ -- cgit v1.2.3 From a45e724ba07c02bcf3da96ddc4efefbfe10957f5 Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Thu, 7 Dec 2006 19:59:35 +0900 Subject: sh: Fix Solution Engine 7619 build. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/boards/se/7619/io.c | 28 ++++++++++++++-------------- arch/sh/boards/se/7619/setup.c | 38 +++++++++++++++++++------------------- 2 files changed, 33 insertions(+), 33 deletions(-) (limited to 'arch') diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c index 176f1f39cd9..2f105c3dd81 100644 --- a/arch/sh/boards/se/7619/io.c +++ b/arch/sh/boards/se/7619/io.c @@ -25,78 +25,78 @@ static inline void delay(void) printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \ #name, (port), (__u32) __builtin_return_address(0)) -unsigned char se7619___inb(unsigned long port) +unsigned char se7619_inb(unsigned long port) { badio(inb, port); return 0; } -unsigned char se7619___inb_p(unsigned long port) +unsigned char se7619_inb_p(unsigned long port) { badio(inb_p, port); delay(); return 0; } -unsigned short se7619___inw(unsigned long port) +unsigned short se7619_inw(unsigned long port) { badio(inw, port); return 0; } -unsigned int se7619___inl(unsigned long port) +unsigned int se7619_inl(unsigned long port) { badio(inl, port); return 0; } -void se7619___outb(unsigned char value, unsigned long port) +void se7619_outb(unsigned char value, unsigned long port) { badio(outb, port); } -void se7619___outb_p(unsigned char value, unsigned long port) +void se7619_outb_p(unsigned char value, unsigned long port) { badio(outb_p, port); delay(); } -void se7619___outw(unsigned short value, unsigned long port) +void se7619_outw(unsigned short value, unsigned long port) { badio(outw, port); } -void se7619___outl(unsigned int value, unsigned long port) +void se7619_outl(unsigned int value, unsigned long port) { badio(outl, port); } -void se7619___insb(unsigned long port, void *addr, unsigned long count) +void se7619_insb(unsigned long port, void *addr, unsigned long count) { badio(inw, port); } -void se7619___insw(unsigned long port, void *addr, unsigned long count) +void se7619_insw(unsigned long port, void *addr, unsigned long count) { badio(inw, port); } -void se7619___insl(unsigned long port, void *addr, unsigned long count) +void se7619_insl(unsigned long port, void *addr, unsigned long count) { badio(insl, port); } -void se7619___outsb(unsigned long port, const void *addr, unsigned long count) +void se7619_outsb(unsigned long port, const void *addr, unsigned long count) { badio(insl, port); } -void se7619___outsw(unsigned long port, const void *addr, unsigned long count) +void se7619_outsw(unsigned long port, const void *addr, unsigned long count) { badio(insl, port); } -void se7619___outsl(unsigned long port, const void *addr, unsigned long count) +void se7619_outsl(unsigned long port, const void *addr, unsigned long count) { badio(outsw, port); } diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c index e627b26de0d..d1b516ea6cf 100644 --- a/arch/sh/boards/se/7619/setup.c +++ b/arch/sh/boards/se/7619/setup.c @@ -8,8 +8,8 @@ #include #include -#include #include +#include #include /* @@ -19,25 +19,25 @@ struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 108, - .mv_inb = se7619___inb, - .mv_inw = se7619___inw, - .mv_inl = se7619___inl, - .mv_outb = se7619___outb, - .mv_outw = se7619___outw, - .mv_outl = se7619___outl, + .mv_inb = se7619_inb, + .mv_inw = se7619_inw, + .mv_inl = se7619_inl, + .mv_outb = se7619_outb, + .mv_outw = se7619_outw, + .mv_outl = se7619_outl, - .mv_inb_p = se7619___inb_p, - .mv_inw_p = se7619___inw, - .mv_inl_p = se7619___inl, - .mv_outb_p = se7619___outb_p, - .mv_outw_p = se7619___outw, - .mv_outl_p = se7619___outl, + .mv_inb_p = se7619_inb_p, + .mv_inw_p = se7619_inw, + .mv_inl_p = se7619_inl, + .mv_outb_p = se7619_outb_p, + .mv_outw_p = se7619_outw, + .mv_outl_p = se7619_outl, - .mv_insb = se7619___insb, - .mv_insw = se7619___insw, - .mv_insl = se7619___insl, - .mv_outsb = se7619___outsb, - .mv_outsw = se7619___outsw, - .mv_outsl = se7619___outsl, + .mv_insb = se7619_insb, + .mv_insw = se7619_insw, + .mv_insl = se7619_insl, + .mv_outsb = se7619_outsb, + .mv_outsw = se7619_outsw, + .mv_outsl = se7619_outsl, }; ALIAS_MV(se) -- cgit v1.2.3 From 55eec11a50f4c5f53421f49e407e2c92cf25c3ca Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Fri, 8 Dec 2006 14:47:02 +0900 Subject: sh: Kill off unused SE7619 I/O ops. This can use the generic routines, so kill off the board-specific ones. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/boards/se/7619/Makefile | 2 +- arch/sh/boards/se/7619/io.c | 102 ---------------------------------------- arch/sh/boards/se/7619/setup.c | 21 --------- 3 files changed, 1 insertion(+), 124 deletions(-) delete mode 100644 arch/sh/boards/se/7619/io.c (limited to 'arch') diff --git a/arch/sh/boards/se/7619/Makefile b/arch/sh/boards/se/7619/Makefile index 3666eca8a65..d21775c28cd 100644 --- a/arch/sh/boards/se/7619/Makefile +++ b/arch/sh/boards/se/7619/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7619 SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o +obj-y := setup.o diff --git a/arch/sh/boards/se/7619/io.c b/arch/sh/boards/se/7619/io.c deleted file mode 100644 index 2f105c3dd81..00000000000 --- a/arch/sh/boards/se/7619/io.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * linux/arch/sh/boards/se/7619/io.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * I/O routine for Hitachi 7619 SolutionEngine. - * - */ - -#include -#include -#include -#include -#include - -/* FIXME: M3A-ZAB7 Compact Flash Slot support */ - -static inline void delay(void) -{ - ctrl_inw(0xa0000000); /* Uncached ROM area (P2) */ -} - -#define badio(name,port) \ - printk("bad I/O operation (%s) for port 0x%lx at 0x%08x\n", \ - #name, (port), (__u32) __builtin_return_address(0)) - -unsigned char se7619_inb(unsigned long port) -{ - badio(inb, port); - return 0; -} - -unsigned char se7619_inb_p(unsigned long port) -{ - badio(inb_p, port); - delay(); - return 0; -} - -unsigned short se7619_inw(unsigned long port) -{ - badio(inw, port); - return 0; -} - -unsigned int se7619_inl(unsigned long port) -{ - badio(inl, port); - return 0; -} - -void se7619_outb(unsigned char value, unsigned long port) -{ - badio(outb, port); -} - -void se7619_outb_p(unsigned char value, unsigned long port) -{ - badio(outb_p, port); - delay(); -} - -void se7619_outw(unsigned short value, unsigned long port) -{ - badio(outw, port); -} - -void se7619_outl(unsigned int value, unsigned long port) -{ - badio(outl, port); -} - -void se7619_insb(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619_insw(unsigned long port, void *addr, unsigned long count) -{ - badio(inw, port); -} - -void se7619_insl(unsigned long port, void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619_outsb(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619_outsw(unsigned long port, const void *addr, unsigned long count) -{ - badio(insl, port); -} - -void se7619_outsl(unsigned long port, const void *addr, unsigned long count) -{ - badio(outsw, port); -} diff --git a/arch/sh/boards/se/7619/setup.c b/arch/sh/boards/se/7619/setup.c index d1b516ea6cf..52d2c4d5d2f 100644 --- a/arch/sh/boards/se/7619/setup.c +++ b/arch/sh/boards/se/7619/setup.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -19,25 +18,5 @@ struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 108, - .mv_inb = se7619_inb, - .mv_inw = se7619_inw, - .mv_inl = se7619_inl, - .mv_outb = se7619_outb, - .mv_outw = se7619_outw, - .mv_outl = se7619_outl, - - .mv_inb_p = se7619_inb_p, - .mv_inw_p = se7619_inw, - .mv_inl_p = se7619_inl, - .mv_outb_p = se7619_outb_p, - .mv_outw_p = se7619_outw, - .mv_outl_p = se7619_outl, - - .mv_insb = se7619_insb, - .mv_insw = se7619_insw, - .mv_insl = se7619_insl, - .mv_outsb = se7619_outsb, - .mv_outsw = se7619_outsw, - .mv_outsl = se7619_outsl, }; ALIAS_MV(se) -- cgit v1.2.3 From dc34d312c7b25d5d0f54c16d143a9526936e5d38 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 8 Dec 2006 17:41:43 +0900 Subject: sh: BUG() handling through trapa vector. Previously we haven't been doing anything with verbose BUG() reporting, and we've been relying on the oops path for handling BUG()'s, which is rather sub-optimal. This switches BUG handling to use a fixed trapa vector (#0x3e) where we construct a small bug frame post trapa instruction to get the context right. This also makes it trivial to wire up a DIE_BUG for the atomic die chain, which we couldn't really do before. Signed-off-by: Paul Mundt --- arch/sh/kernel/process.c | 10 ++++++++++ arch/sh/kernel/traps.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index f3e2631be14..7347f6afa03 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -498,6 +498,16 @@ asmlinkage void break_point_trap_software(unsigned long r4, unsigned long r5, { struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + /* Rewind */ regs->pc -= 2; + +#ifdef CONFIG_BUG + if (__kernel_text_address(instruction_pointer(regs))) { + u16 insn = *(u16 *)instruction_pointer(regs); + if (insn == TRAPA_BUG_OPCODE) + handle_BUG(regs); + } +#endif + force_sig(SIGTRAP, current); } diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 3762d9dc204..ec110157992 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -129,6 +130,40 @@ static int die_if_no_fixup(const char * str, struct pt_regs * regs, long err) return -EFAULT; } +#ifdef CONFIG_BUG +#ifdef CONFIG_DEBUG_BUGVERBOSE +static inline void do_bug_verbose(struct pt_regs *regs) +{ + struct bug_frame f; + long len; + + if (__copy_from_user(&f, (const void __user *)regs->pc, + sizeof(struct bug_frame))) + return; + + len = __strnlen_user(f.file, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.file = ""; + len = __strnlen_user(f.func, PATH_MAX) - 1; + if (unlikely(len < 0 || len >= PATH_MAX)) + f.func = ""; + + printk(KERN_ALERT "kernel BUG in %s() at %s:%d!\n", + f.func, f.file, f.line); +} +#else +static inline void do_bug_verbose(struct pt_regs *regs) +{ +} +#endif /* CONFIG_DEBUG_BUGVERBOSE */ +#endif /* CONFIG_BUG */ + +void handle_BUG(struct pt_regs *regs) +{ + do_bug_verbose(regs); + die("Kernel BUG", regs, TRAPA_BUG_OPCODE & 0xff); +} + /* * handle an instruction that does an unaligned memory access by emulating the * desired behaviour -- cgit v1.2.3 From b652c23cb0f7808bedb5442c416d91705a465c67 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Fri, 8 Dec 2006 17:46:29 +0900 Subject: sh: Fix get_wchan(). Some time ago the schedule frame size changed and we failed to reflect this in get_wchan() at the time. This first popped up as a problem on SH7751R where schedule_frame ended up being unaligned and generating an unaligned trap. This fixes it up again.. Signed-off-by: Paul Mundt --- arch/sh/kernel/process.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 7347f6afa03..486c06e1803 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c @@ -470,9 +470,10 @@ unsigned long get_wchan(struct task_struct *p) */ pc = thread_saved_pc(p); if (in_sched_functions(pc)) { - schedule_frame = ((unsigned long *)(long)p->thread.sp)[1]; - return (unsigned long)((unsigned long *)schedule_frame)[1]; + schedule_frame = (unsigned long)p->thread.sp; + return ((unsigned long *)schedule_frame)[21]; } + return pc; } -- cgit v1.2.3 From 79890c512444aa55a7a42ac5e7d29d7a4edba11b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 9 Dec 2006 09:14:35 +0900 Subject: sh: Fixup kernel_execve() for syscall cleanups. SH-2 and SH-2A need to use a different syscall base for the trapa vector than the other parts, so fixup the logic in the kernel_execve() case. Signed-off-by: Paul Mundt --- arch/sh/kernel/sys_sh.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index f38874def74..e18f183e103 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -314,6 +314,12 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, #endif } +#if defined(CONFIG_CPU_SH2) || defined(CONFIG_CPU_SH2A) +#define SYSCALL_ARG3 "trapa #0x23" +#else +#define SYSCALL_ARG3 "trapa #0x13" +#endif + /* * Do a system call from kernel instead of calling sys_execve so we * end up with proper pt_regs. -- cgit v1.2.3 From 37bda1da4570c2e9c6dd34e77d2120218e384950 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Sat, 9 Dec 2006 09:16:12 +0900 Subject: sh: Convert remaining remap_area_pages() users to ioremap_page_range(). A couple of these were missed. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/sq.c | 7 ++++--- arch/sh/mm/cache-sh4.c | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index 0c9ea38d2ca..d7fff752e56 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -111,8 +111,9 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) vma->phys_addr = map->addr; - if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr, - map->size, flags)) { + if (ioremap_page_range((unsigned long)vma->addr, + (unsigned long)vma->addr + map->size, + vma->phys_addr, __pgprot(flags))) { vunmap(vma->addr); return -EAGAIN; } @@ -176,7 +177,7 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); - ret = __sq_remap(map, flags); + ret = __sq_remap(map, pgprot_val(PAGE_KERNEL_NOCACHE) | flags); if (unlikely(ret != 0)) goto out; diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c index ae531affccb..c6955157c98 100644 --- a/arch/sh/mm/cache-sh4.c +++ b/arch/sh/mm/cache-sh4.c @@ -107,7 +107,7 @@ void __init p3_cache_init(void) emit_cache_params(); - if (remap_area_pages(P3SEG, 0, PAGE_SIZE * 4, _PAGE_CACHABLE)) + if (ioremap_page_range(P3SEG, P3SEG + (PAGE_SIZE * 4), 0, PAGE_KERNEL)) panic("%s failed.", __FUNCTION__); for (i = 0; i < cpu_data->dcache.n_aliases; i++) -- cgit v1.2.3 From 41504c39726a7099e5a42508dd57fe561c8b4129 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Dec 2006 20:28:03 +0900 Subject: sh: SH-MobileR SH7722 CPU support. This adds CPU support for the SH7722. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/Makefile | 1 + arch/sh/kernel/cpu/sh4/Makefile | 9 +-- arch/sh/kernel/cpu/sh4/clock-sh73180.c | 81 -------------------- arch/sh/kernel/cpu/sh4/clock-sh7770.c | 73 ------------------ arch/sh/kernel/cpu/sh4/clock-sh7780.c | 126 -------------------------------- arch/sh/kernel/cpu/sh4/probe.c | 9 +++ arch/sh/kernel/cpu/sh4/setup-sh73180.c | 43 ----------- arch/sh/kernel/cpu/sh4/setup-sh7343.c | 43 ----------- arch/sh/kernel/cpu/sh4/setup-sh7770.c | 53 -------------- arch/sh/kernel/cpu/sh4/setup-sh7780.c | 108 --------------------------- arch/sh/kernel/cpu/sh4a/Makefile | 19 +++++ arch/sh/kernel/cpu/sh4a/clock-sh73180.c | 81 ++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 99 +++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7770.c | 73 ++++++++++++++++++ arch/sh/kernel/cpu/sh4a/clock-sh7780.c | 126 ++++++++++++++++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh73180.c | 43 +++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 43 +++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 76 +++++++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 53 ++++++++++++++ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 108 +++++++++++++++++++++++++++ arch/sh/kernel/setup.c | 14 ++-- arch/sh/mm/Kconfig | 12 ++- 22 files changed, 753 insertions(+), 540 deletions(-) delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh73180.c delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh7770.c delete mode 100644 arch/sh/kernel/cpu/sh4/clock-sh7780.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh73180.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7343.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7770.c delete mode 100644 arch/sh/kernel/cpu/sh4/setup-sh7780.c create mode 100644 arch/sh/kernel/cpu/sh4a/Makefile create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh73180.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7343.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7770.c create mode 100644 arch/sh/kernel/cpu/sh4a/clock-sh7780.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh73180.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7343.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7722.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7770.c create mode 100644 arch/sh/kernel/cpu/sh4a/setup-sh7780.c (limited to 'arch') diff --git a/arch/sh/kernel/cpu/Makefile b/arch/sh/kernel/cpu/Makefile index 0582e6712b7..d055a3ea6b4 100644 --- a/arch/sh/kernel/cpu/Makefile +++ b/arch/sh/kernel/cpu/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_CPU_SH2) = sh2/ obj-$(CONFIG_CPU_SH2A) = sh2a/ obj-$(CONFIG_CPU_SH3) = sh3/ obj-$(CONFIG_CPU_SH4) = sh4/ +obj-$(CONFIG_CPU_SH4A) += sh4a/ obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o diff --git a/arch/sh/kernel/cpu/sh4/Makefile b/arch/sh/kernel/cpu/sh4/Makefile index 6e415baf04b..19ca68c7188 100644 --- a/arch/sh/kernel/cpu/sh4/Makefile +++ b/arch/sh/kernel/cpu/sh4/Makefile @@ -12,17 +12,12 @@ obj-$(CONFIG_SH_STORE_QUEUES) += sq.o obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o -obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o -obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o -obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o -obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o # Primary on-chip clocks (common) +ifndef CONFIG_CPU_SH4A clock-$(CONFIG_CPU_SH4) := clock-sh4.o -clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o -clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o -clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +endif # Additional clocks by subtype clock-$(CONFIG_CPU_SUBTYPE_SH4_202) += clock-sh4-202.o diff --git a/arch/sh/kernel/cpu/sh4/clock-sh73180.c b/arch/sh/kernel/cpu/sh4/clock-sh73180.c deleted file mode 100644 index 2fa5cb2ae68..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh73180.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh73180.c - * - * SH73180 support for the clock framework - * - * Copyright (C) 2005 Paul Mundt - * - * FRQCR parsing hacked out of arch/sh/kernel/time.c - * - * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002, 2003, 2004 Paul Mundt - * Copyright (C) 2002 M. R. Brown - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -/* - * SH73180 uses a common set of divisors, so this is quite simple.. - */ -static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; -} - -static struct clk_ops sh73180_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x0007); - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; - clk->rate = clk->parent->rate / divisors[idx]; -} - -static struct clk_ops sh73180_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh73180_clk_ops[] = { - &sh73180_master_clk_ops, - &sh73180_module_clk_ops, - &sh73180_bus_clk_ops, - &sh73180_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh73180_clk_ops)) - *ops = sh73180_clk_ops[idx]; -} - diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7770.c b/arch/sh/kernel/cpu/sh4/clock-sh7770.c deleted file mode 100644 index c8694bac647..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh7770.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh7770.c - * - * SH7770 support for the clock framework - * - * Copyright (C) 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; -static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; -static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; -} - -static struct clk_ops sh7770_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7770_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x000f); - clk->rate = clk->parent->rate / bfc_divisors[idx]; -} - -static struct clk_ops sh7770_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7770_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7770_clk_ops[] = { - &sh7770_master_clk_ops, - &sh7770_module_clk_ops, - &sh7770_bus_clk_ops, - &sh7770_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7770_clk_ops)) - *ops = sh7770_clk_ops[idx]; -} - diff --git a/arch/sh/kernel/cpu/sh4/clock-sh7780.c b/arch/sh/kernel/cpu/sh4/clock-sh7780.c deleted file mode 100644 index 9e6a216750c..00000000000 --- a/arch/sh/kernel/cpu/sh4/clock-sh7780.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh4/clock-sh7780.c - * - * SH7780 support for the clock framework - * - * Copyright (C) 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -static int ifc_divisors[] = { 2, 4 }; -static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; -static int pfc_divisors[] = { 1, 24, 24, 1 }; -static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; -} - -static struct clk_ops sh7780_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int idx = (ctrl_inl(FRQCR) & 0x0003); - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7780_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); - clk->rate = clk->parent->rate / bfc_divisors[idx]; -} - -static struct clk_ops sh7780_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7780_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7780_clk_ops[] = { - &sh7780_master_clk_ops, - &sh7780_module_clk_ops, - &sh7780_bus_clk_ops, - &sh7780_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7780_clk_ops)) - *ops = sh7780_clk_ops[idx]; -} - -static void shyway_clk_recalc(struct clk *clk) -{ - int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); - clk->rate = clk->parent->rate / cfc_divisors[idx]; -} - -static struct clk_ops sh7780_shyway_clk_ops = { - .recalc = shyway_clk_recalc, -}; - -static struct clk sh7780_shyway_clk = { - .name = "shyway_clk", - .flags = CLK_ALWAYS_ENABLED, - .ops = &sh7780_shyway_clk_ops, -}; - -/* - * Additional SH7780-specific on-chip clocks that aren't already part of the - * clock framework - */ -static struct clk *sh7780_onchip_clocks[] = { - &sh7780_shyway_clk, -}; - -static int __init sh7780_clk_init(void) -{ - struct clk *clk = clk_get(NULL, "master_clk"); - int i; - - for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { - struct clk *clkp = sh7780_onchip_clocks[i]; - - clkp->parent = clk; - clk_register(clkp); - clk_enable(clkp); - } - - /* - * Now that we have the rest of the clocks registered, we need to - * force the parent clock to propagate so that these clocks will - * automatically figure out their rate. We cheat by handing the - * parent clock its current rate and forcing child propagation. - */ - clk_set_rate(clk, clk_get_rate(clk)); - - clk_put(clk); - - return 0; -} - -arch_initcall(sh7780_clk_init); - diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index afe0f1b1c03..9031a22a2ce 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c @@ -119,11 +119,20 @@ int __init detect_cpu_and_cache_system(void) break; case 0x3000: case 0x3003: + case 0x3009: cpu_data->type = CPU_SH7343; cpu_data->icache.ways = 4; cpu_data->dcache.ways = 4; cpu_data->flags |= CPU_HAS_LLSC; break; + case 0x3008: + if (prr == 0xa0) { + cpu_data->type = CPU_SH7722; + cpu_data->icache.ways = 4; + cpu_data->dcache.ways = 4; + cpu_data->flags |= CPU_HAS_LLSC; + } + break; case 0x8000: cpu_data->type = CPU_ST40RA; cpu_data->flags |= CPU_HAS_FPU; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh73180.c b/arch/sh/kernel/cpu/sh4/setup-sh73180.c deleted file mode 100644 index cc9ea1e2e5d..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh73180.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH73180 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh73180_devices[] __initdata = { - &sci_device, -}; - -static int __init sh73180_devices_setup(void) -{ - return platform_add_devices(sh73180_devices, - ARRAY_SIZE(sh73180_devices)); -} -__initcall(sh73180_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7343.c b/arch/sh/kernel/cpu/sh4/setup-sh7343.c deleted file mode 100644 index 91d61cf91ba..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7343.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7343 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7343_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7343_devices_setup(void) -{ - return platform_add_devices(sh7343_devices, - ARRAY_SIZE(sh7343_devices)); -} -__initcall(sh7343_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7770.c b/arch/sh/kernel/cpu/sh4/setup-sh7770.c deleted file mode 100644 index 6a04cc5f5ac..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7770.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SH7770 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xff923000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - }, { - .mapbase = 0xff924000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - }, { - .mapbase = 0xff925000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7770_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7770_devices_setup(void) -{ - return platform_add_devices(sh7770_devices, - ARRAY_SIZE(sh7770_devices)); -} -__initcall(sh7770_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/arch/sh/kernel/cpu/sh4/setup-sh7780.c deleted file mode 100644 index 9aeaa2ddaa2..00000000000 --- a/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SH7780 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct resource rtc_resources[] = { - [0] = { - .start = 0xffe80000, - .end = 0xffe80000 + 0x58 - 1, - .flags = IORESOURCE_IO, - }, - [1] = { - /* Period IRQ */ - .start = 21, - .flags = IORESOURCE_IRQ, - }, - [2] = { - /* Carry IRQ */ - .start = 22, - .flags = IORESOURCE_IRQ, - }, - [3] = { - /* Alarm IRQ */ - .start = 23, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device rtc_device = { - .name = "sh-rtc", - .id = -1, - .num_resources = ARRAY_SIZE(rtc_resources), - .resource = rtc_resources, -}; - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 77, 79, 78 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7780_devices[] __initdata = { - &rtc_device, - &sci_device, -}; - -static int __init sh7780_devices_setup(void) -{ - return platform_add_devices(sh7780_devices, - ARRAY_SIZE(sh7780_devices)); -} -__initcall(sh7780_devices_setup); - -static struct intc2_data intc2_irq_table[] = { - { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ - - { 21, 1, 0, 0, 2, 2 }, - { 22, 1, 1, 0, 2, 2 }, - { 23, 1, 2, 0, 2, 2 }, - - { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ - { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ - { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ - { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ - - { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ - { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ - { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ - { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ - - { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ - { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ - { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ - { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ - { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ -}; - -void __init init_IRQ_intc2(void) -{ - make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); -} diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile new file mode 100644 index 00000000000..a8f493f2f21 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the Linux/SuperH SH-4 backends. +# + +# CPU subtype setup +obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o +obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o +obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o +obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o +obj-$(CONFIG_CPU_SUBTYPE_SH7722) += setup-sh7722.o + +# Primary on-chip clocks (common) +clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o +clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o +clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o +clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o +clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7343.o + +obj-y += $(clock-y) diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh73180.c b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c new file mode 100644 index 00000000000..2fa5cb2ae68 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh73180.c @@ -0,0 +1,81 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh73180.c + * + * SH73180 support for the clock framework + * + * Copyright (C) 2005 Paul Mundt + * + * FRQCR parsing hacked out of arch/sh/kernel/time.c + * + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + * Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 2002, 2003, 2004 Paul Mundt + * Copyright (C) 2002 M. R. Brown + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +/* + * SH73180 uses a common set of divisors, so this is quite simple.. + */ +static int divisors[] = { 1, 2, 3, 4, 6, 8, 12, 16 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= divisors[ctrl_inl(FRQCR) & 0x0007]; +} + +static struct clk_ops sh73180_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x0007); + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 12) & 0x0007; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 20) & 0x0007; + clk->rate = clk->parent->rate / divisors[idx]; +} + +static struct clk_ops sh73180_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh73180_clk_ops[] = { + &sh73180_master_clk_ops, + &sh73180_module_clk_ops, + &sh73180_bus_clk_ops, + &sh73180_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh73180_clk_ops)) + *ops = sh73180_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c new file mode 100644 index 00000000000..1707a213f0c --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c @@ -0,0 +1,99 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7343.c + * + * SH7343/SH7722 support for the clock framework + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +/* + * SH7343/SH7722 uses a common set of multipliers and divisors, so this + * is quite simple.. + */ +static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; +static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; + +#define pll_calc() (((ctrl_inl(FRQCR) >> 24) & 0x1f) + 1) + +static void master_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void master_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x000f); + clk->rate *= clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_master_clk_ops = { + .init = master_clk_init, + .recalc = master_clk_recalc, +}; + +static void module_clk_init(struct clk *clk) +{ + clk->parent = NULL; + clk->rate = CONFIG_SH_PCLK_FREQ; +} + +static struct clk_ops sh7343_module_clk_ops = { + .init = module_clk_init, +}; + +static void bus_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "cpu_clk"); +} + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 8) & 0x000f; + clk->rate = clk->parent->rate * multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_bus_clk_ops = { + .init = bus_clk_init, + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_init(struct clk *clk) +{ + clk->parent = clk_get(NULL, "module_clk"); + clk->flags |= CLK_RATE_PROPAGATES; + clk_set_rate(clk, clk_get_rate(clk)); +} + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) >> 20) & 0x000f; + clk->rate = clk->parent->rate * pll_calc() * + multipliers[idx] / divisors[idx]; +} + +static struct clk_ops sh7343_cpu_clk_ops = { + .init = cpu_clk_init, + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7343_clk_ops[] = { + &sh7343_master_clk_ops, + &sh7343_module_clk_ops, + &sh7343_bus_clk_ops, + &sh7343_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7343_clk_ops)) + *ops = sh7343_clk_ops[idx]; +} diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7770.c b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c new file mode 100644 index 00000000000..c8694bac647 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7770.c @@ -0,0 +1,73 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7770.c + * + * SH7770 support for the clock framework + * + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 }; +static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 }; +static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f]; +} + +static struct clk_ops sh7770_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7770_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x000f); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops sh7770_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7770_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7770_clk_ops[] = { + &sh7770_master_clk_ops, + &sh7770_module_clk_ops, + &sh7770_bus_clk_ops, + &sh7770_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7770_clk_ops)) + *ops = sh7770_clk_ops[idx]; +} + diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7780.c b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c new file mode 100644 index 00000000000..9e6a216750c --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7780.c @@ -0,0 +1,126 @@ +/* + * arch/sh/kernel/cpu/sh4/clock-sh7780.c + * + * SH7780 support for the clock framework + * + * Copyright (C) 2005 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include +#include + +static int ifc_divisors[] = { 2, 4 }; +static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 }; +static int pfc_divisors[] = { 1, 24, 24, 1 }; +static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 }; + +static void master_clk_init(struct clk *clk) +{ + clk->rate *= pfc_divisors[ctrl_inl(FRQCR) & 0x0003]; +} + +static struct clk_ops sh7780_master_clk_ops = { + .init = master_clk_init, +}; + +static void module_clk_recalc(struct clk *clk) +{ + int idx = (ctrl_inl(FRQCR) & 0x0003); + clk->rate = clk->parent->rate / pfc_divisors[idx]; +} + +static struct clk_ops sh7780_module_clk_ops = { + .recalc = module_clk_recalc, +}; + +static void bus_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 16) & 0x0007); + clk->rate = clk->parent->rate / bfc_divisors[idx]; +} + +static struct clk_ops sh7780_bus_clk_ops = { + .recalc = bus_clk_recalc, +}; + +static void cpu_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 24) & 0x0001); + clk->rate = clk->parent->rate / ifc_divisors[idx]; +} + +static struct clk_ops sh7780_cpu_clk_ops = { + .recalc = cpu_clk_recalc, +}; + +static struct clk_ops *sh7780_clk_ops[] = { + &sh7780_master_clk_ops, + &sh7780_module_clk_ops, + &sh7780_bus_clk_ops, + &sh7780_cpu_clk_ops, +}; + +void __init arch_init_clk_ops(struct clk_ops **ops, int idx) +{ + if (idx < ARRAY_SIZE(sh7780_clk_ops)) + *ops = sh7780_clk_ops[idx]; +} + +static void shyway_clk_recalc(struct clk *clk) +{ + int idx = ((ctrl_inl(FRQCR) >> 20) & 0x0007); + clk->rate = clk->parent->rate / cfc_divisors[idx]; +} + +static struct clk_ops sh7780_shyway_clk_ops = { + .recalc = shyway_clk_recalc, +}; + +static struct clk sh7780_shyway_clk = { + .name = "shyway_clk", + .flags = CLK_ALWAYS_ENABLED, + .ops = &sh7780_shyway_clk_ops, +}; + +/* + * Additional SH7780-specific on-chip clocks that aren't already part of the + * clock framework + */ +static struct clk *sh7780_onchip_clocks[] = { + &sh7780_shyway_clk, +}; + +static int __init sh7780_clk_init(void) +{ + struct clk *clk = clk_get(NULL, "master_clk"); + int i; + + for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) { + struct clk *clkp = sh7780_onchip_clocks[i]; + + clkp->parent = clk; + clk_register(clkp); + clk_enable(clkp); + } + + /* + * Now that we have the rest of the clocks registered, we need to + * force the parent clock to propagate so that these clocks will + * automatically figure out their rate. We cheat by handing the + * parent clock its current rate and forcing child propagation. + */ + clk_set_rate(clk, clk_get_rate(clk)); + + clk_put(clk); + + return 0; +} + +arch_initcall(sh7780_clk_init); + diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh73180.c b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c new file mode 100644 index 00000000000..cc9ea1e2e5d --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh73180.c @@ -0,0 +1,43 @@ +/* + * SH73180 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe80000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh73180_devices[] __initdata = { + &sci_device, +}; + +static int __init sh73180_devices_setup(void) +{ + return platform_add_devices(sh73180_devices, + ARRAY_SIZE(sh73180_devices)); +} +__initcall(sh73180_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c new file mode 100644 index 00000000000..91d61cf91ba --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -0,0 +1,43 @@ +/* + * SH7343 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7343_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7343_devices_setup(void) +{ + return platform_add_devices(sh7343_devices, + ARRAY_SIZE(sh7343_devices)); +} +__initcall(sh7343_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c new file mode 100644 index 00000000000..7528fc6b0d6 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -0,0 +1,76 @@ +/* + * SH7722 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 80, 81, 83, 82 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7722_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7722_devices_setup(void) +{ + return platform_add_devices(sh7722_devices, + ARRAY_SIZE(sh7722_devices)); +} +__initcall(sh7722_devices_setup); + +static struct ipr_data sh7722_ipr_map[] = { + /* IRQ, IPR-idx, shift, prio */ + { 16, 0, 12, 2 }, /* TMU0 */ + { 17, 0, 8, 2 }, /* TMU1 */ +}; + +static unsigned long ipr_offsets[] = { + 0xa4080000, /* 0: IPRA */ + 0xa4080004, /* 1: IPRB */ + 0xa4080008, /* 2: IPRC */ + 0xa408000c, /* 3: IPRD */ + 0xa4080010, /* 4: IPRE */ + 0xa4080014, /* 5: IPRF */ + 0xa4080018, /* 6: IPRG */ + 0xa408001c, /* 7: IPRH */ + 0xa4080020, /* 8: IPRI */ + 0xa4080024, /* 9: IPRJ */ + 0xa4080028, /* 10: IPRK */ + 0xa408002c, /* 11: IPRL */ +}; + +unsigned int map_ipridx_to_addr(int idx) +{ + if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) + return 0; + return ipr_offsets[idx]; +} + +void __init init_IRQ_ipr(void) +{ + make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); +} diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c new file mode 100644 index 00000000000..6a04cc5f5ac --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -0,0 +1,53 @@ +/* + * SH7770 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xff923000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 61, 61, 61, 61 }, + }, { + .mapbase = 0xff924000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 62, 62, 62, 62 }, + }, { + .mapbase = 0xff925000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 63, 63, 63, 63 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7770_devices[] __initdata = { + &sci_device, +}; + +static int __init sh7770_devices_setup(void) +{ + return platform_add_devices(sh7770_devices, + ARRAY_SIZE(sh7770_devices)); +} +__initcall(sh7770_devices_setup); diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c new file mode 100644 index 00000000000..9aeaa2ddaa2 --- /dev/null +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -0,0 +1,108 @@ +/* + * SH7780 Setup + * + * Copyright (C) 2006 Paul Mundt + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include +#include +#include +#include + +static struct resource rtc_resources[] = { + [0] = { + .start = 0xffe80000, + .end = 0xffe80000 + 0x58 - 1, + .flags = IORESOURCE_IO, + }, + [1] = { + /* Period IRQ */ + .start = 21, + .flags = IORESOURCE_IRQ, + }, + [2] = { + /* Carry IRQ */ + .start = 22, + .flags = IORESOURCE_IRQ, + }, + [3] = { + /* Alarm IRQ */ + .start = 23, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device rtc_device = { + .name = "sh-rtc", + .id = -1, + .num_resources = ARRAY_SIZE(rtc_resources), + .resource = rtc_resources, +}; + +static struct plat_sci_port sci_platform_data[] = { + { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 40, 41, 43, 42 }, + }, { + .mapbase = 0xffe10000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCIF, + .irqs = { 76, 77, 79, 78 }, + }, { + .flags = 0, + } +}; + +static struct platform_device sci_device = { + .name = "sh-sci", + .id = -1, + .dev = { + .platform_data = sci_platform_data, + }, +}; + +static struct platform_device *sh7780_devices[] __initdata = { + &rtc_device, + &sci_device, +}; + +static int __init sh7780_devices_setup(void) +{ + return platform_add_devices(sh7780_devices, + ARRAY_SIZE(sh7780_devices)); +} +__initcall(sh7780_devices_setup); + +static struct intc2_data intc2_irq_table[] = { + { 28, 0, 24, 0, 0, 2 }, /* TMU0 */ + + { 21, 1, 0, 0, 2, 2 }, + { 22, 1, 1, 0, 2, 2 }, + { 23, 1, 2, 0, 2, 2 }, + + { 40, 8, 24, 0, 3, 3 }, /* SCIF0 ERI */ + { 41, 8, 24, 0, 3, 3 }, /* SCIF0 RXI */ + { 42, 8, 24, 0, 3, 3 }, /* SCIF0 BRI */ + { 43, 8, 24, 0, 3, 3 }, /* SCIF0 TXI */ + + { 76, 8, 16, 0, 4, 3 }, /* SCIF1 ERI */ + { 77, 8, 16, 0, 4, 3 }, /* SCIF1 RXI */ + { 78, 8, 16, 0, 4, 3 }, /* SCIF1 BRI */ + { 79, 8, 16, 0, 4, 3 }, /* SCIF1 TXI */ + + { 64, 0x10, 8, 0, 14, 2 }, /* PCIC0 */ + { 65, 0x10, 0, 0, 15, 2 }, /* PCIC1 */ + { 66, 0x14, 24, 0, 16, 2 }, /* PCIC2 */ + { 67, 0x14, 16, 0, 17, 2 }, /* PCIC3 */ + { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ +}; + +void __init init_IRQ_intc2(void) +{ + make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); +} diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f8dd6b7bfab..fe545bbb1e1 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -325,14 +325,18 @@ void __init setup_arch(char **cmdline_p) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); if (&__rd_start != &__rd_end) { LOADER_TYPE = 1; - INITRD_START = PHYSADDR((unsigned long)&__rd_start) - __MEMORY_START; - INITRD_SIZE = (unsigned long)&__rd_end - (unsigned long)&__rd_start; + INITRD_START = PHYSADDR((unsigned long)&__rd_start) - + __MEMORY_START; + INITRD_SIZE = (unsigned long)&__rd_end - + (unsigned long)&__rd_start; } if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { - reserve_bootmem_node(NODE_DATA(0), INITRD_START+__MEMORY_START, INITRD_SIZE); - initrd_start = INITRD_START + PAGE_OFFSET + __MEMORY_START; + reserve_bootmem_node(NODE_DATA(0), INITRD_START + + __MEMORY_START, INITRD_SIZE); + initrd_start = INITRD_START + PAGE_OFFSET + + __MEMORY_START; initrd_end = initrd_start + INITRD_SIZE; } else { printk("initrd extends beyond end of memory " @@ -404,7 +408,7 @@ static const char *cpu_name[] = { [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", - [CPU_SH7785] = "SH7785", + [CPU_SH7785] = "SH7785", [CPU_SH7722] = "SH7722", [CPU_SH_NONE] = "Unknown" }; diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 4e0362f5038..29f4ee35c6d 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -35,6 +35,9 @@ config CPU_SUBTYPE_ST40 select CPU_SH4 select CPU_HAS_INTC2_IRQ +config CPU_SHX2 + bool + # # Processor subtypes # @@ -180,6 +183,7 @@ config CPU_SUBTYPE_SH7780 config CPU_SUBTYPE_SH7785 bool "Support SH7785 processor" select CPU_SH4A + select CPU_SHX2 select CPU_HAS_INTC2_IRQ comment "SH4AL-DSP Processor Support" @@ -192,6 +196,12 @@ config CPU_SUBTYPE_SH7343 bool "Support SH7343 processor" select CPU_SH4AL_DSP +config CPU_SUBTYPE_SH7722 + bool "Support SH7722 processor" + select CPU_SH4AL_DSP + select CPU_SHX2 + select CPU_HAS_IPR_IRQ + endmenu menu "Memory management options" @@ -250,7 +260,7 @@ config 32BIT config X2TLB bool "Enable extended TLB mode" - depends on CPU_SUBTYPE_SH7785 && MMU && EXPERIMENTAL + depends on CPU_SHX2 && MMU && EXPERIMENTAL help Selecting this option will enable the extended mode of the SH-X2 TLB. For legacy SH-X behaviour and interoperability, say N. For -- cgit v1.2.3 From 1dc417d0390b4897dc1d9bbf335e325baecae2c3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 11 Dec 2006 20:29:28 +0900 Subject: sh: Fixup sh_bios() trap handling. This was inadvertently broken when the entry.S code split up, restore the missing branch and get subsequent traps working under debug again. This manifested itself as a lockup when attempting to reload the VBR base. Signed-off-by: Paul Mundt --- arch/sh/kernel/entry-common.S | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index 29136a35d7c..fc279aeb73a 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -79,18 +79,29 @@ debug_kernel_sw: .align 2 3: .long kgdb_handle_exception #endif /* CONFIG_SH_KGDB */ - +#ifdef CONFIG_SH_STANDARD_BIOS + bra debug_kernel_fw + nop +#endif #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */ - .align 2 debug_trap: #if defined(CONFIG_SH_STANDARD_BIOS) || defined(CONFIG_SH_KGDB) + mov r8, r0 + shlr2 r0 + cmp/eq #0x3f, r0 ! sh_bios() trap + bf 1f +#ifdef CONFIG_SH_KGDB + cmp/eq #0xff, r0 ! XXX: KGDB trap, fix for SH-2. + bf 1f +#endif mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register shll r0 shll r0 ! kernel space? bt/s debug_kernel +1: #endif mov.l @r15, r0 ! Restore R0 value mov.l 1f, r8 -- cgit v1.2.3 From 05c8690d95967ad50dda3c9d552a0c342dde801b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Dec 2006 08:49:06 +0900 Subject: sh: Hook up SH7722 scif ipr interrupts. Add the SCIF IRQs to the IPR table for SH7722. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 7528fc6b0d6..1143fbf65fa 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -46,6 +46,10 @@ static struct ipr_data sh7722_ipr_map[] = { /* IRQ, IPR-idx, shift, prio */ { 16, 0, 12, 2 }, /* TMU0 */ { 17, 0, 8, 2 }, /* TMU1 */ + { 80, 6, 12, 3 }, /* SCIF ERI */ + { 81, 6, 12, 3 }, /* SCIF RXI */ + { 82, 6, 12, 3 }, /* SCIF BRI */ + { 83, 6, 12, 3 }, /* SCIF TXI */ }; static unsigned long ipr_offsets[] = { -- cgit v1.2.3 From f668f55c3941faacc6f298f434b1af3d5142eed7 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Dec 2006 08:50:36 +0900 Subject: sh: Fixup .data.page_aligned. This had a bogus .data.idt reference, fix it up.. Signed-off-by: Paul Mundt --- arch/sh/kernel/vmlinux.lds.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 77b4026d568..f34bdcc33a7 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -51,7 +51,7 @@ SECTIONS } . = ALIGN(PAGE_SIZE); - .data.page_aligned : { *(.data.idt) } + .data.page_aligned : { *(.data.page_aligned) } . = ALIGN(32); __per_cpu_start = .; -- cgit v1.2.3 From e2dfb912d3cea97d8b1d6750abbe9c942b6f73f5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Dec 2006 08:53:29 +0900 Subject: sh: Fix .empty_zero_page alignment for PAGE_SIZE > 4096. Signed-off-by: Paul Mundt --- arch/sh/boot/compressed/head.S | 3 ++- arch/sh/boot/compressed/misc.c | 3 ++- arch/sh/kernel/head.S | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sh/boot/compressed/head.S b/arch/sh/boot/compressed/head.S index 4c26a192277..a8399b01372 100644 --- a/arch/sh/boot/compressed/head.S +++ b/arch/sh/boot/compressed/head.S @@ -8,6 +8,7 @@ .text #include +#include .global startup startup: @@ -97,7 +98,7 @@ init_stack_addr: decompress_kernel_addr: .long decompress_kernel kernel_start_addr: - .long _text+0x1000 + .long _text+PAGE_SIZE .align 9 fake_headers_as_bzImage: diff --git a/arch/sh/boot/compressed/misc.c b/arch/sh/boot/compressed/misc.c index 35452d85b7f..df65e305acf 100644 --- a/arch/sh/boot/compressed/misc.c +++ b/arch/sh/boot/compressed/misc.c @@ -13,6 +13,7 @@ #include #include +#include #ifdef CONFIG_SH_STANDARD_BIOS #include #endif @@ -229,7 +230,7 @@ long* stack_start = &user_stack[STACK_SIZE]; void decompress_kernel(void) { output_data = 0; - output_ptr = P2SEGADDR((unsigned long)&_text+0x1000); + output_ptr = P2SEGADDR((unsigned long)&_text+PAGE_SIZE); free_mem_ptr = (unsigned long)&_end; free_mem_end_ptr = free_mem_ptr + HEAP_SIZE; diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S index 6aca4bc6ec5..71a3ad7d283 100644 --- a/arch/sh/kernel/head.S +++ b/arch/sh/kernel/head.S @@ -33,7 +33,8 @@ ENTRY(empty_zero_page) .long 0x00360000 /* INITRD_START */ .long 0x000a0000 /* INITRD_SIZE */ .long 0 - .balign PAGE_SIZE,0,PAGE_SIZE +1: + .skip PAGE_SIZE - empty_zero_page - 1b .text /* -- cgit v1.2.3 From b641fe016a29fe2c0c7b0d717a5918e3f067a44f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 12 Dec 2006 09:00:47 +0900 Subject: sh: Use early_param() for earlyprintk parsing. Signed-off-by: Paul Mundt --- arch/sh/kernel/early_printk.c | 20 +++++++++++--------- arch/sh/kernel/setup.c | 27 +++++---------------------- 2 files changed, 16 insertions(+), 31 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 60340823798..560b91cdd15 100644 --- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -144,16 +144,16 @@ static struct console *early_console = ; static int __initdata keep_early; +static int early_console_initialized; -int __init setup_early_printk(char *opt) +int __init setup_early_printk(char *buf) { - char *space; - char buf[256]; + if (!buf) + return 0; - strlcpy(buf, opt, sizeof(buf)); - space = strchr(buf, ' '); - if (space) - *space = 0; + if (early_console_initialized) + return 0; + early_console_initialized = 1; if (strstr(buf, "keep")) keep_early = 1; @@ -175,12 +175,14 @@ int __init setup_early_printk(char *opt) if (likely(early_console)) register_console(early_console); - return 1; + return 0; } -__setup("earlyprintk=", setup_early_printk); +early_param("earlyprintk", setup_early_printk); void __init disable_early_printk(void) { + if (!early_console_initialized || !early_console) + return; if (!keep_early) { printk("disabling early console\n"); unregister_console(early_console); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index fe545bbb1e1..225f9ea5cdd 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -84,8 +84,7 @@ unsigned long memory_start, memory_end; static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], struct sh_machine_vector** mvp, - unsigned long *mv_io_base, - int *mv_mmio_enable) + unsigned long *mv_io_base) { char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; @@ -112,23 +111,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], } } -#ifdef CONFIG_EARLY_PRINTK - if (c == ' ' && !memcmp(from, "earlyprintk=", 12)) { - char *ep_end; - - if (to != command_line) - to--; - - from += 12; - ep_end = strchr(from, ' '); - - setup_early_printk(from); - printk("early console enabled\n"); - - from = ep_end; - } -#endif - if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { char* mv_end; char* mv_comma; @@ -145,7 +127,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], int ints[3]; get_options(mv_comma+1, ARRAY_SIZE(ints), ints); *mv_io_base = ints[1]; - *mv_mmio_enable = ints[2]; mv_len = mv_comma - from; } else { mv_len = mv_end - from; @@ -158,6 +139,7 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], *mvp = get_mv_byname(mv_name); } + c = *(from++); if (!c) break; @@ -177,9 +159,8 @@ static int __init sh_mv_setup(char **cmdline_p) struct sh_machine_vector *mv = NULL; char mv_name[MV_NAME_SIZE] = ""; unsigned long mv_io_base = 0; - int mv_mmio_enable = 0; - parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base, &mv_mmio_enable); + parse_cmdline(cmdline_p, mv_name, &mv, &mv_io_base); #ifdef CONFIG_SH_UNKNOWN if (mv == NULL) { @@ -258,6 +239,7 @@ void __init setup_arch(char **cmdline_p) sh_mv_setup(cmdline_p); + /* * Find the highest page frame number we have available */ @@ -305,6 +287,7 @@ void __init setup_arch(char **cmdline_p) PFN_PHYS(pages)); } + /* * Reserve the kernel text and * Reserve the bootmem bitmap. We do this in two steps (first step -- cgit v1.2.3 From e9cfc147df99790a7d260e9d20b865fa31ec56da Mon Sep 17 00:00:00 2001 From: Yoshinori Sato Date: Tue, 12 Dec 2006 09:11:45 +0900 Subject: sh: Fixup SH-2 BUG() trap handling. This adds in support for the BUG() trap on SH-2. Signed-off-by: Yoshinori Sato Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/entry.S | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S index 34d51b3745e..d51fa5e9904 100644 --- a/arch/sh/kernel/cpu/sh2/entry.S +++ b/arch/sh/kernel/cpu/sh2/entry.S @@ -177,15 +177,21 @@ interrupt_entry: 7: .long do_IRQ 8: .long do_exception_error -trap_entry: - add #-0x10,r9 +trap_entry: + /* verbose BUG trapa entry check */ + mov #0x3e,r8 + cmp/ge r8,r9 + bf/s 1f + add #-0x10,r9 + add #0x10,r9 +1: shll2 r9 ! TRA mov #OFF_TRA,r8 add r15,r8 mov.l r9,@r8 mov r9,r8 #ifdef CONFIG_TRACE_IRQFLAGS - mov.l 5f, r9 + mov.l 2f, r9 jsr @r9 nop #endif @@ -194,12 +200,8 @@ trap_entry: nop .align 2 -1: .long syscall_exit -2: .long break_point_trap_software -3: .long NR_syscalls -4: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS -5: .long trace_hardirqs_on +2: .long trace_hardirqs_on #endif #if defined(CONFIG_SH_STANDARD_BIOS) @@ -264,7 +266,7 @@ ENTRY(address_error_handler) restore_all: cli #ifdef CONFIG_TRACE_IRQFLAGS - mov.l 3f, r0 + mov.l 1f, r0 jsr @r0 nop #endif @@ -309,20 +311,14 @@ restore_all: mov.l @r15,r15 rte nop -2: - mov.l 1f,r8 - mov.l 2f,r9 - jmp @r9 - lds r8,pr - .align 2 +#ifdef CONFIG_TRACE_IRQFLAGS +1: .long trace_hardirqs_off +#endif $current_thread_info: .long __current_thread_info $cpu_mode: .long __cpu_mode -#ifdef CONFIG_TRACE_IRQFLAGS -3: .long trace_hardirqs_off -#endif ! common exception handler #include "../../entry-common.S" -- cgit v1.2.3 From 2efac77e82a36bf616d474f2eb721d95543cfae9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 11 Dec 2006 11:54:52 +0000 Subject: [MIPS] Discard .exit.text and .exit.data at runtime. While the recent cset 86384d544157db23879064cde36061cdcafc6794 did improve things it didn't resolve all the problems. So bite the bullet and discard .exit.text and .exit.data at runtime. Which of course sucks because it bloats binaries with code that will never ever be used but it's the only thing that will work reliable as demonstrated by the function sd_major() in drivers/scsi/sd.c. Gcc may compile sd_major() using a jump table which it will put into .rodata. If it also inlines sd_major's function body into exit_sd() which gcc > 3.4.x does. If CONFIG_BLK_DEV_SD has been set to y we would like ld to discard exit_sd's code at link time. However sd_major happens to contain a switch statement which gcc will compile using a jump table in .rodata on the architectures I checked. So, when ld later discards .exit.text only the jump table in .rodata with its stale references to the discard .exit.text will be left which any no antique ld will honor with a link error. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vmlinux.lds.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2f4508f55fc..cecff24cc97 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -109,6 +109,10 @@ SECTIONS .con_initcall.init : { *(.con_initcall.init) } __con_initcall_end = .; SECURITY_INIT + /* .exit.text is discarded at runtime, not link time, to deal with + references from .rodata */ + .exit.text : { *(.exit.text) } + .exit.data : { *(.exit.data) } . = ALIGN(_PAGE_SIZE); __initramfs_start = .; .init.ramfs : { *(.init.ramfs) } @@ -136,8 +140,6 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.exit.text) - *(.exit.data) *(.exitcall.exit) /* ABI crap starts here */ -- cgit v1.2.3 From b228f4c54df37b53c6f364aa7f3efa4280bcc4f0 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 11 Dec 2006 15:33:30 +0000 Subject: [MIPS] Malta: Resurrect MTD support for onboard flash. Signed-off-by: Ralf Baechle --- arch/mips/configs/malta_defconfig | 80 ++++++++++++++++++++++++++++++- arch/mips/mips-boards/malta/Makefile | 2 +- arch/mips/mips-boards/malta/malta_setup.c | 39 --------------- 3 files changed, 80 insertions(+), 41 deletions(-) (limited to 'arch') diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 1f9300f37f5..96e941084c0 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -644,7 +644,85 @@ CONFIG_CONNECTOR=m # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set +# CONFIG_SSFDC is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set # # Parallel port support diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index 77ee5c6d33c..b662c75fb28 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile @@ -19,5 +19,5 @@ # under Linux. # -obj-y := malta_int.o malta_setup.o +obj-y := malta_int.o malta_mtd.o malta_setup.o obj-$(CONFIG_SMP) += malta_smp.o diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 282f3e52eea..56ea76679cd 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c @@ -21,13 +21,6 @@ #include #include -#ifdef CONFIG_MTD -#include -#include -#include -#include -#endif - #include #include #include @@ -58,30 +51,6 @@ struct resource standard_io_resources[] = { { .name = "dma2", .start = 0xc0, .end = 0xdf, .flags = IORESOURCE_BUSY }, }; -#ifdef CONFIG_MTD -static struct mtd_partition malta_mtd_partitions[] = { - { - .name = "YAMON", - .offset = 0x0, - .size = 0x100000, - .mask_flags = MTD_WRITEABLE - }, - { - .name = "User FS", - .offset = 0x100000, - .size = 0x2e0000 - }, - { - .name = "Board Config", - .offset = 0x3e0000, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE - } -}; - -#define number_partitions (sizeof(malta_mtd_partitions)/sizeof(struct mtd_partition)) -#endif - const char *get_system_type(void) { return "MIPS Malta"; @@ -211,14 +180,6 @@ void __init plat_mem_setup(void) #endif #endif -#ifdef CONFIG_MTD - /* - * Support for MTD on Malta. Use the generic physmap driver - */ - physmap_configure(0x1e000000, 0x400000, 4, NULL); - physmap_set_partitions(malta_mtd_partitions, number_partitions); -#endif - mips_reboot_setup(); board_time_init = mips_time_init; -- cgit v1.2.3 From cbb8fc07974073543fdc61da23713ab49ddd3ced Mon Sep 17 00:00:00 2001 From: Franck Bui-Huu Date: Wed, 6 Dec 2006 16:48:28 +0100 Subject: [MIPS] paging_init(): use highend_pfn/highstart_pfn This patch makes paging_init() use highend_pfn/highstart_pfn globals. It removes the need of 'high' local which was needed only by HIGHMEM config. More important perhaps, it fixes a bug when HIGHMEM is set but there's actually no physical highmem (highend_pfn = 0) Signed-off-by: Franck Bui-Huu Signed-off-by: Ralf Baechle --- arch/mips/mm/init.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'arch') diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 9e29ba9205f..ea2d15370bb 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -316,7 +316,7 @@ static int __init page_is_ram(unsigned long pagenr) void __init paging_init(void) { unsigned long zones_size[MAX_NR_ZONES] = { 0, }; - unsigned long max_dma, high, low; + unsigned long max_dma, low; #ifndef CONFIG_FLATMEM unsigned long zholes_size[MAX_NR_ZONES] = { 0, }; unsigned long i, j, pfn; @@ -331,7 +331,6 @@ void __init paging_init(void) max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; low = max_low_pfn; - high = highend_pfn; #ifdef CONFIG_ISA if (low < max_dma) @@ -344,13 +343,13 @@ void __init paging_init(void) zones_size[ZONE_DMA] = low; #endif #ifdef CONFIG_HIGHMEM - if (cpu_has_dc_aliases) { - printk(KERN_WARNING "This processor doesn't support highmem."); - if (high - low) - printk(" %ldk highmem ignored", high - low); - printk("\n"); - } else - zones_size[ZONE_HIGHMEM] = high - low; + zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn; + + if (cpu_has_dc_aliases && zones_size[ZONE_HIGHMEM]) { + printk(KERN_WARNING "This processor doesn't support highmem." + " %ldk highmem ignored\n", zones_size[ZONE_HIGHMEM]); + zones_size[ZONE_HIGHMEM] = 0; + } #endif #ifdef CONFIG_FLATMEM -- cgit v1.2.3