diff options
Diffstat (limited to 'drivers/pci/hotplug/shpchp_hpc.c')
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 149 |
1 files changed, 77 insertions, 72 deletions
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 86dc39847769..5f5e8d2e3552 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c | |||
@@ -660,6 +660,75 @@ static int hpc_slot_disable(struct slot * slot) | |||
660 | return retval; | 660 | return retval; |
661 | } | 661 | } |
662 | 662 | ||
663 | static int shpc_get_cur_bus_speed(struct controller *ctrl) | ||
664 | { | ||
665 | int retval = 0; | ||
666 | struct pci_bus *bus = ctrl->pci_dev->subordinate; | ||
667 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
668 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
669 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
670 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
671 | |||
672 | if ((pi == 1) && (speed_mode > 4)) { | ||
673 | retval = -ENODEV; | ||
674 | goto out; | ||
675 | } | ||
676 | |||
677 | switch (speed_mode) { | ||
678 | case 0x0: | ||
679 | bus_speed = PCI_SPEED_33MHz; | ||
680 | break; | ||
681 | case 0x1: | ||
682 | bus_speed = PCI_SPEED_66MHz; | ||
683 | break; | ||
684 | case 0x2: | ||
685 | bus_speed = PCI_SPEED_66MHz_PCIX; | ||
686 | break; | ||
687 | case 0x3: | ||
688 | bus_speed = PCI_SPEED_100MHz_PCIX; | ||
689 | break; | ||
690 | case 0x4: | ||
691 | bus_speed = PCI_SPEED_133MHz_PCIX; | ||
692 | break; | ||
693 | case 0x5: | ||
694 | bus_speed = PCI_SPEED_66MHz_PCIX_ECC; | ||
695 | break; | ||
696 | case 0x6: | ||
697 | bus_speed = PCI_SPEED_100MHz_PCIX_ECC; | ||
698 | break; | ||
699 | case 0x7: | ||
700 | bus_speed = PCI_SPEED_133MHz_PCIX_ECC; | ||
701 | break; | ||
702 | case 0x8: | ||
703 | bus_speed = PCI_SPEED_66MHz_PCIX_266; | ||
704 | break; | ||
705 | case 0x9: | ||
706 | bus_speed = PCI_SPEED_100MHz_PCIX_266; | ||
707 | break; | ||
708 | case 0xa: | ||
709 | bus_speed = PCI_SPEED_133MHz_PCIX_266; | ||
710 | break; | ||
711 | case 0xb: | ||
712 | bus_speed = PCI_SPEED_66MHz_PCIX_533; | ||
713 | break; | ||
714 | case 0xc: | ||
715 | bus_speed = PCI_SPEED_100MHz_PCIX_533; | ||
716 | break; | ||
717 | case 0xd: | ||
718 | bus_speed = PCI_SPEED_133MHz_PCIX_533; | ||
719 | break; | ||
720 | default: | ||
721 | retval = -ENODEV; | ||
722 | break; | ||
723 | } | ||
724 | |||
725 | out: | ||
726 | bus->cur_bus_speed = bus_speed; | ||
727 | dbg("Current bus speed = %d\n", bus_speed); | ||
728 | return retval; | ||
729 | } | ||
730 | |||
731 | |||
663 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | 732 | static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) |
664 | { | 733 | { |
665 | int retval; | 734 | int retval; |
@@ -720,6 +789,8 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) | |||
720 | retval = shpc_write_cmd(slot, 0, cmd); | 789 | retval = shpc_write_cmd(slot, 0, cmd); |
721 | if (retval) | 790 | if (retval) |
722 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); | 791 | ctrl_err(ctrl, "%s: Write command failed!\n", __func__); |
792 | else | ||
793 | shpc_get_cur_bus_speed(ctrl); | ||
723 | 794 | ||
724 | return retval; | 795 | return retval; |
725 | } | 796 | } |
@@ -803,10 +874,10 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) | |||
803 | return IRQ_HANDLED; | 874 | return IRQ_HANDLED; |
804 | } | 875 | } |
805 | 876 | ||
806 | static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | 877 | static int shpc_get_max_bus_speed(struct controller *ctrl) |
807 | { | 878 | { |
808 | int retval = 0; | 879 | int retval = 0; |
809 | struct controller *ctrl = slot->ctrl; | 880 | struct pci_bus *bus = ctrl->pci_dev->subordinate; |
810 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | 881 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; |
811 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | 882 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); |
812 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); | 883 | u32 slot_avail1 = shpc_readl(ctrl, SLOT_AVAIL1); |
@@ -842,79 +913,12 @@ static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) | |||
842 | retval = -ENODEV; | 913 | retval = -ENODEV; |
843 | } | 914 | } |
844 | 915 | ||
845 | *value = bus_speed; | 916 | bus->max_bus_speed = bus_speed; |
846 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); | 917 | ctrl_dbg(ctrl, "Max bus speed = %d\n", bus_speed); |
847 | 918 | ||
848 | return retval; | 919 | return retval; |
849 | } | 920 | } |
850 | 921 | ||
851 | static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) | ||
852 | { | ||
853 | int retval = 0; | ||
854 | struct controller *ctrl = slot->ctrl; | ||
855 | enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; | ||
856 | u16 sec_bus_reg = shpc_readw(ctrl, SEC_BUS_CONFIG); | ||
857 | u8 pi = shpc_readb(ctrl, PROG_INTERFACE); | ||
858 | u8 speed_mode = (pi == 2) ? (sec_bus_reg & 0xF) : (sec_bus_reg & 0x7); | ||
859 | |||
860 | if ((pi == 1) && (speed_mode > 4)) { | ||
861 | *value = PCI_SPEED_UNKNOWN; | ||
862 | return -ENODEV; | ||
863 | } | ||
864 | |||
865 | switch (speed_mode) { | ||
866 | case 0x0: | ||
867 | *value = PCI_SPEED_33MHz; | ||
868 | break; | ||
869 | case 0x1: | ||
870 | *value = PCI_SPEED_66MHz; | ||
871 | break; | ||
872 | case 0x2: | ||
873 | *value = PCI_SPEED_66MHz_PCIX; | ||
874 | break; | ||
875 | case 0x3: | ||
876 | *value = PCI_SPEED_100MHz_PCIX; | ||
877 | break; | ||
878 | case 0x4: | ||
879 | *value = PCI_SPEED_133MHz_PCIX; | ||
880 | break; | ||
881 | case 0x5: | ||
882 | *value = PCI_SPEED_66MHz_PCIX_ECC; | ||
883 | break; | ||
884 | case 0x6: | ||
885 | *value = PCI_SPEED_100MHz_PCIX_ECC; | ||
886 | break; | ||
887 | case 0x7: | ||
888 | *value = PCI_SPEED_133MHz_PCIX_ECC; | ||
889 | break; | ||
890 | case 0x8: | ||
891 | *value = PCI_SPEED_66MHz_PCIX_266; | ||
892 | break; | ||
893 | case 0x9: | ||
894 | *value = PCI_SPEED_100MHz_PCIX_266; | ||
895 | break; | ||
896 | case 0xa: | ||
897 | *value = PCI_SPEED_133MHz_PCIX_266; | ||
898 | break; | ||
899 | case 0xb: | ||
900 | *value = PCI_SPEED_66MHz_PCIX_533; | ||
901 | break; | ||
902 | case 0xc: | ||
903 | *value = PCI_SPEED_100MHz_PCIX_533; | ||
904 | break; | ||
905 | case 0xd: | ||
906 | *value = PCI_SPEED_133MHz_PCIX_533; | ||
907 | break; | ||
908 | default: | ||
909 | *value = PCI_SPEED_UNKNOWN; | ||
910 | retval = -ENODEV; | ||
911 | break; | ||
912 | } | ||
913 | |||
914 | ctrl_dbg(ctrl, "Current bus speed = %d\n", bus_speed); | ||
915 | return retval; | ||
916 | } | ||
917 | |||
918 | static struct hpc_ops shpchp_hpc_ops = { | 922 | static struct hpc_ops shpchp_hpc_ops = { |
919 | .power_on_slot = hpc_power_on_slot, | 923 | .power_on_slot = hpc_power_on_slot, |
920 | .slot_enable = hpc_slot_enable, | 924 | .slot_enable = hpc_slot_enable, |
@@ -926,8 +930,6 @@ static struct hpc_ops shpchp_hpc_ops = { | |||
926 | .get_latch_status = hpc_get_latch_status, | 930 | .get_latch_status = hpc_get_latch_status, |
927 | .get_adapter_status = hpc_get_adapter_status, | 931 | .get_adapter_status = hpc_get_adapter_status, |
928 | 932 | ||
929 | .get_max_bus_speed = hpc_get_max_bus_speed, | ||
930 | .get_cur_bus_speed = hpc_get_cur_bus_speed, | ||
931 | .get_adapter_speed = hpc_get_adapter_speed, | 933 | .get_adapter_speed = hpc_get_adapter_speed, |
932 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, | 934 | .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, |
933 | .get_prog_int = hpc_get_prog_int, | 935 | .get_prog_int = hpc_get_prog_int, |
@@ -1086,6 +1088,9 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) | |||
1086 | } | 1088 | } |
1087 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); | 1089 | ctrl_dbg(ctrl, "HPC at %s irq=%x\n", pci_name(pdev), pdev->irq); |
1088 | 1090 | ||
1091 | shpc_get_max_bus_speed(ctrl); | ||
1092 | shpc_get_cur_bus_speed(ctrl); | ||
1093 | |||
1089 | /* | 1094 | /* |
1090 | * If this is the first controller to be initialized, | 1095 | * If this is the first controller to be initialized, |
1091 | * initialize the shpchpd work queue | 1096 | * initialize the shpchpd work queue |