Commit a4738105 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'i2c/alert-for-acpi' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux

Pull i2c material for 5.18 that is depended on by subsequent device
properties changes.

* 'i2c/alert-for-acpi' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux:
  i2c: smbus: Use device_*() functions instead of of_*()
  docs: firmware-guide: ACPI: Add named interrupt doc
  device property: Add fwnode_irq_get_byname
parents 754e0b0e a263a840
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -143,6 +143,45 @@ In robust cases the client unfortunately needs to call
acpi_dma_request_slave_chan_by_index() directly and therefore choose the
specific FixedDMA resource by its index.

Named Interrupts
================

Drivers enumerated via ACPI can have names to interrupts in the ACPI table
which can be used to get the IRQ number in the driver.

The interrupt name can be listed in _DSD as 'interrupt-names'. The names
should be listed as an array of strings which will map to the Interrupt()
resource in the ACPI table corresponding to its index.

The table below shows an example of its usage::

    Device (DEV0) {
        ...
        Name (_CRS, ResourceTemplate() {
            ...
            Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) {
                0x20,
                0x24
            }
        })

        Name (_DSD, Package () {
            ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
            Package () {
                Package () {"interrupt-names",
                Package (2) {"default", "alert"}},
            }
        ...
        })
    }

The interrupt name 'default' will correspond to 0x20 in Interrupt()
resource and 'alert' to 0x24. Note that only the Interrupt() resource
is mapped and not GpioInt() or similar.

The driver can call the function - fwnode_irq_get_byname() with the fwnode
and interrupt name as arguments to get the corresponding IRQ number.

SPI serial bus support
======================

+29 −0
Original line number Diff line number Diff line
@@ -935,6 +935,35 @@ void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index)
}
EXPORT_SYMBOL(fwnode_iomap);

/**
 * fwnode_irq_get_byname - Get IRQ from a fwnode using its name
 * @fwnode:	Pointer to the firmware node
 * @name:	IRQ name
 *
 * Description:
 * Find a match to the string @name in the 'interrupt-names' string array
 * in _DSD for ACPI, or of_node for Device Tree. Then get the Linux IRQ
 * number of the IRQ resource corresponding to the index of the matched
 * string.
 *
 * Return:
 * Linux IRQ number on success, or negative errno otherwise.
 */
int fwnode_irq_get_byname(const struct fwnode_handle *fwnode, const char *name)
{
	int index;

	if (!name)
		return -EINVAL;

	index = fwnode_property_match_string(fwnode, "interrupt-names",  name);
	if (index < 0)
		return index;

	return fwnode_irq_get(fwnode, index);
}
EXPORT_SYMBOL(fwnode_irq_get_byname);

/**
 * fwnode_graph_get_next_endpoint - Get next endpoint firmware node
 * @fwnode: Pointer to the parent firmware node
+1 −1
Original line number Diff line number Diff line
@@ -1479,7 +1479,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
		goto out_list;
	}

	res = of_i2c_setup_smbus_alert(adap);
	res = i2c_setup_smbus_alert(adap);
	if (res)
		goto out_reg;

+6 −5
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/property.h>
#include <linux/slab.h>

#include "i2c-core.h"
@@ -701,12 +702,12 @@ struct i2c_client *i2c_new_smbus_alert_device(struct i2c_adapter *adapter,
}
EXPORT_SYMBOL_GPL(i2c_new_smbus_alert_device);

#if IS_ENABLED(CONFIG_I2C_SMBUS) && IS_ENABLED(CONFIG_OF)
int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter)
#if IS_ENABLED(CONFIG_I2C_SMBUS)
int i2c_setup_smbus_alert(struct i2c_adapter *adapter)
{
	int irq;

	irq = of_property_match_string(adapter->dev.of_node, "interrupt-names",
	irq = device_property_match_string(adapter->dev.parent, "interrupt-names",
					   "smbus_alert");
	if (irq == -EINVAL || irq == -ENODATA)
		return 0;
@@ -715,5 +716,5 @@ int of_i2c_setup_smbus_alert(struct i2c_adapter *adapter)

	return PTR_ERR_OR_ZERO(i2c_new_smbus_alert_device(adapter, NULL));
}
EXPORT_SYMBOL_GPL(of_i2c_setup_smbus_alert);
EXPORT_SYMBOL_GPL(i2c_setup_smbus_alert);
#endif
+3 −2
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/workqueue.h>

@@ -128,7 +128,8 @@ static int smbalert_probe(struct i2c_client *ara,
	if (setup) {
		irq = setup->irq;
	} else {
		irq = of_irq_get_byname(adapter->dev.of_node, "smbus_alert");
		irq = fwnode_irq_get_byname(dev_fwnode(adapter->dev.parent),
					    "smbus_alert");
		if (irq <= 0)
			return irq;
	}
Loading