X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Fkernel%2Ffirmware.c;h=6ab67aadd174bdf950b7b821e840a63558f74ced;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=8127a709887055de27284928649ffe5f0f5f81ec;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 8127a7098..6ab67aadd 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -65,6 +65,7 @@ #include #include +#include #include #include /* for boot_cpu_data */ @@ -176,7 +177,9 @@ void __init set_firmware_width(void) */ void pdc_emergency_unlock(void) { - spin_unlock(&pdc_lock); + /* Spinlock DEBUG code freaks out if we unconditionally unlock */ + if (spin_is_locked(&pdc_lock)) + spin_unlock(&pdc_lock); } @@ -234,11 +237,11 @@ int __init pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_inf #ifdef __LP64__ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) { + int retval = 0; + if (!is_pdc_pat()) return -1; - int retval = 0; - spin_lock_irq(&pdc_lock); retval = mem_pdc_call(PDC_PAT_CHASSIS_LOG, PDC_PAT_CHASSIS_WRITE_LOG, __pa(&state), __pa(&data)); spin_unlock_irq(&pdc_lock); @@ -1146,6 +1149,49 @@ int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, return retval; } + +/** + * pdc_pat_io_pci_cfg_read - Read PCI configuration space. + * @pci_addr: PCI configuration space address for which the read request is being made. + * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. + * @mem_addr: Pointer to return memory buffer. + * + */ +int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *mem_addr) +{ + int retval; + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_READ, + __pa(pdc_result), pci_addr, pci_size); + switch(pci_size) { + case 1: *(u8 *) mem_addr = (u8) pdc_result[0]; + case 2: *(u16 *)mem_addr = (u16) pdc_result[0]; + case 4: *(u32 *)mem_addr = (u32) pdc_result[0]; + } + spin_unlock_irq(&pdc_lock); + + return retval; +} + +/** + * pdc_pat_io_pci_cfg_write - Retrieve information about memory address ranges. + * @pci_addr: PCI configuration space address for which the write request is being made. + * @pci_size: Size of write in bytes. Valid values are 1, 2, and 4. + * @value: Pointer to 1, 2, or 4 byte value in low order end of argument to be + * written to PCI Config space. + * + */ +int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val) +{ + int retval; + + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_PAT_IO, PDC_PAT_IO_PCI_CONFIG_WRITE, + pci_addr, pci_size, val); + spin_unlock_irq(&pdc_lock); + + return retval; +} #endif /* __LP64__ */ @@ -1230,29 +1276,29 @@ struct wide_stack { long real64_call(unsigned long fn, ...) { va_list args; - extern struct wide_stack real_stack; + extern struct wide_stack real64_stack __attribute__ ((alias ("real_stack"))); extern unsigned long real64_call_asm(unsigned long *, unsigned long *, unsigned long); va_start(args, fn); - real_stack.arg0 = va_arg(args, unsigned long); - real_stack.arg1 = va_arg(args, unsigned long); - real_stack.arg2 = va_arg(args, unsigned long); - real_stack.arg3 = va_arg(args, unsigned long); - real_stack.arg4 = va_arg(args, unsigned long); - real_stack.arg5 = va_arg(args, unsigned long); - real_stack.arg6 = va_arg(args, unsigned long); - real_stack.arg7 = va_arg(args, unsigned long); - real_stack.arg8 = va_arg(args, unsigned long); - real_stack.arg9 = va_arg(args, unsigned long); - real_stack.arg10 = va_arg(args, unsigned long); - real_stack.arg11 = va_arg(args, unsigned long); - real_stack.arg12 = va_arg(args, unsigned long); - real_stack.arg13 = va_arg(args, unsigned long); + real64_stack.arg0 = va_arg(args, unsigned long); + real64_stack.arg1 = va_arg(args, unsigned long); + real64_stack.arg2 = va_arg(args, unsigned long); + real64_stack.arg3 = va_arg(args, unsigned long); + real64_stack.arg4 = va_arg(args, unsigned long); + real64_stack.arg5 = va_arg(args, unsigned long); + real64_stack.arg6 = va_arg(args, unsigned long); + real64_stack.arg7 = va_arg(args, unsigned long); + real64_stack.arg8 = va_arg(args, unsigned long); + real64_stack.arg9 = va_arg(args, unsigned long); + real64_stack.arg10 = va_arg(args, unsigned long); + real64_stack.arg11 = va_arg(args, unsigned long); + real64_stack.arg12 = va_arg(args, unsigned long); + real64_stack.arg13 = va_arg(args, unsigned long); va_end(args); - return real64_call_asm(&real_stack.sp, &real_stack.arg0, fn); + return real64_call_asm(&real64_stack.sp, &real64_stack.arg0, fn); } #endif /* __LP64__ */