aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/ipic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/ipic.c')
-rw-r--r--arch/powerpc/sysdev/ipic.c112
1 files changed, 45 insertions, 67 deletions
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index d7b9b9c69287..7367d17364cb 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -18,7 +18,7 @@
18#include <linux/stddef.h> 18#include <linux/stddef.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/sysdev.h> 21#include <linux/syscore_ops.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
@@ -521,12 +521,10 @@ static inline struct ipic * ipic_from_irq(unsigned int virq)
521 return primary_ipic; 521 return primary_ipic;
522} 522}
523 523
524#define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) 524static void ipic_unmask_irq(struct irq_data *d)
525
526static void ipic_unmask_irq(unsigned int virq)
527{ 525{
528 struct ipic *ipic = ipic_from_irq(virq); 526 struct ipic *ipic = ipic_from_irq(d->irq);
529 unsigned int src = ipic_irq_to_hw(virq); 527 unsigned int src = irqd_to_hwirq(d);
530 unsigned long flags; 528 unsigned long flags;
531 u32 temp; 529 u32 temp;
532 530
@@ -539,10 +537,10 @@ static void ipic_unmask_irq(unsigned int virq)
539 raw_spin_unlock_irqrestore(&ipic_lock, flags); 537 raw_spin_unlock_irqrestore(&ipic_lock, flags);
540} 538}
541 539
542static void ipic_mask_irq(unsigned int virq) 540static void ipic_mask_irq(struct irq_data *d)
543{ 541{
544 struct ipic *ipic = ipic_from_irq(virq); 542 struct ipic *ipic = ipic_from_irq(d->irq);
545 unsigned int src = ipic_irq_to_hw(virq); 543 unsigned int src = irqd_to_hwirq(d);
546 unsigned long flags; 544 unsigned long flags;
547 u32 temp; 545 u32 temp;
548 546
@@ -559,10 +557,10 @@ static void ipic_mask_irq(unsigned int virq)
559 raw_spin_unlock_irqrestore(&ipic_lock, flags); 557 raw_spin_unlock_irqrestore(&ipic_lock, flags);
560} 558}
561 559
562static void ipic_ack_irq(unsigned int virq) 560static void ipic_ack_irq(struct irq_data *d)
563{ 561{
564 struct ipic *ipic = ipic_from_irq(virq); 562 struct ipic *ipic = ipic_from_irq(d->irq);
565 unsigned int src = ipic_irq_to_hw(virq); 563 unsigned int src = irqd_to_hwirq(d);
566 unsigned long flags; 564 unsigned long flags;
567 u32 temp; 565 u32 temp;
568 566
@@ -578,10 +576,10 @@ static void ipic_ack_irq(unsigned int virq)
578 raw_spin_unlock_irqrestore(&ipic_lock, flags); 576 raw_spin_unlock_irqrestore(&ipic_lock, flags);
579} 577}
580 578
581static void ipic_mask_irq_and_ack(unsigned int virq) 579static void ipic_mask_irq_and_ack(struct irq_data *d)
582{ 580{
583 struct ipic *ipic = ipic_from_irq(virq); 581 struct ipic *ipic = ipic_from_irq(d->irq);
584 unsigned int src = ipic_irq_to_hw(virq); 582 unsigned int src = irqd_to_hwirq(d);
585 unsigned long flags; 583 unsigned long flags;
586 u32 temp; 584 u32 temp;
587 585
@@ -601,11 +599,10 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
601 raw_spin_unlock_irqrestore(&ipic_lock, flags); 599 raw_spin_unlock_irqrestore(&ipic_lock, flags);
602} 600}
603 601
604static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) 602static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
605{ 603{
606 struct ipic *ipic = ipic_from_irq(virq); 604 struct ipic *ipic = ipic_from_irq(d->irq);
607 unsigned int src = ipic_irq_to_hw(virq); 605 unsigned int src = irqd_to_hwirq(d);
608 struct irq_desc *desc = irq_to_desc(virq);
609 unsigned int vold, vnew, edibit; 606 unsigned int vold, vnew, edibit;
610 607
611 if (flow_type == IRQ_TYPE_NONE) 608 if (flow_type == IRQ_TYPE_NONE)
@@ -623,17 +620,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
623 printk(KERN_ERR "ipic: edge sense not supported on internal " 620 printk(KERN_ERR "ipic: edge sense not supported on internal "
624 "interrupts\n"); 621 "interrupts\n");
625 return -EINVAL; 622 return -EINVAL;
623
626 } 624 }
627 625
628 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 626 irqd_set_trigger_type(d, flow_type);
629 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
630 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 627 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
631 desc->status |= IRQ_LEVEL; 628 __irq_set_handler_locked(d->irq, handle_level_irq);
632 desc->handle_irq = handle_level_irq; 629 d->chip = &ipic_level_irq_chip;
633 desc->chip = &ipic_level_irq_chip;
634 } else { 630 } else {
635 desc->handle_irq = handle_edge_irq; 631 __irq_set_handler_locked(d->irq, handle_edge_irq);
636 desc->chip = &ipic_edge_irq_chip; 632 d->chip = &ipic_edge_irq_chip;
637 } 633 }
638 634
639 /* only EXT IRQ senses are programmable on ipic 635 /* only EXT IRQ senses are programmable on ipic
@@ -655,25 +651,25 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
655 } 651 }
656 if (vold != vnew) 652 if (vold != vnew)
657 ipic_write(ipic->regs, IPIC_SECNR, vnew); 653 ipic_write(ipic->regs, IPIC_SECNR, vnew);
658 return 0; 654 return IRQ_SET_MASK_OK_NOCOPY;
659} 655}
660 656
661/* level interrupts and edge interrupts have different ack operations */ 657/* level interrupts and edge interrupts have different ack operations */
662static struct irq_chip ipic_level_irq_chip = { 658static struct irq_chip ipic_level_irq_chip = {
663 .name = "IPIC", 659 .name = "IPIC",
664 .unmask = ipic_unmask_irq, 660 .irq_unmask = ipic_unmask_irq,
665 .mask = ipic_mask_irq, 661 .irq_mask = ipic_mask_irq,
666 .mask_ack = ipic_mask_irq, 662 .irq_mask_ack = ipic_mask_irq,
667 .set_type = ipic_set_irq_type, 663 .irq_set_type = ipic_set_irq_type,
668}; 664};
669 665
670static struct irq_chip ipic_edge_irq_chip = { 666static struct irq_chip ipic_edge_irq_chip = {
671 .name = "IPIC", 667 .name = "IPIC",
672 .unmask = ipic_unmask_irq, 668 .irq_unmask = ipic_unmask_irq,
673 .mask = ipic_mask_irq, 669 .irq_mask = ipic_mask_irq,
674 .mask_ack = ipic_mask_irq_and_ack, 670 .irq_mask_ack = ipic_mask_irq_and_ack,
675 .ack = ipic_ack_irq, 671 .irq_ack = ipic_ack_irq,
676 .set_type = ipic_set_irq_type, 672 .irq_set_type = ipic_set_irq_type,
677}; 673};
678 674
679static int ipic_host_match(struct irq_host *h, struct device_node *node) 675static int ipic_host_match(struct irq_host *h, struct device_node *node)
@@ -687,11 +683,11 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
687{ 683{
688 struct ipic *ipic = h->host_data; 684 struct ipic *ipic = h->host_data;
689 685
690 set_irq_chip_data(virq, ipic); 686 irq_set_chip_data(virq, ipic);
691 set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); 687 irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
692 688
693 /* Set default irq type */ 689 /* Set default irq type */
694 set_irq_type(virq, IRQ_TYPE_NONE); 690 irq_set_irq_type(virq, IRQ_TYPE_NONE);
695 691
696 return 0; 692 return 0;
697} 693}
@@ -795,7 +791,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
795int ipic_set_priority(unsigned int virq, unsigned int priority) 791int ipic_set_priority(unsigned int virq, unsigned int priority)
796{ 792{
797 struct ipic *ipic = ipic_from_irq(virq); 793 struct ipic *ipic = ipic_from_irq(virq);
798 unsigned int src = ipic_irq_to_hw(virq); 794 unsigned int src = virq_to_hw(virq);
799 u32 temp; 795 u32 temp;
800 796
801 if (priority > 7) 797 if (priority > 7)
@@ -823,7 +819,7 @@ int ipic_set_priority(unsigned int virq, unsigned int priority)
823void ipic_set_highest_priority(unsigned int virq) 819void ipic_set_highest_priority(unsigned int virq)
824{ 820{
825 struct ipic *ipic = ipic_from_irq(virq); 821 struct ipic *ipic = ipic_from_irq(virq);
826 unsigned int src = ipic_irq_to_hw(virq); 822 unsigned int src = virq_to_hw(virq);
827 u32 temp; 823 u32 temp;
828 824
829 temp = ipic_read(ipic->regs, IPIC_SICFR); 825 temp = ipic_read(ipic->regs, IPIC_SICFR);
@@ -904,7 +900,7 @@ static struct {
904 u32 sercr; 900 u32 sercr;
905} ipic_saved_state; 901} ipic_saved_state;
906 902
907static int ipic_suspend(struct sys_device *sdev, pm_message_t state) 903static int ipic_suspend(void)
908{ 904{
909 struct ipic *ipic = primary_ipic; 905 struct ipic *ipic = primary_ipic;
910 906
@@ -935,7 +931,7 @@ static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
935 return 0; 931 return 0;
936} 932}
937 933
938static int ipic_resume(struct sys_device *sdev) 934static void ipic_resume(void)
939{ 935{
940 struct ipic *ipic = primary_ipic; 936 struct ipic *ipic = primary_ipic;
941 937
@@ -951,44 +947,26 @@ static int ipic_resume(struct sys_device *sdev)
951 ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr); 947 ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
952 ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr); 948 ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
953 ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr); 949 ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
954
955 return 0;
956} 950}
957#else 951#else
958#define ipic_suspend NULL 952#define ipic_suspend NULL
959#define ipic_resume NULL 953#define ipic_resume NULL
960#endif 954#endif
961 955
962static struct sysdev_class ipic_sysclass = { 956static struct syscore_ops ipic_syscore_ops = {
963 .name = "ipic",
964 .suspend = ipic_suspend, 957 .suspend = ipic_suspend,
965 .resume = ipic_resume, 958 .resume = ipic_resume,
966}; 959};
967 960
968static struct sys_device device_ipic = { 961static int __init init_ipic_syscore(void)
969 .id = 0,
970 .cls = &ipic_sysclass,
971};
972
973static int __init init_ipic_sysfs(void)
974{ 962{
975 int rc;
976
977 if (!primary_ipic || !primary_ipic->regs) 963 if (!primary_ipic || !primary_ipic->regs)
978 return -ENODEV; 964 return -ENODEV;
979 printk(KERN_DEBUG "Registering ipic with sysfs...\n");
980 965
981 rc = sysdev_class_register(&ipic_sysclass); 966 printk(KERN_DEBUG "Registering ipic system core operations\n");
982 if (rc) { 967 register_syscore_ops(&ipic_syscore_ops);
983 printk(KERN_ERR "Failed registering ipic sys class\n"); 968
984 return -ENODEV;
985 }
986 rc = sysdev_register(&device_ipic);
987 if (rc) {
988 printk(KERN_ERR "Failed registering ipic sys device\n");
989 return -ENODEV;
990 }
991 return 0; 969 return 0;
992} 970}
993 971
994subsys_initcall(init_ipic_sysfs); 972subsys_initcall(init_ipic_syscore);