cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

of.c (19506B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * PCI <-> OF mapping helpers
      4 *
      5 * Copyright 2011 IBM Corp.
      6 */
      7#define pr_fmt(fmt)	"PCI: OF: " fmt
      8
      9#include <linux/irqdomain.h>
     10#include <linux/kernel.h>
     11#include <linux/pci.h>
     12#include <linux/of.h>
     13#include <linux/of_irq.h>
     14#include <linux/of_address.h>
     15#include <linux/of_pci.h>
     16#include "pci.h"
     17
     18#ifdef CONFIG_PCI
     19void pci_set_of_node(struct pci_dev *dev)
     20{
     21	if (!dev->bus->dev.of_node)
     22		return;
     23	dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node,
     24						    dev->devfn);
     25	if (dev->dev.of_node)
     26		dev->dev.fwnode = &dev->dev.of_node->fwnode;
     27}
     28
     29void pci_release_of_node(struct pci_dev *dev)
     30{
     31	of_node_put(dev->dev.of_node);
     32	dev->dev.of_node = NULL;
     33	dev->dev.fwnode = NULL;
     34}
     35
     36void pci_set_bus_of_node(struct pci_bus *bus)
     37{
     38	struct device_node *node;
     39
     40	if (bus->self == NULL) {
     41		node = pcibios_get_phb_of_node(bus);
     42	} else {
     43		node = of_node_get(bus->self->dev.of_node);
     44		if (node && of_property_read_bool(node, "external-facing"))
     45			bus->self->external_facing = true;
     46	}
     47
     48	bus->dev.of_node = node;
     49
     50	if (bus->dev.of_node)
     51		bus->dev.fwnode = &bus->dev.of_node->fwnode;
     52}
     53
     54void pci_release_bus_of_node(struct pci_bus *bus)
     55{
     56	of_node_put(bus->dev.of_node);
     57	bus->dev.of_node = NULL;
     58	bus->dev.fwnode = NULL;
     59}
     60
     61struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus)
     62{
     63	/* This should only be called for PHBs */
     64	if (WARN_ON(bus->self || bus->parent))
     65		return NULL;
     66
     67	/*
     68	 * Look for a node pointer in either the intermediary device we
     69	 * create above the root bus or its own parent. Normally only
     70	 * the later is populated.
     71	 */
     72	if (bus->bridge->of_node)
     73		return of_node_get(bus->bridge->of_node);
     74	if (bus->bridge->parent && bus->bridge->parent->of_node)
     75		return of_node_get(bus->bridge->parent->of_node);
     76	return NULL;
     77}
     78
     79struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus)
     80{
     81#ifdef CONFIG_IRQ_DOMAIN
     82	struct irq_domain *d;
     83
     84	if (!bus->dev.of_node)
     85		return NULL;
     86
     87	/* Start looking for a phandle to an MSI controller. */
     88	d = of_msi_get_domain(&bus->dev, bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
     89	if (d)
     90		return d;
     91
     92	/*
     93	 * If we don't have an msi-parent property, look for a domain
     94	 * directly attached to the host bridge.
     95	 */
     96	d = irq_find_matching_host(bus->dev.of_node, DOMAIN_BUS_PCI_MSI);
     97	if (d)
     98		return d;
     99
    100	return irq_find_host(bus->dev.of_node);
    101#else
    102	return NULL;
    103#endif
    104}
    105
    106bool pci_host_of_has_msi_map(struct device *dev)
    107{
    108	if (dev && dev->of_node)
    109		return of_get_property(dev->of_node, "msi-map", NULL);
    110	return false;
    111}
    112
    113static inline int __of_pci_pci_compare(struct device_node *node,
    114				       unsigned int data)
    115{
    116	int devfn;
    117
    118	devfn = of_pci_get_devfn(node);
    119	if (devfn < 0)
    120		return 0;
    121
    122	return devfn == data;
    123}
    124
    125struct device_node *of_pci_find_child_device(struct device_node *parent,
    126					     unsigned int devfn)
    127{
    128	struct device_node *node, *node2;
    129
    130	for_each_child_of_node(parent, node) {
    131		if (__of_pci_pci_compare(node, devfn))
    132			return node;
    133		/*
    134		 * Some OFs create a parent node "multifunc-device" as
    135		 * a fake root for all functions of a multi-function
    136		 * device we go down them as well.
    137		 */
    138		if (of_node_name_eq(node, "multifunc-device")) {
    139			for_each_child_of_node(node, node2) {
    140				if (__of_pci_pci_compare(node2, devfn)) {
    141					of_node_put(node);
    142					return node2;
    143				}
    144			}
    145		}
    146	}
    147	return NULL;
    148}
    149EXPORT_SYMBOL_GPL(of_pci_find_child_device);
    150
    151/**
    152 * of_pci_get_devfn() - Get device and function numbers for a device node
    153 * @np: device node
    154 *
    155 * Parses a standard 5-cell PCI resource and returns an 8-bit value that can
    156 * be passed to the PCI_SLOT() and PCI_FUNC() macros to extract the device
    157 * and function numbers respectively. On error a negative error code is
    158 * returned.
    159 */
    160int of_pci_get_devfn(struct device_node *np)
    161{
    162	u32 reg[5];
    163	int error;
    164
    165	error = of_property_read_u32_array(np, "reg", reg, ARRAY_SIZE(reg));
    166	if (error)
    167		return error;
    168
    169	return (reg[0] >> 8) & 0xff;
    170}
    171EXPORT_SYMBOL_GPL(of_pci_get_devfn);
    172
    173/**
    174 * of_pci_parse_bus_range() - parse the bus-range property of a PCI device
    175 * @node: device node
    176 * @res: address to a struct resource to return the bus-range
    177 *
    178 * Returns 0 on success or a negative error-code on failure.
    179 */
    180int of_pci_parse_bus_range(struct device_node *node, struct resource *res)
    181{
    182	u32 bus_range[2];
    183	int error;
    184
    185	error = of_property_read_u32_array(node, "bus-range", bus_range,
    186					   ARRAY_SIZE(bus_range));
    187	if (error)
    188		return error;
    189
    190	res->name = node->name;
    191	res->start = bus_range[0];
    192	res->end = bus_range[1];
    193	res->flags = IORESOURCE_BUS;
    194
    195	return 0;
    196}
    197EXPORT_SYMBOL_GPL(of_pci_parse_bus_range);
    198
    199/**
    200 * of_get_pci_domain_nr - Find the host bridge domain number
    201 *			  of the given device node.
    202 * @node: Device tree node with the domain information.
    203 *
    204 * This function will try to obtain the host bridge domain number by finding
    205 * a property called "linux,pci-domain" of the given device node.
    206 *
    207 * Return:
    208 * * > 0	- On success, an associated domain number.
    209 * * -EINVAL	- The property "linux,pci-domain" does not exist.
    210 * * -ENODATA	- The linux,pci-domain" property does not have value.
    211 * * -EOVERFLOW	- Invalid "linux,pci-domain" property value.
    212 *
    213 * Returns the associated domain number from DT in the range [0-0xffff], or
    214 * a negative value if the required property is not found.
    215 */
    216int of_get_pci_domain_nr(struct device_node *node)
    217{
    218	u32 domain;
    219	int error;
    220
    221	error = of_property_read_u32(node, "linux,pci-domain", &domain);
    222	if (error)
    223		return error;
    224
    225	return (u16)domain;
    226}
    227EXPORT_SYMBOL_GPL(of_get_pci_domain_nr);
    228
    229/**
    230 * of_pci_check_probe_only - Setup probe only mode if linux,pci-probe-only
    231 *                           is present and valid
    232 */
    233void of_pci_check_probe_only(void)
    234{
    235	u32 val;
    236	int ret;
    237
    238	ret = of_property_read_u32(of_chosen, "linux,pci-probe-only", &val);
    239	if (ret) {
    240		if (ret == -ENODATA || ret == -EOVERFLOW)
    241			pr_warn("linux,pci-probe-only without valid value, ignoring\n");
    242		return;
    243	}
    244
    245	if (val)
    246		pci_add_flags(PCI_PROBE_ONLY);
    247	else
    248		pci_clear_flags(PCI_PROBE_ONLY);
    249
    250	pr_info("PROBE_ONLY %s\n", val ? "enabled" : "disabled");
    251}
    252EXPORT_SYMBOL_GPL(of_pci_check_probe_only);
    253
    254/**
    255 * devm_of_pci_get_host_bridge_resources() - Resource-managed parsing of PCI
    256 *                                           host bridge resources from DT
    257 * @dev: host bridge device
    258 * @busno: bus number associated with the bridge root bus
    259 * @bus_max: maximum number of buses for this bridge
    260 * @resources: list where the range of resources will be added after DT parsing
    261 * @ib_resources: list where the range of inbound resources (with addresses
    262 *                from 'dma-ranges') will be added after DT parsing
    263 * @io_base: pointer to a variable that will contain on return the physical
    264 * address for the start of the I/O range. Can be NULL if the caller doesn't
    265 * expect I/O ranges to be present in the device tree.
    266 *
    267 * This function will parse the "ranges" property of a PCI host bridge device
    268 * node and setup the resource mapping based on its content. It is expected
    269 * that the property conforms with the Power ePAPR document.
    270 *
    271 * It returns zero if the range parsing has been successful or a standard error
    272 * value if it failed.
    273 */
    274static int devm_of_pci_get_host_bridge_resources(struct device *dev,
    275			unsigned char busno, unsigned char bus_max,
    276			struct list_head *resources,
    277			struct list_head *ib_resources,
    278			resource_size_t *io_base)
    279{
    280	struct device_node *dev_node = dev->of_node;
    281	struct resource *res, tmp_res;
    282	struct resource *bus_range;
    283	struct of_pci_range range;
    284	struct of_pci_range_parser parser;
    285	const char *range_type;
    286	int err;
    287
    288	if (io_base)
    289		*io_base = (resource_size_t)OF_BAD_ADDR;
    290
    291	bus_range = devm_kzalloc(dev, sizeof(*bus_range), GFP_KERNEL);
    292	if (!bus_range)
    293		return -ENOMEM;
    294
    295	dev_info(dev, "host bridge %pOF ranges:\n", dev_node);
    296
    297	err = of_pci_parse_bus_range(dev_node, bus_range);
    298	if (err) {
    299		bus_range->start = busno;
    300		bus_range->end = bus_max;
    301		bus_range->flags = IORESOURCE_BUS;
    302		dev_info(dev, "  No bus range found for %pOF, using %pR\n",
    303			 dev_node, bus_range);
    304	} else {
    305		if (bus_range->end > bus_range->start + bus_max)
    306			bus_range->end = bus_range->start + bus_max;
    307	}
    308	pci_add_resource(resources, bus_range);
    309
    310	/* Check for ranges property */
    311	err = of_pci_range_parser_init(&parser, dev_node);
    312	if (err)
    313		return 0;
    314
    315	dev_dbg(dev, "Parsing ranges property...\n");
    316	for_each_of_pci_range(&parser, &range) {
    317		/* Read next ranges element */
    318		if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
    319			range_type = "IO";
    320		else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
    321			range_type = "MEM";
    322		else
    323			range_type = "err";
    324		dev_info(dev, "  %6s %#012llx..%#012llx -> %#012llx\n",
    325			 range_type, range.cpu_addr,
    326			 range.cpu_addr + range.size - 1, range.pci_addr);
    327
    328		/*
    329		 * If we failed translation or got a zero-sized region
    330		 * then skip this range
    331		 */
    332		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
    333			continue;
    334
    335		err = of_pci_range_to_resource(&range, dev_node, &tmp_res);
    336		if (err)
    337			continue;
    338
    339		res = devm_kmemdup(dev, &tmp_res, sizeof(tmp_res), GFP_KERNEL);
    340		if (!res) {
    341			err = -ENOMEM;
    342			goto failed;
    343		}
    344
    345		if (resource_type(res) == IORESOURCE_IO) {
    346			if (!io_base) {
    347				dev_err(dev, "I/O range found for %pOF. Please provide an io_base pointer to save CPU base address\n",
    348					dev_node);
    349				err = -EINVAL;
    350				goto failed;
    351			}
    352			if (*io_base != (resource_size_t)OF_BAD_ADDR)
    353				dev_warn(dev, "More than one I/O resource converted for %pOF. CPU base address for old range lost!\n",
    354					 dev_node);
    355			*io_base = range.cpu_addr;
    356		} else if (resource_type(res) == IORESOURCE_MEM) {
    357			res->flags &= ~IORESOURCE_MEM_64;
    358		}
    359
    360		pci_add_resource_offset(resources, res,	res->start - range.pci_addr);
    361	}
    362
    363	/* Check for dma-ranges property */
    364	if (!ib_resources)
    365		return 0;
    366	err = of_pci_dma_range_parser_init(&parser, dev_node);
    367	if (err)
    368		return 0;
    369
    370	dev_dbg(dev, "Parsing dma-ranges property...\n");
    371	for_each_of_pci_range(&parser, &range) {
    372		/*
    373		 * If we failed translation or got a zero-sized region
    374		 * then skip this range
    375		 */
    376		if (((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM) ||
    377		    range.cpu_addr == OF_BAD_ADDR || range.size == 0)
    378			continue;
    379
    380		dev_info(dev, "  %6s %#012llx..%#012llx -> %#012llx\n",
    381			 "IB MEM", range.cpu_addr,
    382			 range.cpu_addr + range.size - 1, range.pci_addr);
    383
    384
    385		err = of_pci_range_to_resource(&range, dev_node, &tmp_res);
    386		if (err)
    387			continue;
    388
    389		res = devm_kmemdup(dev, &tmp_res, sizeof(tmp_res), GFP_KERNEL);
    390		if (!res) {
    391			err = -ENOMEM;
    392			goto failed;
    393		}
    394
    395		pci_add_resource_offset(ib_resources, res,
    396					res->start - range.pci_addr);
    397	}
    398
    399	return 0;
    400
    401failed:
    402	pci_free_resource_list(resources);
    403	return err;
    404}
    405
    406#if IS_ENABLED(CONFIG_OF_IRQ)
    407/**
    408 * of_irq_parse_pci - Resolve the interrupt for a PCI device
    409 * @pdev:       the device whose interrupt is to be resolved
    410 * @out_irq:    structure of_phandle_args filled by this function
    411 *
    412 * This function resolves the PCI interrupt for a given PCI device. If a
    413 * device-node exists for a given pci_dev, it will use normal OF tree
    414 * walking. If not, it will implement standard swizzling and walk up the
    415 * PCI tree until an device-node is found, at which point it will finish
    416 * resolving using the OF tree walking.
    417 */
    418static int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq)
    419{
    420	struct device_node *dn, *ppnode = NULL;
    421	struct pci_dev *ppdev;
    422	__be32 laddr[3];
    423	u8 pin;
    424	int rc;
    425
    426	/*
    427	 * Check if we have a device node, if yes, fallback to standard
    428	 * device tree parsing
    429	 */
    430	dn = pci_device_to_OF_node(pdev);
    431	if (dn) {
    432		rc = of_irq_parse_one(dn, 0, out_irq);
    433		if (!rc)
    434			return rc;
    435	}
    436
    437	/*
    438	 * Ok, we don't, time to have fun. Let's start by building up an
    439	 * interrupt spec.  we assume #interrupt-cells is 1, which is standard
    440	 * for PCI. If you do different, then don't use that routine.
    441	 */
    442	rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
    443	if (rc != 0)
    444		goto err;
    445	/* No pin, exit with no error message. */
    446	if (pin == 0)
    447		return -ENODEV;
    448
    449	/* Local interrupt-map in the device node? Use it! */
    450	if (of_get_property(dn, "interrupt-map", NULL)) {
    451		pin = pci_swizzle_interrupt_pin(pdev, pin);
    452		ppnode = dn;
    453	}
    454
    455	/* Now we walk up the PCI tree */
    456	while (!ppnode) {
    457		/* Get the pci_dev of our parent */
    458		ppdev = pdev->bus->self;
    459
    460		/* Ouch, it's a host bridge... */
    461		if (ppdev == NULL) {
    462			ppnode = pci_bus_to_OF_node(pdev->bus);
    463
    464			/* No node for host bridge ? give up */
    465			if (ppnode == NULL) {
    466				rc = -EINVAL;
    467				goto err;
    468			}
    469		} else {
    470			/* We found a P2P bridge, check if it has a node */
    471			ppnode = pci_device_to_OF_node(ppdev);
    472		}
    473
    474		/*
    475		 * Ok, we have found a parent with a device-node, hand over to
    476		 * the OF parsing code.
    477		 * We build a unit address from the linux device to be used for
    478		 * resolution. Note that we use the linux bus number which may
    479		 * not match your firmware bus numbering.
    480		 * Fortunately, in most cases, interrupt-map-mask doesn't
    481		 * include the bus number as part of the matching.
    482		 * You should still be careful about that though if you intend
    483		 * to rely on this function (you ship a firmware that doesn't
    484		 * create device nodes for all PCI devices).
    485		 */
    486		if (ppnode)
    487			break;
    488
    489		/*
    490		 * We can only get here if we hit a P2P bridge with no node;
    491		 * let's do standard swizzling and try again
    492		 */
    493		pin = pci_swizzle_interrupt_pin(pdev, pin);
    494		pdev = ppdev;
    495	}
    496
    497	out_irq->np = ppnode;
    498	out_irq->args_count = 1;
    499	out_irq->args[0] = pin;
    500	laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8));
    501	laddr[1] = laddr[2] = cpu_to_be32(0);
    502	rc = of_irq_parse_raw(laddr, out_irq);
    503	if (rc)
    504		goto err;
    505	return 0;
    506err:
    507	if (rc == -ENOENT) {
    508		dev_warn(&pdev->dev,
    509			"%s: no interrupt-map found, INTx interrupts not available\n",
    510			__func__);
    511		pr_warn_once("%s: possibly some PCI slots don't have level triggered interrupts capability\n",
    512			__func__);
    513	} else {
    514		dev_err(&pdev->dev, "%s: failed with rc=%d\n", __func__, rc);
    515	}
    516	return rc;
    517}
    518
    519/**
    520 * of_irq_parse_and_map_pci() - Decode a PCI IRQ from the device tree and map to a VIRQ
    521 * @dev: The PCI device needing an IRQ
    522 * @slot: PCI slot number; passed when used as map_irq callback. Unused
    523 * @pin: PCI IRQ pin number; passed when used as map_irq callback. Unused
    524 *
    525 * @slot and @pin are unused, but included in the function so that this
    526 * function can be used directly as the map_irq callback to
    527 * pci_assign_irq() and struct pci_host_bridge.map_irq pointer
    528 */
    529int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
    530{
    531	struct of_phandle_args oirq;
    532	int ret;
    533
    534	ret = of_irq_parse_pci(dev, &oirq);
    535	if (ret)
    536		return 0; /* Proper return code 0 == NO_IRQ */
    537
    538	return irq_create_of_mapping(&oirq);
    539}
    540EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
    541#endif	/* CONFIG_OF_IRQ */
    542
    543static int pci_parse_request_of_pci_ranges(struct device *dev,
    544					   struct pci_host_bridge *bridge)
    545{
    546	int err, res_valid = 0;
    547	resource_size_t iobase;
    548	struct resource_entry *win, *tmp;
    549
    550	INIT_LIST_HEAD(&bridge->windows);
    551	INIT_LIST_HEAD(&bridge->dma_ranges);
    552
    553	err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &bridge->windows,
    554						    &bridge->dma_ranges, &iobase);
    555	if (err)
    556		return err;
    557
    558	err = devm_request_pci_bus_resources(dev, &bridge->windows);
    559	if (err)
    560		return err;
    561
    562	resource_list_for_each_entry_safe(win, tmp, &bridge->windows) {
    563		struct resource *res = win->res;
    564
    565		switch (resource_type(res)) {
    566		case IORESOURCE_IO:
    567			err = devm_pci_remap_iospace(dev, res, iobase);
    568			if (err) {
    569				dev_warn(dev, "error %d: failed to map resource %pR\n",
    570					 err, res);
    571				resource_list_destroy_entry(win);
    572			}
    573			break;
    574		case IORESOURCE_MEM:
    575			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
    576
    577			if (!(res->flags & IORESOURCE_PREFETCH))
    578				if (upper_32_bits(resource_size(res)))
    579					dev_warn(dev, "Memory resource size exceeds max for 32 bits\n");
    580
    581			break;
    582		}
    583	}
    584
    585	if (!res_valid)
    586		dev_warn(dev, "non-prefetchable memory resource required\n");
    587
    588	return 0;
    589}
    590
    591int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge)
    592{
    593	if (!dev->of_node)
    594		return 0;
    595
    596	bridge->swizzle_irq = pci_common_swizzle;
    597	bridge->map_irq = of_irq_parse_and_map_pci;
    598
    599	return pci_parse_request_of_pci_ranges(dev, bridge);
    600}
    601
    602#endif /* CONFIG_PCI */
    603
    604/**
    605 * of_pci_get_max_link_speed - Find the maximum link speed of the given device node.
    606 * @node: Device tree node with the maximum link speed information.
    607 *
    608 * This function will try to find the limitation of link speed by finding
    609 * a property called "max-link-speed" of the given device node.
    610 *
    611 * Return:
    612 * * > 0	- On success, a maximum link speed.
    613 * * -EINVAL	- Invalid "max-link-speed" property value, or failure to access
    614 *		  the property of the device tree node.
    615 *
    616 * Returns the associated max link speed from DT, or a negative value if the
    617 * required property is not found or is invalid.
    618 */
    619int of_pci_get_max_link_speed(struct device_node *node)
    620{
    621	u32 max_link_speed;
    622
    623	if (of_property_read_u32(node, "max-link-speed", &max_link_speed) ||
    624	    max_link_speed == 0 || max_link_speed > 4)
    625		return -EINVAL;
    626
    627	return max_link_speed;
    628}
    629EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
    630
    631/**
    632 * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
    633 *				 property.
    634 *
    635 * @node: device tree node with the slot power limit information
    636 * @slot_power_limit_value: pointer where the value should be stored in PCIe
    637 *			    Slot Capabilities Register format
    638 * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
    639 *			    Slot Capabilities Register format
    640 *
    641 * Returns the slot power limit in milliwatts and if @slot_power_limit_value
    642 * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
    643 * scale in format used by PCIe Slot Capabilities Register.
    644 *
    645 * If the property is not found or is invalid, returns 0.
    646 */
    647u32 of_pci_get_slot_power_limit(struct device_node *node,
    648				u8 *slot_power_limit_value,
    649				u8 *slot_power_limit_scale)
    650{
    651	u32 slot_power_limit_mw;
    652	u8 value, scale;
    653
    654	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
    655				 &slot_power_limit_mw))
    656		slot_power_limit_mw = 0;
    657
    658	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
    659	if (slot_power_limit_mw == 0) {
    660		value = 0x00;
    661		scale = 0;
    662	} else if (slot_power_limit_mw <= 255) {
    663		value = slot_power_limit_mw;
    664		scale = 3;
    665	} else if (slot_power_limit_mw <= 255*10) {
    666		value = slot_power_limit_mw / 10;
    667		scale = 2;
    668		slot_power_limit_mw = slot_power_limit_mw / 10 * 10;
    669	} else if (slot_power_limit_mw <= 255*100) {
    670		value = slot_power_limit_mw / 100;
    671		scale = 1;
    672		slot_power_limit_mw = slot_power_limit_mw / 100 * 100;
    673	} else if (slot_power_limit_mw <= 239*1000) {
    674		value = slot_power_limit_mw / 1000;
    675		scale = 0;
    676		slot_power_limit_mw = slot_power_limit_mw / 1000 * 1000;
    677	} else if (slot_power_limit_mw < 250*1000) {
    678		value = 0xEF;
    679		scale = 0;
    680		slot_power_limit_mw = 239*1000;
    681	} else if (slot_power_limit_mw <= 600*1000) {
    682		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
    683		scale = 0;
    684		slot_power_limit_mw = slot_power_limit_mw / (1000*25) * (1000*25);
    685	} else {
    686		value = 0xFE;
    687		scale = 0;
    688		slot_power_limit_mw = 600*1000;
    689	}
    690
    691	if (slot_power_limit_value)
    692		*slot_power_limit_value = value;
    693
    694	if (slot_power_limit_scale)
    695		*slot_power_limit_scale = scale;
    696
    697	return slot_power_limit_mw;
    698}
    699EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);