Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Documentation/devicetree/bindings/usb/renesas,upd720201-pci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/usb/renesas,upd720201-pci.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: UPD720201/UPD720202 USB 3.0 xHCI Host Controller (PCIe)

maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>

description:
UPD720201 USB 3.0 xHCI Host Controller via PCIe x1 Gen2 interface.
The UPD720202 supports up to two downstream ports, while UPD720201
supports up to four downstream USB 3.0 rev1.0 ports.

properties:
compatible:
const: pci1912,0014

reg:
maxItems: 1

avdd33-supply:
description: +3.3 V power supply for analog circuit

vdd10-supply:
description: +1.05 V power supply

vdd33-supply:
description: +3.3 V power supply

required:
- compatible
- reg
- avdd33-supply
- vdd10-supply
- vdd33-supply

allOf:
- $ref: usb-xhci.yaml

additionalProperties: true

examples:
- |
pcie@0 {
reg = <0x0 0x1000>;
ranges = <0x02000000 0x0 0x100000 0x10000000 0x0 0x0>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";

usb-controller@0 {
compatible = "pci1912,0014";
reg = <0x0 0x0 0x0 0x0 0x0>;
avdd33-supply = <&avdd33_reg>;
vdd10-supply = <&vdd10_reg>;
vdd33-supply = <&vdd33_reg>;
};
};
4 changes: 2 additions & 2 deletions drivers/pci/controller/dwc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ config PCIE_QCOM
select CRC8
select PCIE_QCOM_COMMON
select PCI_HOST_COMMON
select PCI_PWRCTRL_SLOT
select PCI_PWRCTRL_GENERIC
help
Say Y here to enable PCIe controller support on Qualcomm SoCs. The
PCIe controller uses the DesignWare core plus Qualcomm-specific
Expand Down Expand Up @@ -431,7 +431,7 @@ config PCIE_SPACEMIT_K1
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on HAS_IOMEM
select PCIE_DW_HOST
select PCI_PWRCTRL_SLOT
select PCI_PWRCTRL_GENERIC
default ARCH_SPACEMIT
help
Enables support for the DesignWare based PCIe controller in
Expand Down
13 changes: 7 additions & 6 deletions drivers/pci/pwrctrl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ config PCI_PWRCTRL_PWRSEQ
select POWER_SEQUENCING
select PCI_PWRCTRL

config PCI_PWRCTRL_SLOT
tristate "PCI Power Control driver for PCI slots"
config PCI_PWRCTRL_GENERIC
tristate "Generic PCI Power Control driver for PCI slots and endpoints"
select POWER_SEQUENCING
select PCI_PWRCTRL
help
Say Y here to enable the PCI Power Control driver to control the power
state of PCI slots.
Say Y here to enable the generic PCI Power Control driver to control
the power state of PCI slots and endpoints.

This is a generic driver that controls the power state of different
PCI slots. The voltage regulators powering the rails of the PCI slots
are expected to be defined in the devicetree node of the PCI bridge.
PCI slots and endpoints. The voltage regulators powering the rails
of the PCI slots or endpoints are expected to be defined in the
devicetree node of the PCI bridge.

config PCI_PWRCTRL_TC9563
tristate "PCI Power Control driver for TC9563 PCIe switch"
Expand Down
4 changes: 2 additions & 2 deletions drivers/pci/pwrctrl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pci-pwrctrl-core-y := core.o

obj-$(CONFIG_PCI_PWRCTRL_PWRSEQ) += pci-pwrctrl-pwrseq.o

obj-$(CONFIG_PCI_PWRCTRL_SLOT) += pci-pwrctrl-slot.o
pci-pwrctrl-slot-y := slot.o
obj-$(CONFIG_PCI_PWRCTRL_GENERIC) += pci-pwrctrl-generic.o
pci-pwrctrl-generic-y := generic.o

obj-$(CONFIG_PCI_PWRCTRL_TC9563) += pci-pwrctrl-tc9563.o
143 changes: 143 additions & 0 deletions drivers/pci/pwrctrl/generic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2024 Linaro Ltd.
* Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
*/

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/pci-pwrctrl.h>
#include <linux/platform_device.h>
#include <linux/pwrseq/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

struct generic_pwrctrl {
struct pci_pwrctrl pwrctrl;
struct regulator_bulk_data *supplies;
int num_supplies;
struct clk *clk;
struct pwrseq_desc *pwrseq;
};

static int generic_pwrctrl_power_on(struct pci_pwrctrl *pwrctrl)
{
struct generic_pwrctrl *generic =
container_of(pwrctrl,
struct generic_pwrctrl, pwrctrl);
int ret;

if (generic->pwrseq) {
pwrseq_power_on(generic->pwrseq);
return 0;
}

ret = regulator_bulk_enable(generic->num_supplies, generic->supplies);
if (ret < 0) {
dev_err(generic->pwrctrl.dev, "Failed to enable generic regulators\n");
return ret;
}

return clk_prepare_enable(generic->clk);
}

static int generic_pwrctrl_power_off(struct pci_pwrctrl *pwrctrl)
{
struct generic_pwrctrl *generic =
container_of(pwrctrl,
struct generic_pwrctrl, pwrctrl);

if (generic->pwrseq) {
pwrseq_power_off(generic->pwrseq);
return 0;
}

regulator_bulk_disable(generic->num_supplies, generic->supplies);
clk_disable_unprepare(generic->clk);

return 0;
}

static void devm_generic_pwrctrl_release(void *data)
{
struct generic_pwrctrl *generic = data;

generic_pwrctrl_power_off(&generic->pwrctrl);
regulator_bulk_free(generic->num_supplies, generic->supplies);
}

static int generic_pwrctrl_probe(struct platform_device *pdev)
{
struct generic_pwrctrl *generic;
struct device *dev = &pdev->dev;
int ret;

generic = devm_kzalloc(dev, sizeof(*generic), GFP_KERNEL);
if (!generic)
return -ENOMEM;

if (of_graph_is_present(dev_of_node(dev))) {
generic->pwrseq = devm_pwrseq_get(dev, "pcie");
if (IS_ERR(generic->pwrseq))
return dev_err_probe(dev, PTR_ERR(generic->pwrseq),
"Failed to get the power sequencer\n");

goto skip_resources;
}

ret = of_regulator_bulk_get_all(dev, dev_of_node(dev),
&generic->supplies);
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to get generic regulators\n");

generic->num_supplies = ret;

generic->clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(generic->clk))
return dev_err_probe(dev, PTR_ERR(generic->clk),
"Failed to enable generic clock\n");

skip_resources:
generic->pwrctrl.power_on = generic_pwrctrl_power_on;
generic->pwrctrl.power_off = generic_pwrctrl_power_off;

ret = devm_add_action_or_reset(dev, devm_generic_pwrctrl_release, generic);
if (ret)
return ret;

pci_pwrctrl_init(&generic->pwrctrl, dev);

ret = devm_pci_pwrctrl_device_set_ready(dev, &generic->pwrctrl);
if (ret)
return dev_err_probe(dev, ret, "Failed to register pwrctrl driver\n");

return 0;
}

static const struct of_device_id generic_pwrctrl_of_match[] = {
{
.compatible = "pciclass,0604",
},
/* Renesas UPD720201/UPD720202 USB 3.0 xHCI Host Controller */
{
.compatible = "pci1912,0014",
},
{ }
};
MODULE_DEVICE_TABLE(of, generic_pwrctrl_of_match);

static struct platform_driver generic_pwrctrl_driver = {
.driver = {
.name = "pci-pwrctrl-generic",
.of_match_table = generic_pwrctrl_of_match,
},
.probe = generic_pwrctrl_probe,
};
module_platform_driver(generic_pwrctrl_driver);

MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
MODULE_DESCRIPTION("Generic PCI Power Control driver for PCI Slots and Endpoints");
MODULE_LICENSE("GPL");
140 changes: 0 additions & 140 deletions drivers/pci/pwrctrl/slot.c

This file was deleted.