aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-10-03 14:12:57 -0400
committerBjorn Helgaas <bhelgaas@google.com>2015-10-09 12:12:18 -0400
commit49cb1f718360f86075341e35fad57748a5c182f9 (patch)
treea152a34ceb473a23b21763f8dbe9ea3011109550
parentab7ea3053575f31264bc8b8357203bdf970a6248 (diff)
PCI: mvebu: Move port parsing and resource claiming to separate function
Move the PCIe port parsing and resource claiming to a separate function in preparation to add proper cleanup of claimed resources. Tested-by: Willy Tarreau <w@1wt.eu> (Iomega iConnect Kirkwood, MiraBox Armada 370) Tested-by: Andrew Lunn <andrew@lunn.ch> (D-Link DIR664 Kirkwood) Tested-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> (Armada XP GP) Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
-rw-r--r--drivers/pci/host/pci-mvebu.c130
1 files changed, 74 insertions, 56 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 19144ed7bdad..13ab0350f7fb 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -928,6 +928,76 @@ static int mvebu_pcie_resume(struct device *dev)
928 return 0; 928 return 0;
929} 929}
930 930
931static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
932 struct mvebu_pcie_port *port, struct device_node *child)
933{
934 struct device *dev = &pcie->pdev->dev;
935 enum of_gpio_flags flags;
936 int ret;
937
938 port->pcie = pcie;
939
940 if (of_property_read_u32(child, "marvell,pcie-port", &port->port)) {
941 dev_warn(dev, "ignoring %s, missing pcie-port property\n",
942 of_node_full_name(child));
943 goto skip;
944 }
945
946 if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane))
947 port->lane = 0;
948
949 port->name = kasprintf(GFP_KERNEL, "pcie%d.%d", port->port, port->lane);
950
951 port->devfn = of_pci_get_devfn(child);
952 if (port->devfn < 0)
953 goto skip;
954
955 ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
956 &port->mem_target, &port->mem_attr);
957 if (ret < 0) {
958 dev_err(dev, "%s: cannot get tgt/attr for mem window\n",
959 port->name);
960 goto skip;
961 }
962
963 if (resource_size(&pcie->io) != 0)
964 mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_IO,
965 &port->io_target, &port->io_attr);
966 else {
967 port->io_target = -1;
968 port->io_attr = -1;
969 }
970
971 port->reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0,
972 &flags);
973 if (gpio_is_valid(port->reset_gpio)) {
974 port->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
975 port->reset_name = kasprintf(GFP_KERNEL, "%s-reset",
976 port->name);
977
978 ret = devm_gpio_request_one(dev, port->reset_gpio,
979 GPIOF_DIR_OUT, port->reset_name);
980 if (ret) {
981 if (ret == -EPROBE_DEFER)
982 goto err;
983 goto skip;
984 }
985 }
986
987 port->clk = of_clk_get_by_name(child, NULL);
988 if (IS_ERR(port->clk)) {
989 dev_err(dev, "%s: cannot get clock\n", port->name);
990 goto skip;
991 }
992
993 return 1;
994
995skip:
996 ret = 0;
997err:
998 return ret;
999}
1000
931static int mvebu_pcie_probe(struct platform_device *pdev) 1001static int mvebu_pcie_probe(struct platform_device *pdev)
932{ 1002{
933 struct mvebu_pcie *pcie; 1003 struct mvebu_pcie *pcie;
@@ -980,76 +1050,24 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
980 i = 0; 1050 i = 0;
981 for_each_available_child_of_node(pdev->dev.of_node, child) { 1051 for_each_available_child_of_node(pdev->dev.of_node, child) {
982 struct mvebu_pcie_port *port = &pcie->ports[i]; 1052 struct mvebu_pcie_port *port = &pcie->ports[i];
983 enum of_gpio_flags flags;
984
985 port->pcie = pcie;
986 1053
987 if (of_property_read_u32(child, "marvell,pcie-port", 1054 ret = mvebu_pcie_parse_port(pcie, port, child);
988 &port->port)) { 1055 if (ret < 0)
989 dev_warn(&pdev->dev, 1056 return ret;
990 "ignoring %s, missing pcie-port property\n", 1057 else if (ret == 0)
991 of_node_full_name(child));
992 continue; 1058 continue;
993 }
994 1059
995 if (of_property_read_u32(child, "marvell,pcie-lane",
996 &port->lane))
997 port->lane = 0;
998
999 port->name = kasprintf(GFP_KERNEL, "pcie%d.%d",
1000 port->port, port->lane);
1001
1002 port->devfn = of_pci_get_devfn(child);
1003 if (port->devfn < 0)
1004 continue;
1005
1006 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
1007 &port->mem_target, &port->mem_attr);
1008 if (ret < 0) {
1009 dev_err(&pdev->dev, "%s: cannot get tgt/attr for mem window\n",
1010 port->name);
1011 continue;
1012 }
1013
1014 if (resource_size(&pcie->io) != 0)
1015 mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
1016 &port->io_target, &port->io_attr);
1017 else {
1018 port->io_target = -1;
1019 port->io_attr = -1;
1020 }
1021
1022 port->reset_gpio = of_get_named_gpio_flags(child,
1023 "reset-gpios", 0, &flags);
1024 if (gpio_is_valid(port->reset_gpio)) { 1060 if (gpio_is_valid(port->reset_gpio)) {
1025 u32 reset_udelay = 20000; 1061 u32 reset_udelay = 20000;
1026 1062
1027 port->reset_active_low = flags & OF_GPIO_ACTIVE_LOW;
1028 port->reset_name = kasprintf(GFP_KERNEL, "%s-reset",
1029 port->name);
1030 of_property_read_u32(child, "reset-delay-us", 1063 of_property_read_u32(child, "reset-delay-us",
1031 &reset_udelay); 1064 &reset_udelay);
1032 1065
1033 ret = devm_gpio_request_one(&pdev->dev,
1034 port->reset_gpio, GPIOF_DIR_OUT, port->reset_name);
1035 if (ret) {
1036 if (ret == -EPROBE_DEFER)
1037 return ret;
1038 continue;
1039 }
1040
1041 gpio_set_value(port->reset_gpio, 1066 gpio_set_value(port->reset_gpio,
1042 (port->reset_active_low) ? 1 : 0); 1067 (port->reset_active_low) ? 1 : 0);
1043 msleep(reset_udelay/1000); 1068 msleep(reset_udelay/1000);
1044 } 1069 }
1045 1070
1046 port->clk = of_clk_get_by_name(child, NULL);
1047 if (IS_ERR(port->clk)) {
1048 dev_err(&pdev->dev, "%s: cannot get clock\n",
1049 port->name);
1050 continue;
1051 }
1052
1053 ret = clk_prepare_enable(port->clk); 1071 ret = clk_prepare_enable(port->clk);
1054 if (ret) 1072 if (ret)
1055 continue; 1073 continue;