summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-02-18 08:36:44 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-02-18 08:36:44 +0100
commitd6787a36a64aeaff019bfb61b40f247f04c5ade8 (patch)
tree8f4fd0981b811d925420b5ffb7c8bf12fd730939 /drivers
parent0a54a21f182751a0f256119d8b048d8d169ed395 (diff)
parentf246b4079c746f80e29b07252c546d37a359105f (diff)
downloadbarebox-d6787a36a64aeaff019bfb61b40f247f04c5ade8.tar.gz
barebox-d6787a36a64aeaff019bfb61b40f247f04c5ade8.tar.xz
Merge branch 'for-next/misc'
Diffstat (limited to 'drivers')
-rw-r--r--drivers/base/driver.c3
-rw-r--r--drivers/clocksource/Kconfig2
-rw-r--r--drivers/clocksource/Makefile4
-rw-r--r--drivers/clocksource/arm_architected_timer.c (renamed from drivers/clocksource/armv8-timer.c)19
-rw-r--r--drivers/eeprom/at25.c2
-rw-r--r--drivers/gpio/gpiolib.c245
-rw-r--r--drivers/i2c/busses/i2c-tegra.c2
-rw-r--r--drivers/mci/stm32_sdmmc2.c2
-rw-r--r--drivers/net/designware_socfpga.c18
-rw-r--r--drivers/pinctrl/pinctrl-single.c81
-rw-r--r--drivers/regulator/fixed.c3
-rw-r--r--drivers/usb/gadget/f_fastboot.c2
-rw-r--r--drivers/watchdog/dw_wdt.c13
-rw-r--r--drivers/watchdog/wd_core.c30
14 files changed, 271 insertions, 155 deletions
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 247456a2c6..456750e7d5 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -310,6 +310,9 @@ int register_driver(struct driver_d *drv)
{
struct device_d *dev = NULL;
+ if (!drv->name)
+ return -EINVAL;
+
debug("register_driver: %s\n", drv->name);
BUG_ON(!drv->bus);
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 43c5bfc973..39ddd159f9 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -70,7 +70,7 @@ config CLOCKSOURCE_ROCKCHIP
config CLOCKSOURCE_ATMEL_PIT
bool
-config CLOCKSOURCE_ARMV8_TIMER
+config CLOCKSOURCE_ARM_ARCHITECTED_TIMER
bool
default y
depends on ARM && (CPU_64v8 || CPU_V7)
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 8dbf91f323..cba6344bbb 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -11,9 +11,9 @@ obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o
obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o
obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o
obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o
-obj-$(CONFIG_CLOCKSOURCE_ARMV8_TIMER) += armv8-timer.o
+obj-$(CONFIG_CLOCKSOURCE_ARM_ARCHITECTED_TIMER) += arm_architected_timer.o
ifneq ($(CONFIG_CPU_V8),y)
-CFLAGS_armv8-timer.o := -march=armv7-a
+CFLAGS_arm_architected_timer.o := -march=armv7-a
endif
obj-$(CONFIG_CLOCKSOURCE_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_CLOCKSOURCE_IMX_GPT) += timer-imx-gpt.o
diff --git a/drivers/clocksource/armv8-timer.c b/drivers/clocksource/arm_architected_timer.c
index 3095f8cfc4..3ca7dfd17d 100644
--- a/drivers/clocksource/armv8-timer.c
+++ b/drivers/clocksource/arm_architected_timer.c
@@ -20,34 +20,33 @@
#include <io.h>
#include <asm/system.h>
-static uint64_t armv8_clocksource_read(void)
+static uint64_t arm_arch_clocksource_read(void)
{
return get_cntpct();
}
static struct clocksource cs = {
- .read = armv8_clocksource_read,
+ .read = arm_arch_clocksource_read,
.mask = CLOCKSOURCE_MASK(64),
.shift = 0,
};
-static int armv8_timer_probe(struct device_d *dev)
+static int arm_arch_timer_probe(struct device_d *dev)
{
cs.mult = clocksource_hz2mult(get_cntfrq(), cs.shift);
return init_clock(&cs);
}
-static struct of_device_id armv8_timer_dt_ids[] = {
+static struct of_device_id arm_arch_timer_dt_ids[] = {
{ .compatible = "arm,armv7-timer", },
{ .compatible = "arm,armv8-timer", },
{ }
};
-static struct driver_d armv8_timer_driver = {
- .name = "armv8-timer",
- .probe = armv8_timer_probe,
- .of_compatible = DRV_OF_COMPAT(armv8_timer_dt_ids),
+static struct driver_d arm_arch_timer_driver = {
+ .name = "arm-architected-timer",
+ .probe = arm_arch_timer_probe,
+ .of_compatible = DRV_OF_COMPAT(arm_arch_timer_dt_ids),
};
-postcore_platform_driver(armv8_timer_driver);
-
+postcore_platform_driver(arm_arch_timer_driver);
diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
index 1c9ef12321..56168c216d 100644
--- a/drivers/eeprom/at25.c
+++ b/drivers/eeprom/at25.c
@@ -259,7 +259,7 @@ static int at25_np_to_chip(struct device_d *dev,
if (of_property_read_u32(np, "pagesize", &val) == 0 ||
of_property_read_u32(np, "at25,page-size", &val) == 0) {
- chip->page_size = (u16)val;
+ chip->page_size = val;
} else {
dev_err(dev, "Error: missing \"pagesize\" property\n");
return -ENODEV;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 9764ddf0f0..cfa77360b3 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -48,6 +48,11 @@ static struct gpio_info *gpio_to_desc(unsigned gpio)
return NULL;
}
+static unsigned gpioinfo_chip_offset(struct gpio_info *gi)
+{
+ return (gi - gpio_desc) - gi->chip->base;
+}
+
static int gpio_adjust_value(struct gpio_info *gi,
int value)
{
@@ -57,16 +62,10 @@ static int gpio_adjust_value(struct gpio_info *gi,
return !!value ^ gi->active_low;
}
-int gpio_request(unsigned gpio, const char *label)
+static int gpioinfo_request(struct gpio_info *gi, const char *label)
{
- struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gi) {
- ret = -ENODEV;
- goto done;
- }
-
if (gi->requested) {
ret = -EBUSY;
goto done;
@@ -75,7 +74,8 @@ int gpio_request(unsigned gpio, const char *label)
ret = 0;
if (gi->chip->ops->request) {
- ret = gi->chip->ops->request(gi->chip, gpio - gi->chip->base);
+ ret = gi->chip->ops->request(gi->chip,
+ gpioinfo_chip_offset(gi));
if (ret)
goto done;
}
@@ -86,8 +86,8 @@ int gpio_request(unsigned gpio, const char *label)
done:
if (ret)
- pr_err("_gpio_request: gpio-%d (%s) status %d\n",
- gpio, label ? : "?", ret);
+ pr_err("_gpio_request: gpio-%ld (%s) status %d\n",
+ gi - gpio_desc, label ? : "?", ret);
return ret;
}
@@ -126,18 +126,26 @@ int gpio_find_by_name(const char *name)
return -ENOENT;
}
-void gpio_free(unsigned gpio)
+int gpio_request(unsigned gpio, const char *label)
{
struct gpio_info *gi = gpio_to_desc(gpio);
- if (!gi)
- return;
+ if (!gi) {
+ pr_err("_gpio_request: gpio-%d (%s) status %d\n",
+ gpio, label ? : "?", -ENODEV);
+ return -ENODEV;
+ }
+
+ return gpioinfo_request(gi, label);
+}
+static void gpioinfo_free(struct gpio_info *gi)
+{
if (!gi->requested)
return;
if (gi->chip->ops->free)
- gi->chip->ops->free(gi->chip, gpio - gi->chip->base);
+ gi->chip->ops->free(gi->chip, gpioinfo_chip_offset(gi));
gi->requested = false;
gi->active_low = false;
@@ -145,81 +153,21 @@ void gpio_free(unsigned gpio)
gi->label = NULL;
}
-/**
- * gpio_request_one - request a single GPIO with initial configuration
- * @gpio: the GPIO number
- * @flags: GPIO configuration as specified by GPIOF_*
- * @label: a literal description string of this GPIO
- */
-int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+void gpio_free(unsigned gpio)
{
- int err;
struct gpio_info *gi = gpio_to_desc(gpio);
- /*
- * Not all of the flags below are mulit-bit, but, for the sake
- * of consistency, the code is written as if all of them were.
- */
- const bool active_low = (flags & GPIOF_ACTIVE_LOW) == GPIOF_ACTIVE_LOW;
- const bool dir_in = (flags & GPIOF_DIR_IN) == GPIOF_DIR_IN;
- const bool logical = (flags & GPIOF_LOGICAL) == GPIOF_LOGICAL;
- const bool init_active = (flags & GPIOF_INIT_ACTIVE) == GPIOF_INIT_ACTIVE;
- const bool init_high = (flags & GPIOF_INIT_HIGH) == GPIOF_INIT_HIGH;
-
- err = gpio_request(gpio, label);
- if (err)
- return err;
-
- gi->active_low = active_low;
-
- if (dir_in)
- err = gpio_direction_input(gpio);
- else if (logical)
- err = gpio_direction_active(gpio, init_active);
- else
- err = gpio_direction_output(gpio, init_high);
-
- if (err)
- gpio_free(gpio);
-
- return err;
-}
-EXPORT_SYMBOL_GPL(gpio_request_one);
-
-/**
- * gpio_request_array - request multiple GPIOs in a single call
- * @array: array of the 'struct gpio'
- * @num: how many GPIOs in the array
- */
-int gpio_request_array(const struct gpio *array, size_t num)
-{
- int i, err;
-
- for (i = 0; i < num; i++, array++) {
- err = gpio_request_one(array->gpio, array->flags, array->label);
- if (err)
- goto err_free;
- }
- return 0;
+ if (!gi)
+ return;
-err_free:
- while (i--)
- gpio_free((--array)->gpio);
- return err;
+ gpioinfo_free(gi);
}
-EXPORT_SYMBOL_GPL(gpio_request_array);
-/**
- * gpio_free_array - release multiple GPIOs in a single call
- * @array: array of the 'struct gpio'
- * @num: how many GPIOs in the array
- */
-void gpio_free_array(const struct gpio *array, size_t num)
+static void gpioinfo_set_value(struct gpio_info *gi, int value)
{
- while (num--)
- gpio_free((array++)->gpio);
+ if (gi->chip->ops->set)
+ gi->chip->ops->set(gi->chip, gpioinfo_chip_offset(gi), value);
}
-EXPORT_SYMBOL_GPL(gpio_free_array);
void gpio_set_value(unsigned gpio, int value)
{
@@ -231,8 +179,7 @@ void gpio_set_value(unsigned gpio, int value)
if (gpio_ensure_requested(gi, gpio))
return;
- if (gi->chip->ops->set)
- gi->chip->ops->set(gi->chip, gpio - gi->chip->base, value);
+ gpioinfo_set_value(gi, value);
}
EXPORT_SYMBOL(gpio_set_value);
@@ -247,6 +194,14 @@ void gpio_set_active(unsigned gpio, bool value)
}
EXPORT_SYMBOL(gpio_set_active);
+static int gpioinfo_get_value(struct gpio_info *gi)
+{
+ if (!gi->chip->ops->get)
+ return -ENOSYS;
+
+ return gi->chip->ops->get(gi->chip, gpioinfo_chip_offset(gi));
+}
+
int gpio_get_value(unsigned gpio)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -259,9 +214,7 @@ int gpio_get_value(unsigned gpio)
if (ret)
return ret;
- if (!gi->chip->ops->get)
- return -ENOSYS;
- return gi->chip->ops->get(gi->chip, gpio - gi->chip->base);
+ return gpioinfo_get_value(gi);
}
EXPORT_SYMBOL(gpio_get_value);
@@ -276,6 +229,15 @@ int gpio_is_active(unsigned gpio)
}
EXPORT_SYMBOL(gpio_is_active);
+static int gpioinfo_direction_output(struct gpio_info *gi, int value)
+{
+ if (!gi->chip->ops->direction_output)
+ return -ENOSYS;
+
+ return gi->chip->ops->direction_output(gi->chip,
+ gpioinfo_chip_offset(gi), value);
+}
+
int gpio_direction_output(unsigned gpio, int value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -288,13 +250,15 @@ int gpio_direction_output(unsigned gpio, int value)
if (ret)
return ret;
- if (!gi->chip->ops->direction_output)
- return -ENOSYS;
- return gi->chip->ops->direction_output(gi->chip, gpio - gi->chip->base,
- value);
+ return gpioinfo_direction_output(gi, value);
}
EXPORT_SYMBOL(gpio_direction_output);
+static int gpioinfo_direction_active(struct gpio_info *gi, bool value)
+{
+ return gpioinfo_direction_output(gi, gpio_adjust_value(gi, value));
+}
+
int gpio_direction_active(unsigned gpio, bool value)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -302,10 +266,19 @@ int gpio_direction_active(unsigned gpio, bool value)
if (!gi)
return -ENODEV;
- return gpio_direction_output(gpio, gpio_adjust_value(gi, value));
+ return gpioinfo_direction_active(gi, value);
}
EXPORT_SYMBOL(gpio_direction_active);
+static int gpioinfo_direction_input(struct gpio_info *gi)
+{
+ if (!gi->chip->ops->direction_input)
+ return -ENOSYS;
+
+ return gi->chip->ops->direction_input(gi->chip,
+ gpioinfo_chip_offset(gi));
+}
+
int gpio_direction_input(unsigned gpio)
{
struct gpio_info *gi = gpio_to_desc(gpio);
@@ -318,12 +291,96 @@ int gpio_direction_input(unsigned gpio)
if (ret)
return ret;
- if (!gi->chip->ops->direction_input)
- return -ENOSYS;
- return gi->chip->ops->direction_input(gi->chip, gpio - gi->chip->base);
+ return gpioinfo_direction_input(gi);
}
EXPORT_SYMBOL(gpio_direction_input);
+static int gpioinfo_request_one(struct gpio_info *gi, unsigned long flags,
+ const char *label)
+{
+ int err;
+
+ /*
+ * Not all of the flags below are mulit-bit, but, for the sake
+ * of consistency, the code is written as if all of them were.
+ */
+ const bool active_low = (flags & GPIOF_ACTIVE_LOW) == GPIOF_ACTIVE_LOW;
+ const bool dir_in = (flags & GPIOF_DIR_IN) == GPIOF_DIR_IN;
+ const bool logical = (flags & GPIOF_LOGICAL) == GPIOF_LOGICAL;
+ const bool init_active = (flags & GPIOF_INIT_ACTIVE) == GPIOF_INIT_ACTIVE;
+ const bool init_high = (flags & GPIOF_INIT_HIGH) == GPIOF_INIT_HIGH;
+
+ err = gpioinfo_request(gi, label);
+ if (err)
+ return err;
+
+ gi->active_low = active_low;
+
+ if (dir_in)
+ err = gpioinfo_direction_input(gi);
+ else if (logical)
+ err = gpioinfo_direction_active(gi, init_active);
+ else
+ err = gpioinfo_direction_output(gi, init_high);
+
+ if (err)
+ gpioinfo_free(gi);
+
+ return err;
+}
+
+/**
+ * gpio_request_one - request a single GPIO with initial configuration
+ * @gpio: the GPIO number
+ * @flags: GPIO configuration as specified by GPIOF_*
+ * @label: a literal description string of this GPIO
+ */
+int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+{
+ struct gpio_info *gi = gpio_to_desc(gpio);
+
+ if (!gi)
+ return -ENODEV;
+
+ return gpioinfo_request_one(gi, flags, label);
+}
+EXPORT_SYMBOL_GPL(gpio_request_one);
+
+/**
+ * gpio_request_array - request multiple GPIOs in a single call
+ * @array: array of the 'struct gpio'
+ * @num: how many GPIOs in the array
+ */
+int gpio_request_array(const struct gpio *array, size_t num)
+{
+ int i, err;
+
+ for (i = 0; i < num; i++, array++) {
+ err = gpio_request_one(array->gpio, array->flags, array->label);
+ if (err)
+ goto err_free;
+ }
+ return 0;
+
+err_free:
+ while (i--)
+ gpio_free((--array)->gpio);
+ return err;
+}
+EXPORT_SYMBOL_GPL(gpio_request_array);
+
+/**
+ * gpio_free_array - release multiple GPIOs in a single call
+ * @array: array of the 'struct gpio'
+ * @num: how many GPIOs in the array
+ */
+void gpio_free_array(const struct gpio *array, size_t num)
+{
+ while (num--)
+ gpio_free((array++)->gpio);
+}
+EXPORT_SYMBOL_GPL(gpio_free_array);
+
static int gpiochip_find_base(int start, int ngpio)
{
int i;
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index d56c0def65..94c982d5c2 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -632,7 +632,7 @@ static int tegra_i2c_probe(struct device_d *dev)
i2c_dev->rst = reset_control_get(dev, "i2c");
if (IS_ERR(i2c_dev->rst)) {
- dev_err(dev, "missing controller reset");
+ dev_err(dev, "invalid controller reset");
return PTR_ERR(i2c_dev->rst);
}
diff --git a/drivers/mci/stm32_sdmmc2.c b/drivers/mci/stm32_sdmmc2.c
index 44f7e62399..695e61d1cc 100644
--- a/drivers/mci/stm32_sdmmc2.c
+++ b/drivers/mci/stm32_sdmmc2.c
@@ -622,7 +622,7 @@ static int stm32_sdmmc2_probe(struct amba_device *adev,
priv->reset_ctl = reset_control_get(dev, NULL);
if (IS_ERR(priv->reset_ctl))
- priv->reset_ctl = NULL;
+ return PTR_ERR(priv->reset_ctl);
mci->f_min = 400000;
/* f_max is taken from kernel v5.3 variant_stm32_sdmmc */
diff --git a/drivers/net/designware_socfpga.c b/drivers/net/designware_socfpga.c
index ce3ac38ebe..d6c28af45e 100644
--- a/drivers/net/designware_socfpga.c
+++ b/drivers/net/designware_socfpga.c
@@ -77,8 +77,7 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
}
/* Assert reset to the enet controller before changing the phy mode */
- if (eth_dev->rst)
- reset_control_assert(eth_dev->rst);
+ reset_control_assert(eth_dev->rst);
ctrl = readl(dwc_dev->sys_mgr_base + reg_offset);
ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
@@ -104,8 +103,7 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
/* Deassert reset for the phy configuration to be sampled by
* the enet controller, and operation to start in requested mode
*/
- if (eth_dev->rst)
- reset_control_deassert(eth_dev->rst);
+ reset_control_deassert(eth_dev->rst);
return 0;
}
@@ -124,8 +122,7 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
}
/* Assert reset to the enet controller before changing the phy mode */
- if (eth_dev->rst)
- reset_control_assert(eth_dev->rst);
+ reset_control_assert(eth_dev->rst);
ctrl = readl(dwc_dev->sys_mgr_base + reg_offset);
ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
@@ -151,8 +148,7 @@ static int socfpga_gen10_set_phy_mode(struct socfpga_dwc_dev *dwc_dev)
/* Deassert reset for the phy configuration to be sampled by
* the enet controller, and operation to start in requested mode
*/
- if (eth_dev->rst)
- reset_control_deassert(eth_dev->rst);
+ reset_control_deassert(eth_dev->rst);
return 0;
}
@@ -212,8 +208,10 @@ static int socfpga_dwc_ether_probe(struct device_d *dev)
return PTR_ERR(priv);
priv->rst = reset_control_get(dev, NULL);
- if (IS_ERR(priv->rst))
- dev_warn(dev, "No reset lines.\n");
+ if (IS_ERR(priv->rst)) {
+ dev_err(dev, "Invalid reset lines.\n");
+ return PTR_ERR(priv->rst);
+ }
dwc_dev->priv = priv;
diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
index 3c581ed5d3..d4f411b4ad 100644
--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -29,7 +29,13 @@ struct pinctrl_single {
struct pinctrl_device pinctrl;
unsigned (*read)(void __iomem *reg);
void (*write)(unsigned val, void __iomem *reg);
- unsigned width;
+ unsigned int width;
+ unsigned int fmask;
+ unsigned int fshift;
+ unsigned int fmax;
+
+ bool bits_per_mux;
+ unsigned int bits_per_pin;
};
static unsigned __maybe_unused pcs_readb(void __iomem *reg)
@@ -66,27 +72,47 @@ static int pcs_set_state(struct pinctrl_device *pdev, struct device_node *np)
{
struct pinctrl_single *pcs = container_of(pdev, struct pinctrl_single, pinctrl);
unsigned size = 0, index = 0;
+ unsigned int offset, val, rows, mask, reg, i;
const __be32 *mux;
dev_dbg(pcs->pinctrl.dev, "set state: %s\n", np->full_name);
-
- mux = of_get_property(np, "pinctrl-single,pins", &size);
-
- size /= sizeof(*mux); /* Number of elements in array */
-
- if (!mux || !size || (size & 1)) {
- dev_err(pcs->pinctrl.dev, "bad data for mux %s\n",
- np->full_name);
- return -EINVAL;
- }
-
- while (index < size) {
- unsigned offset, val;
-
- offset = be32_to_cpup(mux + index++);
- val = be32_to_cpup(mux + index++);
-
- pcs->write(val, pcs->base + offset);
+ if (pcs->bits_per_mux) {
+ mux = of_get_property(np, "pinctrl-single,bits", &size);
+ if (size % 3 != 0)
+ dev_err(pcs->pinctrl.dev,
+ "invalid args_count for spec: %u\n", size);
+
+ size /= sizeof(*mux); /* Number of elements in array */
+ rows = size / 3;
+
+ for (i = 0; i < rows; i++) {
+ offset = be32_to_cpup(mux + index++);
+ mask = be32_to_cpup(mux + index++);
+ val = be32_to_cpup(mux + index++);
+ reg = pcs->read(pcs->base + offset);
+ reg &= ~mask;
+ reg |= val;
+ pcs->write(reg, pcs->base + offset);
+ }
+ } else {
+ mux = of_get_property(np, "pinctrl-single,pins", &size);
+
+ size /= sizeof(*mux); /* Number of elements in array */
+
+ if (!mux || !size || (size & 1)) {
+ dev_err(pcs->pinctrl.dev, "bad data for mux %s\n",
+ np->full_name);
+ return -EINVAL;
+ }
+
+ while (index < size) {
+ unsigned int offset, val;
+
+ offset = be32_to_cpup(mux + index++);
+ val = be32_to_cpup(mux + index++);
+
+ pcs->write(val, pcs->base + offset);
+ }
}
return 0;
@@ -137,6 +163,23 @@ static int pcs_probe(struct device_d *dev)
goto out;
}
+ ret = of_property_read_u32(np, "pinctrl-single,function-mask",
+ &pcs->fmask);
+ if (!ret) {
+ pcs->fshift = __ffs(pcs->fmask);
+ pcs->fmax = pcs->fmask >> pcs->fshift;
+ } else {
+ /* If mask property doesn't exist, function mux is invalid. */
+ pcs->fmask = 0;
+ pcs->fshift = 0;
+ pcs->fmax = 0;
+ }
+
+ pcs->bits_per_mux =
+ of_property_read_bool(np, "pinctrl-single,bit-per-mux");
+ if (pcs->bits_per_mux)
+ pcs->bits_per_pin = fls(pcs->fmask);
+
ret = pinctrl_register(&pcs->pinctrl);
if (ret)
goto out;
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index cb5d785817..78b8290ff2 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -86,7 +86,8 @@ static int regulator_fixed_probe(struct device_d *dev)
fix->rdesc.ops = &fixed_ops;
fix->rdev.desc = &fix->rdesc;
- if (of_find_property(dev->device_node, "regulator-always-on", NULL)) {
+ if (of_find_property(dev->device_node, "regulator-always-on", NULL) ||
+ of_find_property(dev->device_node, "regulator-boot-on", NULL)) {
fix->always_on = 1;
regulator_fixed_enable(&fix->rdev);
}
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 35c4b8cf4c..0a3aff3cf0 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -769,7 +769,7 @@ static void __maybe_unused cb_boot(struct f_fastboot *f_fb, const char *opt)
globalvar_set_match("linux.bootargs.dyn.", "");
globalvar_set_match("bootm.image", "");
- data.os_file = xstrdup(FASTBOOT_TMPFILE);
+ data.os_file = FASTBOOT_TMPFILE;
ret = bootm_boot(&data);
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c
index 85e810f248..cb0d17e361 100644
--- a/drivers/watchdog/dw_wdt.c
+++ b/drivers/watchdog/dw_wdt.c
@@ -72,9 +72,9 @@ static int dw_wdt_stop(struct watchdog *wdd)
{
struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
- if (IS_ERR(dw_wdt->rst)) {
- dev_warn(dw_wdt->wdd.hwdev, "No reset line. Will not stop.\n");
- return PTR_ERR(dw_wdt->rst);
+ if (!dw_wdt->rst) {
+ dev_warn(dw_wdt->wdd.hwdev, "No reset line\n");
+ return -ENOSYS;
}
reset_control_assert(dw_wdt->rst);
@@ -153,7 +153,7 @@ static int dw_wdt_drv_probe(struct device_d *dev)
dw_wdt->rst = reset_control_get(dev, NULL);
if (IS_ERR(dw_wdt->rst))
- dev_warn(dev, "No reset lines. Will not be able to stop once started.\n");
+ return PTR_ERR(dw_wdt->rst);
wdd = &dw_wdt->wdd;
wdd->name = "dw_wdt";
@@ -171,8 +171,10 @@ static int dw_wdt_drv_probe(struct device_d *dev)
if (ret)
dev_warn(dev, "cannot register restart handler\n");
- if (!IS_ERR(dw_wdt->rst))
+ if (dw_wdt->rst)
reset_control_deassert(dw_wdt->rst);
+ else
+ dev_warn(dev, "No reset lines. Will not be able to stop once started.\n");
return 0;
@@ -187,6 +189,7 @@ static struct of_device_id dw_wdt_of_match[] = {
};
static struct driver_d dw_wdt_driver = {
+ .name = "dw-wdt",
.probe = dw_wdt_drv_probe,
.of_compatible = DRV_OF_COMPAT(dw_wdt_of_match),
};
diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
index b6e2a37b1f..34040408f7 100644
--- a/drivers/watchdog/wd_core.c
+++ b/drivers/watchdog/wd_core.c
@@ -171,8 +171,10 @@ int watchdog_register(struct watchdog *wd)
return ret;
p = dev_add_param_tristate_ro(&wd->dev, "running", &wd->running);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ goto error_unregister;
+ }
if (!wd->priority)
wd->priority = dev_get_watchdog_priority(wd->hwdev);
@@ -180,8 +182,10 @@ int watchdog_register(struct watchdog *wd)
p = dev_add_param_uint32(&wd->dev, "priority",
watchdog_set_priority, NULL,
&wd->priority, "%u", wd);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ goto error_unregister;
+ }
/* set some default sane value */
if (!wd->timeout_max)
@@ -189,8 +193,10 @@ int watchdog_register(struct watchdog *wd)
p = dev_add_param_uint32_ro(&wd->dev, "timeout_max",
&wd->timeout_max, "%u");
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ goto error_unregister;
+ }
if (IS_ENABLED(CONFIG_WATCHDOG_POLLER)) {
if (!wd->poller_timeout_cur ||
@@ -199,12 +205,14 @@ int watchdog_register(struct watchdog *wd)
p = dev_add_param_uint32(&wd->dev, "timeout_cur", watchdog_set_cur,
NULL, &wd->poller_timeout_cur, "%u", wd);
- if (IS_ERR(p))
- return PTR_ERR(p);
+ if (IS_ERR(p)) {
+ ret = PTR_ERR(p);
+ goto error_unregister;
+ }
ret = watchdog_register_poller(wd);
if (ret)
- return ret;
+ goto error_unregister;
}
list_add_tail(&wd->list, &watchdog_list);
@@ -213,6 +221,10 @@ int watchdog_register(struct watchdog *wd)
wd->priority);
return 0;
+
+error_unregister:
+ unregister_device(&wd->dev);
+ return ret;
}
EXPORT_SYMBOL(watchdog_register);