xref: /openbmc/linux/drivers/thunderbolt/retimer.c (revision cae5f515)
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