aboutsummaryrefslogtreecommitdiff
path: root/pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch')
-rw-r--r--pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch135
1 files changed, 135 insertions, 0 deletions
diff --git a/pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch b/pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch
new file mode 100644
index 0000000..4518849
--- /dev/null
+++ b/pkgs/patches-linux-5.15/0048-PCI-Add-function-for-parsing-slot-power-limit-milliw.patch
@@ -0,0 +1,135 @@
+From 3514828cb2cf52e545fe71bb7dc2d105d8b0084e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org>
+Date: Sun, 31 Oct 2021 16:07:06 +0100
+Subject: [PATCH 48/90] PCI: Add function for parsing
+ 'slot-power-limit-milliwatt' DT property
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add function of_pci_get_slot_power_limit(), which parses the
+'slot-power-limit-milliwatt' DT property, returning the value in
+milliwatts and in format ready for the PCIe Slot Capabilities Register.
+
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Marek Behún <kabel@kernel.org>
+Reviewed-by: Rob Herring <robh@kernel.org>
+---
+ drivers/pci/of.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/pci/pci.h | 15 ++++++++++
+ 2 files changed, 85 insertions(+)
+
+diff --git a/drivers/pci/of.c b/drivers/pci/of.c
+index d84381ce82b5..1372da653929 100644
+--- a/drivers/pci/of.c
++++ b/drivers/pci/of.c
+@@ -627,3 +627,73 @@ int of_pci_get_max_link_speed(struct device_node *node)
+ return max_link_speed;
+ }
+ EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
++
++/**
++ * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
++ * property.
++ *
++ * @node: device tree node with the slot power limit information
++ * @slot_power_limit_value: pointer where the value should be stored in PCIe
++ * Slot Capabilities Register format
++ * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
++ * Slot Capabilities Register format
++ *
++ * Returns the slot power limit in milliwatts and if @slot_power_limit_value
++ * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
++ * scale in format used by PCIe Slot Capabilities Register.
++ *
++ * If the property is not found or is invalid, returns 0.
++ */
++u32 of_pci_get_slot_power_limit(struct device_node *node,
++ u8 *slot_power_limit_value,
++ u8 *slot_power_limit_scale)
++{
++ u32 slot_power_limit_mw;
++ u8 value, scale;
++
++ if (of_property_read_u32(node, "slot-power-limit-milliwatt",
++ &slot_power_limit_mw))
++ slot_power_limit_mw = 0;
++
++ /* Calculate Slot Power Limit Value and Slot Power Limit Scale */
++ if (slot_power_limit_mw == 0) {
++ value = 0x00;
++ scale = 0;
++ } else if (slot_power_limit_mw <= 255) {
++ value = slot_power_limit_mw;
++ scale = 3;
++ } else if (slot_power_limit_mw <= 255*10) {
++ value = slot_power_limit_mw / 10;
++ scale = 2;
++ slot_power_limit_mw = slot_power_limit_mw / 10 * 10;
++ } else if (slot_power_limit_mw <= 255*100) {
++ value = slot_power_limit_mw / 100;
++ scale = 1;
++ slot_power_limit_mw = slot_power_limit_mw / 100 * 100;
++ } else if (slot_power_limit_mw <= 239*1000) {
++ value = slot_power_limit_mw / 1000;
++ scale = 0;
++ slot_power_limit_mw = slot_power_limit_mw / 1000 * 1000;
++ } else if (slot_power_limit_mw < 250*1000) {
++ value = 0xEF;
++ scale = 0;
++ slot_power_limit_mw = 239*1000;
++ } else if (slot_power_limit_mw <= 600*1000) {
++ value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
++ scale = 0;
++ slot_power_limit_mw = slot_power_limit_mw / (1000*25) * (1000*25);
++ } else {
++ value = 0xFE;
++ scale = 0;
++ slot_power_limit_mw = 600*1000;
++ }
++
++ if (slot_power_limit_value)
++ *slot_power_limit_value = value;
++
++ if (slot_power_limit_scale)
++ *slot_power_limit_scale = scale;
++
++ return slot_power_limit_mw;
++}
++EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
+diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
+index 1cce56c2aea0..9352278141be 100644
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -665,6 +665,9 @@ struct device_node;
+ int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
+ int of_get_pci_domain_nr(struct device_node *node);
+ int of_pci_get_max_link_speed(struct device_node *node);
++u32 of_pci_get_slot_power_limit(struct device_node *node,
++ u8 *slot_power_limit_value,
++ u8 *slot_power_limit_scale);
+ void pci_set_of_node(struct pci_dev *dev);
+ void pci_release_of_node(struct pci_dev *dev);
+ void pci_set_bus_of_node(struct pci_bus *bus);
+@@ -691,6 +694,18 @@ of_pci_get_max_link_speed(struct device_node *node)
+ return -EINVAL;
+ }
+
++static inline u32
++of_pci_get_slot_power_limit(struct device_node *node,
++ u8 *slot_power_limit_value,
++ u8 *slot_power_limit_scale)
++{
++ if (slot_power_limit_value)
++ *slot_power_limit_value = 0;
++ if (slot_power_limit_scale)
++ *slot_power_limit_scale = 0;
++ return 0;
++}
++
+ static inline void pci_set_of_node(struct pci_dev *dev) { }
+ static inline void pci_release_of_node(struct pci_dev *dev) { }
+ static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
+--
+2.34.1
+