^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/mailbox_client.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/phy/tegra/xusb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <soc/tegra/fuse.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xusb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct phy *tegra_xusb_pad_of_xlate(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct of_phandle_args *args)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct tegra_xusb_pad *pad = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct phy *phy = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (args->args_count != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) for (i = 0; i < pad->soc->num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (!pad->lanes[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (pad->lanes[i]->dev.of_node == args->np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) phy = pad->lanes[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (phy == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) phy = ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static const struct of_device_id tegra_xusb_padctl_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .compatible = "nvidia,tegra124-xusb-padctl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .data = &tegra124_xusb_padctl_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #if defined(CONFIG_ARCH_TEGRA_210_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .compatible = "nvidia,tegra210-xusb-padctl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .data = &tegra210_xusb_padctl_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #if defined(CONFIG_ARCH_TEGRA_186_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .compatible = "nvidia,tegra186-xusb-padctl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .data = &tegra186_xusb_padctl_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #if defined(CONFIG_ARCH_TEGRA_194_SOC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .compatible = "nvidia,tegra194-xusb-padctl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .data = &tegra194_xusb_padctl_soc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct device_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct device_node *pads, *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) pads = of_get_child_by_name(padctl->dev->of_node, "pads");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (!pads)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) np = of_get_child_by_name(pads, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) of_node_put(pads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static struct device_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct device_node *np, *lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) lanes = of_get_child_by_name(pad->dev.of_node, "lanes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (!lanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) np = of_get_child_by_name(lanes, pad->soc->lanes[index].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) of_node_put(lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct device *dev = &lane->pad->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const char *function;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err = of_property_read_string(np, "nvidia,function", &function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) err = match_string(lane->soc->funcs, lane->soc->num_funcs, function);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dev_err(dev, "invalid function \"%s\" for lane \"%pOFn\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) function, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) lane->function = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void tegra_xusb_lane_destroy(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (phy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) lane->pad->ops->remove(lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) phy_destroy(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void tegra_xusb_pad_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct tegra_xusb_pad *pad = to_tegra_xusb_pad(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) pad->soc->ops->remove(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static struct device_type tegra_xusb_pad_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .release = tegra_xusb_pad_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int tegra_xusb_pad_init(struct tegra_xusb_pad *pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) device_initialize(&pad->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) INIT_LIST_HEAD(&pad->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) pad->dev.parent = padctl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) pad->dev.type = &tegra_xusb_pad_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) pad->dev.of_node = np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pad->padctl = padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) err = dev_set_name(&pad->dev, "%s", pad->soc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) goto unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) err = device_add(&pad->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) goto unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) device_unregister(&pad->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int tegra_xusb_pad_register(struct tegra_xusb_pad *pad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) const struct phy_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct device_node *children;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct phy *lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) children = of_get_child_by_name(pad->dev.of_node, "lanes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!children)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) pad->lanes = devm_kcalloc(&pad->dev, pad->soc->num_lanes, sizeof(lane),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!pad->lanes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) of_node_put(children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) for (i = 0; i < pad->soc->num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct device_node *np = tegra_xusb_pad_find_phy_node(pad, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct tegra_xusb_lane *lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* skip disabled lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!np || !of_device_is_available(np)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) pad->lanes[i] = phy_create(&pad->dev, np, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (IS_ERR(pad->lanes[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) err = PTR_ERR(pad->lanes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) lane = pad->ops->probe(pad, np, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (IS_ERR(lane)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) phy_destroy(pad->lanes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = PTR_ERR(lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) list_add_tail(&lane->list, &pad->padctl->lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) phy_set_drvdata(pad->lanes[i], lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) pad->provider = of_phy_provider_register_full(&pad->dev, children,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) tegra_xusb_pad_of_xlate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (IS_ERR(pad->provider)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) err = PTR_ERR(pad->provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) tegra_xusb_lane_destroy(pad->lanes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) of_node_put(children);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) void tegra_xusb_pad_unregister(struct tegra_xusb_pad *pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int i = pad->soc->num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) of_phy_provider_unregister(pad->provider);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) tegra_xusb_lane_destroy(pad->lanes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) device_unregister(&pad->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static struct tegra_xusb_pad *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) tegra_xusb_pad_create(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) const struct tegra_xusb_pad_soc *soc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct tegra_xusb_pad *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) np = tegra_xusb_find_pad_node(padctl, soc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pad = soc->ops->probe(padctl, soc, np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (IS_ERR(pad)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) err = PTR_ERR(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) dev_err(padctl->dev, "failed to create pad %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) soc->name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* XXX move this into ->probe() to avoid string comparison */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (strcmp(soc->name, "pcie") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) padctl->pcie = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (strcmp(soc->name, "sata") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) padctl->sata = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (strcmp(soc->name, "usb2") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) padctl->usb2 = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (strcmp(soc->name, "ulpi") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) padctl->ulpi = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (strcmp(soc->name, "hsic") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) padctl->hsic = pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static void __tegra_xusb_remove_pads(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) struct tegra_xusb_pad *pad, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) list_for_each_entry_safe_reverse(pad, tmp, &padctl->pads, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) list_del(&pad->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) tegra_xusb_pad_unregister(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static void tegra_xusb_remove_pads(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) mutex_lock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) __tegra_xusb_remove_pads(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) mutex_unlock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static void tegra_xusb_lane_program(struct tegra_xusb_lane *lane)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct tegra_xusb_padctl *padctl = lane->pad->padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) const struct tegra_xusb_lane_soc *soc = lane->soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* skip single function lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (soc->num_funcs < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* choose function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) value = padctl_readl(padctl, soc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) value &= ~(soc->mask << soc->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) value |= lane->function << soc->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) padctl_writel(padctl, value, soc->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void tegra_xusb_pad_program(struct tegra_xusb_pad *pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) for (i = 0; i < pad->soc->num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct tegra_xusb_lane *lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (pad->lanes[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) lane = phy_get_drvdata(pad->lanes[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) tegra_xusb_lane_program(lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static int tegra_xusb_setup_pads(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) struct tegra_xusb_pad *pad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mutex_lock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) for (i = 0; i < padctl->soc->num_pads; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) const struct tegra_xusb_pad_soc *soc = padctl->soc->pads[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) pad = tegra_xusb_pad_create(padctl, soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (IS_ERR(pad)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) err = PTR_ERR(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dev_err(padctl->dev, "failed to create pad %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) soc->name, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) __tegra_xusb_remove_pads(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) mutex_unlock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (!pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) list_add_tail(&pad->list, &padctl->pads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) list_for_each_entry(pad, &padctl->pads, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) tegra_xusb_pad_program(pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) mutex_unlock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static bool tegra_xusb_lane_check(struct tegra_xusb_lane *lane,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) const char *function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) const char *func = lane->soc->funcs[lane->function];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return strcmp(function, func) == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const char *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct tegra_xusb_lane *lane, *hit = ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) name = kasprintf(GFP_KERNEL, "%s-%u", type, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) list_for_each_entry(lane, &padctl->lanes, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (strcmp(lane->soc->name, name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) hit = lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct tegra_xusb_lane *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) tegra_xusb_port_find_lane(struct tegra_xusb_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) const struct tegra_xusb_lane_map *map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) const char *function)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct tegra_xusb_lane *lane, *match = ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (; map->type; map++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (port->index != map->port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) lane = tegra_xusb_find_lane(port->padctl, map->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) map->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (IS_ERR(lane))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!tegra_xusb_lane_check(lane, function))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!IS_ERR(match))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev_err(&port->dev, "conflicting match: %s-%u / %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) map->type, map->index, match->soc->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) match = lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static struct device_node *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct device_node *ports, *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) ports = of_get_child_by_name(padctl->dev->of_node, "ports");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!ports)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) name = kasprintf(GFP_KERNEL, "%s-%u", type, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) of_node_put(ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) np = of_get_child_by_name(ports, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) of_node_put(ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct tegra_xusb_port *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) tegra_xusb_find_port(struct tegra_xusb_padctl *padctl, const char *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct tegra_xusb_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) np = tegra_xusb_find_port_node(padctl, type, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) list_for_each_entry(port, &padctl->ports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (np == port->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct tegra_xusb_usb2_port *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct tegra_xusb_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) port = tegra_xusb_find_port(padctl, "usb2", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return to_usb2_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct tegra_xusb_usb3_port *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct tegra_xusb_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) port = tegra_xusb_find_port(padctl, "usb3", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return to_usb3_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static void tegra_xusb_port_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) struct tegra_xusb_port *port = to_tegra_xusb_port(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (port->ops->release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) port->ops->release(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static struct device_type tegra_xusb_port_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) .release = tegra_xusb_port_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int tegra_xusb_port_init(struct tegra_xusb_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) INIT_LIST_HEAD(&port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) port->padctl = padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) port->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) device_initialize(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) port->dev.type = &tegra_xusb_port_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) port->dev.of_node = of_node_get(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) port->dev.parent = padctl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) err = dev_set_name(&port->dev, "%s-%u", name, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) err = device_add(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) goto unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) device_unregister(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static void tegra_xusb_port_unregister(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (!IS_ERR_OR_NULL(port->usb_role_sw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) of_platform_depopulate(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) usb_role_switch_unregister(port->usb_role_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) cancel_work_sync(&port->usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) usb_remove_phy(&port->usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (port->ops->remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) port->ops->remove(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) device_unregister(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static const char *const modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) [USB_DR_MODE_UNKNOWN] = "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) [USB_DR_MODE_HOST] = "host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) [USB_DR_MODE_PERIPHERAL] = "peripheral",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) [USB_DR_MODE_OTG] = "otg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static const char * const usb_roles[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) [USB_ROLE_NONE] = "none",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) [USB_ROLE_HOST] = "host",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) [USB_ROLE_DEVICE] = "device",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static enum usb_phy_events to_usb_phy_event(enum usb_role role)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) switch (role) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case USB_ROLE_DEVICE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return USB_EVENT_VBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case USB_ROLE_HOST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return USB_EVENT_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return USB_EVENT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static void tegra_xusb_usb_phy_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct tegra_xusb_port *port = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct tegra_xusb_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) enum usb_role role = usb_role_switch_get_role(port->usb_role_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) usb_phy_set_event(&port->usb_phy, to_usb_phy_event(role));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dev_dbg(&port->dev, "%s(): calling notifier for role %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) usb_roles[role]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) atomic_notifier_call_chain(&port->usb_phy.notifier, 0, &port->usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) static int tegra_xusb_role_sw_set(struct usb_role_switch *sw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) enum usb_role role)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct tegra_xusb_port *port = usb_role_switch_get_drvdata(sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) dev_dbg(&port->dev, "%s(): role %s\n", __func__, usb_roles[role]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) schedule_work(&port->usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int tegra_xusb_set_peripheral(struct usb_otg *otg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct usb_gadget *gadget)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct tegra_xusb_port *port = container_of(otg->usb_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) struct tegra_xusb_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (gadget != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) schedule_work(&port->usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static int tegra_xusb_set_host(struct usb_otg *otg, struct usb_bus *host)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct tegra_xusb_port *port = container_of(otg->usb_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct tegra_xusb_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (host != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) schedule_work(&port->usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct tegra_xusb_lane *lane;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct usb_role_switch_desc role_sx_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) .fwnode = dev_fwnode(&port->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) .set = tegra_xusb_role_sw_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * USB role switch driver needs parent driver owner info. This is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * suboptimal solution. TODO: Need to revisit this in a follow-up patch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * where an optimal solution is possible with changes to USB role
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * switch driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) port->dev.driver = devm_kzalloc(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) sizeof(struct device_driver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) port->dev.driver->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) port->usb_role_sw = usb_role_switch_register(&port->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) &role_sx_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (IS_ERR(port->usb_role_sw)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) err = PTR_ERR(port->usb_role_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) dev_err(&port->dev, "failed to register USB role switch: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) INIT_WORK(&port->usb_phy_work, tegra_xusb_usb_phy_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) usb_role_switch_set_drvdata(port->usb_role_sw, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) port->usb_phy.otg = devm_kzalloc(&port->dev, sizeof(struct usb_otg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!port->usb_phy.otg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) lane = tegra_xusb_find_lane(port->padctl, "usb2", port->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Assign phy dev to usb-phy dev. Host/device drivers can use phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * reference to retrieve usb-phy details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) port->usb_phy.dev = &lane->pad->lanes[port->index]->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) port->usb_phy.dev->driver = port->dev.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) port->usb_phy.otg->usb_phy = &port->usb_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) port->usb_phy.otg->set_peripheral = tegra_xusb_set_peripheral;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) port->usb_phy.otg->set_host = tegra_xusb_set_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) err = usb_add_phy_dev(&port->usb_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dev_err(&port->dev, "Failed to add USB PHY: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* populate connector entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) of_platform_populate(port->dev.of_node, NULL, NULL, &port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct tegra_xusb_port *port = &usb2->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct device_node *np = port->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) const char *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) usb2->internal = of_property_read_bool(np, "nvidia,internal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (!of_property_read_string(np, "mode", &mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) int err = match_string(modes, ARRAY_SIZE(modes), mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dev_err(&port->dev, "invalid value %s for \"mode\"\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) usb2->mode = USB_DR_MODE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) usb2->mode = err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) usb2->mode = USB_DR_MODE_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) /* usb-role-switch property is mandatory for OTG/Peripheral modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (usb2->mode == USB_DR_MODE_PERIPHERAL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) usb2->mode == USB_DR_MODE_OTG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (of_property_read_bool(np, "usb-role-switch")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) err = tegra_xusb_setup_usb_role_switch(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dev_err(&port->dev, "usb-role-switch not found for %s mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) modes[usb2->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) usb2->supply = regulator_get(&port->dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return PTR_ERR_OR_ZERO(usb2->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct tegra_xusb_usb2_port *usb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * USB2 ports don't require additional properties, but if the port is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * marked as disabled there is no reason to register it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) np = tegra_xusb_find_port_node(padctl, "usb2", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (!usb2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) err = tegra_xusb_port_init(&usb2->base, padctl, np, "usb2", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) usb2->base.ops = padctl->soc->ports.usb2.ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) usb2->base.lane = usb2->base.ops->map(&usb2->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (IS_ERR(usb2->base.lane)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) err = PTR_ERR(usb2->base.lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) err = tegra_xusb_usb2_port_parse_dt(usb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) tegra_xusb_port_unregister(&usb2->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) list_add_tail(&usb2->base.list, &padctl->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) void tegra_xusb_usb2_port_release(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct tegra_xusb_usb2_port *usb2 = to_usb2_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) kfree(usb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) void tegra_xusb_usb2_port_remove(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct tegra_xusb_usb2_port *usb2 = to_usb2_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) regulator_put(usb2->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static int tegra_xusb_ulpi_port_parse_dt(struct tegra_xusb_ulpi_port *ulpi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct tegra_xusb_port *port = &ulpi->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) struct device_node *np = port->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ulpi->internal = of_property_read_bool(np, "nvidia,internal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct tegra_xusb_ulpi_port *ulpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) np = tegra_xusb_find_port_node(padctl, "ulpi", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (!ulpi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) err = tegra_xusb_port_init(&ulpi->base, padctl, np, "ulpi", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ulpi->base.ops = padctl->soc->ports.ulpi.ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ulpi->base.lane = ulpi->base.ops->map(&ulpi->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (IS_ERR(ulpi->base.lane)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) err = PTR_ERR(ulpi->base.lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) err = tegra_xusb_ulpi_port_parse_dt(ulpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) tegra_xusb_port_unregister(&ulpi->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) list_add_tail(&ulpi->base.list, &padctl->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) void tegra_xusb_ulpi_port_release(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct tegra_xusb_ulpi_port *ulpi = to_ulpi_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) kfree(ulpi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static int tegra_xusb_hsic_port_parse_dt(struct tegra_xusb_hsic_port *hsic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct tegra_xusb_hsic_port *hsic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) np = tegra_xusb_find_port_node(padctl, "hsic", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) hsic = kzalloc(sizeof(*hsic), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!hsic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) err = tegra_xusb_port_init(&hsic->base, padctl, np, "hsic", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) hsic->base.ops = padctl->soc->ports.hsic.ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) hsic->base.lane = hsic->base.ops->map(&hsic->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (IS_ERR(hsic->base.lane)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) err = PTR_ERR(hsic->base.lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) err = tegra_xusb_hsic_port_parse_dt(hsic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) tegra_xusb_port_unregister(&hsic->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) list_add_tail(&hsic->base.list, &padctl->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) void tegra_xusb_hsic_port_release(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) struct tegra_xusb_hsic_port *hsic = to_hsic_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) kfree(hsic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static int tegra_xusb_usb3_port_parse_dt(struct tegra_xusb_usb3_port *usb3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) struct tegra_xusb_port *port = &usb3->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) struct device_node *np = port->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) enum usb_device_speed maximum_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) err = of_property_read_u32(np, "nvidia,usb2-companion", &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) dev_err(&port->dev, "failed to read port: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) usb3->port = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) usb3->internal = of_property_read_bool(np, "nvidia,internal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (device_property_present(&port->dev, "maximum-speed")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) maximum_speed = usb_get_maximum_speed(&port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (maximum_speed == USB_SPEED_SUPER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) usb3->disable_gen2 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) else if (maximum_speed == USB_SPEED_SUPER_PLUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) usb3->disable_gen2 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) usb3->supply = regulator_get(&port->dev, "vbus");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return PTR_ERR_OR_ZERO(usb3->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct tegra_xusb_usb3_port *usb3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * If there is no supplemental configuration in the device tree the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * port is unusable. But it is valid to configure only a single port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * hence return 0 instead of an error to allow ports to be optional.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) np = tegra_xusb_find_port_node(padctl, "usb3", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) usb3 = kzalloc(sizeof(*usb3), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!usb3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) err = tegra_xusb_port_init(&usb3->base, padctl, np, "usb3", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) usb3->base.ops = padctl->soc->ports.usb3.ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) usb3->base.lane = usb3->base.ops->map(&usb3->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (IS_ERR(usb3->base.lane)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) err = PTR_ERR(usb3->base.lane);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) err = tegra_xusb_usb3_port_parse_dt(usb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) tegra_xusb_port_unregister(&usb3->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) list_add_tail(&usb3->base.list, &padctl->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) void tegra_xusb_usb3_port_release(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) kfree(usb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) void tegra_xusb_usb3_port_remove(struct tegra_xusb_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) regulator_put(usb3->supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static void __tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) struct tegra_xusb_port *port, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) list_for_each_entry_safe_reverse(port, tmp, &padctl->ports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) list_del(&port->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) tegra_xusb_port_unregister(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int tegra_xusb_find_unused_usb3_port(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) np = tegra_xusb_find_port_node(padctl, "usb3", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (!np || !of_device_is_available(np))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static bool tegra_xusb_port_is_companion(struct tegra_xusb_usb2_port *usb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct tegra_xusb_usb3_port *usb3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct tegra_xusb_padctl *padctl = usb2->base.padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) usb3 = tegra_xusb_find_usb3_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (usb3 && usb3->port == usb2->base.index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int tegra_xusb_update_usb3_fake_port(struct tegra_xusb_usb2_port *usb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) int fake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /* Disable usb3_port_fake usage by default and assign if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) usb2->usb3_port_fake = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if ((usb2->mode == USB_DR_MODE_OTG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) usb2->mode == USB_DR_MODE_PERIPHERAL) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) !tegra_xusb_port_is_companion(usb2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) fake = tegra_xusb_find_unused_usb3_port(usb2->base.padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (fake < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) dev_err(&usb2->base.dev, "no unused USB3 ports available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) dev_dbg(&usb2->base.dev, "Found unused usb3 port: %d\n", fake);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) usb2->usb3_port_fake = fake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) struct tegra_xusb_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct tegra_xusb_usb2_port *usb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) mutex_lock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) for (i = 0; i < padctl->soc->ports.usb2.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) err = tegra_xusb_add_usb2_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) goto remove_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) for (i = 0; i < padctl->soc->ports.ulpi.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) err = tegra_xusb_add_ulpi_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) goto remove_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) for (i = 0; i < padctl->soc->ports.hsic.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) err = tegra_xusb_add_hsic_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) goto remove_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) err = tegra_xusb_add_usb3_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) goto remove_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (padctl->soc->need_fake_usb3_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) for (i = 0; i < padctl->soc->ports.usb2.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) usb2 = tegra_xusb_find_usb2_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (!usb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) err = tegra_xusb_update_usb3_fake_port(usb2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) goto remove_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) list_for_each_entry(port, &padctl->ports, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) err = port->ops->enable(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_err(padctl->dev, "failed to enable port %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) dev_name(&port->dev), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) remove_ports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) __tegra_xusb_remove_ports(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) mutex_unlock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static void tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) mutex_lock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) __tegra_xusb_remove_ports(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) mutex_unlock(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static int tegra_xusb_padctl_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) const struct tegra_xusb_padctl_soc *soc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct tegra_xusb_padctl *padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* for backwards compatibility with old device trees */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) np = of_get_child_by_name(np, "pads");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return tegra_xusb_padctl_legacy_probe(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) soc = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) padctl = soc->ops->probe(&pdev->dev, soc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (IS_ERR(padctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return PTR_ERR(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) platform_set_drvdata(pdev, padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) INIT_LIST_HEAD(&padctl->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) INIT_LIST_HEAD(&padctl->lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) INIT_LIST_HEAD(&padctl->pads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) mutex_init(&padctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) padctl->regs = devm_ioremap_resource(&pdev->dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (IS_ERR(padctl->regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) err = PTR_ERR(padctl->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) padctl->rst = devm_reset_control_get(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (IS_ERR(padctl->rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) err = PTR_ERR(padctl->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) padctl->supplies = devm_kcalloc(&pdev->dev, padctl->soc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) sizeof(*padctl->supplies), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (!padctl->supplies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) regulator_bulk_set_supply_names(padctl->supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) padctl->soc->supply_names,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) padctl->soc->num_supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) err = devm_regulator_bulk_get(&pdev->dev, padctl->soc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) padctl->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) dev_err(&pdev->dev, "failed to get regulators: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) err = reset_control_deassert(padctl->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) goto remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) err = regulator_bulk_enable(padctl->soc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) padctl->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) dev_err(&pdev->dev, "failed to enable supplies: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) goto reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) err = tegra_xusb_setup_pads(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) dev_err(&pdev->dev, "failed to setup pads: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) goto power_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) err = tegra_xusb_setup_ports(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) const char *level = KERN_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) if (err == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) level = KERN_DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) dev_printk(level, &pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) dev_fmt("failed to setup XUSB ports: %d\n"), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) goto remove_pads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) remove_pads:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) tegra_xusb_remove_pads(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) power_down:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) regulator_bulk_disable(padctl->soc->num_supplies, padctl->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) reset_control_assert(padctl->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) platform_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) soc->ops->remove(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) static int tegra_xusb_padctl_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) tegra_xusb_remove_ports(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) tegra_xusb_remove_pads(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) err = regulator_bulk_disable(padctl->soc->num_supplies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) padctl->supplies);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) dev_err(&pdev->dev, "failed to disable supplies: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) err = reset_control_assert(padctl->rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) padctl->soc->ops->remove(padctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static struct platform_driver tegra_xusb_padctl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) .name = "tegra-xusb-padctl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) .of_match_table = tegra_xusb_padctl_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .probe = tegra_xusb_padctl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .remove = tegra_xusb_padctl_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) module_platform_driver(tegra_xusb_padctl_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) struct tegra_xusb_padctl *padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) np = of_parse_phandle(dev->of_node, "nvidia,xusb-padctl", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * This is slightly ugly. A better implementation would be to keep a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * registry of pad controllers, but since there will almost certainly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * only ever be one per SoC that would be a little overkill.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) pdev = of_find_device_by_node(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if (!pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) padctl = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) if (!padctl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) put_device(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) return ERR_PTR(-EPROBE_DEFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (padctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) put_device(padctl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) int tegra_xusb_padctl_usb3_save_context(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) unsigned int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (padctl->soc->ops->usb3_save_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return padctl->soc->ops->usb3_save_context(padctl, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_usb3_save_context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) unsigned int port, bool idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) if (padctl->soc->ops->hsic_set_idle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return padctl->soc->ops->hsic_set_idle(padctl, port, idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_hsic_set_idle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) unsigned int port, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (padctl->soc->ops->usb3_set_lfps_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return padctl->soc->ops->usb3_set_lfps_detect(padctl, port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_usb3_set_lfps_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) int tegra_xusb_padctl_set_vbus_override(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) bool val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) if (padctl->soc->ops->vbus_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) return padctl->soc->ops->vbus_override(padctl, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_set_vbus_override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int tegra_phy_xusb_utmi_port_reset(struct phy *phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct tegra_xusb_padctl *padctl = lane->pad->padctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (padctl->soc->ops->utmi_port_reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return padctl->soc->ops->utmi_port_reset(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) EXPORT_SYMBOL_GPL(tegra_phy_xusb_utmi_port_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) unsigned int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct tegra_xusb_usb2_port *usb2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) struct tegra_xusb_usb3_port *usb3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) usb2 = tegra_xusb_find_usb2_port(padctl, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (!usb2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) for (i = 0; i < padctl->soc->ports.usb3.count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) usb3 = tegra_xusb_find_usb3_port(padctl, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (usb3 && usb3->port == usb2->base.index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return usb3->base.index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) MODULE_LICENSE("GPL v2");