diff options
| author | Tom Rini <[email protected]> | 2021-10-05 17:16:23 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2021-10-05 17:16:23 -0400 |
| commit | 7240e1b8f94a56db88a2af688cad27e2e6545302 (patch) | |
| tree | 00e07de1f4b83cf96f183b881e80cd273dabd892 /drivers | |
| parent | 50c84208ad50a27382c64af911abba4510a8b608 (diff) | |
| parent | c3ef4550a2c439e9726205769d4381ed7e7fbc3d (diff) | |
Merge branch '2021-10-05-general-updates'
- Assorted OPTEE cleanups
- pinctrl, gpio improvements, assorted livetree migrations
- Assorted pytest improvements
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/demo/demo-uclass.c | 9 | ||||
| -rw-r--r-- | drivers/gpio/gpio-uclass.c | 55 | ||||
| -rw-r--r-- | drivers/pinctrl/pinctrl-single.c | 86 | ||||
| -rw-r--r-- | drivers/reboot-mode/reboot-mode-uclass.c | 20 | ||||
| -rw-r--r-- | drivers/remoteproc/rproc-uclass.c | 16 |
5 files changed, 130 insertions, 56 deletions
diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c index 815f8de6453..09f9a47d4de 100644 --- a/drivers/demo/demo-uclass.c +++ b/drivers/demo/demo-uclass.c @@ -10,15 +10,11 @@ #include <dm.h> #include <dm-demo.h> #include <errno.h> -#include <fdtdec.h> #include <log.h> #include <malloc.h> -#include <asm/global_data.h> #include <asm/io.h> #include <linux/list.h> -DECLARE_GLOBAL_DATA_PTR; - UCLASS_DRIVER(demo) = { .name = "demo", .id = UCLASS_DEMO, @@ -67,10 +63,9 @@ int demo_set_light(struct udevice *dev, int light) int demo_parse_dt(struct udevice *dev) { struct dm_demo_pdata *pdata = dev_get_plat(dev); - int dn = dev_of_offset(dev); - pdata->sides = fdtdec_get_int(gd->fdt_blob, dn, "sides", 0); - pdata->colour = fdt_getprop(gd->fdt_blob, dn, "colour", NULL); + pdata->sides = dev_read_s32_default(dev, "sides", 0); + pdata->colour = dev_read_string(dev, "colour"); if (!pdata->sides || !pdata->colour) { debug("%s: Invalid device tree data\n", __func__); return -EINVAL; diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index bb2f23241ed..1c5e2e79766 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -141,7 +141,8 @@ int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc) if (!strncasecmp(name, uc_priv->bank_name, len)) { if (!strict_strtoul(name + len, 10, &offset)) - break; + if (offset < uc_priv->gpio_count) + break; } /* @@ -185,38 +186,50 @@ int gpio_lookup_name(const char *name, struct udevice **devp, return 0; } -int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc, - struct ofnode_phandle_args *args) +unsigned long gpio_flags_xlate(uint32_t arg) { - if (args->args_count < 1) - return -EINVAL; - - desc->offset = args->args[0]; + unsigned long flags = 0; - if (args->args_count < 2) - return 0; - - desc->flags = 0; - if (args->args[1] & GPIO_ACTIVE_LOW) - desc->flags |= GPIOD_ACTIVE_LOW; + if (arg & GPIO_ACTIVE_LOW) + flags |= GPIOD_ACTIVE_LOW; /* * need to test 2 bits for gpio output binding: * OPEN_DRAIN (0x6) = SINGLE_ENDED (0x2) | LINE_OPEN_DRAIN (0x4) * OPEN_SOURCE (0x2) = SINGLE_ENDED (0x2) | LINE_OPEN_SOURCE (0x0) */ - if (args->args[1] & GPIO_SINGLE_ENDED) { - if (args->args[1] & GPIO_LINE_OPEN_DRAIN) - desc->flags |= GPIOD_OPEN_DRAIN; + if (arg & GPIO_SINGLE_ENDED) { + if (arg & GPIO_LINE_OPEN_DRAIN) + flags |= GPIOD_OPEN_DRAIN; else - desc->flags |= GPIOD_OPEN_SOURCE; + flags |= GPIOD_OPEN_SOURCE; } - if (args->args[1] & GPIO_PULL_UP) - desc->flags |= GPIOD_PULL_UP; + if (arg & GPIO_PULL_UP) + flags |= GPIOD_PULL_UP; + + if (arg & GPIO_PULL_DOWN) + flags |= GPIOD_PULL_DOWN; + + return flags; +} + +int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + if (args->args_count < 1) + return -EINVAL; + + desc->offset = args->args[0]; + if (desc->offset >= uc_priv->gpio_count) + return -EINVAL; + + if (args->args_count < 2) + return 0; - if (args->args[1] & GPIO_PULL_DOWN) - desc->flags |= GPIOD_PULL_DOWN; + desc->flags = gpio_flags_xlate(args->args[1]); return 0; } diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index cf9ad3670f6..8fc07e34986 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -8,6 +8,7 @@ #include <dm.h> #include <dm/device_compat.h> #include <dm/devres.h> +#include <dm/of_access.h> #include <dm/pinctrl.h> #include <linux/libfdt.h> #include <linux/list.h> @@ -45,10 +46,26 @@ struct single_func { }; /** + * struct single_gpiofunc_range - pin ranges with same mux value of gpio fun + * @offset: offset base of pins + * @npins: number pins with the same mux value of gpio function + * @gpiofunc: mux value of gpio function + * @node: list node + */ +struct single_gpiofunc_range { + u32 offset; + u32 npins; + u32 gpiofunc; + struct list_head node; +}; + +/** * struct single_priv - private data * @bits_per_pin: number of bits per pin * @npins: number of selectable pins * @pin_name: temporary buffer to store the pin name + * @functions: list pin functions + * @gpiofuncs: list gpio functions */ struct single_priv { #if (IS_ENABLED(CONFIG_SANDBOX)) @@ -58,6 +75,7 @@ struct single_priv { unsigned int npins; char pin_name[PINNAME_SIZE]; struct list_head functions; + struct list_head gpiofuncs; }; /** @@ -232,6 +250,39 @@ static int single_get_pin_muxing(struct udevice *dev, unsigned int pin, return 0; } +static int single_request(struct udevice *dev, int pin, int flags) +{ + struct single_priv *priv = dev_get_priv(dev); + struct single_pdata *pdata = dev_get_plat(dev); + struct single_gpiofunc_range *frange = NULL; + struct list_head *pos, *tmp; + phys_addr_t reg; + int mux_bytes = 0; + u32 data; + + /* If function mask is null, needn't enable it. */ + if (!pdata->mask) + return -ENOTSUPP; + + list_for_each_safe(pos, tmp, &priv->gpiofuncs) { + frange = list_entry(pos, struct single_gpiofunc_range, node); + if ((pin >= frange->offset + frange->npins) || + pin < frange->offset) + continue; + + mux_bytes = pdata->width / BITS_PER_BYTE; + reg = pdata->base + pin * mux_bytes; + + data = single_read(dev, reg); + data &= ~pdata->mask; + data |= frange->gpiofunc; + single_write(dev, data, reg); + break; + } + + return 0; +} + static struct single_func *single_allocate_function(struct udevice *dev, unsigned int group_pins) { @@ -454,6 +505,36 @@ static int single_get_pins_count(struct udevice *dev) return priv->npins; } +static int single_add_gpio_func(struct udevice *dev) +{ + struct single_priv *priv = dev_get_priv(dev); + const char *propname = "pinctrl-single,gpio-range"; + const char *cellname = "#pinctrl-single,gpio-range-cells"; + struct single_gpiofunc_range *range; + struct ofnode_phandle_args gpiospec; + int ret, i; + + for (i = 0; ; i++) { + ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), propname, + cellname, 0, i, &gpiospec); + /* Do not treat it as error. Only treat it as end condition. */ + if (ret) { + ret = 0; + break; + } + range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL); + if (!range) { + ret = -ENOMEM; + break; + } + range->offset = gpiospec.args[0]; + range->npins = gpiospec.args[1]; + range->gpiofunc = gpiospec.args[2]; + list_add_tail(&range->node, &priv->gpiofuncs); + } + return ret; +} + static int single_probe(struct udevice *dev) { struct single_pdata *pdata = dev_get_plat(dev); @@ -461,6 +542,7 @@ static int single_probe(struct udevice *dev) u32 size; INIT_LIST_HEAD(&priv->functions); + INIT_LIST_HEAD(&priv->gpiofuncs); size = pdata->offset + pdata->width / BITS_PER_BYTE; #if (CONFIG_IS_ENABLED(SANDBOX)) @@ -483,6 +565,9 @@ static int single_probe(struct udevice *dev) priv->npins *= (pdata->width / priv->bits_per_pin); } + if (single_add_gpio_func(dev)) + dev_dbg(dev, "gpio functions are not added\n"); + dev_dbg(dev, "%d pins\n", priv->npins); return 0; } @@ -535,6 +620,7 @@ const struct pinctrl_ops single_pinctrl_ops = { .get_pin_name = single_get_pin_name, .set_state = single_set_state, .get_pin_muxing = single_get_pin_muxing, + .request = single_request, }; static const struct udevice_id single_pinctrl_match[] = { diff --git a/drivers/reboot-mode/reboot-mode-uclass.c b/drivers/reboot-mode/reboot-mode-uclass.c index bb7a355fbf8..2b38aa26b85 100644 --- a/drivers/reboot-mode/reboot-mode-uclass.c +++ b/drivers/reboot-mode/reboot-mode-uclass.c @@ -10,8 +10,6 @@ #include <exports.h> #include <reboot-mode/reboot-mode.h> -DECLARE_GLOBAL_DATA_PTR; - int dm_reboot_mode_update(struct udevice *dev) { struct reboot_mode_ops *ops = reboot_mode_get_ops(dev); @@ -66,25 +64,20 @@ int dm_reboot_mode_pre_probe(struct udevice *dev) return -EINVAL; #if CONFIG_IS_ENABLED(OF_CONTROL) - const int node = dev_of_offset(dev); const char *mode_prefix = "mode-"; const int mode_prefix_len = strlen(mode_prefix); - int property; + struct ofprop property; const u32 *propvalue; const char *propname; - plat_data->env_variable = fdt_getprop(gd->fdt_blob, - node, - "u-boot,env-variable", - NULL); + plat_data->env_variable = dev_read_string(dev, "u-boot,env-variable"); if (!plat_data->env_variable) plat_data->env_variable = "reboot-mode"; plat_data->count = 0; - fdt_for_each_property_offset(property, gd->fdt_blob, node) { - propvalue = fdt_getprop_by_offset(gd->fdt_blob, - property, &propname, NULL); + dev_for_each_property(property, dev) { + propvalue = dev_read_prop_by_prop(&property, &propname, NULL); if (!propvalue) { dev_err(dev, "Could not get the value for property %s\n", propname); @@ -100,9 +93,8 @@ int dm_reboot_mode_pre_probe(struct udevice *dev) struct reboot_mode_mode *next = plat_data->modes; - fdt_for_each_property_offset(property, gd->fdt_blob, node) { - propvalue = fdt_getprop_by_offset(gd->fdt_blob, - property, &propname, NULL); + dev_for_each_property(property, dev) { + propvalue = dev_read_prop_by_prop(&property, &propname, NULL); if (!propvalue) { dev_err(dev, "Could not get the value for property %s\n", propname); diff --git a/drivers/remoteproc/rproc-uclass.c b/drivers/remoteproc/rproc-uclass.c index 64c47c1e722..87e1ec7ad7f 100644 --- a/drivers/remoteproc/rproc-uclass.c +++ b/drivers/remoteproc/rproc-uclass.c @@ -9,19 +9,15 @@ #define pr_fmt(fmt) "%s: " fmt, __func__ #include <common.h> #include <errno.h> -#include <fdtdec.h> #include <log.h> #include <malloc.h> #include <remoteproc.h> -#include <asm/global_data.h> #include <asm/io.h> #include <dm/device-internal.h> #include <dm.h> #include <dm/uclass.h> #include <dm/uclass-internal.h> -DECLARE_GLOBAL_DATA_PTR; - /** * for_each_remoteproc_device() - iterate through the list of rproc devices * @fn: check function to call per match, if this function returns fail, @@ -121,21 +117,13 @@ static int rproc_pre_probe(struct udevice *dev) if (!dev_get_plat(dev)) { #if CONFIG_IS_ENABLED(OF_CONTROL) - int node = dev_of_offset(dev); - const void *blob = gd->fdt_blob; bool tmp; - if (!blob) { - debug("'%s' no dt?\n", dev->name); - return -EINVAL; - } debug("'%s': using fdt\n", dev->name); - uc_pdata->name = fdt_getprop(blob, node, - "remoteproc-name", NULL); + uc_pdata->name = dev_read_string(dev, "remoteproc-name"); /* Default is internal memory mapped */ uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; - tmp = fdtdec_get_bool(blob, node, - "remoteproc-internal-memory-mapped"); + tmp = dev_read_bool(dev, "remoteproc-internal-memory-mapped"); if (tmp) uc_pdata->mem_type = RPROC_INTERNAL_MEMORY_MAPPED; #else |
