]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
pcie: host: tegra: change prsnt override mechanism
authorVidya Sagar <vidyas@nvidia.com>
Tue, 23 Dec 2014 06:26:23 +0000 (11:56 +0530)
committerLaxman Dewangan <ldewangan@nvidia.com>
Fri, 26 Dec 2014 07:38:17 +0000 (23:38 -0800)
overrides prsnt control based on card detection through
GPIO values that reflect PRSNT status
If the platform doesn't support PRSNT through GPIO, software
overrides will be enabled always

Bug 200067556

Change-Id: I43b732ead3bab7dfbe1fcb910dc269c450b34230
Signed-off-by: Vidya Sagar <vidyas@nvidia.com>
Reviewed-on: http://git-master/r/667029
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
drivers/pci/host/pci-tegra.c

index 3c7d11a456c79994ada47b4224bd2fd3668f4863..09112ebb091caa7aedef2146d8ca8aa58725c38b 100644 (file)
@@ -412,6 +412,7 @@ struct tegra_pcie_port {
        void __iomem *base;
        unsigned int index;
        unsigned int lanes;
+       int gpio_presence_detection;
        bool disable_clock_request;
        int status;
        struct dentry *port_debugfs;
@@ -1971,7 +1972,12 @@ static void tegra_pcie_check_ports(struct tegra_pcie *pcie)
                tegra_pcie_port_enable(port);
                tegra_pcie_enable_rp_features(port);
                /* override presence detection */
-               tegra_pcie_prsnt_map_override(port, true);
+               if (gpio_is_valid(port->gpio_presence_detection))
+                       tegra_pcie_prsnt_map_override(port,
+                               !(gpio_get_value_cansleep(
+                                       port->gpio_presence_detection)));
+               else
+                       tegra_pcie_prsnt_map_override(port, true);
        }
        /* Wait for clock to latch (min of 100us) */
        udelay(100);
@@ -1993,6 +1999,7 @@ static void tegra_pcie_check_ports(struct tegra_pcie *pcie)
 static int tegra_pcie_conf_gpios(struct tegra_pcie *pcie)
 {
        int irq, err = 0;
+       struct tegra_pcie_port *port, *tmp;
 
        PR_FUNC_LINE;
        if (gpio_is_valid(pcie->plat_data->gpio_hot_plug)) {
@@ -2070,6 +2077,21 @@ static int tegra_pcie_conf_gpios(struct tegra_pcie *pcie)
                        return err;
                }
        }
+
+       list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+               if (gpio_is_valid(port->gpio_presence_detection)) {
+                       err = devm_gpio_request_one(pcie->dev,
+                                       port->gpio_presence_detection,
+                                       GPIOF_DIR_IN,
+                                       "pcie_presence_detection");
+                       if (err < 0) {
+                               dev_err(pcie->dev,
+                                       "%s: pcie_prsnt gpio_request failed %d\n",
+                                       __func__, err);
+                               return err;
+                       }
+               }
+       }
        return 0;
 }
 
@@ -2966,6 +2988,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
                        return err;
                }
 
+               rp->gpio_presence_detection =
+                       of_get_named_gpio(port,
+                               "nvidia,presence-detection-gpio", 0);
+
                INIT_LIST_HEAD(&rp->list);
                rp->index = index;
                rp->lanes = value;