PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
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. Link: https://lore.kernel.org/r/20220412094946.27069-4-pali@kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Rob Herring <robh@kernel.org> Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
e8e7fbb6a3
commit
35662423fb
@ -633,3 +633,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);
|
||||
|
@ -627,6 +627,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);
|
||||
@ -653,6 +656,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) { }
|
||||
|
Loading…
Reference in New Issue
Block a user