diff options
Diffstat (limited to 'drivers/pci/of.c')
| -rw-r--r-- | drivers/pci/of.c | 78 | 
1 files changed, 71 insertions, 7 deletions
| diff --git a/drivers/pci/of.c b/drivers/pci/of.c index cb2e8351c2cc..196834ed44fe 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -369,7 +369,6 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev,  	dev_dbg(dev, "Parsing dma-ranges property...\n");  	for_each_of_pci_range(&parser, &range) { -		struct resource_entry *entry;  		/*  		 * If we failed translation or got a zero-sized region  		 * then skip this range @@ -393,12 +392,7 @@ static int devm_of_pci_get_host_bridge_resources(struct device *dev,  			goto failed;  		} -		/* Keep the resource list sorted */ -		resource_list_for_each_entry(entry, ib_resources) -			if (entry->res->start > res->start) -				break; - -		pci_add_resource_offset(&entry->node, res, +		pci_add_resource_offset(ib_resources, res,  					res->start - range.pci_addr);  	} @@ -633,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); | 
