^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * cdns3-ti.c - TI specific Glue layer for Cadence USB Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* USB Wrapper register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define USBSS_PID 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define USBSS_W1 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define USBSS_STATIC_CONFIG 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define USBSS_PHY_TEST 0xc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define USBSS_DEBUG_CTRL 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define USBSS_DEBUG_INFO 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define USBSS_DEBUG_LINK_STATE 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define USBSS_DEVICE_CTRL 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Wrapper 1 register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define USBSS_W1_PWRUP_RST BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define USBSS_W1_OVERCURRENT_SEL BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define USBSS_W1_MODESTRAP_SEL BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define USBSS_W1_OVERCURRENT BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define USBSS_W1_MODESTRAP_MASK GENMASK(18, 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define USBSS_W1_MODESTRAP_SHIFT 17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define USBSS_W1_USB2_ONLY BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Static config register bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define USBSS1_STATIC_PLL_REF_SEL_MASK GENMASK(8, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define USBSS1_STATIC_PLL_REF_SEL_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define USBSS1_STATIC_LOOPBACK_MODE_MASK GENMASK(4, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define USBSS1_STATIC_LOOPBACK_MODE_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define USBSS1_STATIC_VBUS_SEL_MASK GENMASK(2, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define USBSS1_STATIC_VBUS_SEL_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define USBSS1_STATIC_LANE_REVERSE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Modestrap modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) enum modestrap_mode { USBSS_MODESTRAP_MODE_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) USBSS_MODESTRAP_MODE_HOST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) USBSS_MODESTRAP_MODE_PERIPHERAL};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct cdns_ti {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) void __iomem *usbss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) unsigned usb2_only:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) unsigned vbus_divider:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct clk *usb2_refclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct clk *lpm_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const int cdns_ti_rate_table[] = { /* in KHZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) 9600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) 10000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 12000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) 19200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) 24000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) 25000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) 26000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 38400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) 40000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 58000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 50000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 52000,
^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) static inline u32 cdns_ti_readl(struct cdns_ti *data, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return readl(data->usbss + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline void cdns_ti_writel(struct cdns_ti *data, u32 offset, u32 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) writel(value, data->usbss + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static int cdns_ti_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct cdns_ti *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int rate_code, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) platform_set_drvdata(pdev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) data->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) data->usbss = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (IS_ERR(data->usbss)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) dev_err(dev, "can't map IOMEM resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return PTR_ERR(data->usbss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) data->usb2_refclk = devm_clk_get(dev, "ref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (IS_ERR(data->usb2_refclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dev_err(dev, "can't get usb2_refclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return PTR_ERR(data->usb2_refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) data->lpm_clk = devm_clk_get(dev, "lpm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (IS_ERR(data->lpm_clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dev_err(dev, "can't get lpm_clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return PTR_ERR(data->lpm_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rate = clk_get_rate(data->usb2_refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rate /= 1000; /* To KHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) for (i = 0; i < ARRAY_SIZE(cdns_ti_rate_table); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (cdns_ti_rate_table[i] == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (i == ARRAY_SIZE(cdns_ti_rate_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev_err(dev, "unsupported usb2_refclk rate: %lu KHz\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rate_code = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) error = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) dev_err(dev, "pm_runtime_get_sync failed: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* assert RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) reg = cdns_ti_readl(data, USBSS_W1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) reg &= ~USBSS_W1_PWRUP_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) cdns_ti_writel(data, USBSS_W1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* set static config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) reg &= ~USBSS1_STATIC_PLL_REF_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) reg |= rate_code << USBSS1_STATIC_PLL_REF_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) reg &= ~USBSS1_STATIC_VBUS_SEL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) data->vbus_divider = device_property_read_bool(dev, "ti,vbus-divider");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (data->vbus_divider)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) reg |= 1 << USBSS1_STATIC_VBUS_SEL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) cdns_ti_writel(data, USBSS_STATIC_CONFIG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reg = cdns_ti_readl(data, USBSS_STATIC_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /* set USB2_ONLY mode if requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) reg = cdns_ti_readl(data, USBSS_W1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) data->usb2_only = device_property_read_bool(dev, "ti,usb2-only");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (data->usb2_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) reg |= USBSS_W1_USB2_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /* set default modestrap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) reg |= USBSS_W1_MODESTRAP_SEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) reg &= ~USBSS_W1_MODESTRAP_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) reg |= USBSS_MODESTRAP_MODE_NONE << USBSS_W1_MODESTRAP_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) cdns_ti_writel(data, USBSS_W1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* de-assert RESET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) reg |= USBSS_W1_PWRUP_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cdns_ti_writel(data, USBSS_W1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) error = of_platform_populate(node, NULL, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dev_err(dev, "failed to create children: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) pm_runtime_put_sync(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pm_runtime_disable(data->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int cdns_ti_remove_core(struct device *dev, void *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) platform_device_unregister(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int cdns_ti_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) device_for_each_child(dev, NULL, cdns_ti_remove_core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) platform_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static const struct of_device_id cdns_ti_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { .compatible = "ti,j721e-usb", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) MODULE_DEVICE_TABLE(of, cdns_ti_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static struct platform_driver cdns_ti_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .probe = cdns_ti_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .remove = cdns_ti_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .name = "cdns3-ti",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .of_match_table = cdns_ti_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) module_platform_driver(cdns_ti_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) MODULE_ALIAS("platform:cdns3-ti");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) MODULE_DESCRIPTION("Cadence USB3 TI Glue Layer");