Commit aac96626 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB/Thunderbolt/PHY driver updates from Greg KH:
 "Here is the big USB and Thunderbolt and PHY driver updates for
  5.6-rc1.

  With the advent of USB4, "Thunderbolt" has really become USB4, so the
  renaming of the Kconfig option and starting to share subsystem code
  has begun, hence both subsystems coming in through the same tree here.

  PHY driver updates also touched USB drivers, so that is coming in
  through here as well.

  Major stuff included in here are:
   - USB 4 initial support added (i.e. Thunderbolt)
   - musb driver updates
   - USB gadget driver updates
   - PHY driver updates
   - USB PHY driver updates
   - lots of USB serial stuff fixed up
   - USB typec updates
   - USB-IP fixes
   - lots of other smaller USB driver updates

  All of these have been in linux-next for a while now (the usb-serial
  tree is already tested in linux-next on its own before merged into
  here), with no reported issues"

[ Removed an incorrect compile test enablement for PHY_EXYNOS5250_SATA
  that causes configuration warnings    - Linus ]

* tag 'usb-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (207 commits)
  Doc: ABI: add usb charger uevent
  usb: phy: show USB charger type for user
  usb: cdns3: fix spelling mistake and rework grammar in text
  usb: phy: phy-gpio-vbus-usb: Convert to GPIO descriptors
  USB: serial: cyberjack: fix spelling mistake "To" -> "Too"
  USB: serial: ir-usb: simplify endpoint check
  USB: serial: ir-usb: make set_termios synchronous
  USB: serial: ir-usb: fix IrLAP framing
  USB: serial: ir-usb: fix link-speed handling
  USB: serial: ir-usb: add missing endpoint sanity check
  usb: typec: fusb302: fix "op-sink-microwatt" default that was in mW
  usb: typec: wcove: fix "op-sink-microwatt" default that was in mW
  usb: dwc3: pci: add ID for the Intel Comet Lake -V variant
  usb: typec: tcpci: mask event interrupts when remove driver
  usb: host: xhci-tegra: set MODULE_FIRMWARE for tegra186
  usb: chipidea: add inline for ci_hdrc_host_driver_init if host is not defined
  usb: chipidea: handle single role for usb role class
  usb: musb: fix spelling mistake: "periperal" -> "peripheral"
  phy: ti: j721e-wiz: Fix build error without CONFIG_OF_ADDRESS
  USB: usbfs: Always unlink URBs in reverse order
  ...
parents 6ba3d706 eaa51998
......@@ -16,6 +16,10 @@ Description:
write UDC's name found in /sys/class/udc/*
to bind a gadget, empty string "" to unbind.
max_speed - maximum speed the driver supports. Valid
names are super-speed-plus, super-speed,
high-speed, full-speed, and low-speed.
bDeviceClass - USB device class code
bDeviceSubClass - USB device subclass code
bDeviceProtocol - USB device protocol code
......
What: Raise a uevent when a USB charger is inserted or removed
Date: 2020-01-14
KernelVersion: 5.6
Contact: linux-usb@vger.kernel.org
Description: There are two USB charger states:
USB_CHARGER_ABSENT
USB_CHARGER_PRESENT
There are five USB charger types:
USB_CHARGER_UNKNOWN_TYPE: Charger type is unknown
USB_CHARGER_SDP_TYPE: Standard Downstream Port
USB_CHARGER_CDP_TYPE: Charging Downstream Port
USB_CHARGER_DCP_TYPE: Dedicated Charging Port
USB_CHARGER_ACA_TYPE: Accessory Charging Adapter
https://www.usb.org/document-library/battery-charging-v12-spec-and-adopters-agreement
Here are two examples taken using udevadm monitor -p when
USB charger is online:
UDEV change /devices/soc0/usbphynop1 (platform)
ACTION=change
DEVPATH=/devices/soc0/usbphynop1
DRIVER=usb_phy_generic
MODALIAS=of:Nusbphynop1T(null)Cusb-nop-xceiv
OF_COMPATIBLE_0=usb-nop-xceiv
OF_COMPATIBLE_N=1
OF_FULLNAME=/usbphynop1
OF_NAME=usbphynop1
SEQNUM=2493
SUBSYSTEM=platform
USB_CHARGER_STATE=USB_CHARGER_PRESENT
USB_CHARGER_TYPE=USB_CHARGER_SDP_TYPE
USEC_INITIALIZED=227422826
USB charger is offline:
KERNEL change /devices/soc0/usbphynop1 (platform)
ACTION=change
DEVPATH=/devices/soc0/usbphynop1
DRIVER=usb_phy_generic
MODALIAS=of:Nusbphynop1T(null)Cusb-nop-xceiv
OF_COMPATIBLE_0=usb-nop-xceiv
OF_COMPATIBLE_N=1
OF_FULLNAME=/usbphynop1
OF_NAME=usbphynop1
SEQNUM=2494
SUBSYSTEM=platform
USB_CHARGER_STATE=USB_CHARGER_ABSENT
USB_CHARGER_TYPE=USB_CHARGER_UNKNOWN_TYPE
=============
Thunderbolt
=============
.. SPDX-License-Identifier: GPL-2.0
======================
USB4 and Thunderbolt
======================
USB4 is the public specification based on Thunderbolt 3 protocol with
some differences at the register level among other things. Connection
manager is an entity running on the host router (host controller)
responsible for enumerating routers and establishing tunnels. A
connection manager can be implemented either in firmware or software.
Typically PCs come with a firmware connection manager for Thunderbolt 3
and early USB4 capable systems. Apple systems on the other hand use
software connection manager and the later USB4 compliant devices follow
the suit.
The Linux Thunderbolt driver supports both and can detect at runtime which
connection manager implementation is to be used. To be on the safe side the
software connection manager in Linux also advertises security level
``user`` which means PCIe tunneling is disabled by default. The
documentation below applies to both implementations with the exception that
the software connection manager only supports ``user`` security level and
is expected to be accompanied with an IOMMU based DMA protection.
Security levels and how to use them
-----------------------------------
The interface presented here is not meant for end users. Instead there
should be a userspace tool that handles all the low-level details, keeps
a database of the authorized devices and prompts users for new connections.
......@@ -18,8 +40,6 @@ This will authorize all devices automatically when they appear. However,
keep in mind that this bypasses the security levels and makes the system
vulnerable to DMA attacks.
Security levels and how to use them
-----------------------------------
Starting with Intel Falcon Ridge Thunderbolt controller there are 4
security levels available. Intel Titan Ridge added one more security level
(usbonly). The reason for these is the fact that the connected devices can
......
USB Connector
=============
USB connector node represents physical USB connector. It should be
a child of USB interface controller.
A USB connector node represents a physical USB connector. It should be
a child of a USB interface controller.
Required properties:
- compatible: describes type of the connector, must be one of:
......
# SPDX-License-Identifier: GPL-2.0
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/allwinner,sun9i-a80-usb-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Allwinner A80 USB PHY Device Tree Bindings
maintainers:
- Chen-Yu Tsai <wens@csie.org>
- Maxime Ripard <mripard@kernel.org>
properties:
"#phy-cells":
const: 0
compatible:
const: allwinner,sun9i-a80-usb-phy
reg:
maxItems: 1
clocks:
anyOf:
- description: Main PHY Clock
- items:
- description: Main PHY clock
- description: HSIC 12MHz clock
- description: HSIC 480MHz clock
clock-names:
oneOf:
- const: phy
- items:
- const: phy
- const: hsic_12M
- const: hsic_480M
resets:
anyOf:
- description: Normal USB PHY reset
- items:
- description: Normal USB PHY reset
- description: HSIC Reset
reset-names:
oneOf:
- const: phy
- items:
- const: phy
- const: hsic
phy_type:
const: hsic
description:
When absent, the PHY type will be assumed to be normal USB.
phy-supply:
description:
Regulator that powers VBUS
required:
- "#phy-cells"
- compatible
- reg
- clocks
- clock-names
- resets
- reset-names
additionalProperties: false
if:
properties:
phy_type:
const: hsic
required:
- phy_type
then:
properties:
clocks:
maxItems: 3
clock-names:
maxItems: 3
resets:
maxItems: 2
reset-names:
maxItems: 2
examples:
- |
#include <dt-bindings/clock/sun9i-a80-usb.h>
#include <dt-bindings/reset/sun9i-a80-usb.h>
usbphy1: phy@a00800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a00800 0x4>;
clocks = <&usb_clocks CLK_USB0_PHY>;
clock-names = "phy";
resets = <&usb_clocks RST_USB0_PHY>;
reset-names = "phy";
phy-supply = <&reg_usb1_vbus>;
#phy-cells = <0>;
};
- |
#include <dt-bindings/clock/sun9i-a80-usb.h>
#include <dt-bindings/reset/sun9i-a80-usb.h>
usbphy3: phy@a02800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a02800 0x4>;
clocks = <&usb_clocks CLK_USB2_PHY>,
<&usb_clocks CLK_USB_HSIC>,
<&usb_clocks CLK_USB2_HSIC>;
clock-names = "phy",
"hsic_12M",
"hsic_480M";
resets = <&usb_clocks RST_USB2_PHY>,
<&usb_clocks RST_USB2_HSIC>;
reset-names = "phy",
"hsic";
phy_type = "hsic";
phy-supply = <&reg_usb3_vbus>;
#phy-cells = <0>;
};
Broadcom STB USB PHY
Required properties:
- compatible: brcm,brcmstb-usb-phy
- reg: two offset and length pairs.
The first pair specifies a manditory set of memory mapped
registers used for general control of the PHY.
The second pair specifies optional registers used by some of
the SoCs that support USB 3.x
- #phy-cells: Shall be 1 as it expects one argument for setting
the type of the PHY. Possible values are:
- PHY_TYPE_USB2 for USB1.1/2.0 PHY
- PHY_TYPE_USB3 for USB3.x PHY
- compatible: should be one of
"brcm,brcmstb-usb-phy"
"brcm,bcm7216-usb-phy"
"brcm,bcm7211-usb-phy"
- reg and reg-names properties requirements are specific to the
compatible string.
"brcm,brcmstb-usb-phy":
- reg: 1 or 2 offset and length pairs. One for the base CTRL registers
and an optional pair for systems with USB 3.x support
- reg-names: not specified
"brcm,bcm7216-usb-phy":
- reg: 3 offset and length pairs for CTRL, XHCI_EC and XHCI_GBL
registers
- reg-names: "ctrl", "xhci_ec", "xhci_gbl"
"brcm,bcm7211-usb-phy":
- reg: 5 offset and length pairs for CTRL, XHCI_EC, XHCI_GBL,
USB_PHY and USB_MDIO registers and an optional pair
for the BDC registers
- reg-names: "ctrl", "xhci_ec", "xhci_gbl", "usb_phy", "usb_mdio", "bdc_ec"
- #phy-cells: Shall be 1 as it expects one argument for setting
the type of the PHY. Possible values are:
- PHY_TYPE_USB2 for USB1.1/2.0 PHY
- PHY_TYPE_USB3 for USB3.x PHY
Optional Properties:
- clocks : clock phandles.
- clock-names: String, clock name.
- interrupts: wakeup interrupt
- interrupt-names: "wakeup"
- brcm,ipp: Boolean, Invert Port Power.
Possible values are: 0 (Don't invert), 1 (Invert)
- brcm,ioc: Boolean, Invert Over Current detection.
Possible values are: 0 (Don't invert), 1 (Invert)
NOTE: one or both of the following two properties must be set
- brcm,has-xhci: Boolean indicating the phy has an XHCI phy.
- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy.
- dr_mode: String, PHY Device mode.
Possible values are: "host", "peripheral ", "drd" or "typec-pd"
If this property is not defined, the phy will default to "host" mode.
- brcm,syscon-piarbctl: phandle to syscon for handling config registers
NOTE: one or both of the following two properties must be set
- brcm,has-xhci: Boolean indicating the phy has an XHCI phy.
- brcm,has-eohci: Boolean indicating the phy has an EHCI/OHCI phy.
Example:
......@@ -41,3 +60,27 @@ usbphy_0: usb-phy@f0470200 {
clocks = <&usb20>, <&usb30>;
clock-names = "sw_usb", "sw_usb3";
};
usb-phy@29f0200 {
reg = <0x29f0200 0x200>,
<0x29c0880 0x30>,
<0x29cc100 0x534>,
<0x2808000 0x24>,
<0x2980080 0x8>;
reg-names = "ctrl",
"xhci_ec",
"xhci_gbl",
"usb_phy",
"usb_mdio";
brcm,ioc = <0x0>;
brcm,ipp = <0x0>;
compatible = "brcm,bcm7211-usb-phy";
interrupts = <0x30>;
interrupt-parent = <&vpu_intr1_nosec_intc>;
interrupt-names = "wake";
#phy-cells = <0x1>;
brcm,has-xhci;
syscon-piarbctl = <&syscon_piarbctl>;
clocks = <&scmi_clk 256>;
clock-names = "sw_usb";
};
......@@ -2,6 +2,7 @@
Required properties:
- compatible: should be one or more of
"brcm,bcm7216-sata-phy"
"brcm,bcm7425-sata-phy"
"brcm,bcm7445-sata-phy"
"brcm,iproc-ns2-sata-phy"
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/phy/intel,lgm-emmc-phy.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Intel Lightning Mountain(LGM) eMMC PHY Device Tree Bindings
maintainers:
- Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>
description: |+
Bindings for eMMC PHY on Intel's Lightning Mountain SoC, syscon
node is used to reference the base address of eMMC phy registers.
The eMMC PHY node should be the child of a syscon node with the
required property:
- compatible: Should be one of the following:
"intel,lgm-syscon", "syscon"
- reg:
maxItems: 1
properties:
compatible:
const: intel,lgm-emmc-phy
"#phy-cells":
const: 0
reg:
maxItems: 1
clocks:
maxItems: 1
required:
- "#phy-cells"
- compatible
- reg
- clocks
examples:
- |
sysconf: chiptop@e0200000 {
compatible = "intel,lgm-syscon", "syscon";
reg = <0xe0200000 0x100>;
emmc-phy: emmc-phy@a8 {
compatible = "intel,lgm-emmc-phy";
reg = <0x00a8 0x10>;
clocks = <&emmc>;
#phy-cells = <0>;
};
};
...
......@@ -2,21 +2,24 @@ Cadence Sierra PHY
-----------------------
Required properties:
- compatible: cdns,sierra-phy-t0
- clocks: Must contain an entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must be "phy_clk"
- compatible: Must be "cdns,sierra-phy-t0" for Sierra in Cadence platform
Must be "ti,sierra-phy-t0" for Sierra in TI's J721E SoC.
- resets: Must contain an entry for each in reset-names.
See ../reset/reset.txt for details.
- reset-names: Must include "sierra_reset" and "sierra_apb".
"sierra_reset" must control the reset line to the PHY.
"sierra_apb" must control the reset line to the APB PHY
interface.
interface ("sierra_apb" is optional).
- reg: register range for the PHY.
- #address-cells: Must be 1
- #size-cells: Must be 0
Optional properties:
- clocks: Must contain an entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must contain "cmn_refclk_dig_div" and
"cmn_refclk1_dig_div" for configuring the frequency of
the clock to the lanes. "phy_clk" is deprecated.
- cdns,autoconf: A boolean property whose presence indicates that the
PHY registers will be configured by hardware. If not
present, all sub-node optional properties must be
......
......@@ -13,9 +13,6 @@ properties:
"#phy-cells":
const: 0
"#clock-cells":
const: 0
compatible:
enum:
- rockchip,px30-dsi-dphy
......@@ -49,7 +46,6 @@ properties:
required:
- "#phy-cells"
- "#clock-cells"
- compatible
- reg
- clocks
......@@ -66,7 +62,6 @@ examples:
reg = <0x0 0xff2e0000 0x0 0x10000>;
clocks = <&pmucru 13>, <&cru 12>;
clock-names = "ref", "pclk";
#clock-cells = <0>;
resets = <&cru 12>;
reset-names = "apb";
#phy-cells = <0>;
......
Allwinner sun9i USB PHY
-----------------------
Required properties:
- compatible : should be one of
* allwinner,sun9i-a80-usb-phy
- reg : a list of offset + length pairs
- #phy-cells : from the generic phy bindings, must be 0
- phy_type : "hsic" for HSIC usage;
other values or absence of this property indicates normal USB
- clocks : phandle + clock specifier for the phy clocks
- clock-names : depending on the "phy_type" property,
* "phy" for normal USB
* "hsic_480M", "hsic_12M" for HSIC
- resets : a list of phandle + reset specifier pairs
- reset-names : depending on the "phy_type" property,
* "phy" for normal USB
* "hsic" for HSIC
Optional Properties:
- phy-supply : from the generic phy bindings, a phandle to a regulator that
provides power to VBUS.
It is recommended to list all clocks and resets available.
The driver will only use those matching the phy_type.
Example:
usbphy1: phy@a01800 {
compatible = "allwinner,sun9i-a80-usb-phy";
reg = <0x00a01800 0x4>;
clocks = <&usb_phy_clk 2>, <&usb_phy_clk 10>,
<&usb_phy_clk 3>;
clock-names = "hsic_480M", "hsic_12M", "phy";
resets = <&usb_phy_clk 18>, <&usb_phy_clk 19>;
reset-names = "hsic", "phy";
#phy-cells = <0>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
%YAML 1.2
---
$id: "http://devicetree.org/schemas/phy/ti,phy-j721e-wiz.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: TI J721E WIZ (SERDES Wrapper)
maintainers:
- Kishon Vijay Abraham I <kishon@ti.com>
properties:
compatible:
enum:
- ti,j721e-wiz-16g
- ti,j721e-wiz-10g
power-domains:
maxItems: 1
clocks:
maxItems: 3
description: clock-specifier to represent input to the WIZ
clock-names:
items:
- const: fck
- const: core_ref_clk
- const: ext_ref_clk
num-lanes:
minimum: 1
maximum: 4
"#address-cells":
const: 1
"#size-cells":
const: 1
"#reset-cells":
const: 1
ranges: true
assigned-clocks:
maxItems: 2
assigned-clock-parents:
maxItems: 2
typec-dir-gpios:
maxItems: 1
description:
GPIO to signal Type-C cable orientation for lane swap.
If GPIO is active, lane 0 and lane 1 of SERDES will be swapped to
achieve the funtionality of an external type-C plug flip mux.
typec-dir-debounce-ms:
minimum: 100
maximum: 1000
default: 100
description:
Number of milliseconds to wait before sampling typec-dir-gpio.
If not specified, the default debounce of 100ms will be used.
Type-C spec states minimum CC pin debounce of 100 ms and maximum
of 200 ms. However, some solutions might need more than 200 ms.
patternProperties:
"^pll[0|1]-refclk$":
type: object
description: |
WIZ node should have subnodes for each of the PLLs present in
the SERDES.
properties:
clocks:
maxItems: 2
description: Phandle to clock nodes representing the two inputs to PLL.
"#clock-cells":
const: 0
assigned-clocks:
maxItems: 1
assigned-clock-parents:
maxItems: 1
required:
- clocks
- "#clock-cells"
- assigned-clocks
- assigned-clock-parents
"^cmn-refclk1?-dig-div$":
type: object
description:
WIZ node should have subnodes for each of the PMA common refclock
provided by the SERDES.
properties:
clocks:
maxItems: 1
description: Phandle to the clock node representing the input to the
divider clock.
"#clock-cells":
const: 0
required:
- clocks
- "#clock-cells"
"^refclk-dig$":
type: object
description: |
WIZ node should have subnode for refclk_dig to select the reference
clock source for the reference clock used in the PHY and PMA digital
logic.
properties:
clocks:
maxItems: 4
description: Phandle to four clock nodes representing the inputs to
refclk_dig
"#clock-cells":
const: 0
assigned-clocks:
maxItems: 1
assigned-clock-parents:
maxItems: 1
required:
- clocks
- "#clock-cells"
- assigned-clocks
- assigned-clock-parents
"^serdes@[0-9a-f]+$":
type: object
description: |
WIZ node should have '1' subnode for the SERDES. It could be either
Sierra SERDES or Torrent SERDES. Sierra SERDES should follow the
bindings specified in
Documentation/devicetree/bindings/phy/phy-cadence-sierra.txt
Torrent SERDES should follow the bindings specified in
Documentation/devicetree/bindings/phy/phy-cadence-dp.txt
required:
- compatible
- power-domains
- clocks
- clock-names
- num-lanes
- "#address-cells"
- "#size-cells"
- "#reset-cells"
- ranges
examples:
- |
#include <dt-bindings/soc/ti,sci_pm_domain.h>
wiz@5000000 {
compatible = "ti,j721e-wiz-16g";
#address-cells = <1>;
#size-cells = <1>;
power-domains = <&k3_pds 292 TI_SCI_PD_EXCLUSIVE>;
clocks = <&k3_clks 292 5>, <&k3_clks 292 11>, <&dummy_cmn_refclk>;
clock-names = "fck", "core_ref_clk", "ext_ref_clk";
assigned-clocks = <&k3_clks 292 11>, <&k3_clks 292 0>;
assigned-clock-parents = <&k3_clks 292 15>, <&k3_clks 292 4>;
num-lanes = <2>;
#reset-cells = <1>;
ranges = <0x5000000 0x5000000 0x10000>;
pll0-refclk {
clocks = <&k3_clks 293 13>, <&dummy_cmn_refclk>;
#clock-cells = <0>;
assigned-clocks = <&wiz1_pll0_refclk>;
assigned-clock-parents = <&k3_clks 293 13>;
};
pll1-refclk {
clocks = <&k3_clks 293 0>, <&dummy_cmn_refclk1>;
#clock-cells = <0>;
assigned-clocks = <&wiz1_pll1_refclk>;
assigned-clock-parents = <&k3_clks 293 0>;
};
cmn-refclk-dig-div {
clocks = <&wiz1_refclk_dig>;
#clock-cells = <0>;
};
cmn-refclk1-dig-div {
clocks = <&wiz1_pll1_refclk>;
#clock-cells = <0>;
};
refclk-dig {
clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>;
#clock-cells = <0>;
assigned-clocks = <&wiz0_refclk_dig>;
assigned-clock-parents = <&k3_clks 292 11>;
};
serdes@5000000 {
compatible = "cdns,ti,sierra-phy-t0";
reg-names = "serdes";
reg = <0x5000000 0x10000>;
#address-cells = <1>;
#size-cells = <0>;
resets = <&serdes_wiz0 0>;
reset-names = "sierra_reset";
clocks = <&wiz0_cmn_refclk_dig_div>, <&wiz0_cmn_refclk1_dig_div>;
clock-names = "cmn_refclk_dig_div", "cmn_refclk1_dig_div";
};
};
......@@ -15,6 +15,10 @@ Required properties:
"qcom,ci-hdrc"
"chipidea,usb2"
"xlnx,zynq-usb-2.20a"
"nvidia,tegra20-udc"
"nvidia,tegra30-udc"
"nvidia,tegra114-udc"
"nvidia,tegra124-udc"
- reg: base address and length of the registers
- interrupts: interrupt for the USB controller
......
MediaTek musb DRD/OTG controller
-------------------------------------------
Required properties:
- compatible : should be one of:
"mediatek,mt2701-musb"
...
followed by "mediatek,mtk-musb"
- reg : specifies physical base address and size of
the registers
- interrupts : interrupt used by musb controller
- interrupt-names : must be "mc"
- phys : PHY specifier for the OTG phy
- dr_mode : should be one of "host", "peripheral" or "otg",
refer to usb/generic.txt
- clocks : a list of phandle + clock-specifier pairs, one for
each entry in clock-names
- clock-names : must contain "main", "mcu", "univpll"
for clocks of controller
Optional properties:
- power-domains : a phandle to USB power domain node to control USB's
MTCMOS
Required child nodes:
usb connector node as defined in bindings/connector/usb-connector.txt
Optional properties:
- id-gpios : input GPIO for USB ID pin.
- vbus-gpios : input GPIO for USB VBUS pin.
- vbus-supply : reference to the VBUS regulator, needed when supports
dual-role mode
- usb-role-switch : use USB Role Switch to support dual-role switch, see
usb/generic.txt.
Example:
usb2: usb@11200000 {
compatible = "mediatek,mt2701-musb",
"mediatek,mtk-musb";
reg = <0 0x11200000 0 0x1000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "mc";
phys = <&u2port2 PHY_TYPE_USB2>;
dr_mode = "otg";
clocks = <&pericfg CLK_PERI_USB0>,
<&pericfg CLK_PERI_USB0_MCU>,
<&pericfg CLK_PERI_USB_SLV>;
clock-names = "main","mcu","univpll";
power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
usb-role-switch;
connector{
compatible = "gpio-usb-b-connector", "usb-b-connector";
type = "micro";
id-gpios = <&pio 44 GPIO_ACTIVE_HIGH>;
vbus-supply = <&usb_vbus>;
};
};
......@@ -16474,6 +16474,7 @@ M: Andreas Noever <andreas.noever@gmail.com>
M: Michael Jamet <michael.jamet@intel.com>
M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Yehezkel Bernat <YehezkelShB@gmail.com>
L: linux-usb@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git
S: Maintained
F: Documentation/admin-guide/thunderbolt.rst
......
......@@ -143,7 +143,7 @@ usbhub: hub@8 {
compatible = "smsc,usb3503a";
reg = <0x8>;
connect-gpios = <&gpioext2 1 GPIO_ACTIVE_HIGH>;
intn-gpios = <&gpioext2 0 GPIO_ACTIVE_LOW>;
intn-gpios = <&gpioext2 0 GPIO_ACTIVE_HIGH>;
initial-mode = <1>;
};
};
......
......@@ -823,6 +823,17 @@ static int davinci_phy_fixup(struct phy_device *phydev)
#define HAS_NAND IS_ENABLED(CONFIG_MTD_NAND_DAVINCI)
#define GPIO_nVBUS_DRV 160
static struct gpiod_lookup_table dm644evm_usb_gpio_table = {
.dev_id = "musb-davinci",
.table = {
GPIO_LOOKUP("davinci_gpio", GPIO_nVBUS_DRV, NULL,
GPIO_ACTIVE_HIGH),
{ }
},
};
static __init void davinci_evm_init(void)
{
int ret;
......@@ -875,6 +886,7 @@ static __init void davinci_evm_init(void)
dm644x_init_asp();
/* irlml6401 switches over 1A, in under 8 msec */
gpiod_add_lookup_table(&dm644evm_usb_gpio_table);
davinci_setup_usb(1000, 8);
if (IS_BUILTIN(CONFIG_PHYLIB)) {
......
......@@ -11,9 +11,9 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <linux/sizes.h>
......@@ -144,17 +144,18 @@ static inline void __init colibri_pxa320_init_eth(void) {}
#endif /* CONFIG_AX88796 */
#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = {
.gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96),
.gpio_pullup = -1,
static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", MFP_PIN_GPIO96,
"vbus", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device colibri_pxa320_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &colibri_pxa320_gpio_vbus_info,
},
};
static void colibri_pxa320_udc_command(int cmd)
......@@ -173,6 +174,7 @@ static struct pxa2xx_udc_mach_info colibri_pxa320_udc_info __initdata = {
static void __init colibri_pxa320_init_udc(void)
{
pxa_set_udc_info(&colibri_pxa320_udc_info);
gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
platform_device_register(&colibri_pxa320_gpio_vbus);
}
#else
......
......@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk-provider.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
......@@ -22,7 +23,6 @@
#include <linux/mfd/t7l66xb.h>
#include <linux/mtd/rawnand.h>
#include <linux/mtd/partitions.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/memblock.h>
#include <video/w100fb.h>
......@@ -51,18 +51,20 @@ void __init eseries_fixup(struct tag *tags, char **cmdline)
memblock_add(0xa0000000, SZ_64M);
}
struct gpio_vbus_mach_info e7xx_udc_info = {
.gpio_vbus = GPIO_E7XX_USB_DISC,
.gpio_pullup = GPIO_E7XX_USB_PULLUP,
.gpio_pullup_inverted = 1
static struct gpiod_lookup_table e7xx_gpio_vbus_gpiod_table __maybe_unused = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO_E7XX_USB_DISC,
"vbus", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", GPIO_E7XX_USB_PULLUP,
"pullup", GPIO_ACTIVE_LOW),
{ },
},
};
static struct platform_device e7xx_gpio_vbus __maybe_unused = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &e7xx_udc_info,
},
};
struct pxaficp_platform_data e7xx_ficp_platform_data = {
......@@ -165,6 +167,7 @@ static void __init e330_init(void)
pxa_set_stuart_info(NULL);
eseries_register_clks();
eseries_get_tmio_gpios();
gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e330_devices));
}
......@@ -216,6 +219,7 @@ static void __init e350_init(void)
pxa_set_stuart_info(NULL);
eseries_register_clks();
eseries_get_tmio_gpios();
gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e350_devices));
}
......@@ -340,6 +344,7 @@ static void __init e400_init(void)
eseries_register_clks();
eseries_get_tmio_gpios();
pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e400_devices));
}
......@@ -534,6 +539,7 @@ static void __init e740_init(void)
clk_add_alias("CLK_CK48M", e740_t7l66xb_device.name,
"UDCCLK", &pxa25x_device_udc.dev),
eseries_get_tmio_gpios();
gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e740_devices));
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data);
......@@ -733,6 +739,7 @@ static void __init e750_init(void)
clk_add_alias("CLK_CK3P6MI", e750_tc6393xb_device.name,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
gpiod_add_lookup_table(&e7xx_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e750_devices));
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data);
......@@ -888,18 +895,20 @@ static struct platform_device e800_fb_device = {
/* --------------------------- UDC definitions --------------------------- */
static struct gpio_vbus_mach_info e800_udc_info = {
.gpio_vbus = GPIO_E800_USB_DISC,
.gpio_pullup = GPIO_E800_USB_PULLUP,
.gpio_pullup_inverted = 1
static struct gpiod_lookup_table e800_gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO_E800_USB_DISC,
"vbus", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", GPIO_E800_USB_PULLUP,
"pullup", GPIO_ACTIVE_LOW),
{ },
},
};
static struct platform_device e800_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &e800_udc_info,
},
};
......@@ -949,6 +958,7 @@ static void __init e800_init(void)
clk_add_alias("CLK_CK3P6MI", e800_tc6393xb_device.name,
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
gpiod_add_lookup_table(&e800_gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(e800_devices));
pxa_set_ac97_info(NULL);
}
......
......@@ -20,10 +20,10 @@
#include <linux/delay.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/setup.h>
#include <asm/memory.h>
......@@ -101,21 +101,25 @@ static void __init gumstix_mmc_init(void)
#endif
#ifdef CONFIG_USB_PXA25X
static struct gpio_vbus_mach_info gumstix_udc_info = {
.gpio_vbus = GPIO_GUMSTIX_USB_GPIOn,
.gpio_pullup = GPIO_GUMSTIX_USB_GPIOx,
static struct gpiod_lookup_table gumstix_gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOn,
"vbus", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", GPIO_GUMSTIX_USB_GPIOx,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device gumstix_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &gumstix_udc_info,
},
};
static void __init gumstix_udc_init(void)
{
gpiod_add_lookup_table(&gumstix_gpio_vbus_gpiod_table);
platform_device_register(&gumstix_gpio_vbus);
}
#else
......
......@@ -34,7 +34,6 @@
#include <linux/spi/ads7846.h>
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/platform_data/i2c-pxa.h>
#include <mach/hardware.h>
......@@ -578,18 +577,24 @@ static struct pwm_lookup hx4700_pwm_lookup[] = {
* USB "Transceiver"
*/
static struct gpio_vbus_mach_info gpio_vbus_info = {
.gpio_pullup = GPIO76_HX4700_USBC_PUEN,
.gpio_vbus = GPIOD14_nUSBC_DETECT,
.gpio_vbus_inverted = 1,
static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
/* This GPIO is on ASIC3 */
GPIO_LOOKUP("asic3",
/* Convert to a local offset on the ASIC3 */
GPIOD14_nUSBC_DETECT - HX4700_ASIC3_GPIO_BASE,
"vbus", GPIO_ACTIVE_LOW),
/* This one is on the primary SOC GPIO */
GPIO_LOOKUP("gpio-pxa", GPIO76_HX4700_USBC_PUEN,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &gpio_vbus_info,
},
};
static struct pxa2xx_udc_mach_info hx4700_udc_info;
......@@ -883,6 +888,7 @@ static void __init hx4700_init(void)
pxa_set_stuart_info(NULL);
gpiod_add_lookup_table(&bq24022_gpiod_table);
gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
platform_add_devices(devices, ARRAY_SIZE(devices));
pwm_add_table(hx4700_pwm_lookup, ARRAY_SIZE(hx4700_pwm_lookup));
......
......@@ -27,7 +27,6 @@
#include <linux/regulator/fixed.h>
#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/platform_data/i2c-pxa.h>
#include <mach/hardware.h>
......@@ -506,9 +505,20 @@ static struct resource gpio_vbus_resource = {
.end = IRQ_MAGICIAN_VBUS,
};
static struct gpio_vbus_mach_info gpio_vbus_info = {
.gpio_pullup = GPIO27_MAGICIAN_USBC_PUEN,
.gpio_vbus = EGPIO_MAGICIAN_CABLE_VBUS,
static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
/*
* EGPIO on register 4 index 1, the second EGPIO chip
* starts at register 4 so this will be at index 1 on that
* chip.
*/
GPIO_LOOKUP("htc-egpio-1", 1,
"vbus", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", GPIO27_MAGICIAN_USBC_PUEN,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device gpio_vbus = {
......@@ -516,9 +526,6 @@ static struct platform_device gpio_vbus = {
.id = -1,
.num_resources = 1,
.resource = &gpio_vbus_resource,
.dev = {
.platform_data = &gpio_vbus_info,
},
};
/*
......@@ -1032,6 +1039,7 @@ static void __init magician_init(void)
ARRAY_SIZE(pwm_backlight_supply), 5000000);
gpiod_add_lookup_table(&bq24022_gpiod_table);
gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
platform_add_devices(ARRAY_AND_SIZE(devices));
}
......
......@@ -24,7 +24,6 @@
#include <linux/power_supply.h>
#include <linux/wm97xx.h>
#include <linux/mtd/physmap.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/reboot.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/max1586.h>
......@@ -368,10 +367,13 @@ static struct pxa2xx_udc_mach_info mioa701_udc_info = {
.gpio_pullup = GPIO22_USB_ENABLE,
};
struct gpio_vbus_mach_info gpio_vbus_data = {
.gpio_vbus = GPIO13_nUSB_DETECT,
.gpio_vbus_inverted = 1,
.gpio_pullup = -1,
static struct gpiod_lookup_table gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO13_nUSB_DETECT,
"vbus", GPIO_ACTIVE_LOW),
{ },
},
};
/*
......@@ -677,7 +679,7 @@ MIO_SIMPLE_DEV(mioa701_led, "leds-gpio", &gpio_led_info)
MIO_SIMPLE_DEV(pxa2xx_pcm, "pxa2xx-pcm", NULL)
MIO_SIMPLE_DEV(mioa701_sound, "mioa701-wm9713", NULL)
MIO_SIMPLE_DEV(mioa701_board, "mioa701-board", NULL)
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", &gpio_vbus_data);
MIO_SIMPLE_DEV(gpio_vbus, "gpio-vbus", NULL);
static struct platform_device *devices[] __initdata = {
&mioa701_gpio_keys,
......@@ -750,6 +752,7 @@ static void __init mioa701_machine_init(void)
pxa_set_ac97_info(&mioa701_ac97_info);
pm_power_off = mioa701_poweroff;
pwm_add_table(mioa701_pwm_lookup, ARRAY_SIZE(mioa701_pwm_lookup));
gpiod_add_lookup_table(&gpio_vbus_gpiod_table);
platform_add_devices(devices, ARRAY_SIZE(devices));
gsm_init();
......
......@@ -13,10 +13,10 @@
#include <linux/pda_power.h>
#include <linux/pwm.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/regulator/max1586.h>
#include <linux/platform_data/i2c-pxa.h>
......@@ -159,32 +159,32 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
******************************************************************************/
#if defined(CONFIG_USB_PXA27X) || \
defined(CONFIG_USB_PXA27X_MODULE)
static struct gpio_vbus_mach_info palm27x_udc_info = {
.gpio_vbus_inverted = 1,
/* The actual GPIO offsets get filled in in the palm27x_udc_init() call */
static struct gpiod_lookup_table palm27x_udc_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", 0,
"vbus", GPIO_ACTIVE_HIGH),
GPIO_LOOKUP("gpio-pxa", 0,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device palm27x_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palm27x_udc_info,
},
};
void __init palm27x_udc_init(int vbus, int pullup, int vbus_inverted)
{
palm27x_udc_info.gpio_vbus = vbus;
palm27x_udc_info.gpio_pullup = pullup;
palm27x_udc_info.gpio_vbus_inverted = vbus_inverted;
if (!gpio_request(pullup, "USB Pullup")) {
gpio_direction_output(pullup,
palm27x_udc_info.gpio_vbus_inverted);
gpio_free(pullup);
} else
return;
palm27x_udc_gpiod_table.table[0].chip_hwnum = vbus;
palm27x_udc_gpiod_table.table[1].chip_hwnum = pullup;
if (vbus_inverted)
palm27x_udc_gpiod_table.table[0].flags = GPIO_ACTIVE_LOW;
gpiod_add_lookup_table(&palm27x_udc_gpiod_table);
platform_device_register(&palm27x_gpio_vbus);
}
#endif
......
......@@ -23,7 +23,6 @@
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......
......@@ -23,7 +23,6 @@
#include <linux/power_supply.h>
#include <linux/gpio_keys.h>
#include <linux/mtd/physmap.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -319,22 +318,25 @@ static inline void palmtc_mkp_init(void) {}
* UDC
******************************************************************************/
#if defined(CONFIG_USB_PXA25X)||defined(CONFIG_USB_PXA25X_MODULE)
static struct gpio_vbus_mach_info palmtc_udc_info = {
.gpio_vbus = GPIO_NR_PALMTC_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTC_USB_POWER,
static struct gpiod_lookup_table palmtc_udc_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_USB_DETECT_N,
"vbus", GPIO_ACTIVE_LOW),
GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTC_USB_POWER,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device palmtc_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmtc_udc_info,
},
};
static void __init palmtc_udc_init(void)
{
gpiod_add_lookup_table(&palmtc_udc_gpiod_table);
platform_device_register(&palmtc_gpio_vbus);
};
#else
......
......@@ -23,7 +23,6 @@
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -201,18 +200,20 @@ static struct pxaficp_platform_data palmte2_ficp_platform_data = {
/******************************************************************************
* UDC
******************************************************************************/
static struct gpio_vbus_mach_info palmte2_udc_info = {
.gpio_vbus = GPIO_NR_PALMTE2_USB_DETECT_N,
.gpio_vbus_inverted = 1,
.gpio_pullup = GPIO_NR_PALMTE2_USB_PULLUP,
static struct gpiod_lookup_table palmte2_udc_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_USB_DETECT_N,
"vbus", GPIO_ACTIVE_LOW),
GPIO_LOOKUP("gpio-pxa", GPIO_NR_PALMTE2_USB_PULLUP,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device palmte2_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &palmte2_udc_info,
},
};
/******************************************************************************
......@@ -368,6 +369,7 @@ static void __init palmte2_init(void)
pxa_set_ficp_info(&palmte2_ficp_platform_data);
pwm_add_table(palmte2_pwm_lookup, ARRAY_SIZE(palmte2_pwm_lookup));
gpiod_add_lookup_table(&palmte2_udc_gpiod_table);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
......
......@@ -23,7 +23,6 @@
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/mtd/platnand.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/physmap.h>
......
......@@ -25,7 +25,6 @@
#include <linux/gpio.h>
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/platform_data/i2c-gpio.h>
#include <linux/gpio/machine.h>
......
......@@ -33,7 +33,6 @@
#include <linux/spi/pxa2xx_spi.h>
#include <linux/input/matrix_keypad.h>
#include <linux/platform_data/i2c-pxa.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/reboot.h>
#include <linux/memblock.h>
......@@ -240,18 +239,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = {
/*
* USB Device Controller
*/
static struct gpio_vbus_mach_info tosa_udc_info = {
.gpio_pullup = TOSA_GPIO_USB_PULLUP,
.gpio_vbus = TOSA_GPIO_USB_IN,
.gpio_vbus_inverted = 1,
static struct gpiod_lookup_table tosa_udc_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_USB_IN,
"vbus", GPIO_ACTIVE_LOW),
GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_USB_PULLUP,
"pullup", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device tosa_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &tosa_udc_info,
},
};
/*
......@@ -949,6 +950,7 @@ static void __init tosa_init(void)
clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
gpiod_add_lookup_table(&tosa_udc_gpiod_table);
platform_add_devices(devices, ARRAY_SIZE(devices));
}
......
......@@ -14,7 +14,6 @@
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
......@@ -352,17 +351,18 @@ static inline void vpac270_uhc_init(void) {}
* USB Gadget
******************************************************************************/
#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE)
static struct gpio_vbus_mach_info vpac270_gpio_vbus_info = {
.gpio_vbus = GPIO41_VPAC270_UDC_DETECT,
.gpio_pullup = -1,
static struct gpiod_lookup_table vpac270_gpio_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("gpio-pxa", GPIO41_VPAC270_UDC_DETECT,
"vbus", GPIO_ACTIVE_HIGH),
{ },
},
};
static struct platform_device vpac270_gpio_vbus = {
.name = "gpio-vbus",
.id = -1,
.dev = {
.platform_data = &vpac270_gpio_vbus_info,
},
};
static void vpac270_udc_command(int cmd)
......@@ -381,6 +381,7 @@ static struct pxa2xx_udc_mach_info vpac270_udc_info __initdata = {
static void __init vpac270_udc_init(void)
{
pxa_set_udc_info(&vpac270_udc_info);
gpiod_add_lookup_table(&vpac270_gpio_vbus_gpiod_table);
platform_device_register(&vpac270_gpio_vbus);
}
#else
......
......@@ -13,7 +13,6 @@
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/spi/spi_gpio.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/platform_data/s3c-hsotg.h>
#include <asm/mach-types.h>
......@@ -124,15 +123,16 @@ static struct s3c2410_hcd_info smartq_usb_host_info = {
.enable_oc = smartq_usb_host_enableoc,
};
static struct gpio_vbus_mach_info smartq_usb_otg_vbus_pdata = {
.gpio_vbus = S3C64XX_GPL(9),
.gpio_pullup = -1,
.gpio_vbus_inverted = true,
static struct gpiod_lookup_table smartq_usb_otg_vbus_gpiod_table = {
.dev_id = "gpio-vbus",
.table = {
GPIO_LOOKUP("GPL", 9, "vbus", GPIO_ACTIVE_LOW),
{ },
},
};
static struct platform_device smartq_usb_otg_vbus_dev = {
.name = "gpio-vbus",
.dev.platform_data = &smartq_usb_otg_vbus_pdata,
};
static struct pwm_lookup smartq_pwm_lookup[] = {
......@@ -418,6 +418,7 @@ void __init smartq_machine_init(void)
pwm_add_table(smartq_pwm_lookup, ARRAY_SIZE(smartq_pwm_lookup));
gpiod_add_lookup_table(&smartq_lcd_control_gpiod_table);
gpiod_add_lookup_table(&smartq_usb_otg_vbus_gpiod_table);
platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices));
gpiod_add_lookup_table(&smartq_audio_gpios);
......
......@@ -171,7 +171,7 @@ obj-$(CONFIG_POWERCAP) += powercap/
obj-$(CONFIG_MCB) += mcb/
obj-$(CONFIG_PERF_EVENTS) += perf/
obj-$(CONFIG_RAS) += ras/
obj-$(CONFIG_THUNDERBOLT) += thunderbolt/
obj-$(CONFIG_USB4) += thunderbolt/
obj-$(CONFIG_CORESIGHT) += hwtracing/coresight/
obj-y += hwtracing/intel_th/
obj-$(CONFIG_STM) += hwtracing/stm/
......
......@@ -532,12 +532,12 @@ config FUJITSU_ES
This driver provides support for Extended Socket network device
on Extended Partitioning of FUJITSU PRIMEQUEST 2000 E2 series.
config THUNDERBOLT_NET
tristate "Networking over Thunderbolt cable"
depends on THUNDERBOLT && INET
config USB4_NET
tristate "Networking over USB4 and Thunderbolt cables"
depends on USB4 && INET
help
Select this if you want to create network between two
computers over a Thunderbolt cable. The driver supports Apple
Select this if you want to create network between two computers
over a USB4 and Thunderbolt cables. The driver supports Apple
ThunderboltIP protocol and allows communication with any host
supporting the same protocol including Windows and macOS.
......
......@@ -77,6 +77,6 @@ obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
obj-$(CONFIG_FUJITSU_ES) += fjes/
thunderbolt-net-y += thunderbolt.o
obj-$(CONFIG_THUNDERBOLT_NET) += thunderbolt-net.o
obj-$(CONFIG_USB4_NET) += thunderbolt-net.o
obj-$(CONFIG_NETDEVSIM) += netdevsim/
obj-$(CONFIG_NET_FAILOVER) += net_failover.o
......@@ -69,5 +69,6 @@ source "drivers/phy/socionext/Kconfig"
source "drivers/phy/st/Kconfig"
source "drivers/phy/tegra/Kconfig"
source "drivers/phy/ti/Kconfig"
source "drivers/phy/intel/Kconfig"
endmenu
......@@ -18,6 +18,7 @@ obj-y += broadcom/ \
cadence/ \
freescale/ \
hisilicon/ \
intel/ \
lantiq/ \
marvell/ \
motorola/ \
......
......@@ -48,7 +48,8 @@ config PHY_SUN9I_USB
config PHY_SUN50I_USB3
tristate "Allwinner H6 SoC USB3 PHY driver"
depends on ARCH_SUNXI && HAS_IOMEM && OF
depends on ARCH_SUNXI || COMPILE_TEST
depends on HAS_IOMEM && OF
depends on RESET_CONTROLLER
select GENERIC_PHY
help
......
......@@ -50,7 +50,7 @@ config PHY_BCM_NS_USB3
config PHY_NS2_PCIE
tristate "Broadcom Northstar2 PCIe PHY driver"
depends on OF && MDIO_BUS_MUX_BCM_IPROC
depends on (OF && MDIO_BUS_MUX_BCM_IPROC) || (COMPILE_TEST && MDIO_BUS)
select GENERIC_PHY
default ARCH_BCM_IPROC
help
......@@ -83,7 +83,7 @@ config PHY_BRCM_SATA
config PHY_BRCM_USB
tristate "Broadcom STB USB PHY driver"
depends on ARCH_BRCMSTB
depends on ARCH_BRCMSTB || COMPILE_TEST
depends on OF
select GENERIC_PHY
select SOC_BRCMSTB
......
......@@ -8,7 +8,7 @@ obj-$(CONFIG_PHY_NS2_USB_DRD) += phy-bcm-ns2-usbdrd.o
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
obj-$(CONFIG_PHY_BRCM_USB) += phy-brcm-usb-dvr.o
phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o
phy-brcm-usb-dvr-objs := phy-brcm-usb.o phy-brcm-usb-init.o phy-brcm-usb-init-synopsys.o
obj-$(CONFIG_PHY_BCM_SR_PCIE) += phy-bcm-sr-pcie.o
obj-$(CONFIG_PHY_BCM_SR_USB) += phy-bcm-sr-usb.o
......@@ -33,6 +33,7 @@
#define SATA_PHY_CTRL_REG_28NM_SPACE_SIZE 0x8
enum brcm_sata_phy_version {
BRCM_SATA_PHY_STB_16NM,
BRCM_SATA_PHY_STB_28NM,
BRCM_SATA_PHY_STB_40NM,
BRCM_SATA_PHY_IPROC_NS2,
......@@ -104,10 +105,13 @@ enum sata_phy_regs {
PLL1_ACTRL5 = 0x85,
PLL1_ACTRL6 = 0x86,
PLL1_ACTRL7 = 0x87,
PLL1_ACTRL8 = 0x88,
TX_REG_BANK = 0x070,
TX_ACTRL0 = 0x80,
TX_ACTRL0_TXPOL_FLIP = BIT(6),
TX_ACTRL5 = 0x85,
TX_ACTRL5_SSC_EN = BIT(11),
AEQRX_REG_BANK_0 = 0xd0,
AEQ_CONTROL1 = 0x81,
......@@ -116,6 +120,7 @@ enum sata_phy_regs {
AEQ_FRC_EQ = 0x83,
AEQ_FRC_EQ_FORCE = BIT(0),
AEQ_FRC_EQ_FORCE_VAL = BIT(1),
AEQ_RFZ_FRC_VAL = BIT(8),
AEQRX_REG_BANK_1 = 0xe0,
AEQRX_SLCAL0_CTRL0 = 0x82,
AEQRX_SLCAL1_CTRL0 = 0x86,
......@@ -152,7 +157,28 @@ enum sata_phy_regs {
TXPMD_TX_FREQ_CTRL_CONTROL3_FMAX_MASK = 0x3ff,
RXPMD_REG_BANK = 0x1c0,
RXPMD_RX_CDR_CONTROL1 = 0x81,
RXPMD_RX_PPM_VAL_MASK = 0x1ff,
RXPMD_RXPMD_EN_FRC = BIT(12),
RXPMD_RXPMD_EN_FRC_VAL = BIT(13),
RXPMD_RX_CDR_CDR_PROP_BW = 0x82,
RXPMD_G_CDR_PROP_BW_MASK = 0x7,
RXPMD_G1_CDR_PROP_BW_SHIFT = 0,
RXPMD_G2_CDR_PROP_BW_SHIFT = 3,
RXPMD_G3_CDR_PROB_BW_SHIFT = 6,
RXPMD_RX_CDR_CDR_ACQ_INTEG_BW = 0x83,
RXPMD_G_CDR_ACQ_INT_BW_MASK = 0x7,
RXPMD_G1_CDR_ACQ_INT_BW_SHIFT = 0,
RXPMD_G2_CDR_ACQ_INT_BW_SHIFT = 3,
RXPMD_G3_CDR_ACQ_INT_BW_SHIFT = 6,
RXPMD_RX_CDR_CDR_LOCK_INTEG_BW = 0x84,
RXPMD_G_CDR_LOCK_INT_BW_MASK = 0x7,
RXPMD_G1_CDR_LOCK_INT_BW_SHIFT = 0,
RXPMD_G2_CDR_LOCK_INT_BW_SHIFT = 3,
RXPMD_G3_CDR_LOCK_INT_BW_SHIFT = 6,
RXPMD_RX_FREQ_MON_CONTROL1 = 0x87,
RXPMD_MON_CORRECT_EN = BIT(8),
RXPMD_MON_MARGIN_VAL_MASK = 0xff,
};
enum sata_phy_ctrl_regs {
......@@ -166,6 +192,7 @@ static inline void __iomem *brcm_sata_pcb_base(struct brcm_sata_port *port)
u32 size = 0;
switch (priv->version) {
case BRCM_SATA_PHY_STB_16NM:
case BRCM_SATA_PHY_STB_28NM:
case BRCM_SATA_PHY_IPROC_NS2:
case BRCM_SATA_PHY_DSL_28NM:
......@@ -287,6 +314,94 @@ static int brcm_stb_sata_init(struct brcm_sata_port *port)
return brcm_stb_sata_rxaeq_init(port);
}
static int brcm_stb_sata_16nm_ssc_init(struct brcm_sata_port *port)
{
void __iomem *base = brcm_sata_pcb_base(port);
u32 tmp, value;
/* Reduce CP tail current to 1/16th of its default value */
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL6, 0, 0x141);
/* Turn off CP tail current boost */
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL8, 0, 0xc006);
/* Set a specific AEQ equalizer value */
tmp = AEQ_FRC_EQ_FORCE_VAL | AEQ_FRC_EQ_FORCE;
brcm_sata_phy_wr(base, AEQRX_REG_BANK_0, AEQ_FRC_EQ,
~(tmp | AEQ_RFZ_FRC_VAL |
AEQ_FRC_EQ_VAL_MASK << AEQ_FRC_EQ_VAL_SHIFT),
tmp | 32 << AEQ_FRC_EQ_VAL_SHIFT);
/* Set RX PPM val center frequency */
if (port->ssc_en)
value = 0x52;
else
value = 0;
brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CONTROL1,
~RXPMD_RX_PPM_VAL_MASK, value);
/* Set proportional loop bandwith Gen1/2/3 */
tmp = RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G1_CDR_PROP_BW_SHIFT |
RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G2_CDR_PROP_BW_SHIFT |
RXPMD_G_CDR_PROP_BW_MASK << RXPMD_G3_CDR_PROB_BW_SHIFT;
if (port->ssc_en)
value = 2 << RXPMD_G1_CDR_PROP_BW_SHIFT |
2 << RXPMD_G2_CDR_PROP_BW_SHIFT |
2 << RXPMD_G3_CDR_PROB_BW_SHIFT;
else
value = 1 << RXPMD_G1_CDR_PROP_BW_SHIFT |
1 << RXPMD_G2_CDR_PROP_BW_SHIFT |
1 << RXPMD_G3_CDR_PROB_BW_SHIFT;
brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_PROP_BW, ~tmp,
value);
/* Set CDR integral loop acquisition bandwidth for Gen1/2/3 */
tmp = RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
RXPMD_G_CDR_ACQ_INT_BW_MASK << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT;
if (port->ssc_en)
value = 1 << RXPMD_G1_CDR_ACQ_INT_BW_SHIFT |
1 << RXPMD_G2_CDR_ACQ_INT_BW_SHIFT |
1 << RXPMD_G3_CDR_ACQ_INT_BW_SHIFT;
else
value = 0;
brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_ACQ_INTEG_BW,
~tmp, value);
/* Set CDR integral loop locking bandwidth to 1 for Gen 1/2/3 */
tmp = RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
RXPMD_G_CDR_LOCK_INT_BW_MASK << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT;
if (port->ssc_en)
value = 1 << RXPMD_G1_CDR_LOCK_INT_BW_SHIFT |
1 << RXPMD_G2_CDR_LOCK_INT_BW_SHIFT |
1 << RXPMD_G3_CDR_LOCK_INT_BW_SHIFT;
else
value = 0;
brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_CDR_CDR_LOCK_INTEG_BW,
~tmp, value);
/* Set no guard band and clamp CDR */
tmp = RXPMD_MON_CORRECT_EN | RXPMD_MON_MARGIN_VAL_MASK;
if (port->ssc_en)
value = 0x51;
else
value = 0;
brcm_sata_phy_wr(base, RXPMD_REG_BANK, RXPMD_RX_FREQ_MON_CONTROL1,
~tmp, RXPMD_MON_CORRECT_EN | value);
/* Turn on/off SSC */
brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL5, ~TX_ACTRL5_SSC_EN,
port->ssc_en ? TX_ACTRL5_SSC_EN : 0);
return 0;
}
static int brcm_stb_sata_16nm_init(struct brcm_sata_port *port)
{
return brcm_stb_sata_16nm_ssc_init(port);
}
/* NS2 SATA PLL1 defaults were characterized by H/W group */
#define NS2_PLL1_ACTRL2_MAGIC 0x1df8
#define NS2_PLL1_ACTRL3_MAGIC 0x2b00
......@@ -544,6 +659,9 @@ static int brcm_sata_phy_init(struct phy *phy)
struct brcm_sata_port *port = phy_get_drvdata(phy);
switch (port->phy_priv->version) {
case BRCM_SATA_PHY_STB_16NM:
rc = brcm_stb_sata_16nm_init(port);
break;
case BRCM_SATA_PHY_STB_28NM:
case BRCM_SATA_PHY_STB_40NM:
rc = brcm_stb_sata_init(port);
......@@ -601,6 +719,8 @@ static const struct phy_ops phy_ops = {
};
static const struct of_device_id brcm_sata_phy_of_match[] = {
{ .compatible = "brcm,bcm7216-sata-phy",
.data = (void *)BRCM_SATA_PHY_STB_16NM },
{ .compatible = "brcm,bcm7445-sata-phy",
.data = (void *)BRCM_SATA_PHY_STB_28NM },
{ .compatible = "brcm,bcm7425-sata-phy",
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,16 +6,50 @@
#ifndef _USB_BRCM_COMMON_INIT_H
#define _USB_BRCM_COMMON_INIT_H
#include <linux/regmap.h>
#define USB_CTLR_MODE_HOST 0
#define USB_CTLR_MODE_DEVICE 1
#define USB_CTLR_MODE_DRD 2
#define USB_CTLR_MODE_TYPEC_PD 3
enum brcmusb_reg_sel {
BRCM_REGS_CTRL = 0,
BRCM_REGS_XHCI_EC,
BRCM_REGS_XHCI_GBL,
BRCM_REGS_USB_PHY,
BRCM_REGS_USB_MDIO,
BRCM_REGS_BDC_EC,
BRCM_REGS_MAX
};
#define USB_CTRL_REG(base, reg) ((void __iomem *)base + USB_CTRL_##reg)
#define USB_XHCI_EC_REG(base, reg) ((void __iomem *)base + USB_XHCI_EC_##reg)
#define USB_CTRL_MASK(reg, field) \
USB_CTRL_##reg##_##field##_MASK
#define USB_CTRL_SET(base, reg, field) \
brcm_usb_ctrl_set(USB_CTRL_REG(base, reg), \
USB_CTRL_##reg##_##field##_MASK)
#define USB_CTRL_UNSET(base, reg, field) \
brcm_usb_ctrl_unset(USB_CTRL_REG(base, reg), \
USB_CTRL_##reg##_##field##_MASK)
struct brcm_usb_init_params;
struct brcm_usb_init_ops {
void (*init_ipp)(struct brcm_usb_init_params *params);
void (*init_common)(struct brcm_usb_init_params *params);
void (*init_eohci)(struct brcm_usb_init_params *params);
void (*init_xhci)(struct brcm_usb_init_params *params);
void (*uninit_common)(struct brcm_usb_init_params *params);
void (*uninit_eohci)(struct brcm_usb_init_params *params);
void (*uninit_xhci)(struct brcm_usb_init_params *params);
int (*get_dual_select)(struct brcm_usb_init_params *params);
void (*set_dual_select)(struct brcm_usb_init_params *params, int mode);
};
struct brcm_usb_init_params {
void __iomem *ctrl_regs;
void __iomem *xhci_ec_regs;
void __iomem *regs[BRCM_REGS_MAX];
int ioc;
int ipp;
int mode;
......@@ -24,19 +58,105 @@ struct brcm_usb_init_params {
int selected_family;
const char *family_name;
const u32 *usb_reg_bits_map;
const struct brcm_usb_init_ops *ops;
struct regmap *syscon_piarbctl;
bool wake_enabled;
bool suspend_with_clocks;
};
void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params);
void brcm_usb_dvr_init_7216(struct brcm_usb_init_params *params);
void brcm_usb_dvr_init_7211b0(struct brcm_usb_init_params *params);
static inline u32 brcm_usb_readl(void __iomem *addr)
{
/*
* MIPS endianness is configured by boot strap, which also reverses all
* bus endianness (i.e., big-endian CPU + big endian bus ==> native
* endian I/O).
*
* Other architectures (e.g., ARM) either do not support big endian, or
* else leave I/O in little endian mode.
*/
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
return __raw_readl(addr);
else
return readl_relaxed(addr);
}
static inline void brcm_usb_writel(u32 val, void __iomem *addr)
{
/* See brcmnand_readl() comments */
if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(__BIG_ENDIAN))
__raw_writel(val, addr);
else
writel_relaxed(val, addr);
}
static inline void brcm_usb_ctrl_unset(void __iomem *reg, u32 mask)
{
brcm_usb_writel(brcm_usb_readl(reg) & ~(mask), reg);
};
void brcm_usb_set_family_map(struct brcm_usb_init_params *params);
int brcm_usb_init_get_dual_select(struct brcm_usb_init_params *params);
void brcm_usb_init_set_dual_select(struct brcm_usb_init_params *params,
int mode);
void brcm_usb_init_ipp(struct brcm_usb_init_params *ini);
void brcm_usb_init_common(struct brcm_usb_init_params *ini);
void brcm_usb_init_eohci(struct brcm_usb_init_params *ini);
void brcm_usb_init_xhci(struct brcm_usb_init_params *ini);
void brcm_usb_uninit_common(struct brcm_usb_init_params *ini);
void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini);
void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini);
static inline void brcm_usb_ctrl_set(void __iomem *reg, u32 mask)
{
brcm_usb_writel(brcm_usb_readl(reg) | (mask), reg);
};
static inline void brcm_usb_init_ipp(struct brcm_usb_init_params *ini)
{
if (ini->ops->init_ipp)
ini->ops->init_ipp(ini);
}
static inline void brcm_usb_init_common(struct brcm_usb_init_params *ini)
{
if (ini->ops->init_common)
ini->ops->init_common(ini);
}
static inline void brcm_usb_init_eohci(struct brcm_usb_init_params *ini)
{
if (ini->ops->init_eohci)
ini->ops->init_eohci(ini);
}
static inline void brcm_usb_init_xhci(struct brcm_usb_init_params *ini)
{
if (ini->ops->init_xhci)
ini->ops->init_xhci(ini);
}
static inline void brcm_usb_uninit_common(struct brcm_usb_init_params *ini)
{
if (ini->ops->uninit_common)
ini->ops->uninit_common(ini);
}
static inline void brcm_usb_uninit_eohci(struct brcm_usb_init_params *ini)
{
if (ini->ops->uninit_eohci)
ini->ops->uninit_eohci(ini);
}
static inline void brcm_usb_uninit_xhci(struct brcm_usb_init_params *ini)
{
if (ini->ops->uninit_xhci)
ini->ops->uninit_xhci(ini);
}
static inline int brcm_usb_get_dual_select(struct brcm_usb_init_params *ini)
{
if (ini->ops->get_dual_select)
return ini->ops->get_dual_select(ini);
return 0;
}
static inline void brcm_usb_set_dual_select(struct brcm_usb_init_params *ini,
int mode)
{
if (ini->ops->set_dual_select)
ini->ops->set_dual_select(ini, mode);
}
#endif /* _USB_BRCM_COMMON_INIT_H */
This diff is collapsed.
This diff is collapsed.
......@@ -33,14 +33,14 @@ config PHY_HISTB_COMBPHY
If unsure, say N.
config PHY_HISI_INNO_USB2
tristate "HiSilicon INNO USB2 PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Support for INNO USB2 PHY on HiSilicon SoCs. This Phy supports
USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It supports one
USB host port to accept one USB device.
tristate "HiSilicon INNO USB2 PHY support"
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
Support for INNO USB2 PHY on HiSilicon SoCs. This Phy supports
USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It supports one
USB host port to accept one USB device.
config PHY_HIX5HD2_SATA
tristate "HIX5HD2 SATA PHY Driver"
......
# SPDX-License-Identifier: GPL-2.0
#
# Phy drivers for Intel Lightning Mountain(LGM) platform
#
config PHY_INTEL_EMMC
tristate "Intel EMMC PHY driver"
select GENERIC_PHY
help
Enable this to support the Intel EMMC PHY
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PHY_INTEL_EMMC) += phy-intel-emmc.o
// SPDX-License-Identifier: GPL-2.0
/*
* Intel eMMC PHY driver
* Copyright (C) 2019 Intel, Corp.
*/
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
/* eMMC phy register definitions */
#define EMMC_PHYCTRL0_REG 0xa8
#define DR_TY_MASK GENMASK(30, 28)
#define DR_TY_SHIFT(x) (((x) << 28) & DR_TY_MASK)
#define OTAPDLYENA BIT(14)
#define OTAPDLYSEL_MASK GENMASK(13, 10)
#define OTAPDLYSEL_SHIFT(x) (((x) << 10) & OTAPDLYSEL_MASK)
#define EMMC_PHYCTRL1_REG 0xac
#define PDB_MASK BIT(0)
#define PDB_SHIFT(x) (((x) << 0) & PDB_MASK)
#define ENDLL_MASK BIT(7)
#define ENDLL_SHIFT(x) (((x) << 7) & ENDLL_MASK)
#define EMMC_PHYCTRL2_REG 0xb0
#define FRQSEL_25M 0
#define FRQSEL_50M 1
#define FRQSEL_100M 2
#define FRQSEL_150M 3
#define FRQSEL_MASK GENMASK(24, 22)
#define FRQSEL_SHIFT(x) (((x) << 22) & FRQSEL_MASK)
#define EMMC_PHYSTAT_REG 0xbc
#define CALDONE_MASK BIT(9)
#define DLLRDY_MASK BIT(8)
#define IS_CALDONE(x) ((x) & CALDONE_MASK)
#define IS_DLLRDY(x) ((x) & DLLRDY_MASK)
struct intel_emmc_phy {
struct regmap *syscfg;
struct clk *emmcclk;
};
static int intel_emmc_phy_power(struct phy *phy, bool on_off)
{
struct intel_emmc_phy *priv = phy_get_drvdata(phy);
unsigned int caldone;
unsigned int dllrdy;
unsigned int freqsel;
unsigned long rate;
int ret, quot;
/*
* Keep phyctrl_pdb and phyctrl_endll low to allow
* initialization of CALIO state M/C DFFs
*/
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL1_REG, PDB_MASK,
PDB_SHIFT(0));
if (ret) {
dev_err(&phy->dev, "CALIO power down bar failed: %d\n", ret);
return ret;
}
/* Already finish power_off above */
if (!on_off)
return 0;
rate = clk_get_rate(priv->emmcclk);
quot = DIV_ROUND_CLOSEST(rate, 50000000);
if (quot > FRQSEL_150M)
dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
freqsel = clamp_t(int, quot, FRQSEL_25M, FRQSEL_150M);
/*
* According to the user manual, calpad calibration
* cycle takes more than 2us without the minimal recommended
* value, so we may need a little margin here
*/
udelay(5);
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL1_REG, PDB_MASK,
PDB_SHIFT(1));
if (ret) {
dev_err(&phy->dev, "CALIO power down bar failed: %d\n", ret);
return ret;
}
/*
* According to the user manual, it asks driver to wait 5us for
* calpad busy trimming. However it is documented that this value is
* PVT(A.K.A process,voltage and temperature) relevant, so some
* failure cases are found which indicates we should be more tolerant
* to calpad busy trimming.
*/
ret = regmap_read_poll_timeout(priv->syscfg, EMMC_PHYSTAT_REG,
caldone, IS_CALDONE(caldone),
0, 50);
if (ret) {
dev_err(&phy->dev, "caldone failed, ret=%d\n", ret);
return ret;
}
/* Set the frequency of the DLL operation */
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL2_REG, FRQSEL_MASK,
FRQSEL_SHIFT(freqsel));
if (ret) {
dev_err(&phy->dev, "set the frequency of dll failed:%d\n", ret);
return ret;
}
/* Turn on the DLL */
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL1_REG, ENDLL_MASK,
ENDLL_SHIFT(1));
if (ret) {
dev_err(&phy->dev, "turn on the dll failed: %d\n", ret);
return ret;
}
/*
* After enabling analog DLL circuits docs say that we need 10.2 us if
* our source clock is at 50 MHz and that lock time scales linearly
* with clock speed. If we are powering on the PHY and the card clock
* is super slow (like 100 kHZ) this could take as long as 5.1 ms as
* per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms
* Hopefully we won't be running at 100 kHz, but we should still make
* sure we wait long enough.
*
* NOTE: There appear to be corner cases where the DLL seems to take
* extra long to lock for reasons that aren't understood. In some
* extreme cases we've seen it take up to over 10ms (!). We'll be
* generous and give it 50ms.
*/
ret = regmap_read_poll_timeout(priv->syscfg,
EMMC_PHYSTAT_REG,
dllrdy, IS_DLLRDY(dllrdy),
0, 50 * USEC_PER_MSEC);
if (ret) {
dev_err(&phy->dev, "dllrdy failed. ret=%d\n", ret);
return ret;
}
return 0;
}
static int intel_emmc_phy_init(struct phy *phy)
{
struct intel_emmc_phy *priv = phy_get_drvdata(phy);
/*
* We purposely get the clock here and not in probe to avoid the
* circular dependency problem. We expect:
* - PHY driver to probe
* - SDHCI driver to start probe
* - SDHCI driver to register it's clock
* - SDHCI driver to get the PHY
* - SDHCI driver to init the PHY
*
* The clock is optional, so upon any error just return it like
* any other error to user.
*
*/
priv->emmcclk = clk_get_optional(&phy->dev, "emmcclk");
if (IS_ERR(priv->emmcclk)) {
dev_err(&phy->dev, "ERROR: getting emmcclk\n");
return PTR_ERR(priv->emmcclk);
}
return 0;
}
static int intel_emmc_phy_exit(struct phy *phy)
{
struct intel_emmc_phy *priv = phy_get_drvdata(phy);
clk_put(priv->emmcclk);
return 0;
}
static int intel_emmc_phy_power_on(struct phy *phy)
{
struct intel_emmc_phy *priv = phy_get_drvdata(phy);
int ret;
/* Drive impedance: 50 Ohm */
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL0_REG, DR_TY_MASK,
DR_TY_SHIFT(6));
if (ret) {
dev_err(&phy->dev, "ERROR set drive-impednce-50ohm: %d\n", ret);
return ret;
}
/* Output tap delay: disable */
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL0_REG, OTAPDLYENA,
0);
if (ret) {
dev_err(&phy->dev, "ERROR Set output tap delay : %d\n", ret);
return ret;
}
/* Output tap delay */
ret = regmap_update_bits(priv->syscfg, EMMC_PHYCTRL0_REG,
OTAPDLYSEL_MASK, OTAPDLYSEL_SHIFT(4));
if (ret) {
dev_err(&phy->dev, "ERROR: output tap dly select: %d\n", ret);
return ret;
}
/* Power up eMMC phy analog blocks */
return intel_emmc_phy_power(phy, true);
}
static int intel_emmc_phy_power_off(struct phy *phy)
{
/* Power down eMMC phy analog blocks */
return intel_emmc_phy_power(phy, false);
}
static const struct phy_ops ops = {
.init = intel_emmc_phy_init,
.exit = intel_emmc_phy_exit,
.power_on = intel_emmc_phy_power_on,
.power_off = intel_emmc_phy_power_off,
.owner = THIS_MODULE,
};
static int intel_emmc_phy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct intel_emmc_phy *priv;
struct phy *generic_phy;
struct phy_provider *phy_provider;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* Get eMMC phy (accessed via chiptop) regmap */
priv->syscfg = syscon_regmap_lookup_by_phandle(np, "intel,syscon");
if (IS_ERR(priv->syscfg)) {
dev_err(dev, "failed to find syscon\n");
return PTR_ERR(priv->syscfg);
}
generic_phy = devm_phy_create(dev, np, &ops);
if (IS_ERR(generic_phy)) {
dev_err(dev, "failed to create PHY\n");
return PTR_ERR(generic_phy);
}
phy_set_drvdata(generic_phy, priv);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
return PTR_ERR_OR_ZERO(phy_provider);
}
static const struct of_device_id intel_emmc_phy_dt_ids[] = {
{ .compatible = "intel,lgm-emmc-phy" },
{}
};
MODULE_DEVICE_TABLE(of, intel_emmc_phy_dt_ids);
static struct platform_driver intel_emmc_driver = {
.probe = intel_emmc_phy_probe,
.driver = {
.name = "intel-emmc-phy",
.of_match_table = intel_emmc_phy_dt_ids,
},
};
module_platform_driver(intel_emmc_driver);
MODULE_AUTHOR("Peter Harliman Liem <peter.harliman.liem@intel.com>");
MODULE_DESCRIPTION("Intel eMMC PHY driver");
MODULE_LICENSE("GPL v2");
......@@ -386,7 +386,7 @@ static struct phy *ltq_vrx200_pcie_phy_xlate(struct device *dev,
default:
dev_err(dev, "invalid PHY mode %u\n", mode);
return ERR_PTR(-EINVAL);
};
}
return priv->phy;
}
......
......@@ -10,14 +10,16 @@ config ARMADA375_USBCLUSTER_PHY
config PHY_BERLIN_SATA
tristate "Marvell Berlin SATA PHY driver"
depends on ARCH_BERLIN && HAS_IOMEM && OF
depends on ARCH_BERLIN || COMPILE_TEST
depends on OF && HAS_IOMEM
select GENERIC_PHY
help
Enable this to support the SATA PHY on Marvell Berlin SoCs.
config PHY_BERLIN_USB
tristate "Marvell Berlin USB PHY Driver"
depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
depends on ARCH_BERLIN || COMPILE_TEST
depends on OF && HAS_IOMEM && RESET_CONTROLLER
select GENERIC_PHY
help
Enable this to support the USB PHY on Marvell Berlin SoCs.
......@@ -95,7 +97,7 @@ config PHY_PXA_28NM_USB2
config PHY_PXA_USB
tristate "Marvell PXA USB PHY Driver"
depends on ARCH_PXA || ARCH_MMP
depends on ARCH_PXA || ARCH_MMP || COMPILE_TEST
select GENERIC_PHY
help
Enable this to support Marvell PXA USB PHY driver for Marvell
......
......@@ -3,12 +3,13 @@
# Phy drivers for Mediatek devices
#
config PHY_MTK_TPHY
tristate "MediaTek T-PHY Driver"
depends on ARCH_MEDIATEK && OF
select GENERIC_PHY
help
Say 'Y' here to add support for MediaTek T-PHY driver,
it supports multiple usb2.0, usb3.0 ports, PCIe and
tristate "MediaTek T-PHY Driver"
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on OF
select GENERIC_PHY
help
Say 'Y' here to add support for MediaTek T-PHY driver,
it supports multiple usb2.0, usb3.0 ports, PCIe and
SATA, and meanwhile supports two version T-PHY which have
different banks layout, the T-PHY with shared banks between
multi-ports is first version, otherwise is second veriosn,
......@@ -16,7 +17,8 @@ config PHY_MTK_TPHY
config PHY_MTK_UFS
tristate "MediaTek UFS M-PHY driver"
depends on ARCH_MEDIATEK && OF
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on OF
select GENERIC_PHY
help
Support for UFS M-PHY on MediaTek chipsets.
......@@ -25,10 +27,11 @@ config PHY_MTK_UFS
specified M-PHYs.
config PHY_MTK_XSPHY
tristate "MediaTek XS-PHY Driver"
depends on ARCH_MEDIATEK && OF
select GENERIC_PHY
help
tristate "MediaTek XS-PHY Driver"
depends on ARCH_MEDIATEK || COMPILE_TEST
depends on OF
select GENERIC_PHY
help
Enable this to support the SuperSpeedPlus XS-PHY transceiver for
USB3.1 GEN2 controllers on MediaTek chips. The driver supports
multiple USB2.0, USB3.1 GEN2 ports.
......@@ -29,7 +29,7 @@ static void devm_phy_release(struct device *dev, void *res)
{
struct phy *phy = *(struct phy **)res;
phy_put(phy);
phy_put(dev, phy);
}
static void devm_phy_provider_release(struct device *dev, void *res)
......@@ -566,12 +566,12 @@ struct phy *of_phy_get(struct device_node *np, const char *con_id)
EXPORT_SYMBOL_GPL(of_phy_get);
/**
* phy_put() - release the PHY
* @phy: the phy returned by phy_get()
* of_phy_put() - release the PHY
* @phy: the phy returned by of_phy_get()
*
* Releases a refcount the caller received from phy_get().
* Releases a refcount the caller received from of_phy_get().
*/
void phy_put(struct phy *phy)
void of_phy_put(struct phy *phy)
{
if (!phy || IS_ERR(phy))
return;
......@@ -584,6 +584,20 @@ void phy_put(struct phy *phy)
module_put(phy->ops->owner);
put_device(&phy->dev);
}
EXPORT_SYMBOL_GPL(of_phy_put);
/**
* phy_put() - release the PHY
* @dev: device that wants to release this phy
* @phy: the phy returned by phy_get()
*
* Releases a refcount the caller received from phy_get().
*/
void phy_put(struct device *dev, struct phy *phy)
{
device_link_remove(dev, &phy->dev);
of_phy_put(phy);
}
EXPORT_SYMBOL_GPL(phy_put);
/**
......@@ -651,6 +665,7 @@ struct phy *phy_get(struct device *dev, const char *string)
{
int index = 0;
struct phy *phy;
struct device_link *link;
if (string == NULL) {
dev_WARN(dev, "missing string\n");
......@@ -672,6 +687,13 @@ struct phy *phy_get(struct device *dev, const char *string)
get_device(&phy->dev);
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) {
dev_err(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy;
}
EXPORT_SYMBOL_GPL(phy_get);
......@@ -765,6 +787,7 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
const char *con_id)
{
struct phy **ptr, *phy;
struct device_link *link;
ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
......@@ -776,6 +799,14 @@ struct phy *devm_of_phy_get(struct device *dev, struct device_node *np,
devres_add(dev, ptr);
} else {
devres_free(ptr);
return phy;
}
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) {
dev_err(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy;
......@@ -798,6 +829,7 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
int index)
{
struct phy **ptr, *phy;
struct device_link *link;
ptr = devres_alloc(devm_phy_release, sizeof(*ptr), GFP_KERNEL);
if (!ptr)
......@@ -819,6 +851,13 @@ struct phy *devm_of_phy_get_by_index(struct device *dev, struct device_node *np,
*ptr = phy;
devres_add(dev, ptr);
link = device_link_add(dev, &phy->dev, DL_FLAG_STATELESS);
if (!link) {
dev_err(dev, "failed to create device link to %s\n",
dev_name(phy->dev.parent));
return ERR_PTR(-EINVAL);
}
return phy;
}
EXPORT_SYMBOL_GPL(devm_of_phy_get_by_index);
......
......@@ -80,7 +80,7 @@ static int read_poll_timeout(void __iomem *addr, u32 mask)
if (readl_relaxed(addr) & mask)
return 0;
usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
usleep_range(DELAY_INTERVAL_US, DELAY_INTERVAL_US + 50);
} while (!time_after(jiffies, timeout));
return (readl_relaxed(addr) & mask) ? 0 : -ETIMEDOUT;
......
......@@ -166,8 +166,9 @@ static const unsigned int sdm845_ufsphy_regs_layout[] = {
};
static const unsigned int sm8150_ufsphy_regs_layout[] = {
[QPHY_START_CTRL] = 0x00,
[QPHY_PCS_READY_STATUS] = 0x180,
[QPHY_START_CTRL] = QPHY_V4_PHY_START,
[QPHY_PCS_READY_STATUS] = QPHY_V4_PCS_READY_STATUS,
[QPHY_SW_RESET] = QPHY_V4_SW_RESET,
};
static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl[] = {
......@@ -885,7 +886,6 @@ static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
};
static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL, 0x01),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
......@@ -1390,7 +1390,6 @@ static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
.pwrdn_ctrl = SW_PWRDN,
.is_dual_lane_phy = true,
.no_pcs_sw_reset = true,
};
static void qcom_qmp_phy_configure(void __iomem *base,
......
// SPDX-License-Identifier: GPL-2.0
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*/
......
......@@ -39,6 +39,7 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
tristate "Rockchip Innosilicon MIPI/LVDS/TTL PHY driver"
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
select GENERIC_PHY
select GENERIC_PHY_MIPI_DPHY
help
Enable this to support the Rockchip MIPI/LVDS/TTL PHY with
Innosilicon IP block.
......
......@@ -32,7 +32,7 @@ config PHY_EXYNOS_PCIE
config PHY_SAMSUNG_USB2
tristate "Samsung USB 2.0 PHY driver"
depends on HAS_IOMEM
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2 || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
default ARCH_EXYNOS
......@@ -60,7 +60,7 @@ config PHY_EXYNOS5250_USB2
config PHY_S5PV210_USB2
bool "Support for S5PV210"
depends on PHY_SAMSUNG_USB2
depends on ARCH_S5PV210
depends on ARCH_S5PV210 || COMPILE_TEST
help
Enable USB PHY support for S5PV210. This option requires that Samsung
USB 2.0 PHY driver is enabled and means that support for this
......@@ -69,7 +69,7 @@ config PHY_S5PV210_USB2
config PHY_EXYNOS5_USBDRD
tristate "Exynos5 SoC series USB DRD PHY driver"
depends on ARCH_EXYNOS && OF
depends on (ARCH_EXYNOS && OF) || COMPILE_TEST
depends on HAS_IOMEM
depends on USB_DWC3_EXYNOS
select GENERIC_PHY
......
......@@ -4,7 +4,7 @@
#
config PHY_DA8XX_USB
tristate "TI DA8xx USB PHY Driver"
depends on ARCH_DAVINCI_DA8XX
depends on ARCH_DAVINCI_DA8XX || COMPILE_TEST
select GENERIC_PHY
select MFD_SYSCON
help
......@@ -14,7 +14,7 @@ config PHY_DA8XX_USB
config PHY_DM816X_USB
tristate "TI dm816x USB PHY driver"
depends on ARCH_OMAP2PLUS
depends on ARCH_OMAP2PLUS || COMPILE_TEST
depends on USB_SUPPORT
select GENERIC_PHY
select USB_PHY
......@@ -33,6 +33,22 @@ config PHY_AM654_SERDES
This option enables support for TI AM654 SerDes PHY used for
PCIe.
config PHY_J721E_WIZ
tristate "TI J721E WIZ (SERDES Wrapper) support"
depends on OF && ARCH_K3 || COMPILE_TEST
depends on HAS_IOMEM && OF_ADDRESS
depends on COMMON_CLK
select GENERIC_PHY
select MULTIPLEXER
select REGMAP_MMIO
select MUX_MMIO
help
This option enables support for WIZ module present in TI's J721E
SoC. WIZ is a serdes wrapper used to configure some of the input
signals to the SERDES (Sierra/Torrent). This driver configures
three clock selects (pll0, pll1, dig) and resets for each of the
lanes.
config OMAP_CONTROL_PHY
tristate "OMAP CONTROL PHY Driver"
depends on ARCH_OMAP2PLUS || COMPILE_TEST
......
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.
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