summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2021-10-05 17:16:23 -0400
committerTom Rini <[email protected]>2021-10-05 17:16:23 -0400
commit7240e1b8f94a56db88a2af688cad27e2e6545302 (patch)
tree00e07de1f4b83cf96f183b881e80cd273dabd892 /drivers
parent50c84208ad50a27382c64af911abba4510a8b608 (diff)
parentc3ef4550a2c439e9726205769d4381ed7e7fbc3d (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.c9
-rw-r--r--drivers/gpio/gpio-uclass.c55
-rw-r--r--drivers/pinctrl/pinctrl-single.c86
-rw-r--r--drivers/reboot-mode/reboot-mode-uclass.c20
-rw-r--r--drivers/remoteproc/rproc-uclass.c16
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