diff options
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/drivers.c | 197 | ||||
-rw-r--r-- | arch/parisc/kernel/hardware.c | 12 | ||||
-rw-r--r-- | arch/parisc/kernel/hpmc.S | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/process.c | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 30 |
5 files changed, 217 insertions, 34 deletions
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 29b99b8964aa..3b8507f71050 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -135,7 +135,7 @@ static int parisc_driver_probe(struct device *dev) return rc; } -static int parisc_driver_remove(struct device *dev) +static int __exit parisc_driver_remove(struct device *dev) { struct parisc_device *pa_dev = to_parisc_device(dev); struct parisc_driver *pa_drv = to_parisc_driver(dev->driver); @@ -205,7 +205,7 @@ static int match_and_count(struct device * dev, void * data) * Use by IOMMU support to "guess" the right size IOPdir. * Formula is something like memsize/(num_iommu * entry_size). */ -int count_parisc_driver(struct parisc_driver *driver) +int __init count_parisc_driver(struct parisc_driver *driver) { struct match_count m = { .driver = driver, @@ -268,7 +268,7 @@ static struct parisc_device *find_device_by_addr(unsigned long hpa) * Walks up the device tree looking for a device of the specified type. * If it finds it, it returns it. If not, it returns NULL. */ -const struct parisc_device * +const struct parisc_device * __init find_pa_parent_type(const struct parisc_device *padev, int type) { const struct device *dev = &padev->dev; @@ -397,7 +397,7 @@ static void setup_bus_id(struct parisc_device *padev) dev_set_name(&padev->dev, name); } -struct parisc_device * create_tree_node(char id, struct device *parent) +struct parisc_device * __init create_tree_node(char id, struct device *parent) { struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) @@ -471,7 +471,7 @@ static struct parisc_device *create_parisc_device(struct hardware_path *modpath) return alloc_tree_node(parent, modpath->mod); } -struct parisc_device * +struct parisc_device * __init alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path) { int status; @@ -609,7 +609,7 @@ struct bus_type parisc_bus_type = { .uevent = parisc_uevent, .dev_groups = parisc_device_groups, .probe = parisc_driver_probe, - .remove = parisc_driver_remove, + .remove = __exit_p(parisc_driver_remove), }; /** @@ -619,7 +619,7 @@ struct bus_type parisc_bus_type = { * Search the driver list for a driver that is willing to manage * this device. */ -int register_parisc_device(struct parisc_device *dev) +int __init register_parisc_device(struct parisc_device *dev) { if (!dev) return 0; @@ -651,6 +651,10 @@ static int match_pci_device(struct device *dev, int index, (modpath->mod == PCI_FUNC(devfn))); } + /* index might be out of bounds for bc[] */ + if (index >= 6) + return 0; + id = PCI_SLOT(pdev->devfn) | (PCI_FUNC(pdev->devfn) << 5); return (modpath->bc[index] == id); } @@ -791,7 +795,7 @@ EXPORT_SYMBOL(device_to_hwpath); static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, struct device *parent); -void walk_lower_bus(struct parisc_device *dev) +static void walk_lower_bus(struct parisc_device *dev) { unsigned long io_io_low, io_io_high; @@ -857,7 +861,7 @@ static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, * PDC doesn't tell us about all devices in the system. This routine * finds devices connected to the central bus. */ -void walk_central_bus(void) +void __init walk_central_bus(void) { walk_native_bus(CENTRAL_BUS_ADDR, CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET), @@ -886,7 +890,7 @@ static void print_parisc_device(struct parisc_device *dev) /** * init_parisc_bus - Some preparation to be done before inventory */ -void init_parisc_bus(void) +void __init init_parisc_bus(void) { if (bus_register(&parisc_bus_type)) panic("Could not register PA-RISC bus type\n"); @@ -895,6 +899,171 @@ void init_parisc_bus(void) get_device(&root); } +static __init void qemu_header(void) +{ + int num; + unsigned long *p; + + pr_info("--- cut here ---\n"); + pr_info("/* AUTO-GENERATED HEADER FILE FOR SEABIOS FIRMWARE */\n"); + pr_cont("/* generated with Linux kernel */\n"); + pr_cont("/* search for PARISC_QEMU_MACHINE_HEADER in Linux */\n\n"); + + pr_info("#define PARISC_MODEL \"%s\"\n\n", + boot_cpu_data.pdc.sys_model_name); + + pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " + "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", + #define p ((unsigned long *)&boot_cpu_data.pdc.model) + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); + #undef p + + pr_info("#define PARISC_PDC_VERSION 0x%04lx\n\n", + boot_cpu_data.pdc.versions); + + pr_info("#define PARISC_PDC_CPUID 0x%04lx\n\n", + boot_cpu_data.pdc.cpuid); + + pr_info("#define PARISC_PDC_CAPABILITIES 0x%04lx\n\n", + boot_cpu_data.pdc.capabilities); + + pr_info("#define PARISC_PDC_ENTRY_ORG 0x%04lx\n\n", +#ifdef CONFIG_64BIT + (unsigned long)(PAGE0->mem_pdc_hi) << 32 | +#endif + (unsigned long)PAGE0->mem_pdc); + + pr_info("#define PARISC_PDC_CACHE_INFO"); + p = (unsigned long *) &cache_info; + for (num = 0; num < sizeof(cache_info); num += sizeof(unsigned long)) { + if (((num % 5) == 0)) { + pr_cont(" \\\n"); + pr_info("\t"); + } + pr_cont("%s0x%04lx", + num?", ":"", *p++); + } + pr_cont("\n\n"); +} + +static __init int qemu_print_hpa(struct device *lin_dev, void *data) +{ + struct parisc_device *dev = to_parisc_device(lin_dev); + unsigned long hpa = dev->hpa.start; + + pr_cont("\t{\t.hpa = 0x%08lx,\\\n", hpa); + pr_cont("\t\t.iodc = &iodc_data_hpa_%08lx,\\\n", hpa); + pr_cont("\t\t.mod_info = &mod_info_hpa_%08lx,\\\n", hpa); + pr_cont("\t\t.mod_path = &mod_path_hpa_%08lx,\\\n", hpa); + pr_cont("\t\t.num_addr = HPA_%08lx_num_addr,\\\n", hpa); + pr_cont("\t\t.add_addr = { HPA_%08lx_add_addr } },\\\n", hpa); + return 0; +} + + +static __init void qemu_footer(void) +{ + pr_info("\n\n#define PARISC_DEVICE_LIST \\\n"); + for_each_padev(qemu_print_hpa, NULL); + pr_cont("\t{ 0, }\n"); + pr_info("--- cut here ---\n"); +} + +/* print iodc data of the various hpa modules for qemu inclusion */ +static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) +{ + struct parisc_device *dev = to_parisc_device(lin_dev); + unsigned long count; + unsigned long hpa = dev->hpa.start; + int status; + struct pdc_iodc iodc_data; + + int mod_index; + struct pdc_system_map_mod_info pdc_mod_info; + struct pdc_module_path mod_path; + + status = pdc_iodc_read(&count, hpa, 0, + &iodc_data, sizeof(iodc_data)); + if (status != PDC_OK) { + pr_info("No IODC data for hpa 0x%08lx\n", hpa); + return 0; + } + + pr_info("\n"); + + pr_info("#define HPA_%08lx_DESCRIPTION \"%s\"\n", + hpa, parisc_hardware_description(&dev->id)); + + mod_index = 0; + do { + status = pdc_system_map_find_mods(&pdc_mod_info, + &mod_path, mod_index++); + } while (status == PDC_OK && pdc_mod_info.mod_addr != hpa); + + pr_info("static struct pdc_system_map_mod_info" + " mod_info_hpa_%08lx = {\n", hpa); + #define DO(member) \ + pr_cont("\t." #member " = 0x%x,\n", \ + (unsigned int)pdc_mod_info.member) + DO(mod_addr); + DO(mod_pgs); + DO(add_addrs); + pr_cont("};\n"); + #undef DO + pr_info("static struct pdc_module_path " + "mod_path_hpa_%08lx = {\n", hpa); + pr_cont("\t.path = { "); + pr_cont(".flags = 0x%x, ", mod_path.path.flags); + pr_cont(".bc = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }, ", + (unsigned char)mod_path.path.bc[0], + (unsigned char)mod_path.path.bc[1], + (unsigned char)mod_path.path.bc[2], + (unsigned char)mod_path.path.bc[3], + (unsigned char)mod_path.path.bc[4], + (unsigned char)mod_path.path.bc[5]); + pr_cont(".mod = 0x%x ", mod_path.path.mod); + pr_cont(" },\n"); + pr_cont("\t.layers = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n", + mod_path.layers[0], mod_path.layers[1], mod_path.layers[2], + mod_path.layers[3], mod_path.layers[4], mod_path.layers[5]); + pr_cont("};\n"); + + pr_info("static struct pdc_iodc iodc_data_hpa_%08lx = {\n", hpa); + #define DO(member) \ + pr_cont("\t." #member " = 0x%04lx,\n", \ + (unsigned long)iodc_data.member) + DO(hversion_model); + DO(hversion); + DO(spa); + DO(type); + DO(sversion_rev); + DO(sversion_model); + DO(sversion_opt); + DO(rev); + DO(dep); + DO(features); + DO(checksum); + DO(length); + #undef DO + pr_cont("\t/* pad: 0x%04x, 0x%04x */\n", + iodc_data.pad[0], iodc_data.pad[1]); + pr_cont("};\n"); + + pr_info("#define HPA_%08lx_num_addr %d\n", hpa, dev->num_addrs); + pr_info("#define HPA_%08lx_add_addr ", hpa); + count = 0; + if (dev->num_addrs == 0) + pr_cont("0"); + while (count < dev->num_addrs) { + pr_cont("0x%08lx, ", dev->addr[count]); + count++; + } + pr_cont("\n\n"); + + return 0; +} + + static int print_one_device(struct device * dev, void * data) { @@ -908,7 +1077,13 @@ static int print_one_device(struct device * dev, void * data) /** * print_parisc_devices - Print out a list of devices found in this system */ -void print_parisc_devices(void) +void __init print_parisc_devices(void) { for_each_padev(print_one_device, NULL); + #define PARISC_QEMU_MACHINE_HEADER 0 + if (PARISC_QEMU_MACHINE_HEADER) { + qemu_header(); + for_each_padev(qemu_print_iodc_data, NULL); + qemu_footer(); + } } diff --git a/arch/parisc/kernel/hardware.c b/arch/parisc/kernel/hardware.c index af3bc359dc70..a2058953a53f 100644 --- a/arch/parisc/kernel/hardware.c +++ b/arch/parisc/kernel/hardware.c @@ -41,7 +41,7 @@ * are guessed. If you know the correct name, please let us know. */ -static struct hp_hardware hp_hardware_list[] = { +static struct hp_hardware hp_hardware_list[] __initdata = { {HPHW_NPROC,0x01,0x4,0x0,"Indigo (840, 930)"}, {HPHW_NPROC,0x8,0x4,0x01,"Firefox(825,925)"}, {HPHW_NPROC,0xA,0x4,0x01,"Top Gun (835,834,935,635)"}, @@ -1238,7 +1238,7 @@ static struct hp_cpu_type_mask { unsigned short model; unsigned short mask; enum cpu_type cpu; -} hp_cpu_type_mask_list[] = { +} hp_cpu_type_mask_list[] __initdata = { { 0x0000, 0x0ff0, pcx }, /* 0x0000 - 0x000f */ { 0x0048, 0x0ff0, pcxl }, /* 0x0040 - 0x004f */ @@ -1325,17 +1325,17 @@ const char * const cpu_name_version[][2] = { [pcxt] = { "PA7100 (PCX-T)", "1.1b" }, [pcxt_] = { "PA7200 (PCX-T')", "1.1c" }, [pcxl] = { "PA7100LC (PCX-L)", "1.1d" }, - [pcxl2] = { "PA7300LC (PCX-L2)", "1.1e" }, + [pcxl2] = { "PA7300LC (PCX-L2)","1.1e" }, [pcxu] = { "PA8000 (PCX-U)", "2.0" }, [pcxu_] = { "PA8200 (PCX-U+)", "2.0" }, [pcxw] = { "PA8500 (PCX-W)", "2.0" }, [pcxw_] = { "PA8600 (PCX-W+)", "2.0" }, [pcxw2] = { "PA8700 (PCX-W2)", "2.0" }, [mako] = { "PA8800 (Mako)", "2.0" }, - [mako2] = { "PA8900 (Shortfin)", "2.0" } + [mako2] = { "PA8900 (Shortfin)","2.0" } }; -const char *parisc_hardware_description(struct parisc_device_id *id) +const char * __init parisc_hardware_description(struct parisc_device_id *id) { struct hp_hardware *listptr; @@ -1373,7 +1373,7 @@ const char *parisc_hardware_description(struct parisc_device_id *id) /* Interpret hversion (ret[0]) from PDC_MODEL(4)/PDC_MODEL_INFO(0) */ -enum cpu_type +enum cpu_type __init parisc_get_cpu_type(unsigned long hversion) { struct hp_cpu_type_mask *ptr; diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S index 8d072c44f300..781c3b9a3e46 100644 --- a/arch/parisc/kernel/hpmc.S +++ b/arch/parisc/kernel/hpmc.S @@ -84,6 +84,7 @@ END(hpmc_pim_data) .text .import intr_save, code + .align 16 ENTRY_CFI(os_hpmc) .os_hpmc: @@ -300,12 +301,15 @@ os_hpmc_6: b . nop + .align 16 /* make function length multiple of 16 bytes */ ENDPROC_CFI(os_hpmc) .os_hpmc_end: __INITRODATA +.globl os_hpmc_size .align 4 - .export os_hpmc_size + .type os_hpmc_size, @object + .size os_hpmc_size, 4 os_hpmc_size: .word .os_hpmc_end-.os_hpmc diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 6975a0627078..bbe46571ff96 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -138,6 +138,10 @@ void machine_power_off(void) pdc_soft_power_button(0); pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); + + /* ipmi_poweroff may have been installed. */ + if (pm_power_off) + pm_power_off(); /* It seems we have no way to power the system off via * software. The user has to press the button himself. */ @@ -151,7 +155,7 @@ void machine_power_off(void) for (;;); } -void (*pm_power_off)(void) = machine_power_off; +void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); void flush_thread(void) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 378a754ca186..8c99ebbe2bac 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -270,8 +270,8 @@ asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, { /* Make sure the shift for mmap2 is constant (12), no matter what PAGE_SIZE we have. */ - return sys_mmap_pgoff(addr, len, prot, flags, fd, - pgoff >> (PAGE_SHIFT - 12)); + return ksys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, @@ -279,7 +279,7 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, unsigned long offset) { if (!(offset & ~PAGE_MASK)) { - return sys_mmap_pgoff(addr, len, prot, flags, fd, + return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); } else { return -EINVAL; @@ -292,24 +292,24 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len, asmlinkage long parisc_truncate64(const char __user * path, unsigned int high, unsigned int low) { - return sys_truncate(path, (long)high << 32 | low); + return ksys_truncate(path, (long)high << 32 | low); } asmlinkage long parisc_ftruncate64(unsigned int fd, unsigned int high, unsigned int low) { - return sys_ftruncate(fd, (long)high << 32 | low); + return ksys_ftruncate(fd, (long)high << 32 | low); } /* stubs for the benefit of the syscall_table since truncate64 and truncate * are identical on LP64 */ asmlinkage long sys_truncate64(const char __user * path, unsigned long length) { - return sys_truncate(path, length); + return ksys_truncate(path, length); } asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length) { - return sys_ftruncate(fd, length); + return ksys_ftruncate(fd, length); } asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) { @@ -320,7 +320,7 @@ asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg asmlinkage long parisc_truncate64(const char __user * path, unsigned int high, unsigned int low) { - return sys_truncate64(path, (loff_t)high << 32 | low); + return ksys_truncate(path, (loff_t)high << 32 | low); } asmlinkage long parisc_ftruncate64(unsigned int fd, @@ -333,26 +333,26 @@ asmlinkage long parisc_ftruncate64(unsigned int fd, asmlinkage ssize_t parisc_pread64(unsigned int fd, char __user *buf, size_t count, unsigned int high, unsigned int low) { - return sys_pread64(fd, buf, count, (loff_t)high << 32 | low); + return ksys_pread64(fd, buf, count, (loff_t)high << 32 | low); } asmlinkage ssize_t parisc_pwrite64(unsigned int fd, const char __user *buf, size_t count, unsigned int high, unsigned int low) { - return sys_pwrite64(fd, buf, count, (loff_t)high << 32 | low); + return ksys_pwrite64(fd, buf, count, (loff_t)high << 32 | low); } asmlinkage ssize_t parisc_readahead(int fd, unsigned int high, unsigned int low, size_t count) { - return sys_readahead(fd, (loff_t)high << 32 | low, count); + return ksys_readahead(fd, (loff_t)high << 32 | low, count); } asmlinkage long parisc_fadvise64_64(int fd, unsigned int high_off, unsigned int low_off, unsigned int high_len, unsigned int low_len, int advice) { - return sys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off, + return ksys_fadvise64_64(fd, (loff_t)high_off << 32 | low_off, (loff_t)high_len << 32 | low_len, advice); } @@ -360,15 +360,15 @@ asmlinkage long parisc_sync_file_range(int fd, u32 hi_off, u32 lo_off, u32 hi_nbytes, u32 lo_nbytes, unsigned int flags) { - return sys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off, + return ksys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off, (loff_t)hi_nbytes << 32 | lo_nbytes, flags); } asmlinkage long parisc_fallocate(int fd, int mode, u32 offhi, u32 offlo, u32 lenhi, u32 lenlo) { - return sys_fallocate(fd, mode, ((u64)offhi << 32) | offlo, - ((u64)lenhi << 32) | lenlo); + return ksys_fallocate(fd, mode, ((u64)offhi << 32) | offlo, + ((u64)lenhi << 32) | lenlo); } long parisc_personality(unsigned long personality) |