8mW sleep for Beagle Board.

1,784 views
Skip to first unread message

Russ Dill

unread,
Apr 27, 2009, 2:39:07 PM4/27/09
to beagl...@googlegroups.com, Russ Dill
For one of my masters courses, I performed research on partial array self
refresh and chose the Beagle Board as my implementation platform. As PASR
only ends up saving about 1mW, the sleep mode current consumption of the
omap/pm branch of ~150-250mW (IIRC) dwarfed any savings I would receive
and make it not only difficult to measure, but would make the utilization
of PASR seem quite pointless.

I set about reducing the sleep mode power consumption of the Beagle
Board from both a software and hardware angle. Any hardware modifications
will of course void any warranty, and I don't make any guarantees that these
modifications won't cause latchup or any other form of damage occur to your
board.

On the hardware side, the 3.3V rail ends up consuming quite a bit of current.
The low power mode of the DVI transceiver chip utilizes about 3mW and the rs232
transceivers are not configured to enter a low power mode and consume about
15-20mW. By disabling the 3.3V LDO during sleep mode, both consumers are cut
as well as any power used by the 3.3V LDO. I just tied the REGEN signal
to the LDO_EN pin to allow the software to control the 3.3V rail.

http://www.flickr.com/photos/31208937@N06/3443906143/
http://www.flickr.com/photos/31208937@N06/3443906137/

The always on power LED consumes about 40-50mW. I tied that to the newly
controllable 3.3V rail to allow it to be powered down along with the 3.3V rail
during sleep.

http://www.flickr.com/photos/31208937@N06/3443906143/

The Beagle Board doesn't utilize any of the high frequency clock request/clock
enable signals. With the proper delays inserted within the TWL 4030 sleep/wake
scripts the high frequency clock circuitry on the TWL 4030 can be powered off
during sleep. The external oscillator can also be put in a low power mode
if it's enable pin is tied to VPLL1 instead of the always on VIO.

http://www.flickr.com/photos/31208937@N06/3443906129/

The 26MHz oscillator that ships with the Beagle Board enters a tri-state output
mode when the enable pin is low. This mode cuts the power usage in half, from
about 15mW to 7mW. However, a variant of the part exists that has a low power
mode instead of just a tri-state output mode. That drops its power consumption
to the microwatt range.

http://www.flickr.com/photos/31208937@N06/3443906135/
http://www.ecliptek.com/pdf/oscillators/EP13E7.pdf
(EP16E7E2J-26.000M vs EP16E7E2H-26.000M)

I have a couple more of this oscillators if someone wants to experiment
with them.

The software changes involved setting up a TWL 4030 sleep script to power
off the necessary rails and to put other resources into sleep mode.
Additionally, the GPIO driver was modified to program the associated
wake padconf wakeenable bits so that the user button can be used to wake
the processor from power off mode. The rs232 driver was also modified to
allow the sysfs power/wakeup to disable the power off wakeup trigger.

As I get more time and a formal paper together, I'll send the changes
I made to actually get PASR working.

---
arch/arm/mach-omap2/board-omap3beagle.c | 104 ++++++++++++++++++-
arch/arm/mach-omap2/serial.c | 165 +++++++++++++++++++++++-------
arch/arm/plat-omap/gpio.c | 58 +++++++----
3 files changed, 264 insertions(+), 63 deletions(-)

Russ Dill

unread,
Apr 27, 2009, 2:39:08 PM4/27/09
to beagl...@googlegroups.com, Russ Dill
This patch creates low power sleep scripts for the Beagle Board. It allows
VDD1, VDD2, and VPLL1 to be powered off during processor off mode. It also
allows the power off of the TWL 4030 internal VINTANA2 reference and the
TWL 4030 high speed clock circuitry. Additionaly, it instructs the VIO
regulator to enter a low power mode as well as the internal VINTANA1,
VINTDIG, and RES_Main_Ref sources.

The scripts require additional changes to allow reset and reboot to function
properly.
---
arch/arm/mach-omap2/board-omap3beagle.c | 103 +++++++++++++++++++++++++++++--
1 files changed, 98 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index ad39abf..d2de0bf 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -46,7 +46,6 @@
#include <mach/omap-pm.h>
#include <mach/clock.h>

-#include "twl4030-generic-scripts.h"
#include "mmc-twl4030.h"
#include "pm.h"
#include "omap3-opp.h"
@@ -255,26 +254,120 @@ static struct regulator_init_data beagle_vpll2 = {
.consumer_supplies = &beagle_vdvi_supply,
};

+/*
+ * This script instructs twl4030 to first put the Reset and Control (RC)
+ * resources to sleep and then all the other resources.
+ * This script:
+ * - Disables the high speed clock.
+ * - Puts all Reset and Control (RC) resources to sleep.
+ * - Puts all Power Provider (PP) resources to sleep.
+ * - Turns all PP resources marked with type 2 off.
+ * - Sleeps the Power Reference (PR).
+ */
+
+static struct twl4030_ins sleep_on_seq[] = {
+ /* Keep HFCLKOUT going for a while... */
+ {MSG_SINGULAR(DEV_GRP_NULL, RES_HFCLKOUT, RES_STATE_ACTIVE), 0x6},
+
+ /* Sleep all our power reset stuff and power supplies */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_SLEEP), 4},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_SLEEP), 4},
+
+ /* Turn off all the power supplies we wanted to turn off */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, 2, RES_TYPE2_R0,
+ RES_STATE_OFF), 0x20},
+
+ /* Sleep the main ref */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PR, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_SLEEP), 0},
+};
+
+static struct twl4030_script sleep_on_script = {
+ .script = sleep_on_seq,
+ .size = ARRAY_SIZE(sleep_on_seq),
+ .flags = TRITON_SLEEP_SCRIPT,
+};
+
+/*
+ * This script:
+ * - Wakes the PR.
+ * - Wakes all PP resources.
+ * - Wakes all RC resources.
+ */
+
+static struct twl4030_ins wakeup_seq[] = {
+
+ /* Wake up main ref */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PR, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_ACTIVE), 0x20},
+
+ /* Turn on all supplies and resets */
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_PP, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_ACTIVE), 4},
+ {MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, RES_TYPE_ALL, RES_TYPE2_R0,
+ RES_STATE_ACTIVE), 0},
+};
+
+static struct twl4030_script wakeup_script = {
+ .script = wakeup_seq,
+ .size = ARRAY_SIZE(wakeup_seq),
+ .flags = TRITON_WAKEUP12_SCRIPT | TRITON_WAKEUP3_SCRIPT,
+};
+
+static struct twl4030_script *twl4030_scripts[] = {
+ &sleep_on_script,
+ &wakeup_script,
+};
+
static const struct twl4030_resconfig beagle_resconfig[] = {
/* disable regulators that u-boot left enabled; the
* devices' drivers should be managing these.
*/
- { .resource = RES_VAUX3, }, /* not even connected! */
+
+ /* Off by default */
+ { .resource = RES_VAUX1, },
+ { .resource = RES_VAUX2, },
+ { .resource = RES_VAUX3, },
+ { .resource = RES_VAUX4, },
{ .resource = RES_VMMC1, },
- { .resource = RES_VSIM, },
+ { .resource = RES_VMMC2, },
{ .resource = RES_VPLL2, },
+ { .resource = RES_VSIM, },
{ .resource = RES_VDAC, },
{ .resource = RES_VUSB_1V5, },
{ .resource = RES_VUSB_1V8, },
{ .resource = RES_VUSB_3V1, },
+ { .resource = RES_VUSBCP, },
+
+ /* PP Stuff we will turn off */
+ { .resource = RES_HFCLKOUT, .devgroup = 1, .type = 1, },
+ { .resource = RES_VDD1, .devgroup = 1, .type = 2, },
+ { .resource = RES_VDD2, .devgroup = 1, .type = 2, },
+ { .resource = RES_VPLL1, .devgroup = 1, .type = 2, },
+ { .resource = RES_VINTANA2, .devgroup = 1, .type = 2, },
+ { .resource = RES_CLKEN, .devgroup = 1, .type = 2, },
+
+ /* PP Sleep only */
+ { .resource = RES_VIO, .devgroup = 1, .type = 4, },
+ { .resource = RES_VINTANA1, .devgroup = 1, .type = 4, },
+ { .resource = RES_VINTDIG, .devgroup = 1, .type = 4, },
+ { .resource = RES_32KCLKOUT, .devgroup = 1, .type = 4, },
+
+ /* PR Sleep only*/
+ { .resource = RES_Main_Ref, .devgroup = 1, .type = 1, },
+
{ 0, },
};

static struct twl4030_power_data beagle_power_data = {
.resource_config = beagle_resconfig,
- /* REVISIT can't use GENERIC3430_T2SCRIPTS_DATA;
- * among other things, it makes reboot fail.
+ /* REVISIT: scripts need modification to allow reboot
+ * to succeed
*/
+ .scripts = twl4030_scripts,
+ .size = ARRAY_SIZE(twl4030_scripts),
};

static struct twl4030_platform_data beagle_twldata = {
--
1.6.0.4

Russ Dill

unread,
Apr 27, 2009, 2:39:09 PM4/27/09
to beagl...@googlegroups.com, Russ Dill
This patch configures the wakeup padconf registers to reflect the sysfs
power/wakeup settings. This allows a GPIO to wake the processor from
off mode.
---
arch/arm/plat-omap/gpio.c | 58 ++++++++++++++++++++++++++++++--------------
1 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 64852db..3b2054b 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -277,7 +277,14 @@ static const struct gpio_pad_range gpio_pads_config[] = {
{ 170, 182, 0x1c6 },
{ 0, 0, 0x1e0 },
{ 186, 186, 0x1e2 },
+ { 187, 187, 0x238 },
+ { 32, 32, 0x23a },
{ 12, 29, 0x5d8 },
+ { 1, 1, 0xa06 },
+ { 30, 30, 0xa08 },
+ { 2, 10, 0xa0a },
+ { 11, 11, 0xa24 },
+ { 31, 31, 0xa26 },
};

/* GPIO -> PAD config mapping for OMAP3 */
@@ -289,7 +296,8 @@ struct gpio_pad {

#define OMAP34XX_GPIO_AMT (32 * OMAP34XX_NR_GPIOS)

-struct gpio_pad *gpio_pads;
+static struct gpio_pad *gpio_pads;
+static u16 gpio_pad_map[OMAP34XX_GPIO_AMT];
#endif

static struct gpio_bank *gpio_bank;
@@ -1353,32 +1361,21 @@ static int __init omap3_gpio_pads_init(void)
{
int i, j, min, max, gpio_amt;
u16 offset;
- u16 *gpio_pad_map;

gpio_amt = 0;

- gpio_pad_map = kzalloc(sizeof(u16) * OMAP34XX_GPIO_AMT, GFP_KERNEL);
- if (gpio_pad_map == NULL) {
- printk(KERN_ERR "FATAL: Failed to allocate gpio_pad_map\n");
- return -ENOMEM;
- }
-
for (i = 0; i < ARRAY_SIZE(gpio_pads_config); i++) {
min = gpio_pads_config[i].min;
max = gpio_pads_config[i].max;
offset = gpio_pads_config[i].offset;

for (j = min; j <= max; j++) {
- /*
- * Check if pad has been configured as GPIO.
- * First module (gpio 0...31) is ignored as it is
- * in wakeup domain and does not need special
- * handling during off mode.
- */
- if (j > 31 && (omap_ctrl_readw(offset) &
+ /* Check if pad has been configured as GPIO. */
+ if ((omap_ctrl_readw(offset) &
OMAP34XX_MUX_MODE7) == OMAP34XX_MUX_MODE4) {
gpio_pad_map[j] = offset;
- gpio_amt++;
+ if (j > 31)
+ gpio_amt++;
}
offset += 2;
}
@@ -1388,20 +1385,23 @@ static int __init omap3_gpio_pads_init(void)

if (gpio_pads == NULL) {
printk(KERN_ERR "FATAL: Failed to allocate gpio_pads\n");
- kfree(gpio_pad_map);
return -ENOMEM;
}

gpio_amt = 0;
for (i = 0; i < OMAP34XX_GPIO_AMT; i++) {
- if (gpio_pad_map[i] != 0) {
+ /*
+ * First module (gpio 0...31) is ignored as it is
+ * in wakeup domain and does not need special
+ * handling during off mode.
+ */
+ if (gpio_pad_map[i] && i > 31) {
gpio_pads[gpio_amt].gpio = i;
gpio_pads[gpio_amt].offset = gpio_pad_map[i];
gpio_amt++;
}
}
gpio_pads[gpio_amt].gpio = -1;
- kfree(gpio_pad_map);
return 0;
}
late_initcall(omap3_gpio_pads_init);
@@ -1676,6 +1676,26 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
__raw_writel(0xffffffff, wake_clear);
__raw_writel(bank->suspend_wakeup, wake_set);
spin_unlock_irqrestore(&bank->lock, flags);
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ if (bank->method == METHOD_GPIO_24XX) {
+ int j;
+ for (j = 0; j < 32; j++) {
+ int offset = gpio_pad_map[j + i * 32];
+ u16 v;
+
+ if (!offset)
+ continue;
+
+ v = omap_ctrl_readw(offset);
+ if (bank->suspend_wakeup & (1 << j))
+ v |= OMAP3_PADCONF_WAKEUPENABLE0;
+ else
+ v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
+ omap_ctrl_writew(v, offset);
+ }
+ }
+#endif
}

return 0;
--
1.6.0.4

Russ Dill

unread,
Apr 27, 2009, 2:39:10 PM4/27/09
to beagl...@googlegroups.com, Russ Dill
This change causes the REGEN signal to go low during suspend. This can be
used to disable devices on the peripheral board during suspend.
---
arch/arm/mach-omap2/board-omap3beagle.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index d2de0bf..4d49a8d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -348,6 +348,7 @@ static const struct twl4030_resconfig beagle_resconfig[] = {


{ .resource = RES_VPLL1, .devgroup = 1, .type = 2, },

{ .resource = RES_VINTANA2, .devgroup = 1, .type = 2, },

{ .resource = RES_CLKEN, .devgroup = 1, .type = 2, },

+ { .resource = RES_REGEN, .devgroup = 1, .type = 2, },



/* PP Sleep only */

{ .resource = RES_VIO, .devgroup = 1, .type = 4, },

--
1.6.0.4

Russ Dill

unread,
Apr 27, 2009, 2:39:11 PM4/27/09
to beagl...@googlegroups.com, Russ Dill
This patch causes the OMAP uarts to honor the sysfs power/wakeup file for
IOPADs. Before the OMAP was always woken up from off mode on a rs232 signal
change.

This patch also creates a different platform device for each serial
port so that the wakeup properties can be control per port.

The patch is not in a complete state, but for my testing it was necessary
to disable rs232 wakeup as allowing the signals to float in off mode by
powering off the level converters was causing a wakeup event.
---
arch/arm/mach-omap2/serial.c | 165 ++++++++++++++++++++++++++++++++----------
1 files changed, 126 insertions(+), 39 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 0762165..95b047a 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -49,6 +49,7 @@ struct omap_uart_state {

struct plat_serial8250_port *p;
struct list_head node;
+ struct platform_device pdev;

#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
int context_valid;
@@ -63,10 +64,9 @@ struct omap_uart_state {
#endif
};

-static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS];
static LIST_HEAD(uart_list);

-static struct plat_serial8250_port serial_platform_data[] = {
+static struct plat_serial8250_port serial_platform_data0[] = {
{
.membase = IO_ADDRESS(OMAP_UART1_BASE),
.mapbase = OMAP_UART1_BASE,
@@ -76,6 +76,12 @@ static struct plat_serial8250_port serial_platform_data[] = {
.regshift = 2,
.uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
+ .flags = 0
+ }
+};
+
+static struct plat_serial8250_port serial_platform_data1[] = {
+ {
.membase = IO_ADDRESS(OMAP_UART2_BASE),
.mapbase = OMAP_UART2_BASE,
.irq = 73,
@@ -84,6 +90,12 @@ static struct plat_serial8250_port serial_platform_data[] = {
.regshift = 2,
.uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
+ .flags = 0
+ }
+};
+
+static struct plat_serial8250_port serial_platform_data2[] = {
+ {
.membase = IO_ADDRESS(OMAP_UART3_BASE),
.mapbase = OMAP_UART3_BASE,
.irq = 74,
@@ -197,6 +209,40 @@ static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
#endif /* CONFIG_ARCH_OMAP3 */

+static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
+{
+ /* Set wake-enable bit */
+ if (uart->wk_en && uart->wk_mask) {
+ u32 v = __raw_readl(uart->wk_en);
+ v |= uart->wk_mask;
+ __raw_writel(v, uart->wk_en);
+ }
+
+ /* Ensure IOPAD wake-enables are set */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 v = omap_ctrl_readw(uart->padconf);
+ v |= OMAP3_PADCONF_WAKEUPENABLE0;
+ omap_ctrl_writew(v, uart->padconf);
+ }
+}
+
+static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
+{
+ /* Clear wake-enable bit */
+ if (uart->wk_en && uart->wk_mask) {
+ u32 v = __raw_readl(uart->wk_en);
+ v &= ~uart->wk_mask;
+ __raw_writel(v, uart->wk_en);
+ }
+
+ /* Ensure IOPAD wake-enables are cleared */
+ if (cpu_is_omap34xx() && uart->padconf) {
+ u16 v = omap_ctrl_readw(uart->padconf);
+ v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
+ omap_ctrl_writew(v, uart->padconf);
+ }
+}
+
static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
int enable)
{
@@ -220,6 +266,11 @@ static inline void omap_uart_restore(struct omap_uart_state *uart)

static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
{
+ if (device_may_wakeup(&uart->pdev.dev))
+ omap_uart_enable_wakeup(uart);
+ else
+ omap_uart_disable_wakeup(uart);
+
if (!uart->clocked)
return;

@@ -290,6 +341,7 @@ void omap_uart_resume_idle(int num)
if (__raw_readl(uart->wk_st) & uart->wk_mask)
omap_uart_block_sleep(uart);

+ omap_uart_enable_wakeup(uart);
return;
}
}
@@ -300,6 +352,7 @@ void omap_uart_prepare_suspend(void)
struct omap_uart_state *uart;

list_for_each_entry(uart, &uart_list, node) {
+ omap_uart_enable_wakeup(uart);
omap_uart_allow_sleep(uart);
}
}
@@ -343,16 +396,13 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}

-static u32 sleep_timeout = DEFAULT_TIMEOUT;
-
static void omap_uart_idle_init(struct omap_uart_state *uart)
{
- u32 v;
struct plat_serial8250_port *p = uart->p;
int ret;

uart->can_sleep = 0;
- uart->timeout = sleep_timeout;
+ uart->timeout = DEFAULT_TIMEOUT;
setup_timer(&uart->timer, omap_uart_idle_timer,
(unsigned long) uart);
mod_timer(&uart->timer, jiffies + uart->timeout);
@@ -410,22 +460,6 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
uart->padconf = 0;
}

- /* Set wake-enable bit */
- if (uart->wk_en && uart->wk_mask) {
- v = __raw_readl(uart->wk_en);
- v |= uart->wk_mask;
- __raw_writel(v, uart->wk_en);
- }
-
- /* Ensure IOPAD wake-enables are set */
- if (cpu_is_omap34xx() && uart->padconf) {
- u16 v;
-
- v = omap_ctrl_readw(uart->padconf);
- v |= OMAP3_PADCONF_WAKEUPENABLE0;
- omap_ctrl_writew(v, uart->padconf);
- }
-
p->flags |= UPF_SHARE_IRQ;
ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
"serial idle", (void *)uart);
@@ -450,23 +484,30 @@ static ssize_t sleep_timeout_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
- return sprintf(buf, "%u\n", sleep_timeout / HZ);
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_uart_state *uart = container_of(pdev,
+ struct omap_uart_state, pdev);
+ return sprintf(buf, "%u\n", uart->timeout / HZ);
}

static ssize_t sleep_timeout_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t n)
{
- struct omap_uart_state *uart;
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_uart_state *uart = container_of(pdev,
+ struct omap_uart_state, pdev);
unsigned int value;

if (sscanf(buf, "%u", &value) != 1) {
printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
return -EINVAL;
}
- sleep_timeout = value * HZ;
- list_for_each_entry(uart, &uart_list, node)
- uart->timeout = sleep_timeout;
+ uart->timeout = value * HZ;
return n;
}

@@ -477,6 +518,34 @@ static struct kobj_attribute sleep_timeout_attr =
static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
#endif /* CONFIG_PM */

+static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
+ {
+ .pdev = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data0,
+ },
+ },
+ }, {
+ .pdev = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = serial_platform_data1,
+ },
+ },
+ }, {
+ .pdev = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM2,
+ .dev = {
+ .platform_data = serial_platform_data2,
+ },
+ },
+ },
+};
+
void __init omap_serial_init(void)
{
int i;
@@ -495,8 +564,8 @@ void __init omap_serial_init(void)
return;

for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
- struct plat_serial8250_port *p = serial_platform_data + i;
struct omap_uart_state *uart = &omap_uart[i];
+ struct plat_serial8250_port *p = uart->pdev.dev.platform_data;

if (!(info->enabled_uarts & (1 << i))) {
p->membase = NULL;
@@ -532,25 +601,43 @@ void __init omap_serial_init(void)
}
}

-static struct platform_device serial_device = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = serial_platform_data,
- },
-};
-
static int __init omap_init(void)
{
int ret;
+ int i;

- ret = platform_device_register(&serial_device);
+ for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
+ ret = platform_device_register(&omap_uart[i].pdev);
+ if (ret < 0)
+ goto device_err;
+ if ((cpu_is_omap34xx() && omap_uart[i].padconf) ||
+ (omap_uart[i].wk_en && omap_uart[i].wk_mask)) {
+ printk(KERN_ERR "%s: Setting init_wakeup\n", __func__);
+ device_init_wakeup(&omap_uart[i].pdev.dev, true);
+ }
+ }

#ifdef CONFIG_PM
- if (!ret)
- ret = sysfs_create_file(&serial_device.dev.kobj,
+ for (i = 0; i < ARRAY_SIZE(omap_uart); i++) {
+ ret = sysfs_create_file(&omap_uart[i].pdev.dev.kobj,
&sleep_timeout_attr.attr);
+ if (ret < 0)
+ goto sysfs_err;
+ }
+#endif
+ return ret;
+
+#ifdef CONFIG_PM
+sysfs_err:
+ for (i--; i >= 0; i--)
+ sysfs_remove_file(&omap_uart[i].pdev.dev.kobj,
+ &sleep_timeout_attr.attr);
+ i = ARRAY_SIZE(omap_uart);
#endif
+
+device_err:
+ for (i--; i >= 0; i--)
+ platform_device_unregister(&omap_uart[i].pdev);
return ret;
}
arch_initcall(omap_init);
--
1.6.0.4

Nishanth Menon

unread,
Apr 27, 2009, 2:52:41 PM4/27/09
to beagl...@googlegroups.com
On Mon, Apr 27, 2009 at 1:39 PM, Russ Dill <russ...@gmail.com> wrote:
>
> For one of my masters courses, I performed research on partial array self
> refresh and chose the Beagle Board as my implementation platform. As PASR
> only ends up saving about 1mW, the sleep mode current consumption of the
> omap/pm branch of ~150-250mW (IIRC) dwarfed any savings I would receive
> and make it not only difficult to measure, but would make the utilization
> of PASR seem quite pointless.
Should these patches go to linux-omap mailing list instead??
Regards,
Nishanth Menon

Russ Dill

unread,
Apr 27, 2009, 3:01:12 PM4/27/09
to beagl...@googlegroups.com
I'll probably forward the GPIO and rs232 padconf wake patches to the
linux-omap list.

Felipe Contreras

unread,
Apr 27, 2009, 3:13:19 PM4/27/09
to beagl...@googlegroups.com

Please :)

--
Felipe Contreras

Kevin Hilman

unread,
May 20, 2009, 2:23:50 PM5/20/09
to Russ Dill, beagl...@googlegroups.com
Russ Dill <russ...@gmail.com> writes:

> For one of my masters courses, I performed research on partial array
> self refresh and chose the Beagle Board as my implementation
> platform. As PASR only ends up saving about 1mW, the sleep mode
> current consumption of the omap/pm branch of ~150-250mW (IIRC)
> dwarfed any savings I would receive and make it not only difficult
> to measure, but would make the utilization of PASR seem quite
> pointless.

Hi Russ,

I'm not an active reader of this list, so just discovered this
discussion now.

I'm curious how you were testing this on the OMAP side. Were you only
testing a full suspend? Were you able see the 8mW in idle as well?
Was this with the OMAP in retention or in off-mode?

Thanks,

Kevin

Russ Dill

unread,
May 22, 2009, 4:00:09 AM5/22/09
to Kevin Hilman, beagl...@googlegroups.com

The 8mW was from a full suspend with the OMAP in off-mode. It also
included modifications to the board and scripts for the twl4030.

Kevin Hilman

unread,
May 26, 2009, 5:43:55 PM5/26/09
to Russ Dill, beagl...@googlegroups.com
Russ Dill <russ...@gmail.com> writes:

Thanks for the clarifications.

Kevin

Reply all
Reply to author
Forward
0 new messages