1dacb1287SKranthi Kuntala // SPDX-License-Identifier: GPL-2.0 2dacb1287SKranthi Kuntala /* 3dacb1287SKranthi Kuntala * Thunderbolt/USB4 retimer support. 4dacb1287SKranthi Kuntala * 5dacb1287SKranthi Kuntala * Copyright (C) 2020, Intel Corporation 6dacb1287SKranthi Kuntala * Authors: Kranthi Kuntala <kranthi.kuntala@intel.com> 7dacb1287SKranthi Kuntala * Mika Westerberg <mika.westerberg@linux.intel.com> 8dacb1287SKranthi Kuntala */ 9dacb1287SKranthi Kuntala 10dacb1287SKranthi Kuntala #include <linux/delay.h> 11dacb1287SKranthi Kuntala #include <linux/pm_runtime.h> 12dacb1287SKranthi Kuntala #include <linux/sched/signal.h> 13dacb1287SKranthi Kuntala 14dacb1287SKranthi Kuntala #include "sb_regs.h" 15dacb1287SKranthi Kuntala #include "tb.h" 16dacb1287SKranthi Kuntala 17dacb1287SKranthi Kuntala #define TB_MAX_RETIMER_INDEX 6 18dacb1287SKranthi Kuntala 19dacb1287SKranthi Kuntala static int tb_retimer_nvm_read(void *priv, unsigned int offset, void *val, 20dacb1287SKranthi Kuntala size_t bytes) 21dacb1287SKranthi Kuntala { 22dacb1287SKranthi Kuntala struct tb_nvm *nvm = priv; 23dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(nvm->dev); 24dacb1287SKranthi Kuntala int ret; 25dacb1287SKranthi Kuntala 26dacb1287SKranthi Kuntala pm_runtime_get_sync(&rt->dev); 27dacb1287SKranthi Kuntala 28dacb1287SKranthi Kuntala if (!mutex_trylock(&rt->tb->lock)) { 29dacb1287SKranthi Kuntala ret = restart_syscall(); 30dacb1287SKranthi Kuntala goto out; 31dacb1287SKranthi Kuntala } 32dacb1287SKranthi Kuntala 33dacb1287SKranthi Kuntala ret = usb4_port_retimer_nvm_read(rt->port, rt->index, offset, val, bytes); 34dacb1287SKranthi Kuntala mutex_unlock(&rt->tb->lock); 35dacb1287SKranthi Kuntala 36dacb1287SKranthi Kuntala out: 37dacb1287SKranthi Kuntala pm_runtime_mark_last_busy(&rt->dev); 38dacb1287SKranthi Kuntala pm_runtime_put_autosuspend(&rt->dev); 39dacb1287SKranthi Kuntala 40dacb1287SKranthi Kuntala return ret; 41dacb1287SKranthi Kuntala } 42dacb1287SKranthi Kuntala 43dacb1287SKranthi Kuntala static int tb_retimer_nvm_write(void *priv, unsigned int offset, void *val, 44dacb1287SKranthi Kuntala size_t bytes) 45dacb1287SKranthi Kuntala { 46dacb1287SKranthi Kuntala struct tb_nvm *nvm = priv; 47dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(nvm->dev); 48dacb1287SKranthi Kuntala int ret = 0; 49dacb1287SKranthi Kuntala 50dacb1287SKranthi Kuntala if (!mutex_trylock(&rt->tb->lock)) 51dacb1287SKranthi Kuntala return restart_syscall(); 52dacb1287SKranthi Kuntala 53dacb1287SKranthi Kuntala ret = tb_nvm_write_buf(nvm, offset, val, bytes); 54dacb1287SKranthi Kuntala mutex_unlock(&rt->tb->lock); 55dacb1287SKranthi Kuntala 56dacb1287SKranthi Kuntala return ret; 57dacb1287SKranthi Kuntala } 58dacb1287SKranthi Kuntala 59dacb1287SKranthi Kuntala static int tb_retimer_nvm_add(struct tb_retimer *rt) 60dacb1287SKranthi Kuntala { 61dacb1287SKranthi Kuntala struct tb_nvm *nvm; 62dacb1287SKranthi Kuntala u32 val, nvm_size; 63dacb1287SKranthi Kuntala int ret; 64dacb1287SKranthi Kuntala 65dacb1287SKranthi Kuntala nvm = tb_nvm_alloc(&rt->dev); 66dacb1287SKranthi Kuntala if (IS_ERR(nvm)) 67dacb1287SKranthi Kuntala return PTR_ERR(nvm); 68dacb1287SKranthi Kuntala 69dacb1287SKranthi Kuntala ret = usb4_port_retimer_nvm_read(rt->port, rt->index, NVM_VERSION, &val, 70dacb1287SKranthi Kuntala sizeof(val)); 71dacb1287SKranthi Kuntala if (ret) 72dacb1287SKranthi Kuntala goto err_nvm; 73dacb1287SKranthi Kuntala 74dacb1287SKranthi Kuntala nvm->major = val >> 16; 75dacb1287SKranthi Kuntala nvm->minor = val >> 8; 76dacb1287SKranthi Kuntala 77dacb1287SKranthi Kuntala ret = usb4_port_retimer_nvm_read(rt->port, rt->index, NVM_FLASH_SIZE, 78dacb1287SKranthi Kuntala &val, sizeof(val)); 79dacb1287SKranthi Kuntala if (ret) 80dacb1287SKranthi Kuntala goto err_nvm; 81dacb1287SKranthi Kuntala 82dacb1287SKranthi Kuntala nvm_size = (SZ_1M << (val & 7)) / 8; 83dacb1287SKranthi Kuntala nvm_size = (nvm_size - SZ_16K) / 2; 84dacb1287SKranthi Kuntala 85dacb1287SKranthi Kuntala ret = tb_nvm_add_active(nvm, nvm_size, tb_retimer_nvm_read); 86dacb1287SKranthi Kuntala if (ret) 87dacb1287SKranthi Kuntala goto err_nvm; 88dacb1287SKranthi Kuntala 89dacb1287SKranthi Kuntala ret = tb_nvm_add_non_active(nvm, NVM_MAX_SIZE, tb_retimer_nvm_write); 90dacb1287SKranthi Kuntala if (ret) 91dacb1287SKranthi Kuntala goto err_nvm; 92dacb1287SKranthi Kuntala 93dacb1287SKranthi Kuntala rt->nvm = nvm; 94dacb1287SKranthi Kuntala return 0; 95dacb1287SKranthi Kuntala 96dacb1287SKranthi Kuntala err_nvm: 97dacb1287SKranthi Kuntala tb_nvm_free(nvm); 98dacb1287SKranthi Kuntala return ret; 99dacb1287SKranthi Kuntala } 100dacb1287SKranthi Kuntala 101dacb1287SKranthi Kuntala static int tb_retimer_nvm_validate_and_write(struct tb_retimer *rt) 102dacb1287SKranthi Kuntala { 103dacb1287SKranthi Kuntala unsigned int image_size, hdr_size; 104dacb1287SKranthi Kuntala const u8 *buf = rt->nvm->buf; 105dacb1287SKranthi Kuntala u16 ds_size, device; 106dacb1287SKranthi Kuntala 107dacb1287SKranthi Kuntala image_size = rt->nvm->buf_data_size; 108dacb1287SKranthi Kuntala if (image_size < NVM_MIN_SIZE || image_size > NVM_MAX_SIZE) 109dacb1287SKranthi Kuntala return -EINVAL; 110dacb1287SKranthi Kuntala 111dacb1287SKranthi Kuntala /* 112dacb1287SKranthi Kuntala * FARB pointer must point inside the image and must at least 113dacb1287SKranthi Kuntala * contain parts of the digital section we will be reading here. 114dacb1287SKranthi Kuntala */ 115dacb1287SKranthi Kuntala hdr_size = (*(u32 *)buf) & 0xffffff; 116dacb1287SKranthi Kuntala if (hdr_size + NVM_DEVID + 2 >= image_size) 117dacb1287SKranthi Kuntala return -EINVAL; 118dacb1287SKranthi Kuntala 119dacb1287SKranthi Kuntala /* Digital section start should be aligned to 4k page */ 120dacb1287SKranthi Kuntala if (!IS_ALIGNED(hdr_size, SZ_4K)) 121dacb1287SKranthi Kuntala return -EINVAL; 122dacb1287SKranthi Kuntala 123dacb1287SKranthi Kuntala /* 124dacb1287SKranthi Kuntala * Read digital section size and check that it also fits inside 125dacb1287SKranthi Kuntala * the image. 126dacb1287SKranthi Kuntala */ 127dacb1287SKranthi Kuntala ds_size = *(u16 *)(buf + hdr_size); 128dacb1287SKranthi Kuntala if (ds_size >= image_size) 129dacb1287SKranthi Kuntala return -EINVAL; 130dacb1287SKranthi Kuntala 131dacb1287SKranthi Kuntala /* 132dacb1287SKranthi Kuntala * Make sure the device ID in the image matches the retimer 133dacb1287SKranthi Kuntala * hardware. 134dacb1287SKranthi Kuntala */ 135dacb1287SKranthi Kuntala device = *(u16 *)(buf + hdr_size + NVM_DEVID); 136dacb1287SKranthi Kuntala if (device != rt->device) 137dacb1287SKranthi Kuntala return -EINVAL; 138dacb1287SKranthi Kuntala 139dacb1287SKranthi Kuntala /* Skip headers in the image */ 140dacb1287SKranthi Kuntala buf += hdr_size; 141dacb1287SKranthi Kuntala image_size -= hdr_size; 142dacb1287SKranthi Kuntala 143dacb1287SKranthi Kuntala return usb4_port_retimer_nvm_write(rt->port, rt->index, 0, buf, 144dacb1287SKranthi Kuntala image_size); 145dacb1287SKranthi Kuntala } 146dacb1287SKranthi Kuntala 147dacb1287SKranthi Kuntala static ssize_t device_show(struct device *dev, struct device_attribute *attr, 148dacb1287SKranthi Kuntala char *buf) 149dacb1287SKranthi Kuntala { 150dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 151dacb1287SKranthi Kuntala 152dacb1287SKranthi Kuntala return sprintf(buf, "%#x\n", rt->device); 153dacb1287SKranthi Kuntala } 154dacb1287SKranthi Kuntala static DEVICE_ATTR_RO(device); 155dacb1287SKranthi Kuntala 156dacb1287SKranthi Kuntala static ssize_t nvm_authenticate_show(struct device *dev, 157dacb1287SKranthi Kuntala struct device_attribute *attr, char *buf) 158dacb1287SKranthi Kuntala { 159dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 160dacb1287SKranthi Kuntala int ret; 161dacb1287SKranthi Kuntala 162dacb1287SKranthi Kuntala if (!mutex_trylock(&rt->tb->lock)) 163dacb1287SKranthi Kuntala return restart_syscall(); 164dacb1287SKranthi Kuntala 165dacb1287SKranthi Kuntala if (!rt->nvm) 166dacb1287SKranthi Kuntala ret = -EAGAIN; 167dacb1287SKranthi Kuntala else 168dacb1287SKranthi Kuntala ret = sprintf(buf, "%#x\n", rt->auth_status); 169dacb1287SKranthi Kuntala 170dacb1287SKranthi Kuntala mutex_unlock(&rt->tb->lock); 171dacb1287SKranthi Kuntala 172dacb1287SKranthi Kuntala return ret; 173dacb1287SKranthi Kuntala } 174dacb1287SKranthi Kuntala 175dacb1287SKranthi Kuntala static ssize_t nvm_authenticate_store(struct device *dev, 176dacb1287SKranthi Kuntala struct device_attribute *attr, const char *buf, size_t count) 177dacb1287SKranthi Kuntala { 178dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 179dacb1287SKranthi Kuntala bool val; 180dacb1287SKranthi Kuntala int ret; 181dacb1287SKranthi Kuntala 182dacb1287SKranthi Kuntala pm_runtime_get_sync(&rt->dev); 183dacb1287SKranthi Kuntala 184dacb1287SKranthi Kuntala if (!mutex_trylock(&rt->tb->lock)) { 185dacb1287SKranthi Kuntala ret = restart_syscall(); 186dacb1287SKranthi Kuntala goto exit_rpm; 187dacb1287SKranthi Kuntala } 188dacb1287SKranthi Kuntala 189dacb1287SKranthi Kuntala if (!rt->nvm) { 190dacb1287SKranthi Kuntala ret = -EAGAIN; 191dacb1287SKranthi Kuntala goto exit_unlock; 192dacb1287SKranthi Kuntala } 193dacb1287SKranthi Kuntala 194dacb1287SKranthi Kuntala ret = kstrtobool(buf, &val); 195dacb1287SKranthi Kuntala if (ret) 196dacb1287SKranthi Kuntala goto exit_unlock; 197dacb1287SKranthi Kuntala 198dacb1287SKranthi Kuntala /* Always clear status */ 199dacb1287SKranthi Kuntala rt->auth_status = 0; 200dacb1287SKranthi Kuntala 201dacb1287SKranthi Kuntala if (val) { 202dacb1287SKranthi Kuntala if (!rt->nvm->buf) { 203dacb1287SKranthi Kuntala ret = -EINVAL; 204dacb1287SKranthi Kuntala goto exit_unlock; 205dacb1287SKranthi Kuntala } 206dacb1287SKranthi Kuntala 207dacb1287SKranthi Kuntala ret = tb_retimer_nvm_validate_and_write(rt); 208dacb1287SKranthi Kuntala if (ret) 209dacb1287SKranthi Kuntala goto exit_unlock; 210dacb1287SKranthi Kuntala 211dacb1287SKranthi Kuntala ret = usb4_port_retimer_nvm_authenticate(rt->port, rt->index); 212dacb1287SKranthi Kuntala } 213dacb1287SKranthi Kuntala 214dacb1287SKranthi Kuntala exit_unlock: 215dacb1287SKranthi Kuntala mutex_unlock(&rt->tb->lock); 216dacb1287SKranthi Kuntala exit_rpm: 217dacb1287SKranthi Kuntala pm_runtime_mark_last_busy(&rt->dev); 218dacb1287SKranthi Kuntala pm_runtime_put_autosuspend(&rt->dev); 219dacb1287SKranthi Kuntala 220dacb1287SKranthi Kuntala if (ret) 221dacb1287SKranthi Kuntala return ret; 222dacb1287SKranthi Kuntala return count; 223dacb1287SKranthi Kuntala } 224dacb1287SKranthi Kuntala static DEVICE_ATTR_RW(nvm_authenticate); 225dacb1287SKranthi Kuntala 226dacb1287SKranthi Kuntala static ssize_t nvm_version_show(struct device *dev, 227dacb1287SKranthi Kuntala struct device_attribute *attr, char *buf) 228dacb1287SKranthi Kuntala { 229dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 230dacb1287SKranthi Kuntala int ret; 231dacb1287SKranthi Kuntala 232dacb1287SKranthi Kuntala if (!mutex_trylock(&rt->tb->lock)) 233dacb1287SKranthi Kuntala return restart_syscall(); 234dacb1287SKranthi Kuntala 235dacb1287SKranthi Kuntala if (!rt->nvm) 236dacb1287SKranthi Kuntala ret = -EAGAIN; 237dacb1287SKranthi Kuntala else 238dacb1287SKranthi Kuntala ret = sprintf(buf, "%x.%x\n", rt->nvm->major, rt->nvm->minor); 239dacb1287SKranthi Kuntala 240dacb1287SKranthi Kuntala mutex_unlock(&rt->tb->lock); 241dacb1287SKranthi Kuntala return ret; 242dacb1287SKranthi Kuntala } 243dacb1287SKranthi Kuntala static DEVICE_ATTR_RO(nvm_version); 244dacb1287SKranthi Kuntala 245dacb1287SKranthi Kuntala static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, 246dacb1287SKranthi Kuntala char *buf) 247dacb1287SKranthi Kuntala { 248dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 249dacb1287SKranthi Kuntala 250dacb1287SKranthi Kuntala return sprintf(buf, "%#x\n", rt->vendor); 251dacb1287SKranthi Kuntala } 252dacb1287SKranthi Kuntala static DEVICE_ATTR_RO(vendor); 253dacb1287SKranthi Kuntala 254dacb1287SKranthi Kuntala static struct attribute *retimer_attrs[] = { 255dacb1287SKranthi Kuntala &dev_attr_device.attr, 256dacb1287SKranthi Kuntala &dev_attr_nvm_authenticate.attr, 257dacb1287SKranthi Kuntala &dev_attr_nvm_version.attr, 258dacb1287SKranthi Kuntala &dev_attr_vendor.attr, 259dacb1287SKranthi Kuntala NULL 260dacb1287SKranthi Kuntala }; 261dacb1287SKranthi Kuntala 262dacb1287SKranthi Kuntala static const struct attribute_group retimer_group = { 263dacb1287SKranthi Kuntala .attrs = retimer_attrs, 264dacb1287SKranthi Kuntala }; 265dacb1287SKranthi Kuntala 266dacb1287SKranthi Kuntala static const struct attribute_group *retimer_groups[] = { 267dacb1287SKranthi Kuntala &retimer_group, 268dacb1287SKranthi Kuntala NULL 269dacb1287SKranthi Kuntala }; 270dacb1287SKranthi Kuntala 271dacb1287SKranthi Kuntala static void tb_retimer_release(struct device *dev) 272dacb1287SKranthi Kuntala { 273dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 274dacb1287SKranthi Kuntala 275dacb1287SKranthi Kuntala kfree(rt); 276dacb1287SKranthi Kuntala } 277dacb1287SKranthi Kuntala 278dacb1287SKranthi Kuntala struct device_type tb_retimer_type = { 279dacb1287SKranthi Kuntala .name = "thunderbolt_retimer", 280dacb1287SKranthi Kuntala .groups = retimer_groups, 281dacb1287SKranthi Kuntala .release = tb_retimer_release, 282dacb1287SKranthi Kuntala }; 283dacb1287SKranthi Kuntala 284dacb1287SKranthi Kuntala static int tb_retimer_add(struct tb_port *port, u8 index, u32 auth_status) 285dacb1287SKranthi Kuntala { 286*cae5f515SMika Westerberg struct usb4_port *usb4; 287dacb1287SKranthi Kuntala struct tb_retimer *rt; 288dacb1287SKranthi Kuntala u32 vendor, device; 289dacb1287SKranthi Kuntala int ret; 290dacb1287SKranthi Kuntala 291*cae5f515SMika Westerberg usb4 = port->usb4; 292*cae5f515SMika Westerberg if (!usb4) 293dacb1287SKranthi Kuntala return -EINVAL; 294dacb1287SKranthi Kuntala 295dacb1287SKranthi Kuntala ret = usb4_port_retimer_read(port, index, USB4_SB_VENDOR_ID, &vendor, 296dacb1287SKranthi Kuntala sizeof(vendor)); 297dacb1287SKranthi Kuntala if (ret) { 298dacb1287SKranthi Kuntala if (ret != -ENODEV) 299dacb1287SKranthi Kuntala tb_port_warn(port, "failed read retimer VendorId: %d\n", ret); 300dacb1287SKranthi Kuntala return ret; 301dacb1287SKranthi Kuntala } 302dacb1287SKranthi Kuntala 303dacb1287SKranthi Kuntala ret = usb4_port_retimer_read(port, index, USB4_SB_PRODUCT_ID, &device, 304dacb1287SKranthi Kuntala sizeof(device)); 305dacb1287SKranthi Kuntala if (ret) { 306dacb1287SKranthi Kuntala if (ret != -ENODEV) 307dacb1287SKranthi Kuntala tb_port_warn(port, "failed read retimer ProductId: %d\n", ret); 308dacb1287SKranthi Kuntala return ret; 309dacb1287SKranthi Kuntala } 310dacb1287SKranthi Kuntala 311dacb1287SKranthi Kuntala if (vendor != PCI_VENDOR_ID_INTEL && vendor != 0x8087) { 312dacb1287SKranthi Kuntala tb_port_info(port, "retimer NVM format of vendor %#x is not supported\n", 313dacb1287SKranthi Kuntala vendor); 314dacb1287SKranthi Kuntala return -EOPNOTSUPP; 315dacb1287SKranthi Kuntala } 316dacb1287SKranthi Kuntala 317dacb1287SKranthi Kuntala /* 318dacb1287SKranthi Kuntala * Check that it supports NVM operations. If not then don't add 319dacb1287SKranthi Kuntala * the device at all. 320dacb1287SKranthi Kuntala */ 321dacb1287SKranthi Kuntala ret = usb4_port_retimer_nvm_sector_size(port, index); 322dacb1287SKranthi Kuntala if (ret < 0) 323dacb1287SKranthi Kuntala return ret; 324dacb1287SKranthi Kuntala 325dacb1287SKranthi Kuntala rt = kzalloc(sizeof(*rt), GFP_KERNEL); 326dacb1287SKranthi Kuntala if (!rt) 327dacb1287SKranthi Kuntala return -ENOMEM; 328dacb1287SKranthi Kuntala 329dacb1287SKranthi Kuntala rt->index = index; 330dacb1287SKranthi Kuntala rt->vendor = vendor; 331dacb1287SKranthi Kuntala rt->device = device; 332dacb1287SKranthi Kuntala rt->auth_status = auth_status; 333dacb1287SKranthi Kuntala rt->port = port; 334dacb1287SKranthi Kuntala rt->tb = port->sw->tb; 335dacb1287SKranthi Kuntala 336*cae5f515SMika Westerberg rt->dev.parent = &usb4->dev; 337dacb1287SKranthi Kuntala rt->dev.bus = &tb_bus_type; 338dacb1287SKranthi Kuntala rt->dev.type = &tb_retimer_type; 339dacb1287SKranthi Kuntala dev_set_name(&rt->dev, "%s:%u.%u", dev_name(&port->sw->dev), 340dacb1287SKranthi Kuntala port->port, index); 341dacb1287SKranthi Kuntala 342dacb1287SKranthi Kuntala ret = device_register(&rt->dev); 343dacb1287SKranthi Kuntala if (ret) { 344dacb1287SKranthi Kuntala dev_err(&rt->dev, "failed to register retimer: %d\n", ret); 345dacb1287SKranthi Kuntala put_device(&rt->dev); 346dacb1287SKranthi Kuntala return ret; 347dacb1287SKranthi Kuntala } 348dacb1287SKranthi Kuntala 349dacb1287SKranthi Kuntala ret = tb_retimer_nvm_add(rt); 350dacb1287SKranthi Kuntala if (ret) { 351dacb1287SKranthi Kuntala dev_err(&rt->dev, "failed to add NVM devices: %d\n", ret); 352bec4d7c9SDan Carpenter device_unregister(&rt->dev); 353dacb1287SKranthi Kuntala return ret; 354dacb1287SKranthi Kuntala } 355dacb1287SKranthi Kuntala 356dacb1287SKranthi Kuntala dev_info(&rt->dev, "new retimer found, vendor=%#x device=%#x\n", 357dacb1287SKranthi Kuntala rt->vendor, rt->device); 358dacb1287SKranthi Kuntala 359dacb1287SKranthi Kuntala pm_runtime_no_callbacks(&rt->dev); 360dacb1287SKranthi Kuntala pm_runtime_set_active(&rt->dev); 361dacb1287SKranthi Kuntala pm_runtime_enable(&rt->dev); 362dacb1287SKranthi Kuntala pm_runtime_set_autosuspend_delay(&rt->dev, TB_AUTOSUSPEND_DELAY); 363dacb1287SKranthi Kuntala pm_runtime_mark_last_busy(&rt->dev); 364dacb1287SKranthi Kuntala pm_runtime_use_autosuspend(&rt->dev); 365dacb1287SKranthi Kuntala 366dacb1287SKranthi Kuntala return 0; 367dacb1287SKranthi Kuntala } 368dacb1287SKranthi Kuntala 369dacb1287SKranthi Kuntala static void tb_retimer_remove(struct tb_retimer *rt) 370dacb1287SKranthi Kuntala { 371dacb1287SKranthi Kuntala dev_info(&rt->dev, "retimer disconnected\n"); 372dacb1287SKranthi Kuntala tb_nvm_free(rt->nvm); 373dacb1287SKranthi Kuntala device_unregister(&rt->dev); 374dacb1287SKranthi Kuntala } 375dacb1287SKranthi Kuntala 376dacb1287SKranthi Kuntala struct tb_retimer_lookup { 377dacb1287SKranthi Kuntala const struct tb_port *port; 378dacb1287SKranthi Kuntala u8 index; 379dacb1287SKranthi Kuntala }; 380dacb1287SKranthi Kuntala 381dacb1287SKranthi Kuntala static int retimer_match(struct device *dev, void *data) 382dacb1287SKranthi Kuntala { 383dacb1287SKranthi Kuntala const struct tb_retimer_lookup *lookup = data; 384dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 385dacb1287SKranthi Kuntala 386dacb1287SKranthi Kuntala return rt && rt->port == lookup->port && rt->index == lookup->index; 387dacb1287SKranthi Kuntala } 388dacb1287SKranthi Kuntala 389dacb1287SKranthi Kuntala static struct tb_retimer *tb_port_find_retimer(struct tb_port *port, u8 index) 390dacb1287SKranthi Kuntala { 391dacb1287SKranthi Kuntala struct tb_retimer_lookup lookup = { .port = port, .index = index }; 392dacb1287SKranthi Kuntala struct device *dev; 393dacb1287SKranthi Kuntala 394*cae5f515SMika Westerberg dev = device_find_child(&port->usb4->dev, &lookup, retimer_match); 395dacb1287SKranthi Kuntala if (dev) 396dacb1287SKranthi Kuntala return tb_to_retimer(dev); 397dacb1287SKranthi Kuntala 398dacb1287SKranthi Kuntala return NULL; 399dacb1287SKranthi Kuntala } 400dacb1287SKranthi Kuntala 401dacb1287SKranthi Kuntala /** 402dacb1287SKranthi Kuntala * tb_retimer_scan() - Scan for on-board retimers under port 403dacb1287SKranthi Kuntala * @port: USB4 port to scan 404dacb1287SKranthi Kuntala * 405dacb1287SKranthi Kuntala * Tries to enumerate on-board retimers connected to @port. Found 406dacb1287SKranthi Kuntala * retimers are registered as children of @port. Does not scan for cable 407dacb1287SKranthi Kuntala * retimers for now. 408dacb1287SKranthi Kuntala */ 409dacb1287SKranthi Kuntala int tb_retimer_scan(struct tb_port *port) 410dacb1287SKranthi Kuntala { 41108fe7ae1SDan Carpenter u32 status[TB_MAX_RETIMER_INDEX + 1] = {}; 412dacb1287SKranthi Kuntala int ret, i, last_idx = 0; 413dacb1287SKranthi Kuntala 414dacb1287SKranthi Kuntala if (!port->cap_usb4) 415dacb1287SKranthi Kuntala return 0; 416dacb1287SKranthi Kuntala 417dacb1287SKranthi Kuntala /* 418dacb1287SKranthi Kuntala * Send broadcast RT to make sure retimer indices facing this 419dacb1287SKranthi Kuntala * port are set. 420dacb1287SKranthi Kuntala */ 421dacb1287SKranthi Kuntala ret = usb4_port_enumerate_retimers(port); 422dacb1287SKranthi Kuntala if (ret) 423dacb1287SKranthi Kuntala return ret; 424dacb1287SKranthi Kuntala 425dacb1287SKranthi Kuntala /* 426dacb1287SKranthi Kuntala * Before doing anything else, read the authentication status. 427dacb1287SKranthi Kuntala * If the retimer has it set, store it for the new retimer 428dacb1287SKranthi Kuntala * device instance. 429dacb1287SKranthi Kuntala */ 430dacb1287SKranthi Kuntala for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) 431dacb1287SKranthi Kuntala usb4_port_retimer_nvm_authenticate_status(port, i, &status[i]); 432dacb1287SKranthi Kuntala 433dacb1287SKranthi Kuntala for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { 434dacb1287SKranthi Kuntala /* 435dacb1287SKranthi Kuntala * Last retimer is true only for the last on-board 436dacb1287SKranthi Kuntala * retimer (the one connected directly to the Type-C 437dacb1287SKranthi Kuntala * port). 438dacb1287SKranthi Kuntala */ 439dacb1287SKranthi Kuntala ret = usb4_port_retimer_is_last(port, i); 440dacb1287SKranthi Kuntala if (ret > 0) 441dacb1287SKranthi Kuntala last_idx = i; 442dacb1287SKranthi Kuntala else if (ret < 0) 443dacb1287SKranthi Kuntala break; 444dacb1287SKranthi Kuntala } 445dacb1287SKranthi Kuntala 446dacb1287SKranthi Kuntala if (!last_idx) 447dacb1287SKranthi Kuntala return 0; 448dacb1287SKranthi Kuntala 449dacb1287SKranthi Kuntala /* Add on-board retimers if they do not exist already */ 450dacb1287SKranthi Kuntala for (i = 1; i <= last_idx; i++) { 451dacb1287SKranthi Kuntala struct tb_retimer *rt; 452dacb1287SKranthi Kuntala 453dacb1287SKranthi Kuntala rt = tb_port_find_retimer(port, i); 454dacb1287SKranthi Kuntala if (rt) { 455dacb1287SKranthi Kuntala put_device(&rt->dev); 456dacb1287SKranthi Kuntala } else { 457dacb1287SKranthi Kuntala ret = tb_retimer_add(port, i, status[i]); 458dacb1287SKranthi Kuntala if (ret && ret != -EOPNOTSUPP) 459dacb1287SKranthi Kuntala return ret; 460dacb1287SKranthi Kuntala } 461dacb1287SKranthi Kuntala } 462dacb1287SKranthi Kuntala 463dacb1287SKranthi Kuntala return 0; 464dacb1287SKranthi Kuntala } 465dacb1287SKranthi Kuntala 466dacb1287SKranthi Kuntala static int remove_retimer(struct device *dev, void *data) 467dacb1287SKranthi Kuntala { 468dacb1287SKranthi Kuntala struct tb_retimer *rt = tb_to_retimer(dev); 469dacb1287SKranthi Kuntala struct tb_port *port = data; 470dacb1287SKranthi Kuntala 471dacb1287SKranthi Kuntala if (rt && rt->port == port) 472dacb1287SKranthi Kuntala tb_retimer_remove(rt); 473dacb1287SKranthi Kuntala return 0; 474dacb1287SKranthi Kuntala } 475dacb1287SKranthi Kuntala 476dacb1287SKranthi Kuntala /** 477dacb1287SKranthi Kuntala * tb_retimer_remove_all() - Remove all retimers under port 478dacb1287SKranthi Kuntala * @port: USB4 port whose retimers to remove 479dacb1287SKranthi Kuntala * 480dacb1287SKranthi Kuntala * This removes all previously added retimers under @port. 481dacb1287SKranthi Kuntala */ 482dacb1287SKranthi Kuntala void tb_retimer_remove_all(struct tb_port *port) 483dacb1287SKranthi Kuntala { 484*cae5f515SMika Westerberg struct usb4_port *usb4; 485*cae5f515SMika Westerberg 486*cae5f515SMika Westerberg usb4 = port->usb4; 487*cae5f515SMika Westerberg if (usb4) 488*cae5f515SMika Westerberg device_for_each_child_reverse(&usb4->dev, port, 489dacb1287SKranthi Kuntala remove_retimer); 490dacb1287SKranthi Kuntala } 491