Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

Merge branch 'acpi-modules'

* acpi-modules:
  platform: introduce OF style 'modalias' support for platform bus
  ACPI: fix module autoloading for ACPI enumerated devices
  ACPI: add module autoloading support for ACPI enumerated devices
  ACPI: fix create_modalias() return value handling
parents 8341ecc9 b9f73067
Loading
Loading
Loading
Loading
+67 −6
Original line number Diff line number Diff line
@@ -86,6 +86,9 @@ int acpi_scan_add_handler_with_hotplug(struct acpi_scan_handler *handler,
 * Creates hid/cid(s) string needed for modalias and uevent
 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
 * char *modalias: "acpi:IBM0001:ACPI0001"
 * Return: 0: no _HID and no _CID
 *         -EINVAL: output error
 *         -ENOMEM: output is truncated
*/
static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
			   int size)
@@ -102,8 +105,10 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,

	list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
		count = snprintf(&modalias[len], size, "%s:", id->id);
		if (count < 0 || count >= size)
			return -EINVAL;
		if (count < 0)
			return EINVAL;
		if (count >= size)
			return -ENOMEM;
		len += count;
		size -= count;
	}
@@ -112,15 +117,71 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
	return len;
}

/*
 * Creates uevent modalias field for ACPI enumerated devices.
 * Because the other buses does not support ACPI HIDs & CIDs.
 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
 * "acpi:IBM0001:ACPI0001"
 */
int acpi_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env)
{
	struct acpi_device *acpi_dev;
	int len;

	acpi_dev = ACPI_COMPANION(dev);
	if (!acpi_dev)
		return -ENODEV;

	/* Fall back to bus specific way of modalias exporting */
	if (list_empty(&acpi_dev->pnp.ids))
		return -ENODEV;

	if (add_uevent_var(env, "MODALIAS="))
		return -ENOMEM;
	len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
				sizeof(env->buf) - env->buflen);
	if (len <= 0)
		return len;
	env->buflen += len;
	return 0;
}
EXPORT_SYMBOL_GPL(acpi_device_uevent_modalias);

/*
 * Creates modalias sysfs attribute for ACPI enumerated devices.
 * Because the other buses does not support ACPI HIDs & CIDs.
 * e.g. for a device with hid:IBM0001 and cid:ACPI0001 you get:
 * "acpi:IBM0001:ACPI0001"
 */
int acpi_device_modalias(struct device *dev, char *buf, int size)
{
	struct acpi_device *acpi_dev;
	int len;

	acpi_dev = ACPI_COMPANION(dev);
	if (!acpi_dev)
		return -ENODEV;

	/* Fall back to bus specific way of modalias exporting */
	if (list_empty(&acpi_dev->pnp.ids))
		return -ENODEV;

	len = create_modalias(acpi_dev, buf, size -1);
	if (len <= 0)
		return len;
	buf[len++] = '\n';
	return len;
}
EXPORT_SYMBOL_GPL(acpi_device_modalias);

static ssize_t
acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, char *buf) {
	struct acpi_device *acpi_dev = to_acpi_device(dev);
	int len;

	/* Device has no HID and no CID or string is >1024 */
	len = create_modalias(acpi_dev, buf, 1024);
	if (len <= 0)
		return 0;
		return len;
	buf[len++] = '\n';
	return len;
}
@@ -839,8 +900,8 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
		return -ENOMEM;
	len = create_modalias(acpi_dev, &env->buf[env->buflen - 1],
			      sizeof(env->buf) - env->buflen);
	if (len >= (sizeof(env->buf) - env->buflen))
		return -ENOMEM;
	if (len <= 0)
		return len;
	env->buflen += len;
	return 0;
}
+15 −1
Original line number Diff line number Diff line
@@ -677,7 +677,17 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
			     char *buf)
{
	struct platform_device	*pdev = to_platform_device(dev);
	int len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);
	int len;

	len = of_device_get_modalias(dev, buf, PAGE_SIZE -1);
	if (len != -ENODEV)
		return len;

	len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
	if (len != -ENODEV)
		return len;

	len = snprintf(buf, PAGE_SIZE, "platform:%s\n", pdev->name);

	return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
}
@@ -699,6 +709,10 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
	if (rc != -ENODEV)
		return rc;

	rc = acpi_device_uevent_modalias(dev, env);
	if (rc != -ENODEV)
		return rc;

	add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
			pdev->name);
	return 0;
+11 −0
Original line number Diff line number Diff line
@@ -104,6 +104,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
static int i2c_device_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct i2c_client	*client = to_i2c_client(dev);
	int rc;

	rc = acpi_device_uevent_modalias(dev, env);
	if (rc != -ENODEV)
		return rc;

	if (add_uevent_var(env, "MODALIAS=%s%s",
			   I2C_MODULE_PREFIX, client->name))
@@ -409,6 +414,12 @@ static ssize_t
show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	int len;

	len = acpi_device_modalias(dev, buf, PAGE_SIZE -1);
	if (len != -ENODEV)
		return len;

	return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
}

+3 −0
Original line number Diff line number Diff line
@@ -85,6 +85,9 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len)
	int cplen, i;
	ssize_t tsize, csize, repend;

	if ((!dev) || (!dev->of_node))
		return -ENODEV;

	/* Name & Type */
	csize = snprintf(str, len, "of:N%sT%s", dev->of_node->name,
			 dev->of_node->type);
+10 −0
Original line number Diff line number Diff line
@@ -58,6 +58,11 @@ static ssize_t
modalias_show(struct device *dev, struct device_attribute *a, char *buf)
{
	const struct spi_device	*spi = to_spi_device(dev);
	int len;

	len = acpi_device_modalias(dev, buf, PAGE_SIZE - 1);
	if (len != -ENODEV)
		return len;

	return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias);
}
@@ -114,6 +119,11 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
static int spi_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	const struct spi_device		*spi = to_spi_device(dev);
	int rc;

	rc = acpi_device_uevent_modalias(dev, env);
	if (rc != -ENODEV)
		return rc;

	add_uevent_var(env, "MODALIAS=%s%s", SPI_MODULE_PREFIX, spi->modalias);
	return 0;
Loading