diff options
Diffstat (limited to 'arch')
48 files changed, 674 insertions, 285 deletions
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 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 */ 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 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 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 */ 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 */ diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 74ba7637811..1443024b1c7 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,9 +425,8 @@ 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 - select ARCH_SPARSEMEM_ENABLE help The Ocelot is a MIPS-based Single Board Computer (SBC) made by Momentum Computer <http://www.momenco.com/>. @@ -560,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 @@ -1633,9 +1633,6 @@ config ARCH_DISCONTIGMEM_ENABLE config ARCH_SPARSEMEM_ENABLE bool - -config ARCH_SPARSEMEM_ENABLE - bool select SPARSEMEM_STATIC config NUMA 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 diff --git a/arch/mips/gt64120/common/time.c b/arch/mips/gt64120/common/time.c index c83ae6acd60..c47eeb76819 100644 --- a/arch/mips/gt64120/common/time.c +++ b/arch/mips/gt64120/common/time.c @@ -64,14 +64,14 @@ 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; /* 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 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; 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 <asm/system.h> #include <asm/uaccess.h> +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/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 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(); } 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/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 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 <linux/delay.h> +#include <linux/if_ether.h> +#include <linux/ioport.h> +#include <linux/mv643xx.h> +#include <linux/platform_device.h> + +#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 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/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 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 <linux/delay.h> +#include <linux/if_ether.h> +#include <linux/ioport.h> +#include <linux/mv643xx.h> +#include <linux/platform_device.h> + +#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 4c50a147f42..d0b77e101d7 100644 --- a/arch/mips/momentum/ocelot_c/prom.c +++ b/arch/mips/momentum/ocelot_c/prom.c @@ -29,11 +29,7 @@ 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 +extern unsigned int cpu_clock; const char *get_system_type(void) { @@ -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 9c0c462af65..0b6b2338cfb 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c @@ -69,8 +69,7 @@ #include "ocelot_c_fpga.h" unsigned long marvell_base; -extern unsigned long mv64340_sram_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); @@ -119,7 +118,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 +127,6 @@ void PMON_v2_setup(void) add_wired_entry(ENTRYLO(0xfe000000), ENTRYLO(0xff000000), 0xfe000000, PM_16M); marvell_base = 0xf4000000; - mv64340_sram_base = 0xfe000000; #endif } @@ -346,22 +343,20 @@ 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 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 */ } 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 <linux/pci.h> -#include <linux/init.h> - -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 <linux/pci.h> + +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; +} 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(); 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..2aa13e8e000 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); @@ -434,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); @@ -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) 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 <asm/mxcc.h> #include <asm/thread_info.h> #include <asm/param.h> +#include <asm/unistd.h> #include <asm/asmmacro.h> #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 <asm/auxio.h> #include <asm/sfafsr.h> #include <asm/pil.h> +#include <asm/unistd.h> #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 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/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 <stdio.h> #include <errno.h> #include <signal.h> -#include <linux/unistd.h> #include <sys/mman.h> #include <sys/wait.h> #include <sys/mman.h> 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; 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 <sys/mman.h> #include <sys/user.h> #include <sys/time.h> -#include <asm/unistd.h> +#include <sys/syscall.h> #include <asm/types.h> #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 <errno.h> +#include <unistd.h> #include <sys/ptrace.h> #include <sys/syscall.h> -#include <unistd.h> #include <asm/ldt.h> #include "sysdep/tls.h" #include "uml-config.h" |