Commit e09bf86f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB / Thunderbolt updates from Greg KH:
 "Here is the big set of USB and Thunderbolt changes for 6.9-rc1. Lots
  of tiny changes and forward progress to support new hardware and
  better support for existing devices. Included in here are:

   - Thunderbolt (i.e. USB4) updates for newer hardware and uses as more
     people start to use the hardware

   - default USB authentication mode Kconfig and documentation update to
     make it more obvious what is going on

   - USB typec updates and enhancements

   - usual dwc3 driver updates

   - usual xhci driver updates

   - function USB (i.e. gadget) driver updates and additions

   - new device ids for lots of drivers

   - loads of other small updates, full details in the shortlog

  All of these, including a "last minute regression fix" have been in
  linux-next with no reported issues"

* tag 'usb-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (185 commits)
  usb: usb-acpi: Fix oops due to freeing uninitialized pld pointer
  usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin
  usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic
  phy: tegra: xusb: Add API to retrieve the port number of phy
  USB: gadget: pxa27x_udc: Remove unused of_gpio.h
  usb: gadget/snps_udc_plat: Remove unused of_gpio.h
  usb: ohci-pxa27x: Remove unused of_gpio.h
  usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined
  usb: Clarify expected behavior of dev_bin_attrs_are_visible()
  xhci: Allow RPM on the USB controller (1022:43f7) by default
  usb: isp1760: remove SLAB_MEM_SPREAD flag usage
  usb: misc: onboard_hub: use pointer consistently in the probe function
  usb: gadget: fsl: Increase size of name buffer for endpoints
  usb: gadget: fsl: Add of device table to enable module autoloading
  usb: typec: tcpm: add support to set tcpc connector orientatition
  usb: typec: tcpci: add generic tcpci fallback compatible
  dt-bindings: usb: typec-tcpci: add tcpci fallback binding
  usb: gadget: fsl-udc: Replace custom log wrappers by dev_{err,warn,dbg,vdbg}
  usb: core: Set connect_type of ports based on DT node
  dt-bindings: usb: Add downstream facing ports to realtek binding
  ...
parents 2ac2b166 a788e53c
...@@ -4,6 +4,14 @@ KernelVersion: 3.13 ...@@ -4,6 +4,14 @@ KernelVersion: 3.13
Description: The purpose of this directory is to create and remove it. Description: The purpose of this directory is to create and remove it.
A corresponding USB function instance is created/removed. A corresponding USB function instance is created/removed.
There are no attributes here.
All parameters are set through FunctionFS. All attributes are read only:
============= ============================================
ready 1 if the function is ready to be used, E.G.
if userspace has written descriptors and
strings to ep0, so the gadget can be
enabled - 0 otherwise.
============= ============================================
All other parameters are set through FunctionFS.
...@@ -442,6 +442,16 @@ What: /sys/bus/usb/devices/usbX/descriptors ...@@ -442,6 +442,16 @@ What: /sys/bus/usb/devices/usbX/descriptors
Description: Description:
Contains the interface descriptors, in binary. Contains the interface descriptors, in binary.
What: /sys/bus/usb/devices/usbX/bos_descriptors
Date: March 2024
Contact: Elbert Mai <code@elbertmai.com>
Description:
Binary file containing the cached binary device object store (BOS)
of the device. This consists of the BOS descriptor followed by the
set of device capability descriptors. All descriptors read from
this file are in bus-endian format. Note that the kernel will not
request the BOS from a device if its bcdUSB is less than 0x0201.
What: /sys/bus/usb/devices/usbX/idProduct What: /sys/bus/usb/devices/usbX/idProduct
Description: Description:
Product ID, in hexadecimal. Product ID, in hexadecimal.
......
...@@ -19,3 +19,9 @@ Description: ...@@ -19,3 +19,9 @@ Description:
- none - none
- host - host
- device - device
What: /sys/class/usb_role/<switch>/connector
Date: Feb 2024
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Description:
Optional symlink to the USB Type-C connector.
...@@ -26,6 +26,7 @@ properties: ...@@ -26,6 +26,7 @@ properties:
- enum: - enum:
- qcom,pm4125-vbus-reg - qcom,pm4125-vbus-reg
- qcom,pm6150-vbus-reg - qcom,pm6150-vbus-reg
- qcom,pmi632-vbus-reg
- const: qcom,pm8150b-vbus-reg - const: qcom,pm8150b-vbus-reg
reg: reg:
......
...@@ -23,6 +23,7 @@ properties: ...@@ -23,6 +23,7 @@ properties:
oneOf: oneOf:
- items: - items:
- enum: - enum:
- qcom,qcm6490-pmic-glink
- qcom,sc8180x-pmic-glink - qcom,sc8180x-pmic-glink
- qcom,sc8280xp-pmic-glink - qcom,sc8280xp-pmic-glink
- qcom,sm8350-pmic-glink - qcom,sm8350-pmic-glink
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/qcom,q6usb.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm ASoC DPCM USB backend DAI
maintainers:
- Wesley Cheng <quic_wcheng@quicinc.com>
description:
The USB port is a supported AFE path on the Q6 DSP. This ASoC DPCM
backend DAI will communicate the required settings to initialize the
XHCI host controller properly for enabling the offloaded audio stream.
Parameters defined under this node will carry settings, which will be
passed along during the QMI stream enable request and configuration of
the XHCI host controller.
allOf:
- $ref: dai-common.yaml#
properties:
compatible:
enum:
- qcom,q6usb
iommus:
maxItems: 1
"#sound-dai-cells":
const: 1
qcom,usb-audio-intr-idx:
description:
Desired XHCI interrupter number to use. Depending on the audio DSP
on the platform, it will operate on a specific XHCI interrupter.
$ref: /schemas/types.yaml#/definitions/uint16
maximum: 8
required:
- compatible
- "#sound-dai-cells"
- qcom,usb-audio-intr-idx
additionalProperties: false
examples:
- |
dais {
compatible = "qcom,q6usb";
#sound-dai-cells = <1>;
iommus = <&apps_smmu 0x180f 0x0>;
qcom,usb-audio-intr-idx = /bits/ 16 <2>;
};
...@@ -23,24 +23,11 @@ properties: ...@@ -23,24 +23,11 @@ properties:
connector: connector:
type: object type: object
$ref: ../connector/usb-connector.yaml $ref: ../connector/usb-connector.yaml
unevaluatedProperties: false
description:
Properties for usb c connector.
properties: properties:
compatible: compatible:
const: usb-c-connector const: usb-c-connector
power-role: true
data-role: true
try-power-role: true
required:
- compatible
required: required:
- compatible - compatible
- reg - reg
......
...@@ -313,7 +313,7 @@ properties: ...@@ -313,7 +313,7 @@ properties:
usb-phy: usb-phy:
description: phandle for the PHY device. Use "phys" instead. description: phandle for the PHY device. Use "phys" instead.
$ref: /schemas/types.yaml#/definitions/phandle maxItems: 1
deprecated: true deprecated: true
fsl,usbphy: fsl,usbphy:
......
...@@ -27,13 +27,8 @@ properties: ...@@ -27,13 +27,8 @@ properties:
vcc-supply: vcc-supply:
description: power supply (2.7V-5.5V) description: power supply (2.7V-5.5V)
mode-switch: mode-switch: true
description: Flag the port as possible handle of altmode switching orientation-switch: true
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
port: port:
$ref: /schemas/graph.yaml#/$defs/port-base $ref: /schemas/graph.yaml#/$defs/port-base
...@@ -79,6 +74,9 @@ required: ...@@ -79,6 +74,9 @@ required:
- reg - reg
- port - port
allOf:
- $ref: usb-switch.yaml#
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -77,6 +77,7 @@ properties: ...@@ -77,6 +77,7 @@ properties:
- const: usb-ehci - const: usb-ehci
- enum: - enum:
- generic-ehci - generic-ehci
- marvell,ac5-ehci
- marvell,armada-3700-ehci - marvell,armada-3700-ehci
- marvell,orion-ehci - marvell,orion-ehci
- nuvoton,npcm750-ehci - nuvoton,npcm750-ehci
......
...@@ -33,13 +33,8 @@ properties: ...@@ -33,13 +33,8 @@ properties:
vcc-supply: vcc-supply:
description: power supply description: power supply
mode-switch: mode-switch: true
description: Flag the port as possible handle of altmode switching orientation-switch: true
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
port: port:
$ref: /schemas/graph.yaml#/properties/port $ref: /schemas/graph.yaml#/properties/port
...@@ -54,6 +49,9 @@ required: ...@@ -54,6 +49,9 @@ required:
- orientation-switch - orientation-switch
- port - port
allOf:
- $ref: usb-switch.yaml#
additionalProperties: false additionalProperties: false
examples: examples:
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/hisilicon,hi3798mv200-dwc3.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: HiSilicon Hi3798MV200 DWC3 USB SoC controller
maintainers:
- Yang Xiwen <forbidden405@foxmail.com>
properties:
compatible:
const: hisilicon,hi3798mv200-dwc3
'#address-cells':
const: 1
'#size-cells':
const: 1
ranges: true
clocks:
items:
- description: Controller bus clock
- description: Controller suspend clock
- description: Controller reference clock
- description: Controller gm clock
- description: Controller gs clock
- description: Controller utmi clock
- description: Controller pipe clock
clock-names:
items:
- const: bus
- const: suspend
- const: ref
- const: gm
- const: gs
- const: utmi
- const: pipe
resets:
maxItems: 1
reset-names:
const: soft
patternProperties:
'^usb@[0-9a-f]+$':
$ref: snps,dwc3.yaml#
required:
- compatible
- ranges
- '#address-cells'
- '#size-cells'
- clocks
- clock-names
- resets
- reset-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
usb {
compatible = "hisilicon,hi3798mv200-dwc3";
ranges;
#address-cells = <1>;
#size-cells = <1>;
clocks = <&clk_bus>,
<&clk_suspend>,
<&clk_ref>,
<&clk_gm>,
<&clk_gs>,
<&clk_utmi>,
<&clk_pipe>;
clock-names = "bus", "suspend", "ref", "gm", "gs", "utmi", "pipe";
resets = <&crg 0xb0 12>;
reset-names = "soft";
usb@98a0000 {
compatible = "snps,dwc3";
reg = <0x98a0000 0x10000>;
interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clk_bus>,
<&clk_suspend>,
<&clk_ref>;
clock-names = "bus_early", "suspend", "ref";
phys = <&usb2_phy1_port2>, <&combphy0 0>;
phy-names = "usb2-phy", "usb3-phy";
maximum-speed = "super-speed";
dr_mode = "host";
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/ite,it5205.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ITE IT5202 Type-C USB Alternate Mode Passive MUX
maintainers:
- AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
- Tianping Fang <tianping.fang@mediatek.com>
properties:
compatible:
const: ite,it5205
reg:
maxItems: 1
vcc-supply:
description: Power supply for VCC pin (3.3V)
mode-switch:
description: Flag the port as possible handle of altmode switching
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
ite,ovp-enable:
description: Enable Over Voltage Protection functionality
type: boolean
port:
$ref: /schemas/graph.yaml#/properties/port
description:
A port node to link the IT5205 to a TypeC controller for the purpose of
handling altmode muxing and orientation switching.
required:
- compatible
- reg
- orientation-switch
- port
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c2 {
#address-cells = <1>;
#size-cells = <0>;
typec-mux@48 {
compatible = "ite,it5205";
reg = <0x48>;
mode-switch;
orientation-switch;
vcc-supply = <&mt6359_vibr_ldo_reg>;
port {
it5205_usbss_sbu: endpoint {
remote-endpoint = <&typec_controller>;
};
};
};
};
...
...@@ -185,7 +185,10 @@ properties: ...@@ -185,7 +185,10 @@ properties:
2 - used by mt2712 etc, revision 2 with following IPM rule; 2 - used by mt2712 etc, revision 2 with following IPM rule;
101 - used by mt8183, specific 1.01; 101 - used by mt8183, specific 1.01;
102 - used by mt8192, specific 1.02; 102 - used by mt8192, specific 1.02;
enum: [1, 2, 101, 102] 103 - used by mt8195, IP0, specific 1.03;
105 - used by mt8195, IP2, specific 1.05;
106 - used by mt8195, IP3, specific 1.06;
enum: [1, 2, 101, 102, 103, 105, 106]
mediatek,u3p-dis-msk: mediatek,u3p-dis-msk:
$ref: /schemas/types.yaml#/definitions/uint32 $ref: /schemas/types.yaml#/definitions/uint32
......
...@@ -72,8 +72,6 @@ allOf: ...@@ -72,8 +72,6 @@ allOf:
i2c-bus: false i2c-bus: false
else: else:
$ref: /schemas/usb/usb-device.yaml $ref: /schemas/usb/usb-device.yaml
required:
- peer-hub
additionalProperties: false additionalProperties: false
......
...@@ -20,13 +20,8 @@ properties: ...@@ -20,13 +20,8 @@ properties:
vdd18-supply: vdd18-supply:
description: Power supply for VDD18 pin description: Power supply for VDD18 pin
retimer-switch: orientation-switch: true
description: Flag the port as possible handle of SuperSpeed signals retiming retimer-switch: true
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
...@@ -49,6 +44,9 @@ required: ...@@ -49,6 +44,9 @@ required:
- compatible - compatible
- reg - reg
allOf:
- $ref: usb-switch.yaml#
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -11,7 +11,9 @@ maintainers: ...@@ -11,7 +11,9 @@ maintainers:
properties: properties:
compatible: compatible:
const: nxp,ptn5110 items:
- const: nxp,ptn5110
- const: tcpci
reg: reg:
maxItems: 1 maxItems: 1
...@@ -41,7 +43,7 @@ examples: ...@@ -41,7 +43,7 @@ examples:
#size-cells = <0>; #size-cells = <0>;
tcpci@50 { tcpci@50 {
compatible = "nxp,ptn5110"; compatible = "nxp,ptn5110", "tcpci";
reg = <0x50>; reg = <0x50>;
interrupt-parent = <&gpio3>; interrupt-parent = <&gpio3>;
interrupts = <3 IRQ_TYPE_LEVEL_LOW>; interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
......
...@@ -21,14 +21,8 @@ properties: ...@@ -21,14 +21,8 @@ properties:
description: power supply (1.8V) description: power supply (1.8V)
enable-gpios: true enable-gpios: true
orientation-switch: true
retimer-switch: retimer-switch: true
description: Flag the port as possible handle of SuperSpeed signals retiming
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
...@@ -95,6 +89,9 @@ required: ...@@ -95,6 +89,9 @@ required:
- compatible - compatible
- reg - reg
allOf:
- $ref: usb-switch.yaml#
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -102,7 +102,7 @@ properties: ...@@ -102,7 +102,7 @@ properties:
description: | description: |
Different types of interrupts are used based on HS PHY used on target: Different types of interrupts are used based on HS PHY used on target:
- pwr_event: Used for wakeup based on other power events. - pwr_event: Used for wakeup based on other power events.
- hs_phY_irq: Apart from DP/DM/QUSB2 PHY interrupts, there is - hs_phy_irq: Apart from DP/DM/QUSB2 PHY interrupts, there is
hs_phy_irq which is not triggered by default and its hs_phy_irq which is not triggered by default and its
functionality is mutually exclusive to that of functionality is mutually exclusive to that of
{dp/dm}_hs_phy_irq and qusb2_phy_irq. {dp/dm}_hs_phy_irq and qusb2_phy_irq.
......
...@@ -14,8 +14,19 @@ description: ...@@ -14,8 +14,19 @@ description:
properties: properties:
compatible: compatible:
enum: oneOf:
- enum:
- qcom,pmi632-typec
- qcom,pm8150b-typec - qcom,pm8150b-typec
- items:
- enum:
- qcom,pm6150-typec
- const: qcom,pm8150b-typec
- items:
- enum:
- qcom,pm4125-typec
- const: qcom,pmi632-typec
connector: connector:
type: object type: object
...@@ -24,9 +35,11 @@ properties: ...@@ -24,9 +35,11 @@ properties:
reg: reg:
description: Type-C port and pdphy SPMI register base offsets description: Type-C port and pdphy SPMI register base offsets
minItems: 1
maxItems: 2 maxItems: 2
interrupts: interrupts:
minItems: 8
items: items:
- description: Type-C CC attach notification, VBUS error, tCCDebounce done - description: Type-C CC attach notification, VBUS error, tCCDebounce done
- description: Type-C VCONN powered - description: Type-C VCONN powered
...@@ -46,6 +59,7 @@ properties: ...@@ -46,6 +59,7 @@ properties:
- description: Power Domain Fast Role Swap event - description: Power Domain Fast Role Swap event
interrupt-names: interrupt-names:
minItems: 8
items: items:
- const: or-rid-detect-change - const: or-rid-detect-change
- const: vpd-detect - const: vpd-detect
...@@ -81,6 +95,32 @@ required: ...@@ -81,6 +95,32 @@ required:
- interrupts - interrupts
- interrupt-names - interrupt-names
- vdd-vbus-supply - vdd-vbus-supply
allOf:
- if:
properties:
compatible:
contains:
enum:
- qcom,pmi632-typec
then:
properties:
reg:
maxItems: 1
interrupts:
maxItems: 8
interrupt-names:
maxItems: 8
vdd-pdphy-supply: false
else:
properties:
reg:
maxItems: 2
interrupts:
minItems: 16
interrupt-names:
maxItems: 16
required:
- vdd-pdphy-supply - vdd-pdphy-supply
additionalProperties: false additionalProperties: false
......
...@@ -35,13 +35,8 @@ properties: ...@@ -35,13 +35,8 @@ properties:
vdd-supply: vdd-supply:
description: USBSS VDD power supply description: USBSS VDD power supply
mode-switch: mode-switch: true
description: Flag the port as possible handle of altmode switching orientation-switch: true
type: boolean
orientation-switch:
description: Flag the port as possible handler of orientation switching
type: boolean
ports: ports:
$ref: /schemas/graph.yaml#/properties/ports $ref: /schemas/graph.yaml#/properties/ports
...@@ -63,6 +58,9 @@ required: ...@@ -63,6 +58,9 @@ required:
- reg - reg
- ports - ports
allOf:
- $ref: usb-switch.yaml#
additionalProperties: false additionalProperties: false
examples: examples:
......
...@@ -21,6 +21,12 @@ properties: ...@@ -21,6 +21,12 @@ properties:
reg: true reg: true
'#address-cells':
const: 1
'#size-cells':
const: 0
vdd-supply: vdd-supply:
description: description:
phandle to the regulator that provides power to the hub. phandle to the regulator that provides power to the hub.
...@@ -30,6 +36,36 @@ properties: ...@@ -30,6 +36,36 @@ properties:
description: description:
phandle to the peer hub on the controller. phandle to the peer hub on the controller.
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@1:
$ref: /schemas/graph.yaml#/properties/port
description:
1st downstream facing USB port
port@2:
$ref: /schemas/graph.yaml#/properties/port
description:
2nd downstream facing USB port
port@3:
$ref: /schemas/graph.yaml#/properties/port
description:
3rd downstream facing USB port
port@4:
$ref: /schemas/graph.yaml#/properties/port
description:
4th downstream facing USB port
patternProperties:
'^.*@[1-4]$':
description: The hard wired USB devices
type: object
$ref: /schemas/usb/usb-device.yaml
required: required:
- peer-hub - peer-hub
- compatible - compatible
...@@ -50,6 +86,13 @@ examples: ...@@ -50,6 +86,13 @@ examples:
reg = <1>; reg = <1>;
vdd-supply = <&pp3300_hub>; vdd-supply = <&pp3300_hub>;
peer-hub = <&hub_3_0>; peer-hub = <&hub_3_0>;
#address-cells = <1>;
#size-cells = <0>;
/* USB 2.0 device on port 2 */
device@2 {
compatible = "usb123,4567";
reg = <2>;
};
}; };
/* 3.0 hub on port 2 */ /* 3.0 hub on port 2 */
...@@ -58,5 +101,17 @@ examples: ...@@ -58,5 +101,17 @@ examples:
reg = <2>; reg = <2>;
vdd-supply = <&pp3300_hub>; vdd-supply = <&pp3300_hub>;
peer-hub = <&hub_2_0>; peer-hub = <&hub_2_0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
/* Type-A connector on port 4 */
port@4 {
reg = <4>;
endpoint {
remote-endpoint = <&usb_a0_ss>;
};
};
};
}; };
}; };
...@@ -14,7 +14,10 @@ properties: ...@@ -14,7 +14,10 @@ properties:
const: ti,am62-usb const: ti,am62-usb
reg: reg:
maxItems: 1 minItems: 1
items:
- description: USB CFG register space
- description: USB PHY2 register space
ranges: true ranges: true
...@@ -82,7 +85,8 @@ examples: ...@@ -82,7 +85,8 @@ examples:
usbss1: usb@f910000 { usbss1: usb@f910000 {
compatible = "ti,am62-usb"; compatible = "ti,am62-usb";
reg = <0x00 0x0f910000 0x00 0x800>; reg = <0x00 0x0f910000 0x00 0x800>,
<0x00 0x0f918000 0x00 0x400>;
clocks = <&k3_clks 162 3>; clocks = <&k3_clks 162 3>;
clock-names = "ref"; clock-names = "ref";
ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>; ti,syscon-phy-pll-refclk = <&wkup_conf 0x4018>;
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/ti,usb8020b.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI USB8020B USB 3.0 hub controller
maintainers:
- Macpaul Lin <macpaul.lin@mediatek.com>
allOf:
- $ref: usb-device.yaml#
properties:
compatible:
enum:
- usb451,8025
- usb451,8027
reg: true
reset-gpios:
items:
- description: GPIO specifier for GRST# pin.
vdd-supply:
description:
VDD power supply to the hub
peer-hub:
$ref: /schemas/types.yaml#/definitions/phandle
description:
phandle to the peer hub on the controller.
required:
- compatible
- reg
- peer-hub
additionalProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
usb {
dr_mode = "host";
#address-cells = <1>;
#size-cells = <0>;
/* 2.0 hub on port 1 */
hub_2_0: hub@1 {
compatible = "usb451,8027";
reg = <1>;
peer-hub = <&hub_3_0>;
reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
vdd-supply = <&usb_hub_fixed_3v3>;
};
/* 3.0 hub on port 2 */
hub_3_0: hub@2 {
compatible = "usb451,8025";
reg = <2>;
peer-hub = <&hub_2_0>;
reset-gpios = <&pio 7 GPIO_ACTIVE_HIGH>;
vdd-supply = <&usb_hub_fixed_3v3>;
};
};
...@@ -37,10 +37,11 @@ properties: ...@@ -37,10 +37,11 @@ properties:
description: Should specify the GPIO detecting a VBus insertion description: Should specify the GPIO detecting a VBus insertion
maxItems: 1 maxItems: 1
vbus-regulator: vbus-supply:
description: Should specify the regulator supplying current drawn from description: regulator supplying VBUS. It will be enabled and disabled
the VBus line. dynamically in OTG mode. If the regulator is controlled by a
$ref: /schemas/types.yaml#/definitions/phandle GPIO line, this should be modeled as a regulator-fixed and
referenced by this supply.
wakeup-source: wakeup-source:
description: description:
...@@ -65,7 +66,7 @@ examples: ...@@ -65,7 +66,7 @@ examples:
vcc-supply = <&hsusb1_vcc_regulator>; vcc-supply = <&hsusb1_vcc_regulator>;
reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>; reset-gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
vbus-detect-gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>; vbus-detect-gpio = <&gpio2 13 GPIO_ACTIVE_HIGH>;
vbus-regulator = <&vbus_regulator>; vbus-supply = <&vbus_regulator>;
#phy-cells = <0>; #phy-cells = <0>;
}; };
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/usb-switch.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: USB Orientation and Mode Switches Common Properties
maintainers:
- Greg Kroah-Hartman <gregkh@linuxfoundation.org>
description:
Common properties for devices handling USB mode and orientation switching.
properties:
mode-switch:
description: Possible handler of altmode switching
type: boolean
orientation-switch:
description: Possible handler of orientation switching
type: boolean
retimer-switch:
description: Possible handler of SuperSpeed signals retiming
type: boolean
port:
$ref: /schemas/graph.yaml#/properties/port
description:
A port node to link the device to a TypeC controller for the purpose of
handling altmode muxing and orientation switching.
ports:
$ref: /schemas/graph.yaml#/properties/ports
properties:
port@0:
$ref: /schemas/graph.yaml#/properties/port
description:
Super Speed (SS) Output endpoint to the Type-C connector
port@1:
$ref: /schemas/graph.yaml#/$defs/port-base
description:
Super Speed (SS) Input endpoint from the Super-Speed PHY
unevaluatedProperties: false
properties:
endpoint:
$ref: /schemas/graph.yaml#/$defs/endpoint-base
unevaluatedProperties: false
properties:
data-lanes:
$ref: /schemas/types.yaml#/definitions/uint32-array
minItems: 1
maxItems: 8
uniqueItems: true
items:
maximum: 8
oneOf:
- required:
- port
- required:
- ports
additionalProperties: true
...@@ -25,6 +25,8 @@ properties: ...@@ -25,6 +25,8 @@ properties:
usb-phy: usb-phy:
$ref: /schemas/types.yaml#/definitions/phandle-array $ref: /schemas/types.yaml#/definitions/phandle-array
items:
maxItems: 1
description: description:
List of all the USB PHYs on this HCD to be accepted by the legacy USB List of all the USB PHYs on this HCD to be accepted by the legacy USB
Physical Layer subsystem. Physical Layer subsystem.
......
...@@ -99,8 +99,10 @@ The disconnect() callback ...@@ -99,8 +99,10 @@ The disconnect() callback
This callback is a signal to break any connection with an interface. This callback is a signal to break any connection with an interface.
You are not allowed any IO to a device after returning from this You are not allowed any IO to a device after returning from this
callback. You also may not do any other operation that may interfere callback. You also may not do any other operation that may interfere
with another driver bound the interface, eg. a power management with another driver bound to the interface, eg. a power management
operation. operation. Outstanding operations on the device must be completed or
aborted before this callback may return.
If you are called due to a physical disconnection, all your URBs will be If you are called due to a physical disconnection, all your URBs will be
killed by usbcore. Note that in this case disconnect will be called some killed by usbcore. Note that in this case disconnect will be called some
time after the physical disconnection. Thus your driver must be prepared time after the physical disconnection. Thus your driver must be prepared
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
How FunctionFS works How FunctionFS works
==================== ====================
Overview
========
From kernel point of view it is just a composite function with some From kernel point of view it is just a composite function with some
unique behaviour. It may be added to an USB configuration only after unique behaviour. It may be added to an USB configuration only after
the user space driver has registered by writing descriptors and the user space driver has registered by writing descriptors and
...@@ -66,3 +69,36 @@ have been written to their ep0's. ...@@ -66,3 +69,36 @@ have been written to their ep0's.
Conversely, the gadget is unregistered after the first USB function Conversely, the gadget is unregistered after the first USB function
closes its endpoints. closes its endpoints.
DMABUF interface
================
FunctionFS additionally supports a DMABUF based interface, where the
userspace can attach DMABUF objects (externally created) to an endpoint,
and subsequently use them for data transfers.
A userspace application can then use this interface to share DMABUF
objects between several interfaces, allowing it to transfer data in a
zero-copy fashion, for instance between IIO and the USB stack.
As part of this interface, three new IOCTLs have been added. These three
IOCTLs have to be performed on a data endpoint (ie. not ep0). They are:
``FUNCTIONFS_DMABUF_ATTACH(int)``
Attach the DMABUF object, identified by its file descriptor, to the
data endpoint. Returns zero on success, and a negative errno value
on error.
``FUNCTIONFS_DMABUF_DETACH(int)``
Detach the given DMABUF object, identified by its file descriptor,
from the data endpoint. Returns zero on success, and a negative
errno value on error. Note that closing the endpoint's file
descriptor will automatically detach all attached DMABUFs.
``FUNCTIONFS_DMABUF_TRANSFER(struct usb_ffs_dmabuf_transfer_req *)``
Enqueue the previously attached DMABUF to the transfer queue.
The argument is a structure that packs the DMABUF's file descriptor,
the size in bytes to transfer (which should generally correspond to
the size of the DMABUF), and a 'flags' field which is unused
for now. Returns zero on success, and a negative errno value on
error.
...@@ -206,6 +206,14 @@ the standard procedure for using FunctionFS (mount it, run the userspace ...@@ -206,6 +206,14 @@ the standard procedure for using FunctionFS (mount it, run the userspace
process which implements the function proper). The gadget should be enabled process which implements the function proper). The gadget should be enabled
by writing a suitable string to usb_gadget/<gadget>/UDC. by writing a suitable string to usb_gadget/<gadget>/UDC.
The FFS function provides just one attribute in its function directory:
ready
The attribute is read-only and signals if the function is ready (1) to be
used, E.G. if userspace has written descriptors and strings to ep0, so
the gadget can be enabled.
Testing the FFS function Testing the FFS function
------------------------ ------------------------
......
...@@ -63,6 +63,52 @@ pm6150_resin: resin { ...@@ -63,6 +63,52 @@ pm6150_resin: resin {
}; };
}; };
pm6150_vbus: usb-vbus-regulator@1100 {
compatible = "qcom,pm6150-vbus-reg,
qcom,pm8150b-vbus-reg";
reg = <0x1100>;
status = "disabled";
};
pm6150_typec: typec@1500 {
compatible = "qcom,pm6150-typec,
qcom,pm8150b-typec";
reg = <0x1500>, <0x1700>;
interrupts = <0x0 0x15 0x00 IRQ_TYPE_EDGE_RISING>,
<0x0 0x15 0x01 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x15 0x02 IRQ_TYPE_EDGE_RISING>,
<0x0 0x15 0x03 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x15 0x04 IRQ_TYPE_EDGE_RISING>,
<0x0 0x15 0x05 IRQ_TYPE_EDGE_RISING>,
<0x0 0x15 0x06 IRQ_TYPE_EDGE_BOTH>,
<0x0 0x15 0x07 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x00 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x01 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x02 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x03 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x04 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x05 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x06 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x07 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "or-rid-detect-change",
"vpd-detect",
"cc-state-change",
"vconn-oc",
"vbus-change",
"attach-detach",
"legacy-cable-detect",
"try-snk-src-detect",
"sig-tx",
"sig-rx",
"msg-tx",
"msg-rx",
"msg-tx-failed",
"msg-tx-discarded",
"msg-rx-discarded",
"fr-swap";
status = "disabled";
};
pm6150_temp: temp-alarm@2400 { pm6150_temp: temp-alarm@2400 {
compatible = "qcom,spmi-temp-alarm"; compatible = "qcom,spmi-temp-alarm";
reg = <0x2400>; reg = <0x2400>;
......
...@@ -126,7 +126,7 @@ SATA0: sata@30000010000 { ...@@ -126,7 +126,7 @@ SATA0: sata@30000010000 {
interrupts = <93 2>; interrupts = <93 2>;
}; };
EHCI0: ehci@30010000000 { EHCI0: usb@30010000000 {
compatible = "ibm,476gtr-ehci", "generic-ehci"; compatible = "ibm,476gtr-ehci", "generic-ehci";
reg = <0x300 0x10000000 0x0 0x10000>; reg = <0x300 0x10000000 0x0 0x10000>;
interrupt-parent = <&MPIC>; interrupt-parent = <&MPIC>;
...@@ -140,14 +140,14 @@ SD0: sd@30000000000 { ...@@ -140,14 +140,14 @@ SD0: sd@30000000000 {
interrupt-parent = <&MPIC>; interrupt-parent = <&MPIC>;
}; };
OHCI0: ohci@30010010000 { OHCI0: usb@30010010000 {
compatible = "ibm,476gtr-ohci", "generic-ohci"; compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x10010000 0x0 0x10000>; reg = <0x300 0x10010000 0x0 0x10000>;
interrupt-parent = <&MPIC>; interrupt-parent = <&MPIC>;
interrupts = <89 1>; interrupts = <89 1>;
}; };
OHCI1: ohci@30010020000 { OHCI1: usb@30010020000 {
compatible = "ibm,476gtr-ohci", "generic-ohci"; compatible = "ibm,476gtr-ohci", "generic-ohci";
reg = <0x300 0x10020000 0x0 0x10000>; reg = <0x300 0x10020000 0x0 0x10000>;
interrupt-parent = <&MPIC>; interrupt-parent = <&MPIC>;
......
...@@ -87,6 +87,7 @@ source "drivers/phy/motorola/Kconfig" ...@@ -87,6 +87,7 @@ source "drivers/phy/motorola/Kconfig"
source "drivers/phy/mscc/Kconfig" source "drivers/phy/mscc/Kconfig"
source "drivers/phy/qualcomm/Kconfig" source "drivers/phy/qualcomm/Kconfig"
source "drivers/phy/ralink/Kconfig" source "drivers/phy/ralink/Kconfig"
source "drivers/phy/realtek/Kconfig"
source "drivers/phy/renesas/Kconfig" source "drivers/phy/renesas/Kconfig"
source "drivers/phy/rockchip/Kconfig" source "drivers/phy/rockchip/Kconfig"
source "drivers/phy/samsung/Kconfig" source "drivers/phy/samsung/Kconfig"
......
...@@ -26,6 +26,7 @@ obj-y += allwinner/ \ ...@@ -26,6 +26,7 @@ obj-y += allwinner/ \
mscc/ \ mscc/ \
qualcomm/ \ qualcomm/ \
ralink/ \ ralink/ \
realtek/ \
renesas/ \ renesas/ \
rockchip/ \ rockchip/ \
samsung/ \ samsung/ \
......
...@@ -489,6 +489,53 @@ int phy_calibrate(struct phy *phy) ...@@ -489,6 +489,53 @@ int phy_calibrate(struct phy *phy)
} }
EXPORT_SYMBOL_GPL(phy_calibrate); EXPORT_SYMBOL_GPL(phy_calibrate);
/**
* phy_notify_connect() - phy connect notification
* @phy: the phy returned by phy_get()
* @port: the port index for connect
*
* If the phy needs to get connection status, the callback can be used.
* Returns: %0 if successful, a negative error code otherwise
*/
int phy_notify_connect(struct phy *phy, int port)
{
int ret;
if (!phy || !phy->ops->connect)
return 0;
mutex_lock(&phy->mutex);
ret = phy->ops->connect(phy, port);
mutex_unlock(&phy->mutex);
return ret;
}
EXPORT_SYMBOL_GPL(phy_notify_connect);
/**
* phy_notify_disconnect() - phy disconnect notification
* @phy: the phy returned by phy_get()
* @port: the port index for disconnect
*
* If the phy needs to get connection status, the callback can be used.
*
* Returns: %0 if successful, a negative error code otherwise
*/
int phy_notify_disconnect(struct phy *phy, int port)
{
int ret;
if (!phy || !phy->ops->disconnect)
return 0;
mutex_lock(&phy->mutex);
ret = phy->ops->disconnect(phy, port);
mutex_unlock(&phy->mutex);
return ret;
}
EXPORT_SYMBOL_GPL(phy_notify_disconnect);
/** /**
* phy_configure() - Changes the phy parameters * phy_configure() - Changes the phy parameters
* @phy: the phy returned by phy_get() * @phy: the phy returned by phy_get()
......
# SPDX-License-Identifier: GPL-2.0
#
# Phy drivers for Realtek platforms
#
if ARCH_REALTEK || COMPILE_TEST
config PHY_RTK_RTD_USB2PHY
tristate "Realtek RTD USB2 PHY Transceiver Driver"
depends on USB_SUPPORT
select GENERIC_PHY
select USB_PHY
select USB_COMMON
help
Enable this to support Realtek SoC USB2 phy transceiver.
The DHC (digital home center) RTD series SoCs used the Synopsys
DWC3 USB IP. This driver will do the PHY initialization
of the parameters.
config PHY_RTK_RTD_USB3PHY
tristate "Realtek RTD USB3 PHY Transceiver Driver"
depends on USB_SUPPORT
select GENERIC_PHY
select USB_PHY
select USB_COMMON
help
Enable this to support Realtek SoC USB3 phy transceiver.
The DHC (digital home center) RTD series SoCs used the Synopsys
DWC3 USB IP. This driver will do the PHY initialization
of the parameters.
endif # ARCH_REALTEK || COMPILE_TEST
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PHY_RTK_RTD_USB2PHY) += phy-rtk-usb2.o
obj-$(CONFIG_PHY_RTK_RTD_USB3PHY) += phy-rtk-usb3.o
This diff is collapsed.
This diff is collapsed.
...@@ -1531,6 +1531,19 @@ int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl, ...@@ -1531,6 +1531,19 @@ int tegra_xusb_padctl_get_usb3_companion(struct tegra_xusb_padctl *padctl,
} }
EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion); EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_usb3_companion);
int tegra_xusb_padctl_get_port_number(struct phy *phy)
{
struct tegra_xusb_lane *lane;
if (!phy)
return -ENODEV;
lane = phy_get_drvdata(phy);
return lane->index;
}
EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get_port_number);
MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver"); MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -24,6 +24,23 @@ ...@@ -24,6 +24,23 @@
#define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \ #define DP_PORT_VDO (DP_CONF_SET_PIN_ASSIGN(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D)) | \
DP_CAP_DFP_D | DP_CAP_RECEPTACLE) DP_CAP_DFP_D | DP_CAP_RECEPTACLE)
static void cros_typec_role_switch_quirk(struct fwnode_handle *fwnode)
{
#ifdef CONFIG_ACPI
struct fwnode_handle *switch_fwnode;
/* Supply the USB role switch with the correct pld_crc if it's missing. */
switch_fwnode = fwnode_find_reference(fwnode, "usb-role-switch", 0);
if (!IS_ERR_OR_NULL(switch_fwnode)) {
struct acpi_device *adev = to_acpi_device_node(switch_fwnode);
if (adev && !adev->pld_crc)
adev->pld_crc = to_acpi_device_node(fwnode)->pld_crc;
fwnode_handle_put(switch_fwnode);
}
#endif
}
static int cros_typec_parse_port_props(struct typec_capability *cap, static int cros_typec_parse_port_props(struct typec_capability *cap,
struct fwnode_handle *fwnode, struct fwnode_handle *fwnode,
struct device *dev) struct device *dev)
...@@ -66,6 +83,8 @@ static int cros_typec_parse_port_props(struct typec_capability *cap, ...@@ -66,6 +83,8 @@ static int cros_typec_parse_port_props(struct typec_capability *cap,
cap->prefer_role = ret; cap->prefer_role = ret;
} }
cros_typec_role_switch_quirk(fwnode);
cap->fwnode = fwnode; cap->fwnode = fwnode;
return 0; return 0;
......
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
ccflags-y := -I$(src)
obj-${CONFIG_USB4} := thunderbolt.o obj-${CONFIG_USB4} := thunderbolt.o
thunderbolt-objs := nhi.o nhi_ops.o ctl.o tb.o switch.o cap.o path.o tunnel.o eeprom.o thunderbolt-objs := nhi.o nhi_ops.o ctl.o tb.o switch.o cap.o path.o tunnel.o eeprom.o
thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o usb4.o thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o tmu.o usb4.o
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include "ctl.h" #include "ctl.h"
#define CREATE_TRACE_POINTS
#include "trace.h"
#define TB_CTL_RX_PKG_COUNT 10 #define TB_CTL_RX_PKG_COUNT 10
#define TB_CTL_RETRIES 4 #define TB_CTL_RETRIES 4
...@@ -32,6 +34,7 @@ ...@@ -32,6 +34,7 @@
* @timeout_msec: Default timeout for non-raw control messages * @timeout_msec: Default timeout for non-raw control messages
* @callback: Callback called when hotplug message is received * @callback: Callback called when hotplug message is received
* @callback_data: Data passed to @callback * @callback_data: Data passed to @callback
* @index: Domain number. This will be output with the trace record.
*/ */
struct tb_ctl { struct tb_ctl {
struct tb_nhi *nhi; struct tb_nhi *nhi;
...@@ -47,6 +50,8 @@ struct tb_ctl { ...@@ -47,6 +50,8 @@ struct tb_ctl {
int timeout_msec; int timeout_msec;
event_cb callback; event_cb callback;
void *callback_data; void *callback_data;
int index;
}; };
...@@ -369,6 +374,9 @@ static int tb_ctl_tx(struct tb_ctl *ctl, const void *data, size_t len, ...@@ -369,6 +374,9 @@ static int tb_ctl_tx(struct tb_ctl *ctl, const void *data, size_t len,
pkg->frame.size = len + 4; pkg->frame.size = len + 4;
pkg->frame.sof = type; pkg->frame.sof = type;
pkg->frame.eof = type; pkg->frame.eof = type;
trace_tb_tx(ctl->index, type, data, len);
cpu_to_be32_array(pkg->buffer, data, len / 4); cpu_to_be32_array(pkg->buffer, data, len / 4);
*(__be32 *) (pkg->buffer + len) = tb_crc(pkg->buffer, len); *(__be32 *) (pkg->buffer + len) = tb_crc(pkg->buffer, len);
...@@ -384,6 +392,7 @@ static int tb_ctl_tx(struct tb_ctl *ctl, const void *data, size_t len, ...@@ -384,6 +392,7 @@ static int tb_ctl_tx(struct tb_ctl *ctl, const void *data, size_t len,
static bool tb_ctl_handle_event(struct tb_ctl *ctl, enum tb_cfg_pkg_type type, static bool tb_ctl_handle_event(struct tb_ctl *ctl, enum tb_cfg_pkg_type type,
struct ctl_pkg *pkg, size_t size) struct ctl_pkg *pkg, size_t size)
{ {
trace_tb_event(ctl->index, type, pkg->buffer, size);
return ctl->callback(ctl->callback_data, type, pkg->buffer, size); return ctl->callback(ctl->callback_data, type, pkg->buffer, size);
} }
...@@ -489,6 +498,9 @@ static void tb_ctl_rx_callback(struct tb_ring *ring, struct ring_frame *frame, ...@@ -489,6 +498,9 @@ static void tb_ctl_rx_callback(struct tb_ring *ring, struct ring_frame *frame,
* triggered from messing with the active requests. * triggered from messing with the active requests.
*/ */
req = tb_cfg_request_find(pkg->ctl, pkg); req = tb_cfg_request_find(pkg->ctl, pkg);
trace_tb_rx(pkg->ctl->index, frame->eof, pkg->buffer, frame->size, !req);
if (req) { if (req) {
if (req->copy(req, pkg)) if (req->copy(req, pkg))
schedule_work(&req->work); schedule_work(&req->work);
...@@ -614,6 +626,7 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl, ...@@ -614,6 +626,7 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl,
/** /**
* tb_ctl_alloc() - allocate a control channel * tb_ctl_alloc() - allocate a control channel
* @nhi: Pointer to NHI * @nhi: Pointer to NHI
* @index: Domain number
* @timeout_msec: Default timeout used with non-raw control messages * @timeout_msec: Default timeout used with non-raw control messages
* @cb: Callback called for plug events * @cb: Callback called for plug events
* @cb_data: Data passed to @cb * @cb_data: Data passed to @cb
...@@ -622,14 +635,16 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl, ...@@ -622,14 +635,16 @@ struct tb_cfg_result tb_cfg_request_sync(struct tb_ctl *ctl,
* *
* Return: Returns a pointer on success or NULL on failure. * Return: Returns a pointer on success or NULL on failure.
*/ */
struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int timeout_msec, event_cb cb, struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int index, int timeout_msec,
void *cb_data) event_cb cb, void *cb_data)
{ {
int i; int i;
struct tb_ctl *ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); struct tb_ctl *ctl = kzalloc(sizeof(*ctl), GFP_KERNEL);
if (!ctl) if (!ctl)
return NULL; return NULL;
ctl->nhi = nhi; ctl->nhi = nhi;
ctl->index = index;
ctl->timeout_msec = timeout_msec; ctl->timeout_msec = timeout_msec;
ctl->callback = cb; ctl->callback = cb;
ctl->callback_data = cb_data; ctl->callback_data = cb_data;
......
...@@ -21,8 +21,8 @@ struct tb_ctl; ...@@ -21,8 +21,8 @@ struct tb_ctl;
typedef bool (*event_cb)(void *data, enum tb_cfg_pkg_type type, typedef bool (*event_cb)(void *data, enum tb_cfg_pkg_type type,
const void *buf, size_t size); const void *buf, size_t size);
struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int timeout_msec, event_cb cb, struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int index, int timeout_msec,
void *cb_data); event_cb cb, void *cb_data);
void tb_ctl_start(struct tb_ctl *ctl); void tb_ctl_start(struct tb_ctl *ctl);
void tb_ctl_stop(struct tb_ctl *ctl); void tb_ctl_stop(struct tb_ctl *ctl);
void tb_ctl_free(struct tb_ctl *ctl); void tb_ctl_free(struct tb_ctl *ctl);
......
...@@ -321,12 +321,12 @@ static void tb_domain_release(struct device *dev) ...@@ -321,12 +321,12 @@ static void tb_domain_release(struct device *dev)
tb_ctl_free(tb->ctl); tb_ctl_free(tb->ctl);
destroy_workqueue(tb->wq); destroy_workqueue(tb->wq);
ida_simple_remove(&tb_domain_ida, tb->index); ida_free(&tb_domain_ida, tb->index);
mutex_destroy(&tb->lock); mutex_destroy(&tb->lock);
kfree(tb); kfree(tb);
} }
struct device_type tb_domain_type = { const struct device_type tb_domain_type = {
.name = "thunderbolt_domain", .name = "thunderbolt_domain",
.release = tb_domain_release, .release = tb_domain_release,
}; };
...@@ -389,7 +389,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize ...@@ -389,7 +389,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
tb->nhi = nhi; tb->nhi = nhi;
mutex_init(&tb->lock); mutex_init(&tb->lock);
tb->index = ida_simple_get(&tb_domain_ida, 0, 0, GFP_KERNEL); tb->index = ida_alloc(&tb_domain_ida, GFP_KERNEL);
if (tb->index < 0) if (tb->index < 0)
goto err_free; goto err_free;
...@@ -397,7 +397,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize ...@@ -397,7 +397,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
if (!tb->wq) if (!tb->wq)
goto err_remove_ida; goto err_remove_ida;
tb->ctl = tb_ctl_alloc(nhi, timeout_msec, tb_domain_event_cb, tb); tb->ctl = tb_ctl_alloc(nhi, tb->index, timeout_msec, tb_domain_event_cb, tb);
if (!tb->ctl) if (!tb->ctl)
goto err_destroy_wq; goto err_destroy_wq;
...@@ -413,7 +413,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize ...@@ -413,7 +413,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
err_destroy_wq: err_destroy_wq:
destroy_workqueue(tb->wq); destroy_workqueue(tb->wq);
err_remove_ida: err_remove_ida:
ida_simple_remove(&tb_domain_ida, tb->index); ida_free(&tb_domain_ida, tb->index);
err_free: err_free:
kfree(tb); kfree(tb);
...@@ -423,6 +423,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize ...@@ -423,6 +423,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
/** /**
* tb_domain_add() - Add domain to the system * tb_domain_add() - Add domain to the system
* @tb: Domain to add * @tb: Domain to add
* @reset: Issue reset to the host router
* *
* Starts the domain and adds it to the system. Hotplugging devices will * Starts the domain and adds it to the system. Hotplugging devices will
* work after this has been returned successfully. In order to remove * work after this has been returned successfully. In order to remove
...@@ -431,7 +432,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize ...@@ -431,7 +432,7 @@ struct tb *tb_domain_alloc(struct tb_nhi *nhi, int timeout_msec, size_t privsize
* *
* Return: %0 in case of success and negative errno in case of error * Return: %0 in case of success and negative errno in case of error
*/ */
int tb_domain_add(struct tb *tb) int tb_domain_add(struct tb *tb, bool reset)
{ {
int ret; int ret;
...@@ -460,7 +461,7 @@ int tb_domain_add(struct tb *tb) ...@@ -460,7 +461,7 @@ int tb_domain_add(struct tb *tb)
/* Start the domain */ /* Start the domain */
if (tb->cm_ops->start) { if (tb->cm_ops->start) {
ret = tb->cm_ops->start(tb); ret = tb->cm_ops->start(tb, reset);
if (ret) if (ret)
goto err_domain_del; goto err_domain_del;
} }
...@@ -505,6 +506,10 @@ void tb_domain_remove(struct tb *tb) ...@@ -505,6 +506,10 @@ void tb_domain_remove(struct tb *tb)
mutex_unlock(&tb->lock); mutex_unlock(&tb->lock);
flush_workqueue(tb->wq); flush_workqueue(tb->wq);
if (tb->cm_ops->deinit)
tb->cm_ops->deinit(tb);
device_unregister(&tb->dev); device_unregister(&tb->dev);
} }
......
...@@ -2144,7 +2144,7 @@ static int icm_runtime_resume(struct tb *tb) ...@@ -2144,7 +2144,7 @@ static int icm_runtime_resume(struct tb *tb)
return 0; return 0;
} }
static int icm_start(struct tb *tb) static int icm_start(struct tb *tb, bool not_used)
{ {
struct icm *icm = tb_priv(tb); struct icm *icm = tb_priv(tb);
int ret; int ret;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
* Author: Mika Westerberg <mika.westerberg@linux.intel.com> * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/ */
#include <linux/delay.h>
#include "tb.h" #include "tb.h"
/** /**
...@@ -45,6 +47,49 @@ static int find_port_lc_cap(struct tb_port *port) ...@@ -45,6 +47,49 @@ static int find_port_lc_cap(struct tb_port *port)
return sw->cap_lc + start + phys * size; return sw->cap_lc + start + phys * size;
} }
/**
* tb_lc_reset_port() - Trigger downstream port reset through LC
* @port: Port that is reset
*
* Triggers downstream port reset through link controller registers.
* Returns %0 in case of success negative errno otherwise. Only supports
* non-USB4 routers with link controller (that's Thunderbolt 2 and
* Thunderbolt 3).
*/
int tb_lc_reset_port(struct tb_port *port)
{
struct tb_switch *sw = port->sw;
int cap, ret;
u32 mode;
if (sw->generation < 2)
return -EINVAL;
cap = find_port_lc_cap(port);
if (cap < 0)
return cap;
ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
if (ret)
return ret;
mode |= TB_LC_PORT_MODE_DPR;
ret = tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
if (ret)
return ret;
fsleep(10000);
ret = tb_sw_read(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
if (ret)
return ret;
mode &= ~TB_LC_PORT_MODE_DPR;
return tb_sw_write(sw, &mode, TB_CFG_SWITCH, cap + TB_LC_PORT_MODE, 1);
}
static int tb_lc_set_port_configured(struct tb_port *port, bool configured) static int tb_lc_set_port_configured(struct tb_port *port, bool configured)
{ {
bool upstream = tb_is_upstream_port(port); bool upstream = tb_is_upstream_port(port);
......
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
static bool host_reset = true; static bool host_reset = true;
module_param(host_reset, bool, 0444); module_param(host_reset, bool, 0444);
MODULE_PARM_DESC(host_reset, "reset USBv2 host router (default: true)"); MODULE_PARM_DESC(host_reset, "reset USB4 host router (default: true)");
static int ring_interrupt_index(const struct tb_ring *ring) static int ring_interrupt_index(const struct tb_ring *ring)
{ {
...@@ -465,7 +465,7 @@ static int ring_request_msix(struct tb_ring *ring, bool no_suspend) ...@@ -465,7 +465,7 @@ static int ring_request_msix(struct tb_ring *ring, bool no_suspend)
if (!nhi->pdev->msix_enabled) if (!nhi->pdev->msix_enabled)
return 0; return 0;
ret = ida_simple_get(&nhi->msix_ida, 0, MSIX_MAX_VECS, GFP_KERNEL); ret = ida_alloc_max(&nhi->msix_ida, MSIX_MAX_VECS - 1, GFP_KERNEL);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -485,7 +485,7 @@ static int ring_request_msix(struct tb_ring *ring, bool no_suspend) ...@@ -485,7 +485,7 @@ static int ring_request_msix(struct tb_ring *ring, bool no_suspend)
return 0; return 0;
err_ida_remove: err_ida_remove:
ida_simple_remove(&nhi->msix_ida, ring->vector); ida_free(&nhi->msix_ida, ring->vector);
return ret; return ret;
} }
...@@ -496,7 +496,7 @@ static void ring_release_msix(struct tb_ring *ring) ...@@ -496,7 +496,7 @@ static void ring_release_msix(struct tb_ring *ring)
return; return;
free_irq(ring->irq, ring); free_irq(ring->irq, ring);
ida_simple_remove(&ring->nhi->msix_ida, ring->vector); ida_free(&ring->nhi->msix_ida, ring->vector);
ring->vector = 0; ring->vector = 0;
ring->irq = 0; ring->irq = 0;
} }
...@@ -1364,7 +1364,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1364,7 +1364,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
nhi_check_quirks(nhi); nhi_check_quirks(nhi);
nhi_check_iommu(nhi); nhi_check_iommu(nhi);
nhi_reset(nhi); nhi_reset(nhi);
res = nhi_init_msi(nhi); res = nhi_init_msi(nhi);
...@@ -1392,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1392,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
dev_dbg(dev, "NHI initialized, starting thunderbolt\n"); dev_dbg(dev, "NHI initialized, starting thunderbolt\n");
res = tb_domain_add(tb); res = tb_domain_add(tb, host_reset);
if (res) { if (res) {
/* /*
* At this point the RX/TX rings might already have been * At this point the RX/TX rings might already have been
......
...@@ -330,7 +330,7 @@ struct tb_nvm *tb_nvm_alloc(struct device *dev) ...@@ -330,7 +330,7 @@ struct tb_nvm *tb_nvm_alloc(struct device *dev)
if (!nvm) if (!nvm)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = ida_simple_get(&nvm_ida, 0, 0, GFP_KERNEL); ret = ida_alloc(&nvm_ida, GFP_KERNEL);
if (ret < 0) { if (ret < 0) {
kfree(nvm); kfree(nvm);
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -528,7 +528,7 @@ void tb_nvm_free(struct tb_nvm *nvm) ...@@ -528,7 +528,7 @@ void tb_nvm_free(struct tb_nvm *nvm)
nvmem_unregister(nvm->non_active); nvmem_unregister(nvm->non_active);
nvmem_unregister(nvm->active); nvmem_unregister(nvm->active);
vfree(nvm->buf); vfree(nvm->buf);
ida_simple_remove(&nvm_ida, nvm->id); ida_free(&nvm_ida, nvm->id);
} }
kfree(nvm); kfree(nvm);
} }
......
...@@ -446,6 +446,19 @@ static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index, ...@@ -446,6 +446,19 @@ static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index,
return -ETIMEDOUT; return -ETIMEDOUT;
} }
/**
* tb_path_deactivate_hop() - Deactivate one path in path config space
* @port: Lane or protocol adapter
* @hop_index: HopID of the path to be cleared
*
* This deactivates or clears a single path config space entry at
* @hop_index. Returns %0 in success and negative errno otherwise.
*/
int tb_path_deactivate_hop(struct tb_port *port, int hop_index)
{
return __tb_path_deactivate_hop(port, hop_index, true);
}
static void __tb_path_deactivate_hops(struct tb_path *path, int first_hop) static void __tb_path_deactivate_hops(struct tb_path *path, int first_hop)
{ {
int i, res; int i, res;
......
...@@ -43,6 +43,12 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw) ...@@ -43,6 +43,12 @@ static void quirk_usb3_maximum_bandwidth(struct tb_switch *sw)
} }
} }
static void quirk_block_rpm_in_redrive(struct tb_switch *sw)
{
sw->quirks |= QUIRK_KEEP_POWER_IN_DP_REDRIVE;
tb_sw_dbg(sw, "preventing runtime PM in DP redrive mode\n");
}
struct tb_quirk { struct tb_quirk {
u16 hw_vendor_id; u16 hw_vendor_id;
u16 hw_device_id; u16 hw_device_id;
...@@ -86,6 +92,14 @@ static const struct tb_quirk tb_quirks[] = { ...@@ -86,6 +92,14 @@ static const struct tb_quirk tb_quirks[] = {
quirk_usb3_maximum_bandwidth }, quirk_usb3_maximum_bandwidth },
{ 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE, 0x0000, 0x0000, { 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HUB_40G_BRIDGE, 0x0000, 0x0000,
quirk_usb3_maximum_bandwidth }, quirk_usb3_maximum_bandwidth },
/*
* Block Runtime PM in DP redrive mode for Intel Barlow Ridge host
* controllers.
*/
{ 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_80G_NHI, 0x0000, 0x0000,
quirk_block_rpm_in_redrive },
{ 0x8087, PCI_DEVICE_ID_INTEL_BARLOW_RIDGE_HOST_40G_NHI, 0x0000, 0x0000,
quirk_block_rpm_in_redrive },
/* /*
* CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms. * CLx is not supported on AMD USB4 Yellow Carp and Pink Sardine platforms.
*/ */
......
...@@ -356,7 +356,7 @@ static void tb_retimer_release(struct device *dev) ...@@ -356,7 +356,7 @@ static void tb_retimer_release(struct device *dev)
kfree(rt); kfree(rt);
} }
struct device_type tb_retimer_type = { const struct device_type tb_retimer_type = {
.name = "thunderbolt_retimer", .name = "thunderbolt_retimer",
.groups = retimer_groups, .groups = retimer_groups,
.release = tb_retimer_release, .release = tb_retimer_release,
......
...@@ -676,6 +676,13 @@ int tb_port_disable(struct tb_port *port) ...@@ -676,6 +676,13 @@ int tb_port_disable(struct tb_port *port)
return __tb_port_enable(port, false); return __tb_port_enable(port, false);
} }
static int tb_port_reset(struct tb_port *port)
{
if (tb_switch_is_usb4(port->sw))
return port->cap_usb4 ? usb4_port_reset(port) : 0;
return tb_lc_reset_port(port);
}
/* /*
* tb_init_port() - initialize a port * tb_init_port() - initialize a port
* *
...@@ -771,7 +778,7 @@ static int tb_port_alloc_hopid(struct tb_port *port, bool in, int min_hopid, ...@@ -771,7 +778,7 @@ static int tb_port_alloc_hopid(struct tb_port *port, bool in, int min_hopid,
if (max_hopid < 0 || max_hopid > port_max_hopid) if (max_hopid < 0 || max_hopid > port_max_hopid)
max_hopid = port_max_hopid; max_hopid = port_max_hopid;
return ida_simple_get(ida, min_hopid, max_hopid + 1, GFP_KERNEL); return ida_alloc_range(ida, min_hopid, max_hopid, GFP_KERNEL);
} }
/** /**
...@@ -809,7 +816,7 @@ int tb_port_alloc_out_hopid(struct tb_port *port, int min_hopid, int max_hopid) ...@@ -809,7 +816,7 @@ int tb_port_alloc_out_hopid(struct tb_port *port, int min_hopid, int max_hopid)
*/ */
void tb_port_release_in_hopid(struct tb_port *port, int hopid) void tb_port_release_in_hopid(struct tb_port *port, int hopid)
{ {
ida_simple_remove(&port->in_hopids, hopid); ida_free(&port->in_hopids, hopid);
} }
/** /**
...@@ -819,7 +826,7 @@ void tb_port_release_in_hopid(struct tb_port *port, int hopid) ...@@ -819,7 +826,7 @@ void tb_port_release_in_hopid(struct tb_port *port, int hopid)
*/ */
void tb_port_release_out_hopid(struct tb_port *port, int hopid) void tb_port_release_out_hopid(struct tb_port *port, int hopid)
{ {
ida_simple_remove(&port->out_hopids, hopid); ida_free(&port->out_hopids, hopid);
} }
static inline bool tb_switch_is_reachable(const struct tb_switch *parent, static inline bool tb_switch_is_reachable(const struct tb_switch *parent,
...@@ -1120,7 +1127,7 @@ int tb_port_lane_bonding_enable(struct tb_port *port) ...@@ -1120,7 +1127,7 @@ int tb_port_lane_bonding_enable(struct tb_port *port)
ret = tb_port_set_link_width(port->dual_link_port, ret = tb_port_set_link_width(port->dual_link_port,
TB_LINK_WIDTH_DUAL); TB_LINK_WIDTH_DUAL);
if (ret) if (ret)
goto err_lane0; goto err_lane1;
} }
/* /*
...@@ -1534,21 +1541,51 @@ static void tb_dump_switch(const struct tb *tb, const struct tb_switch *sw) ...@@ -1534,21 +1541,51 @@ static void tb_dump_switch(const struct tb *tb, const struct tb_switch *sw)
regs->__unknown1, regs->__unknown4); regs->__unknown1, regs->__unknown4);
} }
/** static int tb_switch_reset_host(struct tb_switch *sw)
* tb_switch_reset() - reconfigure route, enable and send TB_CFG_PKG_RESET
* @sw: Switch to reset
*
* Return: Returns 0 on success or an error code on failure.
*/
int tb_switch_reset(struct tb_switch *sw)
{ {
struct tb_cfg_result res; if (sw->generation > 1) {
struct tb_port *port;
if (sw->generation > 1) tb_switch_for_each_port(sw, port) {
return 0; int i, ret;
tb_sw_dbg(sw, "resetting switch\n"); /*
* For lane adapters we issue downstream port
* reset and clear up path config spaces.
*
* For protocol adapters we disable the path and
* clear path config space one by one (from 8 to
* Max Input HopID of the adapter).
*/
if (tb_port_is_null(port) && !tb_is_upstream_port(port)) {
ret = tb_port_reset(port);
if (ret)
return ret;
} else if (tb_port_is_usb3_down(port) ||
tb_port_is_usb3_up(port)) {
tb_usb3_port_enable(port, false);
} else if (tb_port_is_dpin(port) ||
tb_port_is_dpout(port)) {
tb_dp_port_enable(port, false);
} else if (tb_port_is_pcie_down(port) ||
tb_port_is_pcie_up(port)) {
tb_pci_port_enable(port, false);
} else {
continue;
}
/* Cleanup path config space of protocol adapter */
for (i = TB_PATH_MIN_HOPID;
i <= port->config.max_in_hop_id; i++) {
ret = tb_path_deactivate_hop(port, i);
if (ret)
return ret;
}
}
} else {
struct tb_cfg_result res;
/* Thunderbolt 1 uses the "reset" config space packet */
res.err = tb_sw_write(sw, ((u32 *) &sw->config) + 2, res.err = tb_sw_write(sw, ((u32 *) &sw->config) + 2,
TB_CFG_SWITCH, 2, 2); TB_CFG_SWITCH, 2, 2);
if (res.err) if (res.err)
...@@ -1556,7 +1593,72 @@ int tb_switch_reset(struct tb_switch *sw) ...@@ -1556,7 +1593,72 @@ int tb_switch_reset(struct tb_switch *sw)
res = tb_cfg_reset(sw->tb->ctl, tb_route(sw)); res = tb_cfg_reset(sw->tb->ctl, tb_route(sw));
if (res.err > 0) if (res.err > 0)
return -EIO; return -EIO;
else if (res.err < 0)
return res.err; return res.err;
}
return 0;
}
static int tb_switch_reset_device(struct tb_switch *sw)
{
return tb_port_reset(tb_switch_downstream_port(sw));
}
static bool tb_switch_enumerated(struct tb_switch *sw)
{
u32 val;
int ret;
/*
* Read directly from the hardware because we use this also
* during system sleep where sw->config.enabled is already set
* by us.
*/
ret = tb_sw_read(sw, &val, TB_CFG_SWITCH, ROUTER_CS_3, 1);
if (ret)
return false;
return !!(val & ROUTER_CS_3_V);
}
/**
* tb_switch_reset() - Perform reset to the router
* @sw: Router to reset
*
* Issues reset to the router @sw. Can be used for any router. For host
* routers, resets all the downstream ports and cleans up path config
* spaces accordingly. For device routers issues downstream port reset
* through the parent router, so as side effect there will be unplug
* soon after this is finished.
*
* If the router is not enumerated does nothing.
*
* Returns %0 on success or negative errno in case of failure.
*/
int tb_switch_reset(struct tb_switch *sw)
{
int ret;
/*
* We cannot access the port config spaces unless the router is
* already enumerated. If the router is not enumerated it is
* equal to being reset so we can skip that here.
*/
if (!tb_switch_enumerated(sw))
return 0;
tb_sw_dbg(sw, "resetting\n");
if (tb_route(sw))
ret = tb_switch_reset_device(sw);
else
ret = tb_switch_reset_host(sw);
if (ret)
tb_sw_warn(sw, "failed to reset\n");
return ret;
} }
/** /**
...@@ -2228,7 +2330,7 @@ static const struct dev_pm_ops tb_switch_pm_ops = { ...@@ -2228,7 +2330,7 @@ static const struct dev_pm_ops tb_switch_pm_ops = {
NULL) NULL)
}; };
struct device_type tb_switch_type = { const struct device_type tb_switch_type = {
.name = "thunderbolt_device", .name = "thunderbolt_device",
.release = tb_switch_release, .release = tb_switch_release,
.uevent = tb_switch_uevent, .uevent = tb_switch_uevent,
......
This diff is collapsed.
This diff is collapsed.
...@@ -194,6 +194,8 @@ struct tb_regs_switch_header { ...@@ -194,6 +194,8 @@ struct tb_regs_switch_header {
#define USB4_VERSION_MAJOR_MASK GENMASK(7, 5) #define USB4_VERSION_MAJOR_MASK GENMASK(7, 5)
#define ROUTER_CS_1 0x01 #define ROUTER_CS_1 0x01
#define ROUTER_CS_3 0x03
#define ROUTER_CS_3_V BIT(31)
#define ROUTER_CS_4 0x04 #define ROUTER_CS_4 0x04
/* Used with the router cmuv field */ /* Used with the router cmuv field */
#define ROUTER_CS_4_CMUV_V1 0x10 #define ROUTER_CS_4_CMUV_V1 0x10
...@@ -389,6 +391,7 @@ struct tb_regs_port_header { ...@@ -389,6 +391,7 @@ struct tb_regs_port_header {
#define PORT_CS_18_CSA BIT(22) #define PORT_CS_18_CSA BIT(22)
#define PORT_CS_18_TIP BIT(24) #define PORT_CS_18_TIP BIT(24)
#define PORT_CS_19 0x13 #define PORT_CS_19 0x13
#define PORT_CS_19_DPR BIT(0)
#define PORT_CS_19_PC BIT(3) #define PORT_CS_19_PC BIT(3)
#define PORT_CS_19_PID BIT(4) #define PORT_CS_19_PID BIT(4)
#define PORT_CS_19_WOC BIT(16) #define PORT_CS_19_WOC BIT(16)
...@@ -584,6 +587,9 @@ struct tb_regs_hop { ...@@ -584,6 +587,9 @@ struct tb_regs_hop {
#define TB_LC_POWER 0x740 #define TB_LC_POWER 0x740
/* Link controller registers */ /* Link controller registers */
#define TB_LC_PORT_MODE 0x26
#define TB_LC_PORT_MODE_DPR BIT(0)
#define TB_LC_CS_42 0x2a #define TB_LC_CS_42 0x2a
#define TB_LC_CS_42_USB_PLUGGED BIT(31) #define TB_LC_CS_42_USB_PLUGGED BIT(31)
......
This diff is collapsed.
This diff is collapsed.
...@@ -139,6 +139,12 @@ static inline bool tb_tunnel_is_usb3(const struct tb_tunnel *tunnel) ...@@ -139,6 +139,12 @@ static inline bool tb_tunnel_is_usb3(const struct tb_tunnel *tunnel)
return tunnel->type == TB_TUNNEL_USB3; return tunnel->type == TB_TUNNEL_USB3;
} }
static inline bool tb_tunnel_direction_downstream(const struct tb_tunnel *tunnel)
{
return tb_port_path_direction_downstream(tunnel->src_port,
tunnel->dst_port);
}
const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel); const char *tb_tunnel_type_name(const struct tb_tunnel *tunnel);
#define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \ #define __TB_TUNNEL_PRINT(level, tunnel, fmt, arg...) \
......
This diff is collapsed.
...@@ -243,7 +243,7 @@ static void usb4_port_device_release(struct device *dev) ...@@ -243,7 +243,7 @@ static void usb4_port_device_release(struct device *dev)
kfree(usb4); kfree(usb4);
} }
struct device_type usb4_port_device_type = { const struct device_type usb4_port_device_type = {
.name = "usb4_port", .name = "usb4_port",
.groups = usb4_port_device_groups, .groups = usb4_port_device_groups,
.release = usb4_port_device_release, .release = usb4_port_device_release,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment