diff options
author | Kyle McMartin <kyle@mcmartin.ca> | 2008-07-29 00:09:22 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@hera.kernel.org> | 2008-10-10 12:32:29 -0400 |
commit | 24b574d052a1996bac42fbd56715ab602092c291 (patch) | |
tree | d1c1d79a535123a3d8f193d0fb10f34413fe8ef3 | |
parent | deae26bf6a10e47983606f5df080b91e97650ead (diff) |
parisc: add pdc_coproc_cfg_unlocked and set_firmware_width_unlocked
These functions are called only when bringing up the monarch cpu,
so it is safe to call them without taking the pdc spinlock. In the
future, this may become relevant for lockdep, since these functions were
taking spinlocks before start_kernel called the lockdep initializers.
-rw-r--r-- | arch/parisc/include/asm/pdc.h | 2 | ||||
-rw-r--r-- | arch/parisc/kernel/firmware.c | 65 |
2 files changed, 46 insertions, 21 deletions
diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 46b75f9cce51..c584b00c6074 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h | |||
@@ -603,6 +603,7 @@ int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsi | |||
603 | int pdc_chassis_disp(unsigned long disp); | 603 | int pdc_chassis_disp(unsigned long disp); |
604 | int pdc_chassis_warn(unsigned long *warn); | 604 | int pdc_chassis_warn(unsigned long *warn); |
605 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); | 605 | int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); |
606 | int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info); | ||
606 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, | 607 | int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, |
607 | void *iodc_data, unsigned int iodc_data_size); | 608 | void *iodc_data, unsigned int iodc_data_size); |
608 | int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info, | 609 | int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info, |
@@ -641,6 +642,7 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr, | |||
641 | #endif | 642 | #endif |
642 | 643 | ||
643 | void set_firmware_width(void); | 644 | void set_firmware_width(void); |
645 | void set_firmware_width_unlocked(void); | ||
644 | int pdc_do_firm_test_reset(unsigned long ftc_bitmap); | 646 | int pdc_do_firm_test_reset(unsigned long ftc_bitmap); |
645 | int pdc_do_reset(void); | 647 | int pdc_do_reset(void); |
646 | int pdc_soft_power_info(unsigned long *power_reg); | 648 | int pdc_soft_power_info(unsigned long *power_reg); |
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 99a9e505edf9..03f26bd75bd8 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c | |||
@@ -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 | /** |