diff options
Diffstat (limited to 'arch/parisc/kernel/firmware.c')
| -rw-r--r-- | arch/parisc/kernel/firmware.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 7177a6cd1b7f..03f26bd75bd8 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
| @@ -71,8 +71,8 @@ | |||
| 71 | #include <asm/processor.h> /* for boot_cpu_data */ | 71 | #include <asm/processor.h> /* for boot_cpu_data */ |
| 72 | 72 | ||
| 73 | static DEFINE_SPINLOCK(pdc_lock); | 73 | static DEFINE_SPINLOCK(pdc_lock); |
| 74 | static unsigned long pdc_result[32] __attribute__ ((aligned (8))); | 74 | extern unsigned long pdc_result[NUM_PDC_RESULT]; |
| 75 | static unsigned long pdc_result2[32] __attribute__ ((aligned (8))); | 75 | extern unsigned long pdc_result2[NUM_PDC_RESULT]; |
| 76 | 76 | ||
| 77 | #ifdef CONFIG_64BIT | 77 | #ifdef CONFIG_64BIT |
| 78 | #define WIDE_FIRMWARE 0x1 | 78 | #define WIDE_FIRMWARE 0x1 |
| @@ -150,26 +150,40 @@ static void convert_to_wide(unsigned long *addr) | |||
| 150 | #endif | 150 | #endif |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | #ifdef CONFIG_64BIT | ||
| 154 | void __init set_firmware_width_unlocked(void) | ||
| 155 | { | ||
| 156 | int ret; | ||
| 157 | |||
| 158 | ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, | ||
| 159 | __pa(pdc_result), 0); | ||
| 160 | convert_to_wide(pdc_result); | ||
| 161 | if (pdc_result[0] != NARROW_FIRMWARE) | ||
| 162 | parisc_narrow_firmware = 0; | ||
| 163 | } | ||
| 164 | |||
| 153 | /** | 165 | /** |
| 154 | * set_firmware_width - Determine if the firmware is wide or narrow. | 166 | * set_firmware_width - Determine if the firmware is wide or narrow. |
| 155 | * | 167 | * |
| 156 | * This function must be called before any pdc_* function that uses the convert_to_wide | 168 | * This function must be called before any pdc_* function that uses the |
| 157 | * function. | 169 | * convert_to_wide function. |
| 158 | */ | 170 | */ |
| 159 | void __init set_firmware_width(void) | 171 | void __init set_firmware_width(void) |
| 160 | { | 172 | { |
| 161 | #ifdef CONFIG_64BIT | ||
| 162 | int retval; | ||
| 163 | unsigned long flags; | 173 | unsigned long flags; |
| 174 | spin_lock_irqsave(&pdc_lock, flags); | ||
| 175 | set_firmware_width_unlocked(); | ||
| 176 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 177 | } | ||
| 178 | #else | ||
| 179 | void __init set_firmware_width_unlocked(void) { | ||
| 180 | return; | ||
| 181 | } | ||
| 164 | 182 | ||
| 165 | spin_lock_irqsave(&pdc_lock, flags); | 183 | void __init set_firmware_width(void) { |
| 166 | retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0); | 184 | return; |
| 167 | convert_to_wide(pdc_result); | ||
| 168 | if(pdc_result[0] != NARROW_FIRMWARE) | ||
| 169 | parisc_narrow_firmware = 0; | ||
| 170 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 171 | #endif | ||
| 172 | } | 185 | } |
| 186 | #endif /*CONFIG_64BIT*/ | ||
| 173 | 187 | ||
| 174 | /** | 188 | /** |
| 175 | * pdc_emergency_unlock - Unlock the linux pdc lock | 189 | * pdc_emergency_unlock - Unlock the linux pdc lock |
| @@ -288,6 +302,20 @@ int pdc_chassis_warn(unsigned long *warn) | |||
| 288 | return retval; | 302 | return retval; |
| 289 | } | 303 | } |
| 290 | 304 | ||
| 305 | int __init pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info) | ||
| 306 | { | ||
| 307 | int ret; | ||
| 308 | |||
| 309 | ret = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result)); | ||
| 310 | convert_to_wide(pdc_result); | ||
| 311 | pdc_coproc_info->ccr_functional = pdc_result[0]; | ||
| 312 | pdc_coproc_info->ccr_present = pdc_result[1]; | ||
| 313 | pdc_coproc_info->revision = pdc_result[17]; | ||
| 314 | pdc_coproc_info->model = pdc_result[18]; | ||
| 315 | |||
| 316 | return ret; | ||
| 317 | } | ||
| 318 | |||
| 291 | /** | 319 | /** |
| 292 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. | 320 | * pdc_coproc_cfg - To identify coprocessors attached to the processor. |
| 293 | * @pdc_coproc_info: Return buffer address. | 321 | * @pdc_coproc_info: Return buffer address. |
| @@ -297,19 +325,14 @@ int pdc_chassis_warn(unsigned long *warn) | |||
| 297 | */ | 325 | */ |
| 298 | int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) | 326 | int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) |
| 299 | { | 327 | { |
| 300 | int retval; | 328 | int ret; |
| 301 | unsigned long flags; | 329 | unsigned long flags; |
| 302 | 330 | ||
| 303 | spin_lock_irqsave(&pdc_lock, flags); | 331 | spin_lock_irqsave(&pdc_lock, flags); |
| 304 | retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result)); | 332 | ret = pdc_coproc_cfg_unlocked(pdc_coproc_info); |
| 305 | convert_to_wide(pdc_result); | 333 | spin_unlock_irqrestore(&pdc_lock, flags); |
| 306 | pdc_coproc_info->ccr_functional = pdc_result[0]; | ||
| 307 | pdc_coproc_info->ccr_present = pdc_result[1]; | ||
| 308 | pdc_coproc_info->revision = pdc_result[17]; | ||
| 309 | pdc_coproc_info->model = pdc_result[18]; | ||
| 310 | spin_unlock_irqrestore(&pdc_lock, flags); | ||
| 311 | 334 | ||
| 312 | return retval; | 335 | return ret; |
| 313 | } | 336 | } |
| 314 | 337 | ||
| 315 | /** | 338 | /** |
