aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc
diff options
context:
space:
mode:
authorKyle McMartin <kyle@mcmartin.ca>2008-07-29 00:09:22 -0400
committerKyle McMartin <kyle@hera.kernel.org>2008-10-10 12:32:29 -0400
commit24b574d052a1996bac42fbd56715ab602092c291 (patch)
treed1c1d79a535123a3d8f193d0fb10f34413fe8ef3 /arch/parisc
parentdeae26bf6a10e47983606f5df080b91e97650ead (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.
Diffstat (limited to 'arch/parisc')
-rw-r--r--arch/parisc/include/asm/pdc.h2
-rw-r--r--arch/parisc/kernel/firmware.c65
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
603int pdc_chassis_disp(unsigned long disp); 603int pdc_chassis_disp(unsigned long disp);
604int pdc_chassis_warn(unsigned long *warn); 604int pdc_chassis_warn(unsigned long *warn);
605int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info); 605int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
606int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info);
606int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index, 607int 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);
608int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info, 609int 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
643void set_firmware_width(void); 644void set_firmware_width(void);
645void set_firmware_width_unlocked(void);
644int pdc_do_firm_test_reset(unsigned long ftc_bitmap); 646int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
645int pdc_do_reset(void); 647int pdc_do_reset(void);
646int pdc_soft_power_info(unsigned long *power_reg); 648int 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
154void __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 */
159void __init set_firmware_width(void) 171void __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
179void __init set_firmware_width_unlocked(void) {
180 return;
181}
164 182
165 spin_lock_irqsave(&pdc_lock, flags); 183void __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
305int __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 */
298int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info) 326int __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/**