From f625d4601759f1cf1fd3ae58abeb0e203b8993b1 Mon Sep 17 00:00:00 2001 From: Benoit Parrot Date: Mon, 2 Feb 2015 11:44:44 -0600 Subject: gpio: add GPIO hogging mechanism Based on Boris Brezillion's work this is a reworked patch of his initial GPIO hogging mechanism. This patch provides a way to initially configure specific GPIO when the GPIO controller is probed. The actual DT scanning to collect the GPIO specific data is performed as part of gpiochip_add(). The purpose of this is to allow specific GPIOs to be configured without any driver specific code. This is particularly useful because board design are getting increasingly complex and given SoC pins can now have more than 10 mux values, a lot of connections are now dependent on external IO muxes to switch various modes. Specific drivers should not necessarily need to be aware of what accounts to a specific board implementation. This board level "description" should be best kept as part of the dts file. Signed-off-by: Benoit Parrot Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/gpio/gpiolib.h') diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 550a5eafbd38..cadba26c45a6 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -78,6 +78,7 @@ struct gpio_desc { #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ #define FLAG_SYSFS_DIR 10 /* show sysfs direction attribute */ +#define FLAG_IS_HOGGED 11 /* GPIO is hogged */ #define ID_SHIFT 16 /* add new flags before this one */ @@ -89,6 +90,8 @@ struct gpio_desc { int gpiod_request(struct gpio_desc *desc, const char *label); void gpiod_free(struct gpio_desc *desc); +int gpiod_hog(struct gpio_desc *desc, const char *name, + unsigned long lflags, enum gpiod_flags dflags); /* * Return the GPIO number of the passed descriptor relative to its chip -- cgit v1.2.3-59-g8ed1b From 7f2e553a7173b485db41a52060f91fb8e5ab1c69 Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Wed, 11 Feb 2015 17:27:55 +0100 Subject: gpiolib: define gpio suffixes globally Avoid multiple identical definitions of the gpio suffix strings by putting them into a global constant array. Signed-off-by: Rojhalat Ibrahim Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 14 ++++++-------- drivers/gpio/gpiolib.h | 3 +++ 2 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers/gpio/gpiolib.h') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 15837263dbb3..2f8296c021e5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1662,19 +1662,18 @@ static struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { - static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ enum of_gpio_flags of_flags; struct gpio_desc *desc; unsigned int i; - for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id) snprintf(prop_name, sizeof(prop_name), "%s-%s", con_id, - suffixes[i]); + gpio_suffixes[i]); else snprintf(prop_name, sizeof(prop_name), "%s", - suffixes[i]); + gpio_suffixes[i]); desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx, &of_flags); @@ -1695,7 +1694,6 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, unsigned int idx, enum gpio_lookup_flags *flags) { - static const char * const suffixes[] = { "gpios", "gpio" }; struct acpi_device *adev = ACPI_COMPANION(dev); struct acpi_gpio_info info; struct gpio_desc *desc; @@ -1703,13 +1701,13 @@ static struct gpio_desc *acpi_find_gpio(struct device *dev, const char *con_id, int i; /* Try first from _DSD */ - for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { if (con_id && strcmp(con_id, "gpios")) { snprintf(propname, sizeof(propname), "%s-%s", - con_id, suffixes[i]); + con_id, gpio_suffixes[i]); } else { snprintf(propname, sizeof(propname), "%s", - suffixes[i]); + gpio_suffixes[i]); } desc = acpi_get_gpiod_by_index(adev, propname, idx, &info); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index cadba26c45a6..205dd12659c0 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -27,6 +27,9 @@ struct acpi_gpio_info { bool active_low; }; +/* gpio suffixes used for ACPI and device tree lookup */ +static const char * const gpio_suffixes[] = { "gpios", "gpio" }; + #ifdef CONFIG_ACPI void acpi_gpiochip_add(struct gpio_chip *chip); void acpi_gpiochip_remove(struct gpio_chip *chip); -- cgit v1.2.3-59-g8ed1b From 668585273246f67b0cdafa30dd2da2047a2e1290 Mon Sep 17 00:00:00 2001 From: Rojhalat Ibrahim Date: Wed, 11 Feb 2015 17:27:58 +0100 Subject: gpiolib: add gpiod_get_array and gpiod_put_array functions Introduce new functions for conveniently obtaining and disposing of an entire array of GPIOs with one function call. ACPI parts tested by Mika Westerberg, DT parts tested by Rojhalat Ibrahim. Change log: v5: move the ACPI functions to gpiolib-acpi.c v4: - use shorter names for members of struct gpio_descs - rename lut_gpio_count to platform_gpio_count for clarity - add check for successful memory allocation - use ERR_CAST() v3: - rebase on current linux-gpio devel branch - fix ACPI GPIO counting - allow for zero-sized arrays - make the flags argument mandatory for the new functions - clarify documentation v2: change interface Suggested-by: Alexandre Courbot Signed-off-by: Rojhalat Ibrahim Reviewed-by: Alexandre Courbot Reviewed-by: Mika Westerberg Tested-by: Mika Westerberg Tested-by: Rojhalat Ibrahim Signed-off-by: Linus Walleij --- Documentation/gpio/consumer.txt | 33 ++++++++- drivers/gpio/gpiolib-acpi.c | 84 +++++++++++++++++++++++ drivers/gpio/gpiolib.c | 145 ++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.h | 7 ++ include/linux/gpio/consumer.h | 46 +++++++++++++ 5 files changed, 312 insertions(+), 3 deletions(-) (limited to 'drivers/gpio/gpiolib.h') diff --git a/Documentation/gpio/consumer.txt b/Documentation/gpio/consumer.txt index d85fbae451ea..2924f2ffcd91 100644 --- a/Documentation/gpio/consumer.txt +++ b/Documentation/gpio/consumer.txt @@ -58,7 +58,6 @@ pattern where a GPIO is optional, the gpiod_get_optional() and gpiod_get_index_optional() functions can be used. These functions return NULL instead of -ENOENT if no GPIO has been assigned to the requested function: - struct gpio_desc *gpiod_get_optional(struct device *dev, const char *con_id, enum gpiod_flags flags) @@ -68,6 +67,27 @@ instead of -ENOENT if no GPIO has been assigned to the requested function: unsigned int index, enum gpiod_flags flags) +For a function using multiple GPIOs all of those can be obtained with one call: + + struct gpio_descs *gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + +This function returns a struct gpio_descs which contains an array of +descriptors: + + struct gpio_descs { + unsigned int ndescs; + struct gpio_desc *desc[]; + } + +The following function returns NULL instead of -ENOENT if no GPIOs have been +assigned to the requested function: + + struct gpio_descs *gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) + Device-managed variants of these functions are also defined: struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id, @@ -91,8 +111,15 @@ A GPIO descriptor can be disposed of using the gpiod_put() function: void gpiod_put(struct gpio_desc *desc) -It is strictly forbidden to use a descriptor after calling this function. The -device-managed variant is, unsurprisingly: +For an array of GPIOs this function can be used: + + void gpiod_put_array(struct gpio_descs *descs) + +It is strictly forbidden to use a descriptor after calling these functions. +It is also not allowed to individually release descriptors (using gpiod_put()) +from an array acquired with gpiod_get_array(). + +The device-managed variant is, unsurprisingly: void devm_gpiod_put(struct device *dev, struct gpio_desc *desc) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index c0929d938ced..c4919966453d 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -712,3 +712,87 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) acpi_detach_data(handle, acpi_gpio_chip_dh); kfree(acpi_gpio); } + +static unsigned int acpi_gpio_package_count(const union acpi_object *obj) +{ + const union acpi_object *element = obj->package.elements; + const union acpi_object *end = element + obj->package.count; + unsigned int count = 0; + + while (element < end) { + if (element->type == ACPI_TYPE_LOCAL_REFERENCE) + count++; + + element++; + } + return count; +} + +static int acpi_find_gpio_count(struct acpi_resource *ares, void *data) +{ + unsigned int *count = data; + + if (ares->type == ACPI_RESOURCE_TYPE_GPIO) + *count += ares->data.gpio.pin_table_length; + + return 1; +} + +/** + * acpi_gpio_count - return the number of GPIOs associated with a + * device / function or -ENOENT if no GPIO has been + * assigned to the requested function. + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + */ +int acpi_gpio_count(struct device *dev, const char *con_id) +{ + struct acpi_device *adev = ACPI_COMPANION(dev); + const union acpi_object *obj; + const struct acpi_gpio_mapping *gm; + int count = -ENOENT; + int ret; + char propname[32]; + unsigned int i; + + /* Try first from _DSD */ + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { + if (con_id && strcmp(con_id, "gpios")) + snprintf(propname, sizeof(propname), "%s-%s", + con_id, gpio_suffixes[i]); + else + snprintf(propname, sizeof(propname), "%s", + gpio_suffixes[i]); + + ret = acpi_dev_get_property(adev, propname, ACPI_TYPE_ANY, + &obj); + if (ret == 0) { + if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) + count = 1; + else if (obj->type == ACPI_TYPE_PACKAGE) + count = acpi_gpio_package_count(obj); + } else if (adev->driver_gpios) { + for (gm = adev->driver_gpios; gm->name; gm++) + if (strcmp(propname, gm->name) == 0) { + count = gm->size; + break; + } + } + if (count >= 0) + break; + } + + /* Then from plain _CRS GPIOs */ + if (count < 0) { + struct list_head resource_list; + unsigned int crs_count = 0; + + INIT_LIST_HEAD(&resource_list); + acpi_dev_get_resources(adev, &resource_list, + acpi_find_gpio_count, &crs_count); + acpi_dev_free_resource_list(&resource_list); + if (crs_count > 0) + count = crs_count; + } + return count; +} diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 2f8296c021e5..3d5b85a7dcdf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1806,6 +1806,70 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id, return desc; } +static int dt_gpio_count(struct device *dev, const char *con_id) +{ + int ret; + char propname[32]; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) { + if (con_id) + snprintf(propname, sizeof(propname), "%s-%s", + con_id, gpio_suffixes[i]); + else + snprintf(propname, sizeof(propname), "%s", + gpio_suffixes[i]); + + ret = of_gpio_named_count(dev->of_node, propname); + if (ret >= 0) + break; + } + return ret; +} + +static int platform_gpio_count(struct device *dev, const char *con_id) +{ + struct gpiod_lookup_table *table; + struct gpiod_lookup *p; + unsigned int count = 0; + + table = gpiod_find_lookup_table(dev); + if (!table) + return -ENOENT; + + for (p = &table->table[0]; p->chip_label; p++) { + if ((con_id && p->con_id && !strcmp(con_id, p->con_id)) || + (!con_id && !p->con_id)) + count++; + } + if (!count) + return -ENOENT; + + return count; +} + +/** + * gpiod_count - return the number of GPIOs associated with a device / function + * or -ENOENT if no GPIO has been assigned to the requested function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + */ +int gpiod_count(struct device *dev, const char *con_id) +{ + int count = -ENOENT; + + if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node) + count = dt_gpio_count(dev, con_id); + else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev)) + count = acpi_gpio_count(dev, con_id); + + if (count < 0) + count = platform_gpio_count(dev, con_id); + + return count; +} +EXPORT_SYMBOL_GPL(gpiod_count); + /** * gpiod_get - obtain a GPIO for a given GPIO function * @dev: GPIO consumer, can be NULL for system-global GPIOs @@ -2089,6 +2153,72 @@ static void gpiochip_free_hogs(struct gpio_chip *chip) } } +/** + * gpiod_get_array - obtain multiple GPIOs from a multi-index GPIO function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * This function acquires all the GPIOs defined under a given function. + * + * Return a struct gpio_descs containing an array of descriptors, -ENOENT if + * no GPIO has been assigned to the requested function, or another IS_ERR() + * code if an error occurred while trying to acquire the GPIOs. + */ +struct gpio_descs *__must_check gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_desc *desc; + struct gpio_descs *descs; + int count; + + count = gpiod_count(dev, con_id); + if (count < 0) + return ERR_PTR(count); + + descs = kzalloc(sizeof(*descs) + sizeof(descs->desc[0]) * count, + GFP_KERNEL); + if (!descs) + return ERR_PTR(-ENOMEM); + + for (descs->ndescs = 0; descs->ndescs < count; ) { + desc = gpiod_get_index(dev, con_id, descs->ndescs, flags); + if (IS_ERR(desc)) { + gpiod_put_array(descs); + return ERR_CAST(desc); + } + descs->desc[descs->ndescs] = desc; + descs->ndescs++; + } + return descs; +} +EXPORT_SYMBOL_GPL(gpiod_get_array); + +/** + * gpiod_get_array_optional - obtain multiple GPIOs from a multi-index GPIO + * function + * @dev: GPIO consumer, can be NULL for system-global GPIOs + * @con_id: function within the GPIO consumer + * @flags: optional GPIO initialization flags + * + * This is equivalent to gpiod_get_array(), except that when no GPIO was + * assigned to the requested function it will return NULL. + */ +struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags) +{ + struct gpio_descs *descs; + + descs = gpiod_get_array(dev, con_id, flags); + if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT)) + return NULL; + + return descs; +} +EXPORT_SYMBOL_GPL(gpiod_get_array_optional); + /** * gpiod_put - dispose of a GPIO descriptor * @desc: GPIO descriptor to dispose of @@ -2101,6 +2231,21 @@ void gpiod_put(struct gpio_desc *desc) } EXPORT_SYMBOL_GPL(gpiod_put); +/** + * gpiod_put_array - dispose of multiple GPIO descriptors + * @descs: struct gpio_descs containing an array of descriptors + */ +void gpiod_put_array(struct gpio_descs *descs) +{ + unsigned int i; + + for (i = 0; i < descs->ndescs; i++) + gpiod_put(descs->desc[i]); + + kfree(descs); +} +EXPORT_SYMBOL_GPL(gpiod_put_array); + #ifdef CONFIG_DEBUG_FS static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip) diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 205dd12659c0..54bc5ec91398 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -40,6 +40,8 @@ void acpi_gpiochip_free_interrupts(struct gpio_chip *chip); struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, int index, struct acpi_gpio_info *info); + +int acpi_gpio_count(struct device *dev, const char *con_id); #else static inline void acpi_gpiochip_add(struct gpio_chip *chip) { } static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { } @@ -56,6 +58,11 @@ acpi_get_gpiod_by_index(struct acpi_device *adev, const char *propname, { return ERR_PTR(-ENOSYS); } + +static inline int acpi_gpio_count(struct device *dev, const char *con_id) +{ + return -ENODEV; +} #endif struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np, diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index ed20759229eb..33eb52fd0932 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -16,6 +16,15 @@ struct device; */ struct gpio_desc; +/** + * Struct containing an array of descriptors that can be obtained using + * gpiod_get_array(). + */ +struct gpio_descs { + unsigned int ndescs; + struct gpio_desc *desc[]; +}; + #define GPIOD_FLAGS_BIT_DIR_SET BIT(0) #define GPIOD_FLAGS_BIT_DIR_OUT BIT(1) #define GPIOD_FLAGS_BIT_DIR_VAL BIT(2) @@ -34,6 +43,9 @@ enum gpiod_flags { #ifdef CONFIG_GPIOLIB +/* Return the number of GPIOs associated with a device / function */ +int gpiod_count(struct device *dev, const char *con_id); + /* Acquire and dispose GPIOs */ struct gpio_desc *__must_check __gpiod_get(struct device *dev, const char *con_id, @@ -49,7 +61,14 @@ struct gpio_desc *__must_check __gpiod_get_index_optional(struct device *dev, const char *con_id, unsigned int index, enum gpiod_flags flags); +struct gpio_descs *__must_check gpiod_get_array(struct device *dev, + const char *con_id, + enum gpiod_flags flags); +struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev, + const char *con_id, + enum gpiod_flags flags); void gpiod_put(struct gpio_desc *desc); +void gpiod_put_array(struct gpio_descs *descs); struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev, const char *con_id, @@ -114,6 +133,11 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, struct fwnode_handle *child); #else /* CONFIG_GPIOLIB */ +static inline int gpiod_count(struct device *dev, const char *con_id) +{ + return 0; +} + static inline struct gpio_desc *__must_check __gpiod_get(struct device *dev, const char *con_id, enum gpiod_flags flags) @@ -143,6 +167,20 @@ __gpiod_get_index_optional(struct device *dev, const char *con_id, return ERR_PTR(-ENOSYS); } +static inline struct gpio_descs *__must_check +gpiod_get_array(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + +static inline struct gpio_descs *__must_check +gpiod_get_array_optional(struct device *dev, const char *con_id, + enum gpiod_flags flags) +{ + return ERR_PTR(-ENOSYS); +} + static inline void gpiod_put(struct gpio_desc *desc) { might_sleep(); @@ -151,6 +189,14 @@ static inline void gpiod_put(struct gpio_desc *desc) WARN_ON(1); } +static inline void gpiod_put_array(struct gpio_descs *descs) +{ + might_sleep(); + + /* GPIO can never have been requested */ + WARN_ON(1); +} + static inline struct gpio_desc *__must_check __devm_gpiod_get(struct device *dev, const char *con_id, -- cgit v1.2.3-59-g8ed1b From ce793486e23e0162a732c605189c8028e0910e86 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 16 Mar 2015 23:49:03 +0100 Subject: driver core / ACPI: Represent ACPI companions using fwnode_handle Now that we have struct fwnode_handle, we can use that to point to ACPI companions from struct device objects instead of pointing to struct acpi_device directly. There are two benefits from that. First, the somewhat ugly and hackish struct acpi_dev_node can be dropped and, second, the same struct fwnode_handle pointer can be used in the future to point to other (non-ACPI) firmware device node types. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Acked-by: Grant Likely --- drivers/acpi/acpi_platform.c | 2 +- drivers/acpi/dock.c | 2 +- drivers/base/platform.c | 2 +- drivers/gpio/gpiolib.h | 2 ++ drivers/i2c/i2c-core.c | 4 ++-- include/acpi/acpi_bus.h | 3 ++- include/linux/acpi.h | 5 +++-- include/linux/device.h | 13 +++---------- include/linux/fwnode.h | 25 +++++++++++++++++++++++++ include/linux/i2c.h | 4 ++-- include/linux/platform_device.h | 2 +- include/linux/property.h | 11 +---------- 12 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 include/linux/fwnode.h (limited to 'drivers/gpio/gpiolib.h') diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1284138e42ab..4bf75597f732 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -102,7 +102,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev) pdevinfo.id = -1; pdevinfo.res = resources; pdevinfo.num_res = count; - pdevinfo.acpi_node.companion = adev; + pdevinfo.fwnode = acpi_fwnode_handle(adev); pdevinfo.dma_mask = DMA_BIT_MASK(32); pdev = platform_device_register_full(&pdevinfo); if (IS_ERR(pdev)) diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index d9339b442a4e..a688aa243f6c 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -615,7 +615,7 @@ void acpi_dock_add(struct acpi_device *adev) memset(&pdevinfo, 0, sizeof(pdevinfo)); pdevinfo.name = "dock"; pdevinfo.id = dock_station_count; - pdevinfo.acpi_node.companion = adev; + pdevinfo.fwnode = acpi_fwnode_handle(adev); pdevinfo.data = &ds; pdevinfo.size_data = sizeof(ds); dd = platform_device_register_full(&pdevinfo); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 9421fed40905..17f0204fabef 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -454,7 +454,7 @@ struct platform_device *platform_device_register_full( goto err_alloc; pdev->dev.parent = pdevinfo->parent; - ACPI_COMPANION_SET(&pdev->dev, pdevinfo->acpi_node.companion); + pdev->dev.fwnode = pdevinfo->fwnode; if (pdevinfo->dma_mask) { /* diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index 550a5eafbd38..ab892be26dc2 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -17,6 +17,8 @@ enum of_gpio_flags; +struct acpi_device; + /** * struct acpi_gpio_info - ACPI GPIO specific information * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index edf274cabe81..c87c31387e2d 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -133,7 +133,7 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, return AE_OK; memset(&info, 0, sizeof(info)); - info.acpi_node.companion = adev; + info.fwnode = acpi_fwnode_handle(adev); info.irq = -1; INIT_LIST_HEAD(&resource_list); @@ -971,7 +971,7 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.bus = &i2c_bus_type; client->dev.type = &i2c_client_type; client->dev.of_node = info->of_node; - ACPI_COMPANION_SET(&client->dev, info->acpi_node.companion); + client->dev.fwnode = info->fwnode; i2c_dev_set_name(adap, client); status = device_register(&client->dev); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 61e32ec1fc4d..dae2a16fe93f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -386,7 +386,8 @@ static inline bool is_acpi_node(struct fwnode_handle *fwnode) static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode) { - return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL; + return is_acpi_node(fwnode) ? + container_of(fwnode, struct acpi_device, fwnode) : NULL; } static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 24c7aa8b1d20..402ddbdc2da1 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -53,8 +53,9 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) return adev ? adev->handle : NULL; } -#define ACPI_COMPANION(dev) ((dev)->acpi_node.companion) -#define ACPI_COMPANION_SET(dev, adev) ACPI_COMPANION(dev) = (adev) +#define ACPI_COMPANION(dev) acpi_node((dev)->fwnode) +#define ACPI_COMPANION_SET(dev, adev) (dev)->fwnode = (adev) ? \ + acpi_fwnode_handle(adev) : NULL #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) static inline void acpi_preset_companion(struct device *dev, diff --git a/include/linux/device.h b/include/linux/device.h index 0eb8ee2dc6d1..badef20b876a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -38,6 +38,7 @@ struct class; struct subsys_private; struct bus_type; struct device_node; +struct fwnode_handle; struct iommu_ops; struct iommu_group; @@ -650,14 +651,6 @@ struct device_dma_parameters { unsigned long segment_boundary_mask; }; -struct acpi_device; - -struct acpi_dev_node { -#ifdef CONFIG_ACPI - struct acpi_device *companion; -#endif -}; - /** * struct device - The basic device structure * @parent: The device's "parent" device, the device to which it is attached. @@ -703,7 +696,7 @@ struct acpi_dev_node { * @cma_area: Contiguous memory area for dma allocations * @archdata: For arch-specific additions. * @of_node: Associated device tree node. - * @acpi_node: Associated ACPI device node. + * @fwnode: Associated device node supplied by platform firmware. * @devt: For creating the sysfs "dev". * @id: device instance * @devres_lock: Spinlock to protect the resource of the device. @@ -779,7 +772,7 @@ struct device { struct dev_archdata archdata; struct device_node *of_node; /* associated device tree node */ - struct acpi_dev_node acpi_node; /* associated ACPI device node */ + struct fwnode_handle *fwnode; /* firmware device node */ dev_t devt; /* dev_t, creates the sysfs "dev" */ u32 id; /* device instance */ diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h new file mode 100644 index 000000000000..17bb5f039509 --- /dev/null +++ b/include/linux/fwnode.h @@ -0,0 +1,25 @@ +/* + * fwnode.h - Firmware device node object handle type definition. + * + * Copyright (C) 2015, Intel Corporation + * Author: Rafael J. Wysocki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef _LINUX_FWNODE_H_ +#define _LINUX_FWNODE_H_ + +enum fwnode_type { + FWNODE_INVALID = 0, + FWNODE_OF, + FWNODE_ACPI, +}; + +struct fwnode_handle { + enum fwnode_type type; +}; + +#endif diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f17da50402a4..6d89575361a8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -278,7 +278,7 @@ static inline int i2c_slave_event(struct i2c_client *client, * @platform_data: stored in i2c_client.dev.platform_data * @archdata: copied into i2c_client.dev.archdata * @of_node: pointer to OpenFirmware device node - * @acpi_node: ACPI device node + * @fwnode: device node supplied by the platform firmware * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and @@ -299,7 +299,7 @@ struct i2c_board_info { void *platform_data; struct dev_archdata *archdata; struct device_node *of_node; - struct acpi_dev_node acpi_node; + struct fwnode_handle *fwnode; int irq; }; diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index ae4882ca4a64..58f1e75ba105 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -59,7 +59,7 @@ extern int platform_add_devices(struct platform_device **, int); struct platform_device_info { struct device *parent; - struct acpi_dev_node acpi_node; + struct fwnode_handle *fwnode; const char *name; int id; diff --git a/include/linux/property.h b/include/linux/property.h index a6a3d98bd7e9..31dfd3db35d6 100644 --- a/include/linux/property.h +++ b/include/linux/property.h @@ -13,6 +13,7 @@ #ifndef _LINUX_PROPERTY_H_ #define _LINUX_PROPERTY_H_ +#include #include struct device; @@ -40,16 +41,6 @@ int device_property_read_string_array(struct device *dev, const char *propname, int device_property_read_string(struct device *dev, const char *propname, const char **val); -enum fwnode_type { - FWNODE_INVALID = 0, - FWNODE_OF, - FWNODE_ACPI, -}; - -struct fwnode_handle { - enum fwnode_type type; -}; - bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname); int fwnode_property_read_u8_array(struct fwnode_handle *fwnode, const char *propname, u8 *val, -- cgit v1.2.3-59-g8ed1b