forked from Minki/linux
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
This commit is contained in:
commit
bc411b8a64
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -416,6 +416,9 @@ static inline bool acpi_driver_match_device(struct device *dev,
|
||||
return !!acpi_match_device(drv->acpi_match_table, dev);
|
||||
}
|
||||
|
||||
int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
|
||||
int acpi_device_modalias(struct device *, char *, int);
|
||||
|
||||
#define ACPI_PTR(_ptr) (_ptr)
|
||||
|
||||
#else /* !CONFIG_ACPI */
|
||||
@ -495,6 +498,18 @@ static inline bool acpi_driver_match_device(struct device *dev,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int acpi_device_uevent_modalias(struct device *dev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int acpi_device_modalias(struct device *dev,
|
||||
char *buf, int size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#define ACPI_PTR(_ptr) (NULL)
|
||||
|
||||
#endif /* !CONFIG_ACPI */
|
||||
|
@ -64,6 +64,12 @@ static inline int of_driver_match_device(struct device *dev,
|
||||
static inline void of_device_uevent(struct device *dev,
|
||||
struct kobj_uevent_env *env) { }
|
||||
|
||||
static inline int of_device_get_modalias(struct device *dev,
|
||||
char *str, ssize_t len)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int of_device_uevent_modalias(struct device *dev,
|
||||
struct kobj_uevent_env *env)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user