summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/led/led-uclass.c63
-rw-r--r--drivers/led/led_bcm6328.c12
-rw-r--r--drivers/led/led_bcm6358.c12
-rw-r--r--drivers/led/led_bcm6753.c12
-rw-r--r--drivers/led/led_bcm6858.c12
-rw-r--r--drivers/led/led_cortina.c11
-rw-r--r--drivers/led/led_gpio.c8
-rw-r--r--drivers/led/led_pwm.c10
-rw-r--r--drivers/misc/atsha204a-i2c.c2
-rw-r--r--drivers/misc/qfw.c3
-rw-r--r--drivers/power/domain/ti-power-domain.c23
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/sandbox.c48
-rw-r--r--drivers/serial/serial-uclass.c32
-rw-r--r--drivers/serial/serial_semihosting.c31
15 files changed, 163 insertions, 118 deletions
diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c
index 7e298dbb06f..5d7bf40896b 100644
--- a/drivers/led/led-uclass.c
+++ b/drivers/led/led-uclass.c
@@ -66,37 +66,56 @@ int led_set_period(struct udevice *dev, int period_ms)
}
#endif
+/* This is superseded by led_post_bind()/led_post_probe() below. */
int led_default_state(void)
{
- struct udevice *dev;
- struct uclass *uc;
+ return 0;
+}
+
+static int led_post_bind(struct udevice *dev)
+{
+ struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
const char *default_state;
- int ret;
- ret = uclass_get(UCLASS_LED, &uc);
- if (ret)
- return ret;
- for (uclass_find_first_device(UCLASS_LED, &dev);
- dev;
- uclass_find_next_device(&dev)) {
- default_state = dev_read_string(dev, "default-state");
- if (!default_state)
- continue;
- ret = device_probe(dev);
- if (ret)
- return ret;
- if (!strncmp(default_state, "on", 2))
- led_set_state(dev, LEDST_ON);
- else if (!strncmp(default_state, "off", 3))
- led_set_state(dev, LEDST_OFF);
- /* default-state = "keep" : device is only probed */
- }
+ uc_plat->label = dev_read_string(dev, "label");
+ if (!uc_plat->label)
+ uc_plat->label = ofnode_get_name(dev_ofnode(dev));
+
+ uc_plat->default_state = LEDST_COUNT;
+
+ default_state = dev_read_string(dev, "default-state");
+ if (!default_state)
+ return 0;
+
+ if (!strncmp(default_state, "on", 2))
+ uc_plat->default_state = LEDST_ON;
+ else if (!strncmp(default_state, "off", 3))
+ uc_plat->default_state = LEDST_OFF;
+ else
+ return 0;
+
+ /*
+ * In case the LED has default-state DT property, trigger
+ * probe() to configure its default state during startup.
+ */
+ return device_probe(dev);
+}
+
+static int led_post_probe(struct udevice *dev)
+{
+ struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev);
+
+ if (uc_plat->default_state == LEDST_ON ||
+ uc_plat->default_state == LEDST_OFF)
+ led_set_state(dev, uc_plat->default_state);
- return ret;
+ return 0;
}
UCLASS_DRIVER(led) = {
.id = UCLASS_LED,
.name = "led",
.per_device_plat_auto = sizeof(struct led_uc_plat),
+ .post_bind = led_post_bind,
+ .post_probe = led_post_probe,
};
diff --git a/drivers/led/led_bcm6328.c b/drivers/led/led_bcm6328.c
index bf8207d638d..f59a92fb1fd 100644
--- a/drivers/led/led_bcm6328.c
+++ b/drivers/led/led_bcm6328.c
@@ -204,26 +204,14 @@ static int bcm6328_led_bind(struct udevice *parent)
ofnode node;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
struct udevice *dev;
- const char *label;
int ret;
- label = ofnode_read_string(node, "label");
- if (!label) {
- debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
- return -EINVAL;
- }
-
ret = device_bind_driver_to_node(parent, "bcm6328-led",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
-
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_bcm6358.c b/drivers/led/led_bcm6358.c
index 3e57cdfd17d..25aa3994d0e 100644
--- a/drivers/led/led_bcm6358.c
+++ b/drivers/led/led_bcm6358.c
@@ -174,26 +174,14 @@ static int bcm6358_led_bind(struct udevice *parent)
ofnode node;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
struct udevice *dev;
- const char *label;
int ret;
- label = ofnode_read_string(node, "label");
- if (!label) {
- debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
- return -EINVAL;
- }
-
ret = device_bind_driver_to_node(parent, "bcm6358-led",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
-
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_bcm6753.c b/drivers/led/led_bcm6753.c
index a32bd8204fa..88b650cbfca 100644
--- a/drivers/led/led_bcm6753.c
+++ b/drivers/led/led_bcm6753.c
@@ -229,26 +229,14 @@ static int bcm6753_led_bind(struct udevice *parent)
ofnode node;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
struct udevice *dev;
- const char *label;
int ret;
- label = ofnode_read_string(node, "label");
- if (!label) {
- debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
- return -EINVAL;
- }
-
ret = device_bind_driver_to_node(parent, "bcm6753-led",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
-
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_bcm6858.c b/drivers/led/led_bcm6858.c
index 3ca6c5b8a9e..6b3698674b9 100644
--- a/drivers/led/led_bcm6858.c
+++ b/drivers/led/led_bcm6858.c
@@ -241,26 +241,14 @@ static int bcm6858_led_bind(struct udevice *parent)
ofnode node;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
struct udevice *dev;
- const char *label;
int ret;
- label = ofnode_read_string(node, "label");
- if (!label) {
- debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
- return -EINVAL;
- }
-
ret = device_bind_driver_to_node(parent, "bcm6858-led",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
-
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_cortina.c b/drivers/led/led_cortina.c
index 598c0a03db5..bcbe78d632a 100644
--- a/drivers/led/led_cortina.c
+++ b/drivers/led/led_cortina.c
@@ -256,25 +256,14 @@ static int cortina_led_bind(struct udevice *parent)
ofnode node;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
struct udevice *dev;
- const char *label;
int ret;
- label = ofnode_read_string(node, "label");
- if (!label) {
- debug("%s: node %s has no label\n", __func__,
- ofnode_get_name(node));
- return -EINVAL;
- }
-
ret = device_bind_driver_to_node(parent, "ca-leds",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c
index 67ece3cbcd0..958dbd31e77 100644
--- a/drivers/led/led_gpio.c
+++ b/drivers/led/led_gpio.c
@@ -95,19 +95,11 @@ static int led_gpio_bind(struct udevice *parent)
int ret;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
- const char *label;
-
- label = ofnode_read_string(node, "label");
- if (!label)
- label = ofnode_get_name(node);
ret = device_bind_driver_to_node(parent, "gpio_led",
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
diff --git a/drivers/led/led_pwm.c b/drivers/led/led_pwm.c
index 4e502722587..10bd1636c38 100644
--- a/drivers/led/led_pwm.c
+++ b/drivers/led/led_pwm.c
@@ -151,21 +151,11 @@ static int led_pwm_bind(struct udevice *parent)
int ret;
dev_for_each_subnode(node, parent) {
- struct led_uc_plat *uc_plat;
- const char *label;
-
- label = ofnode_read_string(node, "label");
- if (!label)
- label = ofnode_get_name(node);
-
ret = device_bind_driver_to_node(parent, LEDS_PWM_DRIVER_NAME,
ofnode_get_name(node),
node, &dev);
if (ret)
return ret;
-
- uc_plat = dev_get_uclass_plat(dev);
- uc_plat->label = label;
}
return 0;
}
diff --git a/drivers/misc/atsha204a-i2c.c b/drivers/misc/atsha204a-i2c.c
index b89463babb5..63fe541dade 100644
--- a/drivers/misc/atsha204a-i2c.c
+++ b/drivers/misc/atsha204a-i2c.c
@@ -146,7 +146,7 @@ static u16 atsha204a_crc16(const u8 *buffer, size_t len)
while (len--)
crc = crc16_byte(crc, *buffer++);
- return cpu_to_le16(crc);
+ return crc;
}
static int atsha204a_send(struct udevice *dev, const u8 *buf, u8 len)
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index 677841aac5e..1d54b7542b8 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -15,9 +15,6 @@
#include <dm.h>
#include <misc.h>
#include <tables_csum.h>
-#ifdef CONFIG_GENERATE_ACPI_TABLE
-#include <asm/tables.h>
-#endif
#if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX)
/*
diff --git a/drivers/power/domain/ti-power-domain.c b/drivers/power/domain/ti-power-domain.c
index a7dadf2eea7..752e76b3996 100644
--- a/drivers/power/domain/ti-power-domain.c
+++ b/drivers/power/domain/ti-power-domain.c
@@ -16,7 +16,9 @@
#include <linux/iopoll.h>
#define PSC_PTCMD 0x120
+#define PSC_PTCMD_H 0x124
#define PSC_PTSTAT 0x128
+#define PSC_PTSTAT_H 0x12C
#define PSC_PDSTAT 0x200
#define PSC_PDCTL 0x300
#define PSC_MDSTAT 0x800
@@ -120,10 +122,17 @@ static int ti_power_domain_probe(struct udevice *dev)
static int ti_pd_wait(struct ti_pd *pd)
{
u32 ptstat;
+ u32 pdoffset = 0;
+ u32 ptstatreg = PSC_PTSTAT;
int ret;
- ret = readl_poll_timeout(pd->psc->base + PSC_PTSTAT, ptstat,
- !(ptstat & BIT(pd->id)), PD_TIMEOUT);
+ if (pd->id > 31) {
+ pdoffset = 32;
+ ptstatreg = PSC_PTSTAT_H;
+ }
+
+ ret = readl_poll_timeout(pd->psc->base + ptstatreg, ptstat,
+ !(ptstat & BIT(pd->id - pdoffset)), PD_TIMEOUT);
if (ret)
printf("%s: psc%d, pd%d failed to transition.\n", __func__,
@@ -134,7 +143,15 @@ static int ti_pd_wait(struct ti_pd *pd)
static void ti_pd_transition(struct ti_pd *pd)
{
- psc_write(BIT(pd->id), pd->psc, PSC_PTCMD);
+ u32 pdoffset = 0;
+ u32 ptcmdreg = PSC_PTCMD;
+
+ if (pd->id > 31) {
+ pdoffset = 32;
+ ptcmdreg = PSC_PTCMD_H;
+ }
+
+ psc_write(BIT(pd->id - pdoffset), pd->psc, ptcmdreg);
}
u8 ti_pd_state(struct ti_pd *pd)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 286c99800f0..dc514c95d33 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -779,6 +779,7 @@ config S5P_SERIAL
config SANDBOX_SERIAL
bool "Sandbox UART support"
depends on SANDBOX
+ imply SERIAL_PUTS
help
Select this to enable a seral UART for sandbox. This is required to
operate correctly, otherwise you will see no serial output from
@@ -833,6 +834,7 @@ config SH_SCIF_CLK_FREQ
config SEMIHOSTING_SERIAL
bool "Semihosting UART support"
depends on SEMIHOSTING && !SERIAL_RX_BUFFER
+ imply SERIAL_PUTS
help
Select this to enable a serial UART using semihosting. Special halt
instructions will be issued which an external debugger (such as a
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 0b1756f5c0c..e726e19c46f 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -23,6 +23,19 @@
DECLARE_GLOBAL_DATA_PTR;
+static size_t _sandbox_serial_written = 1;
+static bool sandbox_serial_enabled = true;
+
+size_t sandbox_serial_written(void)
+{
+ return _sandbox_serial_written;
+}
+
+void sandbox_serial_endisable(bool enabled)
+{
+ sandbox_serial_enabled = enabled;
+}
+
/**
* output_ansi_colour() - Output an ANSI colour code
*
@@ -67,7 +80,7 @@ static int sandbox_serial_remove(struct udevice *dev)
return 0;
}
-static int sandbox_serial_putc(struct udevice *dev, const char ch)
+static void sandbox_print_color(struct udevice *dev)
{
struct sandbox_serial_priv *priv = dev_get_priv(dev);
struct sandbox_serial_plat *plat = dev_get_plat(dev);
@@ -78,14 +91,44 @@ static int sandbox_serial_putc(struct udevice *dev, const char ch)
priv->start_of_line = false;
output_ansi_colour(plat->colour);
}
+}
+
+static int sandbox_serial_putc(struct udevice *dev, const char ch)
+{
+ struct sandbox_serial_priv *priv = dev_get_priv(dev);
- os_write(1, &ch, 1);
if (ch == '\n')
priv->start_of_line = true;
+ if (sandbox_serial_enabled) {
+ sandbox_print_color(dev);
+ os_write(1, &ch, 1);
+ }
+ _sandbox_serial_written += 1;
return 0;
}
+static ssize_t sandbox_serial_puts(struct udevice *dev, const char *s,
+ size_t len)
+{
+ struct sandbox_serial_priv *priv = dev_get_priv(dev);
+ ssize_t ret;
+
+ if (s[len - 1] == '\n')
+ priv->start_of_line = true;
+
+ if (sandbox_serial_enabled) {
+ sandbox_print_color(dev);
+ ret = os_write(1, s, len);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = len;
+ }
+ _sandbox_serial_written += ret;
+ return ret;
+}
+
static int sandbox_serial_pending(struct udevice *dev, bool input)
{
struct sandbox_serial_priv *priv = dev_get_priv(dev);
@@ -212,6 +255,7 @@ static int sandbox_serial_of_to_plat(struct udevice *dev)
static const struct dm_serial_ops sandbox_serial_ops = {
.putc = sandbox_serial_putc,
+ .puts = sandbox_serial_puts,
.pending = sandbox_serial_pending,
.getc = sandbox_serial_getc,
.getconfig = sandbox_serial_getconfig,
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 10d6b800e2f..30650e37b0d 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -198,6 +198,22 @@ static void _serial_putc(struct udevice *dev, char ch)
} while (err == -EAGAIN);
}
+static int __serial_puts(struct udevice *dev, const char *str, size_t len)
+{
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+
+ do {
+ ssize_t written = ops->puts(dev, str, len);
+
+ if (written < 0)
+ return written;
+ str += written;
+ len -= written;
+ } while (len);
+
+ return 0;
+}
+
static void _serial_puts(struct udevice *dev, const char *str)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
@@ -210,19 +226,15 @@ static void _serial_puts(struct udevice *dev, const char *str)
do {
const char *newline = strchrnul(str, '\n');
- size_t len = newline - str + !!*newline;
+ size_t len = newline - str;
- do {
- ssize_t written = ops->puts(dev, str, len);
+ if (__serial_puts(dev, str, len))
+ return;
- if (written < 0)
- return;
- str += written;
- len -= written;
- } while (len);
+ if (*newline && __serial_puts(dev, "\r\n", 2))
+ return;
- if (*newline)
- _serial_putc(dev, '\r');
+ str += len + !!*newline;
} while (*str);
}
diff --git a/drivers/serial/serial_semihosting.c b/drivers/serial/serial_semihosting.c
index 62b1b2241b3..4328b3dac5b 100644
--- a/drivers/serial/serial_semihosting.c
+++ b/drivers/serial/serial_semihosting.c
@@ -5,12 +5,14 @@
#include <common.h>
#include <dm.h>
+#include <malloc.h>
#include <serial.h>
#include <semihosting.h>
/**
* struct smh_serial_priv - Semihosting serial private data
* @infd: stdin file descriptor (or error)
+ * @outfd: stdout file descriptor (or error)
*/
struct smh_serial_priv {
int infd;
@@ -36,8 +38,36 @@ static int smh_serial_putc(struct udevice *dev, const char ch)
return 0;
}
+static ssize_t smh_serial_puts(struct udevice *dev, const char *s, size_t len)
+{
+ int ret;
+ struct smh_serial_priv *priv = dev_get_priv(dev);
+ unsigned long written;
+
+ if (priv->outfd < 0) {
+ char *buf;
+
+ /* Try and avoid a copy if we can */
+ if (!s[len + 1]) {
+ smh_puts(s);
+ return len;
+ }
+
+ buf = strndup(s, len);
+ smh_puts(buf);
+ free(buf);
+ return len;
+ }
+
+ ret = smh_write(priv->outfd, s, len, &written);
+ if (written)
+ return written;
+ return ret;
+}
+
static const struct dm_serial_ops smh_serial_ops = {
.putc = smh_serial_putc,
+ .puts = smh_serial_puts,
.getc = smh_serial_getc,
};
@@ -53,6 +83,7 @@ static int smh_serial_probe(struct udevice *dev)
struct smh_serial_priv *priv = dev_get_priv(dev);
priv->infd = smh_open(":tt", MODE_READ);
+ priv->outfd = smh_open(":tt", MODE_WRITE);
return 0;
}