aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/prom.c')
-rw-r--r--arch/sparc64/kernel/prom.c112
1 files changed, 95 insertions, 17 deletions
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
index 5e1fcd05160d..c54d4d8af014 100644
--- a/arch/sparc64/kernel/prom.c
+++ b/arch/sparc64/kernel/prom.c
@@ -386,11 +386,9 @@ static unsigned int psycho_irq_build(struct device_node *dp,
386 386
387 /* Now build the IRQ bucket. */ 387 /* Now build the IRQ bucket. */
388 imap = controller_regs + imap_off; 388 imap = controller_regs + imap_off;
389 imap += 4;
390 389
391 iclr_off = psycho_iclr_offset(ino); 390 iclr_off = psycho_iclr_offset(ino);
392 iclr = controller_regs + iclr_off; 391 iclr = controller_regs + iclr_off;
393 iclr += 4;
394 392
395 if ((ino & 0x20) == 0) 393 if ((ino & 0x20) == 0)
396 inofixup = ino & 0x03; 394 inofixup = ino & 0x03;
@@ -398,7 +396,7 @@ static unsigned int psycho_irq_build(struct device_node *dp,
398 return build_irq(inofixup, iclr, imap); 396 return build_irq(inofixup, iclr, imap);
399} 397}
400 398
401static void psycho_irq_trans_init(struct device_node *dp) 399static void __init psycho_irq_trans_init(struct device_node *dp)
402{ 400{
403 const struct linux_prom64_registers *regs; 401 const struct linux_prom64_registers *regs;
404 402
@@ -613,11 +611,9 @@ static unsigned int sabre_irq_build(struct device_node *dp,
613 611
614 /* Now build the IRQ bucket. */ 612 /* Now build the IRQ bucket. */
615 imap = controller_regs + imap_off; 613 imap = controller_regs + imap_off;
616 imap += 4;
617 614
618 iclr_off = sabre_iclr_offset(ino); 615 iclr_off = sabre_iclr_offset(ino);
619 iclr = controller_regs + iclr_off; 616 iclr = controller_regs + iclr_off;
620 iclr += 4;
621 617
622 if ((ino & 0x20) == 0) 618 if ((ino & 0x20) == 0)
623 inofixup = ino & 0x03; 619 inofixup = ino & 0x03;
@@ -640,7 +636,7 @@ static unsigned int sabre_irq_build(struct device_node *dp,
640 return virt_irq; 636 return virt_irq;
641} 637}
642 638
643static void sabre_irq_trans_init(struct device_node *dp) 639static void __init sabre_irq_trans_init(struct device_node *dp)
644{ 640{
645 const struct linux_prom64_registers *regs; 641 const struct linux_prom64_registers *regs;
646 struct sabre_irq_data *irq_data; 642 struct sabre_irq_data *irq_data;
@@ -679,13 +675,14 @@ static unsigned long schizo_iclr_offset(unsigned long ino)
679static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs, 675static unsigned long schizo_ino_to_iclr(unsigned long pbm_regs,
680 unsigned int ino) 676 unsigned int ino)
681{ 677{
682 return pbm_regs + schizo_iclr_offset(ino) + 4; 678
679 return pbm_regs + schizo_iclr_offset(ino);
683} 680}
684 681
685static unsigned long schizo_ino_to_imap(unsigned long pbm_regs, 682static unsigned long schizo_ino_to_imap(unsigned long pbm_regs,
686 unsigned int ino) 683 unsigned int ino)
687{ 684{
688 return pbm_regs + schizo_imap_offset(ino) + 4; 685 return pbm_regs + schizo_imap_offset(ino);
689} 686}
690 687
691#define schizo_read(__reg) \ 688#define schizo_read(__reg) \
@@ -796,7 +793,8 @@ static unsigned int schizo_irq_build(struct device_node *dp,
796 return virt_irq; 793 return virt_irq;
797} 794}
798 795
799static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo) 796static void __init __schizo_irq_trans_init(struct device_node *dp,
797 int is_tomatillo)
800{ 798{
801 const struct linux_prom64_registers *regs; 799 const struct linux_prom64_registers *regs;
802 struct schizo_irq_data *irq_data; 800 struct schizo_irq_data *irq_data;
@@ -818,12 +816,12 @@ static void __schizo_irq_trans_init(struct device_node *dp, int is_tomatillo)
818 irq_data->chip_version = of_getintprop_default(dp, "version#", 0); 816 irq_data->chip_version = of_getintprop_default(dp, "version#", 0);
819} 817}
820 818
821static void schizo_irq_trans_init(struct device_node *dp) 819static void __init schizo_irq_trans_init(struct device_node *dp)
822{ 820{
823 __schizo_irq_trans_init(dp, 0); 821 __schizo_irq_trans_init(dp, 0);
824} 822}
825 823
826static void tomatillo_irq_trans_init(struct device_node *dp) 824static void __init tomatillo_irq_trans_init(struct device_node *dp)
827{ 825{
828 __schizo_irq_trans_init(dp, 1); 826 __schizo_irq_trans_init(dp, 1);
829} 827}
@@ -837,7 +835,7 @@ static unsigned int pci_sun4v_irq_build(struct device_node *dp,
837 return sun4v_build_irq(devhandle, devino); 835 return sun4v_build_irq(devhandle, devino);
838} 836}
839 837
840static void pci_sun4v_irq_trans_init(struct device_node *dp) 838static void __init pci_sun4v_irq_trans_init(struct device_node *dp)
841{ 839{
842 const struct linux_prom64_registers *regs; 840 const struct linux_prom64_registers *regs;
843 841
@@ -848,6 +846,85 @@ static void pci_sun4v_irq_trans_init(struct device_node *dp)
848 dp->irq_trans->data = (void *) (unsigned long) 846 dp->irq_trans->data = (void *) (unsigned long)
849 ((regs->phys_addr >> 32UL) & 0x0fffffff); 847 ((regs->phys_addr >> 32UL) & 0x0fffffff);
850} 848}
849
850struct fire_irq_data {
851 unsigned long pbm_regs;
852 u32 portid;
853};
854
855#define FIRE_IMAP_BASE 0x001000
856#define FIRE_ICLR_BASE 0x001400
857
858static unsigned long fire_imap_offset(unsigned long ino)
859{
860 return FIRE_IMAP_BASE + (ino * 8UL);
861}
862
863static unsigned long fire_iclr_offset(unsigned long ino)
864{
865 return FIRE_ICLR_BASE + (ino * 8UL);
866}
867
868static unsigned long fire_ino_to_iclr(unsigned long pbm_regs,
869 unsigned int ino)
870{
871 return pbm_regs + fire_iclr_offset(ino);
872}
873
874static unsigned long fire_ino_to_imap(unsigned long pbm_regs,
875 unsigned int ino)
876{
877 return pbm_regs + fire_imap_offset(ino);
878}
879
880static unsigned int fire_irq_build(struct device_node *dp,
881 unsigned int ino,
882 void *_data)
883{
884 struct fire_irq_data *irq_data = _data;
885 unsigned long pbm_regs = irq_data->pbm_regs;
886 unsigned long imap, iclr;
887 unsigned long int_ctrlr;
888
889 ino &= 0x3f;
890
891 /* Now build the IRQ bucket. */
892 imap = fire_ino_to_imap(pbm_regs, ino);
893 iclr = fire_ino_to_iclr(pbm_regs, ino);
894
895 /* Set the interrupt controller number. */
896 int_ctrlr = 1 << 6;
897 upa_writeq(int_ctrlr, imap);
898
899 /* The interrupt map registers do not have an INO field
900 * like other chips do. They return zero in the INO
901 * field, and the interrupt controller number is controlled
902 * in bits 6 thru 9. So in order for build_irq() to get
903 * the INO right we pass it in as part of the fixup
904 * which will get added to the map register zero value
905 * read by build_irq().
906 */
907 ino |= (irq_data->portid << 6);
908 ino -= int_ctrlr;
909 return build_irq(ino, iclr, imap);
910}
911
912static void __init fire_irq_trans_init(struct device_node *dp)
913{
914 const struct linux_prom64_registers *regs;
915 struct fire_irq_data *irq_data;
916
917 dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
918 dp->irq_trans->irq_build = fire_irq_build;
919
920 irq_data = prom_early_alloc(sizeof(struct fire_irq_data));
921
922 regs = of_get_property(dp, "reg", NULL);
923 dp->irq_trans->data = irq_data;
924
925 irq_data->pbm_regs = regs[0].phys_addr;
926 irq_data->portid = of_getintprop_default(dp, "portid", 0);
927}
851#endif /* CONFIG_PCI */ 928#endif /* CONFIG_PCI */
852 929
853#ifdef CONFIG_SBUS 930#ifdef CONFIG_SBUS
@@ -995,7 +1072,7 @@ static unsigned int sbus_of_build_irq(struct device_node *dp,
995 return build_irq(sbus_level, iclr, imap); 1072 return build_irq(sbus_level, iclr, imap);
996} 1073}
997 1074
998static void sbus_irq_trans_init(struct device_node *dp) 1075static void __init sbus_irq_trans_init(struct device_node *dp)
999{ 1076{
1000 const struct linux_prom64_registers *regs; 1077 const struct linux_prom64_registers *regs;
1001 1078
@@ -1042,7 +1119,7 @@ static unsigned int central_build_irq(struct device_node *dp,
1042 return build_irq(0, iclr, imap); 1119 return build_irq(0, iclr, imap);
1043} 1120}
1044 1121
1045static void central_irq_trans_init(struct device_node *dp) 1122static void __init central_irq_trans_init(struct device_node *dp)
1046{ 1123{
1047 dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller)); 1124 dp->irq_trans = prom_early_alloc(sizeof(struct of_irq_controller));
1048 dp->irq_trans->irq_build = central_build_irq; 1125 dp->irq_trans->irq_build = central_build_irq;
@@ -1056,7 +1133,7 @@ struct irq_trans {
1056}; 1133};
1057 1134
1058#ifdef CONFIG_PCI 1135#ifdef CONFIG_PCI
1059static struct irq_trans pci_irq_trans_table[] = { 1136static struct irq_trans __initdata pci_irq_trans_table[] = {
1060 { "SUNW,sabre", sabre_irq_trans_init }, 1137 { "SUNW,sabre", sabre_irq_trans_init },
1061 { "pci108e,a000", sabre_irq_trans_init }, 1138 { "pci108e,a000", sabre_irq_trans_init },
1062 { "pci108e,a001", sabre_irq_trans_init }, 1139 { "pci108e,a001", sabre_irq_trans_init },
@@ -1069,6 +1146,7 @@ static struct irq_trans pci_irq_trans_table[] = {
1069 { "SUNW,tomatillo", tomatillo_irq_trans_init }, 1146 { "SUNW,tomatillo", tomatillo_irq_trans_init },
1070 { "pci108e,a801", tomatillo_irq_trans_init }, 1147 { "pci108e,a801", tomatillo_irq_trans_init },
1071 { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init }, 1148 { "SUNW,sun4v-pci", pci_sun4v_irq_trans_init },
1149 { "pciex108e,80f0", fire_irq_trans_init },
1072}; 1150};
1073#endif 1151#endif
1074 1152
@@ -1081,7 +1159,7 @@ static unsigned int sun4v_vdev_irq_build(struct device_node *dp,
1081 return sun4v_build_irq(devhandle, devino); 1159 return sun4v_build_irq(devhandle, devino);
1082} 1160}
1083 1161
1084static void sun4v_vdev_irq_trans_init(struct device_node *dp) 1162static void __init sun4v_vdev_irq_trans_init(struct device_node *dp)
1085{ 1163{
1086 const struct linux_prom64_registers *regs; 1164 const struct linux_prom64_registers *regs;
1087 1165
@@ -1093,7 +1171,7 @@ static void sun4v_vdev_irq_trans_init(struct device_node *dp)
1093 ((regs->phys_addr >> 32UL) & 0x0fffffff); 1171 ((regs->phys_addr >> 32UL) & 0x0fffffff);
1094} 1172}
1095 1173
1096static void irq_trans_init(struct device_node *dp) 1174static void __init irq_trans_init(struct device_node *dp)
1097{ 1175{
1098#ifdef CONFIG_PCI 1176#ifdef CONFIG_PCI
1099 const char *model; 1177 const char *model;