diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 1 | ||||
-rw-r--r-- | arch/powerpc/kernel/traps.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/vio.c | 27 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/setup.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/setup.c | 16 |
5 files changed, 42 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 5c330c3366e4..36d67a8d7cbb 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -510,6 +510,7 @@ int __devinit start_secondary(void *unused) | |||
510 | 510 | ||
511 | smp_store_cpu_info(cpu); | 511 | smp_store_cpu_info(cpu); |
512 | set_dec(tb_ticks_per_jiffy); | 512 | set_dec(tb_ticks_per_jiffy); |
513 | preempt_disable(); | ||
513 | cpu_callin_map[cpu] = 1; | 514 | cpu_callin_map[cpu] = 1; |
514 | 515 | ||
515 | smp_ops->setup_cpu(cpu); | 516 | smp_ops->setup_cpu(cpu); |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 32f215825e8d..0578f8387603 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -887,10 +887,6 @@ void altivec_unavailable_exception(struct pt_regs *regs) | |||
887 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); | 887 | die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); |
888 | } | 888 | } |
889 | 889 | ||
890 | #ifdef CONFIG_PPC64 | ||
891 | extern perf_irq_t perf_irq; | ||
892 | #endif | ||
893 | |||
894 | #if defined(CONFIG_PPC64) || defined(CONFIG_E500) | 890 | #if defined(CONFIG_PPC64) || defined(CONFIG_E500) |
895 | void performance_monitor_exception(struct pt_regs *regs) | 891 | void performance_monitor_exception(struct pt_regs *regs) |
896 | { | 892 | { |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 97082a4203ad..71a6addf9f7f 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/iommu.h> | 21 | #include <asm/iommu.h> |
22 | #include <asm/dma.h> | 22 | #include <asm/dma.h> |
23 | #include <asm/vio.h> | 23 | #include <asm/vio.h> |
24 | #include <asm/prom.h> | ||
24 | 25 | ||
25 | static const struct vio_device_id *vio_match_device( | 26 | static const struct vio_device_id *vio_match_device( |
26 | const struct vio_device_id *, const struct vio_dev *); | 27 | const struct vio_device_id *, const struct vio_dev *); |
@@ -265,7 +266,33 @@ static int vio_bus_match(struct device *dev, struct device_driver *drv) | |||
265 | return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); | 266 | return (ids != NULL) && (vio_match_device(ids, vio_dev) != NULL); |
266 | } | 267 | } |
267 | 268 | ||
269 | static int vio_hotplug(struct device *dev, char **envp, int num_envp, | ||
270 | char *buffer, int buffer_size) | ||
271 | { | ||
272 | const struct vio_dev *vio_dev = to_vio_dev(dev); | ||
273 | char *cp; | ||
274 | int length; | ||
275 | |||
276 | if (!num_envp) | ||
277 | return -ENOMEM; | ||
278 | |||
279 | if (!vio_dev->dev.platform_data) | ||
280 | return -ENODEV; | ||
281 | cp = (char *)get_property(vio_dev->dev.platform_data, "compatible", &length); | ||
282 | if (!cp) | ||
283 | return -ENODEV; | ||
284 | |||
285 | envp[0] = buffer; | ||
286 | length = scnprintf(buffer, buffer_size, "MODALIAS=vio:T%sS%s", | ||
287 | vio_dev->type, cp); | ||
288 | if (buffer_size - length <= 0) | ||
289 | return -ENOMEM; | ||
290 | envp[1] = NULL; | ||
291 | return 0; | ||
292 | } | ||
293 | |||
268 | struct bus_type vio_bus_type = { | 294 | struct bus_type vio_bus_type = { |
269 | .name = "vio", | 295 | .name = "vio", |
296 | .hotplug = vio_hotplug, | ||
270 | .match = vio_bus_match, | 297 | .match = vio_bus_match, |
271 | }; | 298 | }; |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index d3e4bf756c83..7f8f0cda6a74 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -694,20 +694,19 @@ static void iseries_shared_idle(void) | |||
694 | if (hvlpevent_is_pending()) | 694 | if (hvlpevent_is_pending()) |
695 | process_iSeries_events(); | 695 | process_iSeries_events(); |
696 | 696 | ||
697 | preempt_enable_no_resched(); | ||
697 | schedule(); | 698 | schedule(); |
699 | preempt_disable(); | ||
698 | } | 700 | } |
699 | } | 701 | } |
700 | 702 | ||
701 | static void iseries_dedicated_idle(void) | 703 | static void iseries_dedicated_idle(void) |
702 | { | 704 | { |
703 | long oldval; | 705 | long oldval; |
706 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
704 | 707 | ||
705 | while (1) { | 708 | while (1) { |
706 | oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); | 709 | if (!need_resched()) { |
707 | |||
708 | if (!oldval) { | ||
709 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
710 | |||
711 | while (!need_resched()) { | 710 | while (!need_resched()) { |
712 | ppc64_runlatch_off(); | 711 | ppc64_runlatch_off(); |
713 | HMT_low(); | 712 | HMT_low(); |
@@ -720,13 +719,12 @@ static void iseries_dedicated_idle(void) | |||
720 | } | 719 | } |
721 | 720 | ||
722 | HMT_medium(); | 721 | HMT_medium(); |
723 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
724 | } else { | ||
725 | set_need_resched(); | ||
726 | } | 722 | } |
727 | 723 | ||
728 | ppc64_runlatch_on(); | 724 | ppc64_runlatch_on(); |
725 | preempt_enable_no_resched(); | ||
729 | schedule(); | 726 | schedule(); |
727 | preempt_disable(); | ||
730 | } | 728 | } |
731 | } | 729 | } |
732 | 730 | ||
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e78c39368841..a093a0d4dd69 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -469,6 +469,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu) | |||
469 | * more. | 469 | * more. |
470 | */ | 470 | */ |
471 | clear_thread_flag(TIF_POLLING_NRFLAG); | 471 | clear_thread_flag(TIF_POLLING_NRFLAG); |
472 | smp_mb__after_clear_bit(); | ||
472 | 473 | ||
473 | /* | 474 | /* |
474 | * SMT dynamic mode. Cede will result in this thread going | 475 | * SMT dynamic mode. Cede will result in this thread going |
@@ -481,6 +482,7 @@ static inline void dedicated_idle_sleep(unsigned int cpu) | |||
481 | cede_processor(); | 482 | cede_processor(); |
482 | else | 483 | else |
483 | local_irq_enable(); | 484 | local_irq_enable(); |
485 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
484 | } else { | 486 | } else { |
485 | /* | 487 | /* |
486 | * Give the HV an opportunity at the processor, since we are | 488 | * Give the HV an opportunity at the processor, since we are |
@@ -492,11 +494,11 @@ static inline void dedicated_idle_sleep(unsigned int cpu) | |||
492 | 494 | ||
493 | static void pseries_dedicated_idle(void) | 495 | static void pseries_dedicated_idle(void) |
494 | { | 496 | { |
495 | long oldval; | ||
496 | struct paca_struct *lpaca = get_paca(); | 497 | struct paca_struct *lpaca = get_paca(); |
497 | unsigned int cpu = smp_processor_id(); | 498 | unsigned int cpu = smp_processor_id(); |
498 | unsigned long start_snooze; | 499 | unsigned long start_snooze; |
499 | unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); | 500 | unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); |
501 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
500 | 502 | ||
501 | while (1) { | 503 | while (1) { |
502 | /* | 504 | /* |
@@ -505,10 +507,7 @@ static void pseries_dedicated_idle(void) | |||
505 | */ | 507 | */ |
506 | lpaca->lppaca.idle = 1; | 508 | lpaca->lppaca.idle = 1; |
507 | 509 | ||
508 | oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); | 510 | if (!need_resched()) { |
509 | if (!oldval) { | ||
510 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
511 | |||
512 | start_snooze = __get_tb() + | 511 | start_snooze = __get_tb() + |
513 | *smt_snooze_delay * tb_ticks_per_usec; | 512 | *smt_snooze_delay * tb_ticks_per_usec; |
514 | 513 | ||
@@ -531,15 +530,14 @@ static void pseries_dedicated_idle(void) | |||
531 | } | 530 | } |
532 | 531 | ||
533 | HMT_medium(); | 532 | HMT_medium(); |
534 | clear_thread_flag(TIF_POLLING_NRFLAG); | ||
535 | } else { | ||
536 | set_need_resched(); | ||
537 | } | 533 | } |
538 | 534 | ||
539 | lpaca->lppaca.idle = 0; | 535 | lpaca->lppaca.idle = 0; |
540 | ppc64_runlatch_on(); | 536 | ppc64_runlatch_on(); |
541 | 537 | ||
538 | preempt_enable_no_resched(); | ||
542 | schedule(); | 539 | schedule(); |
540 | preempt_disable(); | ||
543 | 541 | ||
544 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) | 542 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) |
545 | cpu_die(); | 543 | cpu_die(); |
@@ -583,7 +581,9 @@ static void pseries_shared_idle(void) | |||
583 | lpaca->lppaca.idle = 0; | 581 | lpaca->lppaca.idle = 0; |
584 | ppc64_runlatch_on(); | 582 | ppc64_runlatch_on(); |
585 | 583 | ||
584 | preempt_enable_no_resched(); | ||
586 | schedule(); | 585 | schedule(); |
586 | preempt_disable(); | ||
587 | 587 | ||
588 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) | 588 | if (cpu_is_offline(cpu) && system_state == SYSTEM_RUNNING) |
589 | cpu_die(); | 589 | cpu_die(); |